2011-12-10

NXShield API的功能擴充-加入Hitechnic IRReceiver裝置

NXShield API中提供了多款NXT類比式與I2C數位感應器的Device Class,幾乎涵蓋了Mindsensors所有上市中的產品,而如果要運用其他沒有預先提供Device Class的裝置,如HitechnicDexter的產品,特別是I2C裝置,也可以透過以下兩種方式來建立使用的功能:
(1)  Arduino sketch中使用NXShieldI2C class的通用I2C access methods,對於該裝置的registers進行存取或寫入指令,以實現所需要的控制功能。
(2)  製作該裝置的Device class加入NXShield _AVR程式庫中,後續就可以比照預設Device class的用法,在Arduino sketch中使用相關methodsproperties
以下以HitechnicIRReceiver sensor為範例,整理以上兩種運用方式。


(
NXShield API架構參考:NXShield Arduino API摘要整理)
IRReceiver I2C registers摘要:
HitechnicIRReceiver sensor(I2C address: 0x02),是一個實用又好玩的感應器,它可以接收與解碼PFIR的四個頻道Port APort BIR信號。IR信號的發送來源除了L8885L8879兩款PF 遙控器之外,
(PF RC)

也可以是MindsensorsPFMateHitechnic IRLinkIR信號發送裝置。
(PF IRSensor)
IRReceiver sensor
會將偵測到的PF IR信號解碼後,分別將4 channels 2 ports8的值存放在0x42 - 0x49暫存器中,所以,使用方式就是持續讀取這幾個暫存器中的值,再套用所需要的應用中,例如:NXT 馬達speed的設定。(參考文章:測試Hitechnic IRReceiver的回傳狀態及行為)
方式一:使用NXShieldI2C I2C methods
NXShield APINXShieldI2C是作為所有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

#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);
}
方式二:建立IRReceiver Device class
NXShield_AVR程式庫中Device classes使用的是C++語言,IDE除了Visual Studio之外也可以下載免費的Code::Block
(CodeBlock IDE)


每一個Device Class包含兩個檔案:
IRReceiver.h - 宣告Class propertiesmethods
IRReceiver.cpp - 實作methods的功能,亦即methods的程式碼。
將這兩個檔案存放在 Arduinolibraries\NXShield_AVR路徑。
IRReceiverDevice Class中定義了三個methods
(1)
讀取指定之channelport的值:
  
char getPortPowerLevel(uint8_t channel, char port);

(2)
讀取指定之channel的兩個port的值:
  
void getChannelPowerLevel(uint8_t channel, char &portA_PowerLevel, char &portB_PowerLevel);

(3) 讀取全部channels8ports的值:
   
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);
}
比較兩個範例程式中的用法,主要的差異在於後者可以依據對於Device Class應用功能的規劃,建立一些實用的methods,有利於程式碼的再運用與分享。

沒有留言:

張貼留言