920MHz帯無線通信モジュールIM920のライブラリ
Dependents: Hybrid_OB2021_MAIN Hybrid_OB2021_GROUND pressure_control_system pressure_control_receiver ... more
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 }
Generated on Tue Jul 26 2022 04:07:01 by
1.7.2