920MHz帯無線通信モジュールIM920のライブラリ

Dependents:   Hybrid_OB2021_MAIN Hybrid_OB2021_GROUND pressure_control_system pressure_control_receiver ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IM920.cpp Source File

IM920.cpp

00001 #include "IM920.h"
00002 #include "mbed.h"
00003 
00004 short IM920::toShort(char *array){
00005     im920_cast.s = ((uint16_t)array[0] << 8) | (uint16_t)array[1];
00006     return im920_cast.s;   
00007 }
00008 int IM920::toInt(char *array){
00009     im920_cast.i = ((uint32_t)array[0] << 24) | ((uint32_t)array[1] << 16) | ((uint32_t)array[2] << 8) | (uint32_t)array[3];
00010     return im920_cast.i;   
00011 }
00012 float IM920::toFloat(char *array){
00013     im920_cast.u[0] = array[0];
00014     im920_cast.u[1] = array[1];
00015     im920_cast.u[2] = array[2];
00016     im920_cast.u[3] = array[3];
00017     
00018     return im920_cast.f;   
00019 }
00020 long IM920::toLong(char *array){
00021     for(int i = 0; i < 8; i++){
00022         im920_cast.u[i] = array[i];   
00023     }   
00024     return im920_cast.l;
00025 }
00026 double IM920::toDouble(char *array){
00027     for(int i = 0; i< 8; i++){
00028         im920_cast.u[i] = array[i];   
00029     }   
00030     return im920_cast.d;
00031 }
00032 
00033 void IM920::dummyFunc(){
00034     printf("NO FUNCTION\r\n");    
00035 };
00036 
00037 char IM920::im920CheckSum(int count){
00038     char ans = 0;
00039     for(int i = 0; i < count; i++){
00040        ans = ans ^ data[i];
00041     }
00042     return ans;
00043 }
00044 
00045 IM920::IM920(Serial &serial, Serial &pc, int baudrate){
00046     
00047     ser = &serial;//参照渡し
00048     _pc = &pc;
00049     
00050     ser->baud(baudrate);
00051     
00052     memset(buff_A, '\0', IM920_BUFF_SIZE);
00053     memset(buff_B, '\0', IM920_BUFF_SIZE);
00054     readBuffAddr = buff_B;
00055     writeBuffAddr = buff_A;
00056     sendDataSize = 0;
00057     interactiveFlag = 0;
00058     for(int i = 0;i < 256; i++){
00059         p_callFunc[i] = &this->dummyFunc;   
00060     }
00061     memset(data, 0, 64);
00062     im920_dataLength = 0;
00063     memset(im920_sendBuff, '\0', 129);
00064     sendDataSize = 0;
00065     nodeNumber = 0;
00066     AS = DATA_STRING;
00067     checkSum = 0;
00068     for(int i = 0; i < 8; i++){
00069         im920_cast.u[i] = 0;   
00070     }
00071     node = 0;
00072     RSSI = 0;
00073     rID = 0;
00074     ID = 0;
00075     
00076     receiveCheckSum = 0;
00077     ser->attach(this, &IM920::im920Handler, Serial::RxIrq);
00078 }
00079 
00080 
00081 
00082 
00083 
00084 
00085 void IM920::im920_debug(){
00086     printf("%s\r\n", readBuffAddr);
00087     return;
00088 }
00089 
00090 
00091 
00092 int IM920::asciiToNumber(char c){
00093     //printf("%c ", c);
00094     if((int)c >= 65){//A ~ F
00095         return ((int)c - 55);
00096     }
00097     else{//0 ~ 9
00098         return ((int)c - 48);
00099     }
00100 }
00101 
00102 void IM920::data_analyze(){
00103     //00,0001,78:01,02,03,04,...,FF\0
00104     //|  |    |  |                  +- <CR><LF>文字列終了
00105     //|  |    |  +-------------------- 16進数をascii文字にしたもの、最大64区切り(64Byte)
00106     //|  |    +----------------------- 受信強度、RSSI値
00107     //|  +---------------------------- 送信モジュールの固有ID
00108     //+------------------------------- ノード番号
00109     char tempStr[160];
00110     strcpy(tempStr, readBuffAddr);
00111     char *tok = strtok(tempStr, ",");//ノード番号
00112     node = ((asciiToNumber(tok[0]) << 4)) | asciiToNumber(tok[1]);
00113     tok = strtok(NULL, ",");//送信機のID
00114     rID = 0;
00115     rID = (asciiToNumber(tok[0]) << 12) | (asciiToNumber(tok[1]) << 8) | (asciiToNumber(tok[2]) << 4) | asciiToNumber(tok[3]);
00116     tok = strtok(NULL, ":");//受信強度
00117     RSSI = (char)((asciiToNumber(tok[0]) << 4) | (asciiToNumber(tok[1])));
00118     im920_dataLength = 64;
00119     memset(data, 0, 64);
00120     receiveCheckSum = 0;
00121     if(tok != NULL){
00122         for(int i = 0; i < 64; i++){
00123             if(tok[0] == '\0'){
00124                 im920_dataLength = i - 1;
00125                 break;
00126             }
00127             tok = strtok(NULL, ",");
00128             data[i] = (asciiToNumber(tok[0]) << 4) | asciiToNumber(tok[1]);
00129             receiveCheckSum = receiveCheckSum ^ tok[0] ^ tok[1];
00130         }
00131     }
00132     else{
00133         im920_dataLength = 0;   
00134     }
00135     return;
00136 }
00137 
00138 void IM920::im920Handler(){
00139     static int current = 0;
00140     static char c = 0;
00141     c = ser->getc();
00142     /*
00143     if(AS == RESPONSE_STRING || AS == INTERACTIVE_STRING){
00144         printf("%c", c);//描画、後で1行描画だと次の行がすぐ来た時にハングアップしてしまう
00145     }
00146     */
00147 
00148     if(c == '\r'){//文字列終了
00149         writeBuffAddr[current] = '\0';
00150         if(AB == BUFF_A){//現在バッファAに書き込み中
00151             readBuffAddr = buff_A;
00152             writeBuffAddr = buff_B;
00153             AB = BUFF_B;
00154         }
00155         else{//現在バッファBに書き込み中
00156             readBuffAddr = buff_B;
00157             writeBuffAddr = buff_A;
00158             AB = BUFF_A;
00159         }
00160 
00161         //im920_debug();
00162         //----------------------
00163         //  文字列の解析
00164         //----------------------
00165         if(AS == DATA_STRING){//データの形式によって分岐 
00166             if(current > 9){
00167                 //データの取り出し、配列化
00168                 data_analyze();
00169                 /*
00170                 for(int i = 0;i < 64;i++){
00171                     printf("%d ",data[i]);   
00172                 }
00173                 printf("\r\n");
00174                 */
00175                 //printf("header: %0X\r\n",(uint8_t)data[0]);
00176                 //header0xFF();
00177                 // 関数の呼び出し
00178                 (*p_callFunc[(uint8_t)data[0]])();
00179             }        
00180         }
00181         //初期化
00182         current = 0;
00183         //memset(writeBuffAddr, '\0', IM920_BUFF_SIZE);
00184         return;
00185     }
00186     else if(c !='\n'){
00187         //文字列生成
00188         writeBuffAddr[current] = c;
00189         current++;
00190         if(current >= IM920_BUFF_SIZE){//初期化
00191             current = 0;
00192             memset(writeBuffAddr, '\0', IM920_BUFF_SIZE);   
00193         }
00194         return;   
00195     }
00196 }
00197 
00198 void IM920::attach(void (*funcAddr)(void), unsigned header){
00199     p_callFunc[header] = funcAddr;
00200     return;    
00201 }
00202 
00203 /**
00204       @bref パラメータ不揮発メモリ書き込み許可モードへ移行
00205 */
00206 bool IM920::enableWrite(){
00207     AS = RESPONSE_STRING;//レスポンス受信モードへ移行
00208     ser->printf("ENWR\r\n");
00209     wait_us(WAIT_TIME_US);//待つ
00210     AS = DATA_STRING; //データ受信モードへ以降
00211     if(strncmp(readBuffAddr, "OK", 2) == 0){
00212         return true;   
00213     }
00214     else{
00215         return false;   
00216     }
00217 }
00218 
00219 bool IM920::disableWrite(){
00220     AS = RESPONSE_STRING;//レスポンス受信モードへ移行
00221     ser->printf("DSWR\r\n");
00222     wait_us(WAIT_TIME_US);
00223     AS = DATA_STRING;  
00224     if(strncmp(readBuffAddr, "OK", 2) == 0){
00225         return true;   
00226     }
00227     else{
00228         return false;   
00229     }         
00230 }
00231     
00232 /**
00233     @bref 固有IDを読み出す
00234 */
00235 int IM920::readID(){
00236     AS = NORMAL_STRING;
00237     ser->printf("RDID\r\n");
00238     wait_us(WAIT_TIME_US);
00239     AS = DATA_STRING;
00240     int val = 0;
00241   
00242     //pc.printf("%c:%c:%c:%c\r\n",readBuffAddr[0],readBuffAddr[1],readBuffAddr[2],readBuffAddr[3]); 
00243     val = asciiToNumber(readBuffAddr[0]) << 24;
00244     val |= asciiToNumber(readBuffAddr[1]) << 16;
00245     val |= asciiToNumber(readBuffAddr[2]) << 8;
00246     val |= asciiToNumber(readBuffAddr[3]);
00247     ID = val;
00248     return val;   
00249 }         
00250 
00251 bool IM920::setReceiveID(int ID){
00252     AS = RESPONSE_STRING;
00253     printf("SRID %4X\r\n", ID);   
00254     ser->printf("SRID %4X\r\n", ID);
00255     wait_us(WAIT_TIME_US);
00256     if(strncmp(readBuffAddr, "OK", 2) == 0){
00257         return true;   
00258     }
00259     else{
00260         return false;   
00261     }   
00262 }
00263     
00264 bool IM920::setChannel(char ch){
00265     AS = RESPONSE_STRING;
00266     printf("STCH %2d\r\n", ch);
00267     ser->printf("STCH %4d\r\n", ch);
00268     wait_us(WAIT_TIME_US);
00269     AS = DATA_STRING;
00270     if(strncmp(readBuffAddr, "OK", 2) == 0){
00271         return true;
00272     }
00273     else return false;
00274 }  
00275     
00276 char IM920::readChannel(){
00277     AS = RESPONSE_STRING;
00278     printf("RDCH\r\n");
00279     ser->printf("RDCH\r\n");
00280     wait_us(WAIT_TIME_US);
00281     AS = DATA_STRING;
00282     if(strncmp(readBuffAddr, "OK", 2 ) == 0){
00283         return true;   
00284     }
00285     else{
00286         return false;   
00287     }
00288 }     
00289     
00290 bool IM920::enableCharacterIO(){
00291     AS = RESPONSE_STRING;
00292     printf("ECIO\r\n");
00293     ser->printf("ECIO\r\n");
00294     wait_us(WAIT_TIME_US);
00295     AS = DATA_STRING;
00296     if(strncmp(readBuffAddr, "OK", 2) == 0){
00297         return true;   
00298     }
00299     else{
00300         return false;   
00301     }
00302 }
00303     
00304 bool IM920::disableCharacterIO(){
00305     AS = RESPONSE_STRING;
00306     printf("DCIO\r\n");
00307     ser->printf("DCIO\r\n");
00308     wait_us(WAIT_TIME_US);
00309     AS = DATA_STRING;
00310     if(strncmp(readBuffAddr, "OK", 2) == 0){
00311         return true;   
00312     }
00313     else{
00314         return false;   
00315     }
00316 }
00317 void IM920::printFormat(){
00318     _pc->printf("-----------------------\r\n");
00319     _pc->printf(" ENWR            : EEPROMへの書き込みを許可\r\n");
00320     _pc->printf(" DSWR            : EEPROMへの書き込みを禁止\r\n");
00321     _pc->printf(" RDID            : 固有IDを読み出す\r\n");
00322     _pc->printf(" STNN パラメータ : ノード番号を設定,00~FF\r\n");
00323     _pc->printf(" RDNN            : ノード番号を読み出す\r\n");
00324     _pc->printf(" SRID XXXX       : 受信ID設定,0000~FFFF\r\n");
00325     _pc->printf(" RRID            : 受信IDを読み出す\r\n");
00326     _pc->printf(" ERID            : 設定された受信IDの全消去\r\n");
00327     _pc->printf(" STCH XX         : チャンネル設定,01~15\r\n");
00328     _pc->printf(" RDCH            : チャンネル読み出し\r\n");
00329     _pc->printf(" ECIO            : キャラクタ入出力設定\r\n");
00330     _pc->printf(" DCIO            : キャラクタ入出力設定解除\r\n");
00331     _pc->printf(" TXDT data       : 8バイトデータ送信,dataは16進数をASCII文字で入力\r\n");
00332     _pc->printf(" TXDA data       : 1~64バイトデータ送信,dataは16進数をASCII文字で入力\r\n");
00333     _pc->printf(" RDRS            : RSSI値読み出し\r\n");
00334     _pc->printf(" STPO 送信出力   : 1~3で入力, 1:0.1mW, 2:1mW, 3:10mW\r\n");
00335     _pc->printf(" RDPO            : 送信出力読み出し\r\n");
00336     _pc->printf(" STRT 速度値     : 無線通信速度設定, 1:高速(50kbps), 2:長距離(1.25kbps)\r\n");
00337     _pc->printf(" RDRT            : 無線通信速度を読み出す\r\n");
00338     _pc->printf(" RDVR            : 製品バージョンの読み出し\r\n");
00339     _pc->printf(" ERPT            : 簡易中継ON\r\n");
00340     _pc->printf(" DRPT            : 簡易中継OFF\r\n");
00341     _pc->printf(" RPRM            : パラメータ一括読み出し\r\n");
00342     _pc->printf(" SRST            : ソフトウェアリセット\r\n");
00343     _pc->printf(" PCLR            : パラメータクリア\r\n");
00344     _pc->printf("-----------------------\r\n");
00345 }
00346 void IM920::interactiveMode(){
00347     AS = INTERACTIVE_STRING;
00348     //interactiveFlag = 1;
00349     int current = 0;
00350     static char buf[IM920_BUFF_SIZE] = {'\0'};
00351     memset(buf, '\0', IM920_BUFF_SIZE);
00352     _pc->printf("Start Interactive mode!!\r\n");
00353     printFormat();
00354     while(1){
00355         if(_pc->readable()){
00356             char ccc = _pc->getc();  
00357              
00358             if(ccc == '@'){
00359                 _pc->printf("Interactive mode finish!!\r\n");
00360                 break;
00361             }
00362             if(ccc == '\r'){
00363                 _pc->printf("\r\n");
00364                 buf[current] = '\0';
00365                 
00366                 ser->printf("%s\r\n", buf);
00367                 current = 0;
00368                 memset(buf, '\0', IM920_BUFF_SIZE);
00369                 wait(1.0);
00370                 printFormat();
00371                 while(_pc->readable()){ _pc->getc();}
00372             }
00373             else if(ccc != '\n'){
00374                 _pc->printf("%c", ccc);
00375                 buf[current] = ccc;
00376                 current++;
00377                 if(current >= 160){
00378                     current = 0;
00379                     memset(buf, '\0', IM920_BUFF_SIZE);   
00380                 }
00381             }
00382         }
00383     }
00384     AS = DATA_STRING;
00385     return;
00386 }