(1) 在Arduino sketch中使用NXShieldI2C class的通用I2C access methods,對於該裝置的registers進行存取或寫入指令,以實現所需要的控制功能。
(2) 製作該裝置的Device class加入NXShield _AVR程式庫中,後續就可以比照預設Device class的用法,在Arduino sketch中使用相關methods或properties。
以下以Hitechnic的IRReceiver sensor為範例,整理以上兩種運用方式。
(NXShield API架構參考:NXShield Arduino API摘要整理)
#include <Wire.h>
#include <NXShield.h>
// 使用NXShieldI2C通用I2C class
#include <NXShieldI2C.h>
NXShield nxshield;
//建立NXShieldI2C物件(I2C位址)
NXShieldI2C ir_rcv(0x02);
void setup()
{
Serial.begin(9600);
delay(500);
Serial.println ("Initializing the devices ...");
nxshield.init( SH_HardwareI2C );
Serial.println ("Press GO button to continue");
nxshield.waitForButtonPress(BTN_GO);
//接在那一個port
ir_rcv.init(&nxshield, SH_BAS2 );
}
void loop()
{
char aa[80], str[256];
char resultA, resultB;
char result[8];
strcpy(aa, ir_rcv.getDeviceID());
sprintf(str, "ir_rcv: DeviceID:%s", aa);
Serial.println(str);
//使用NXshieldI2C method
(NXShield API架構參考:NXShield Arduino API摘要整理)
IRReceiver I2C registers摘要:
Hitechnic的IRReceiver sensor(I2C address: 0x02),是一個實用又好玩的感應器,它可以接收與解碼PFIR的四個頻道Port A與Port B的IR信號。而IR信號的發送來源除了L8885與L8879兩款PF 遙控器之外,
(PF RC)
也可以是Mindsensors的PFMate與Hitechnic IRLink等IR信號發送裝置。
(PF IRSensor)
IRReceiver sensor會將偵測到的PF IR信號解碼後,分別將4 channels 2 ports的8的值存放在0x42 - 0x49暫存器中,所以,使用方式就是持續讀取這幾個暫存器中的值,再套用所需要的應用中,例如:NXT 馬達speed的設定。(參考文章:測試Hitechnic IRReceiver的回傳狀態及行為)
(PF RC)
也可以是Mindsensors的PFMate與Hitechnic IRLink等IR信號發送裝置。
(PF IRSensor)
IRReceiver sensor會將偵測到的PF IR信號解碼後,分別將4 channels 2 ports的8的值存放在0x42 - 0x49暫存器中,所以,使用方式就是持續讀取這幾個暫存器中的值,再套用所需要的應用中,例如:NXT 馬達speed的設定。(參考文章:測試Hitechnic IRReceiver的回傳狀態及行為)
方式一:使用NXShieldI2C I2C methods
在NXShield API中NXShieldI2C是作為所有I2C device classes的父類別,所以也可以直接在Arduino sketch中透過建立NXShieldI2C物件然後運用它的通用I2C methods來讀寫裝置的暫存器。
以下為範例程式:(程式碼:HT_IRReceiver_NSI2C.pde)
/* **************************** */
#define IRRECV_CH_1A 0x42
#define IRRECV_CH_1B 0x43
#define IRRECV_CH_2A 0x44
#define IRRECV_CH_2B 0x45
#define IRRECV_CH_3A 0x46
#define IRRECV_CH_3B 0x47
#define IRRECV_CH_4A 0x48
#define IRRECV_CH_4B 0x49
以下為範例程式:(程式碼:HT_IRReceiver_NSI2C.pde)
/* **************************** */
#define IRRECV_CH_1A 0x42
#define IRRECV_CH_1B 0x43
#define IRRECV_CH_2A 0x44
#define IRRECV_CH_2B 0x45
#define IRRECV_CH_3A 0x46
#define IRRECV_CH_3B 0x47
#define IRRECV_CH_4A 0x48
#define IRRECV_CH_4B 0x49
#include <Wire.h>
#include <NXShield.h>
// 使用NXShieldI2C通用I2C class
#include <NXShieldI2C.h>
NXShield nxshield;
//建立NXShieldI2C物件(I2C位址)
NXShieldI2C ir_rcv(0x02);
void setup()
{
Serial.begin(9600);
delay(500);
Serial.println ("Initializing the devices ...");
nxshield.init( SH_HardwareI2C );
Serial.println ("Press GO button to continue");
nxshield.waitForButtonPress(BTN_GO);
//接在那一個port
ir_rcv.init(&nxshield, SH_BAS2 );
}
void loop()
{
char aa[80], str[256];
char resultA, resultB;
char result[8];
strcpy(aa, ir_rcv.getDeviceID());
sprintf(str, "ir_rcv: DeviceID:%s", aa);
Serial.println(str);
//使用NXshieldI2C method
resultA = ir_rcv.readByte(IRRECV_CH_1A);
resultB = ir_rcv.readByte(IRRECV_CH_1B); sprintf (str, "Channel 1 Port A: %d Port B: %d", resultA, resultB);
Serial.println(str);
Serial.println("-------------" );
delay (200);
}
resultB = ir_rcv.readByte(IRRECV_CH_1B); sprintf (str, "Channel 1 Port A: %d Port B: %d", resultA, resultB);
Serial.println(str);
Serial.println("-------------" );
delay (200);
}
方式二:建立IRReceiver Device class
NXShield_AVR程式庫中Device classes使用的是C++語言,IDE除了Visual Studio之外也可以下載免費的Code::Block。
(CodeBlock IDE)
每一個Device Class包含兩個檔案:
IRReceiver.h - 宣告Class properties與methods。
IRReceiver.cpp - 實作methods的功能,亦即methods的程式碼。
將這兩個檔案存放在 Arduino的libraries\NXShield_AVR路徑。
在IRReceiver的Device Class中定義了三個methods:
(1) 讀取指定之channel與port的值:
char getPortPowerLevel(uint8_t channel, char port);
(2) 讀取指定之channel的兩個port的值:
void getChannelPowerLevel(uint8_t channel, char &portA_PowerLevel, char &portB_PowerLevel);
(3) 讀取全部channels的8個ports的值:
void getAllPortsPowerLevel(char *port_PowerLevel);
(CodeBlock IDE)
每一個Device Class包含兩個檔案:
IRReceiver.h - 宣告Class properties與methods。
IRReceiver.cpp - 實作methods的功能,亦即methods的程式碼。
將這兩個檔案存放在 Arduino的libraries\NXShield_AVR路徑。
在IRReceiver的Device Class中定義了三個methods:
(1) 讀取指定之channel與port的值:
char getPortPowerLevel(uint8_t channel, char port);
(2) 讀取指定之channel的兩個port的值:
void getChannelPowerLevel(uint8_t channel, char &portA_PowerLevel, char &portB_PowerLevel);
(3) 讀取全部channels的8個ports的值:
void getAllPortsPowerLevel(char *port_PowerLevel);
以下為範例程式:(程式碼:HT_IRReceiver_DevClass.pde)
/* **************************** */
#include <Wire.h>
#include <NXShield.h>
// 使用IRReceiver Device Class
#include <IRReceiver.h>
NXShield nxshield;
//建立IRReceiver物件
IRReceiver ir_rcv;
void setup()
{
Serial.begin(9600);
delay(500);
Serial.println ("Initializing the devices ...");
nxshield.init( SH_HardwareI2C );
Serial.println ("Press GO button to continue");
nxshield.waitForButtonPress(BTN_GO);
//接在那一個port
ir_rcv.init(&nxshield, SH_BAS2 );
}
void loop()
{
char aa[80], str[256];
char resultA, resultB;
char result[8];
strcpy(aa, ir_rcv.getDeviceID());
sprintf(str, "ir_rcv: DeviceID:%s", aa);
Serial.println(str);
//使用IRReceiver class method
resultA = ir_rcv.getPortPowerLevel(1, ‘A’);
resultB = ir_rcv.getPortPowerLevel(1, ‘B’); sprintf (str, "Channel 1 Port A: %d Port B: %d", resultA, resultB);
Serial.println(str);
Serial.println("-------------" );
delay (200);
}
/* **************************** */
#include <Wire.h>
#include <NXShield.h>
// 使用IRReceiver Device Class
#include <IRReceiver.h>
NXShield nxshield;
//建立IRReceiver物件
IRReceiver ir_rcv;
void setup()
{
Serial.begin(9600);
delay(500);
Serial.println ("Initializing the devices ...");
nxshield.init( SH_HardwareI2C );
Serial.println ("Press GO button to continue");
nxshield.waitForButtonPress(BTN_GO);
//接在那一個port
ir_rcv.init(&nxshield, SH_BAS2 );
}
void loop()
{
char aa[80], str[256];
char resultA, resultB;
char result[8];
strcpy(aa, ir_rcv.getDeviceID());
sprintf(str, "ir_rcv: DeviceID:%s", aa);
Serial.println(str);
//使用IRReceiver class method
resultA = ir_rcv.getPortPowerLevel(1, ‘A’);
resultB = ir_rcv.getPortPowerLevel(1, ‘B’); sprintf (str, "Channel 1 Port A: %d Port B: %d", resultA, resultB);
Serial.println(str);
Serial.println("-------------" );
delay (200);
}
比較兩個範例程式中的用法,主要的差異在於後者可以依據對於Device Class應用功能的規劃,建立一些實用的methods,有利於程式碼的再運用與分享。
沒有留言:
張貼留言