IM920のライブラリ
IM920.cpp
- Committer:
- Gaku0606
- Date:
- 2018-02-22
- Revision:
- 1:11ae0d702ecc
- Parent:
- 0:ccdeb3bea793
File content as of revision 1:11ae0d702ecc:
#include "IM920.h" #include "mbed.h" short IM920::toShort(char *array){ im920_cast.s = ((uint16_t)array[0] << 8) | (uint16_t)array[1]; return im920_cast.s; } int IM920::toInt(char *array){ im920_cast.i = ((uint32_t)array[0] << 24) | ((uint32_t)array[1] << 16) | ((uint32_t)array[2] << 8) | (uint32_t)array[3]; return im920_cast.i; } float IM920::toFloat(char *array){ im920_cast.u[0] = array[0]; im920_cast.u[1] = array[1]; im920_cast.u[2] = array[2]; im920_cast.u[3] = array[3]; return im920_cast.f; } long IM920::toLong(char *array){ for(int i = 0; i < 8; i++){ im920_cast.u[i] = array[i]; } return im920_cast.l; } double IM920::toDouble(char *array){ for(int i = 0; i< 8; i++){ im920_cast.u[i] = array[i]; } return im920_cast.d; } void IM920::dummyFunc(){ printf("NO FUNCTION\r\n"); }; char IM920::im920CheckSum(int count){ char ans = 0; for(int i = 0; i < count; i++){ ans = ans ^ data[i]; } return ans; } IM920::IM920(Serial &serial, Serial &pc, int baudrate){ ser = &serial;//参照渡し _pc = &pc; ser->baud(baudrate); memset(buff_A, '\0', IM920_BUFF_SIZE); memset(buff_B, '\0', IM920_BUFF_SIZE); readBuffAddr = buff_B; writeBuffAddr = buff_A; sendDataSize = 0; interactiveFlag = 0; for(int i = 0;i < 256; i++){ p_callFunc[i] = &this->dummyFunc; } memset(data, 0, 64); im920_dataLength = 0; memset(im920_sendBuff, '\0', 129); sendDataSize = 0; nodeNumber = 0; AS = DATA_STRING; checkSum = 0; for(int i = 0; i < 8; i++){ im920_cast.u[i] = 0; } node = 0; RSSI = 0; rID = 0; ID = 0; receiveCheckSum = 0; ser->attach(this, &IM920::im920Handler, Serial::RxIrq); } void IM920::im920_debug(){ printf("%s\r\n", readBuffAddr); return; } int IM920::asciiToNumber(char c){ //printf("%c ", c); if((int)c >= 65){//A ~ F return ((int)c - 55); } else{//0 ~ 9 return ((int)c - 48); } } void IM920::data_analyze(){ //00,0001,78:01,02,03,04,...,FF\0 //| | | | +- <CR><LF>文字列終了 //| | | +-------------------- 16進数をascii文字にしたもの、最大64区切り(64Byte) //| | +----------------------- 受信強度、RSSI値 //| +---------------------------- 送信モジュールの固有ID //+------------------------------- ノード番号 char tempStr[IM920_BUFF_SIZE]; strcpy(tempStr, readBuffAddr); char *tok = strtok(tempStr, ",");//ノード番号 node = ((asciiToNumber(tok[0]) << 4)) | asciiToNumber(tok[1]); tok = strtok(NULL, ",");//送信機のID rID = 0; rID = (asciiToNumber(tok[0]) << 12) | (asciiToNumber(tok[1]) << 8) | (asciiToNumber(tok[2]) << 4) | asciiToNumber(tok[3]); tok = strtok(NULL, ":");//受信強度 RSSI = (char)((asciiToNumber(tok[0]) << 4) | (asciiToNumber(tok[1]))); im920_dataLength = 64; memset(data, 0, 64); receiveCheckSum = 0; if(tok != NULL){ for(int i = 0; i < 64; i++){ if(tok[0] == '\0'){ im920_dataLength = i - 1; break; } tok = strtok(NULL, ","); data[i] = (asciiToNumber(tok[0]) << 4) | asciiToNumber(tok[1]); receiveCheckSum = receiveCheckSum ^ tok[0] ^ tok[1]; } } else{ im920_dataLength = 0; } return; } void IM920::im920Handler(){ static int current = 0; static char c = 0; c = ser->getc(); if(AS == RESPONSE_STRING || AS == INTERACTIVE_STRING){ printf("%c", c);//描画、後で1行描画だと次の行がすぐ来た時にハングアップしてしまう } if(c == '\r'){//文字列終了 printf("\r\n"); writeBuffAddr[current] = '\0'; if(AB == BUFF_A){//現在バッファAに書き込み中 readBuffAddr = buff_A; writeBuffAddr = buff_B; AB = BUFF_B; } else{//現在バッファBに書き込み中 readBuffAddr = buff_B; writeBuffAddr = buff_A; AB = BUFF_A; } //im920_debug(); //---------------------- // 文字列の解析 //---------------------- if(AS == DATA_STRING){//データの形式によって分岐 if(current > 9){ //データの取り出し、配列化 data_analyze(); /*for(int i = 0;i < 64;i++){ printf("%d ",data[i]); } printf("\r\n"); printf("header: %0X\r\n",(uint8_t)data[0]);*/ //header0xFF(); // 関数の呼び出し (*p_callFunc[(uint8_t)data[0]])(); } } //初期化 current = 0; //memset(writeBuffAddr, '\0', IM920_BUFF_SIZE); return; } else if(c !='\n'){ //文字列生成 writeBuffAddr[current] = c; current++; if(current >= IM920_BUFF_SIZE){//初期化 current = 0; memset(writeBuffAddr, '\0', IM920_BUFF_SIZE); } return; } } void IM920::attach(void (*funcAddr)(void), unsigned header){ p_callFunc[header] = funcAddr; return; } /** @bref パラメータ不揮発メモリ書き込み許可モードへ移行 */ bool IM920::enableWrite(){ AS = RESPONSE_STRING;//レスポンス受信モードへ移行 ser->printf("ENWR\r\n"); wait_us(WAIT_TIME_US);//待つ AS = DATA_STRING; //データ受信モードへ以降 if(strncmp(readBuffAddr, "OK", 2) == 0){ return true; } else{ return false; } } bool IM920::disableWrite(){ AS = RESPONSE_STRING;//レスポンス受信モードへ移行 ser->printf("DSWR\r\n"); wait_us(WAIT_TIME_US); AS = DATA_STRING; if(strncmp(readBuffAddr, "OK", 2) == 0){ return true; } else{ return false; } } /** @bref 固有IDを読み出す */ int IM920::readID(){ AS = NORMAL_STRING; ser->printf("RDID\r\n"); wait_us(WAIT_TIME_US); AS = DATA_STRING; int val = 0; //pc.printf("%c:%c:%c:%c\r\n",readBuffAddr[0],readBuffAddr[1],readBuffAddr[2],readBuffAddr[3]); val = asciiToNumber(readBuffAddr[0]) << 24; val |= asciiToNumber(readBuffAddr[1]) << 16; val |= asciiToNumber(readBuffAddr[2]) << 8; val |= asciiToNumber(readBuffAddr[3]); ID = val; return val; } bool IM920::setReceiveID(int ID){ AS = RESPONSE_STRING; printf("SRID %4X\r\n", ID); ser->printf("SRID %4X\r\n", ID); wait_us(WAIT_TIME_US); if(strncmp(readBuffAddr, "OK", 2) == 0){ return true; } else{ return false; } } bool IM920::setChannel(char ch){ AS = RESPONSE_STRING; printf("STCH %2d\r\n", ch); ser->printf("STCH %4d\r\n", ch); wait_us(WAIT_TIME_US); AS = DATA_STRING; if(strncmp(readBuffAddr, "OK", 2) == 0){ return true; } else return false; } char IM920::readChannel(){ AS = RESPONSE_STRING; printf("RDCH\r\n"); ser->printf("RDCH\r\n"); wait_us(WAIT_TIME_US); AS = DATA_STRING; if(strncmp(readBuffAddr, "OK", 2 ) == 0){ return true; } else{ return false; } } bool IM920::enableCharacterIO(){ AS = RESPONSE_STRING; printf("ECIO\r\n"); ser->printf("ECIO\r\n"); wait_us(WAIT_TIME_US); AS = DATA_STRING; if(strncmp(readBuffAddr, "OK", 2) == 0){ return true; } else{ return false; } } bool IM920::disableCharacterIO(){ AS = RESPONSE_STRING; printf("DCIO\r\n"); ser->printf("DCIO\r\n"); wait_us(WAIT_TIME_US); AS = DATA_STRING; if(strncmp(readBuffAddr, "OK", 2) == 0){ return true; } else{ return false; } } void IM920::printFormat(){ _pc->printf("-----------------------\r\n"); _pc->printf(" ENWR : EEPROMへの書き込みを許可\r\n"); _pc->printf(" DSWR : EEPROMへの書き込みを禁止\r\n"); _pc->printf(" RDID : 固有IDを読み出す\r\n"); _pc->printf(" STNN パラメータ : ノード番号を設定,00~FF\r\n"); _pc->printf(" RDNN : ノード番号を読み出す\r\n"); _pc->printf(" SRID XXXX : 受信ID設定,0000~FFFF\r\n"); _pc->printf(" RRID : 受信IDを読み出す\r\n"); _pc->printf(" ERID : 設定された受信IDの全消去\r\n"); _pc->printf(" STCH XX : チャンネル設定,01~15\r\n"); _pc->printf(" RDCH : チャンネル読み出し\r\n"); _pc->printf(" ECIO : キャラクタ入出力設定\r\n"); _pc->printf(" DCIO : キャラクタ入出力設定解除\r\n"); _pc->printf(" TXDT data : 8バイトデータ送信,dataは16進数をASCII文字で入力\r\n"); _pc->printf(" TXDA data : 1~64バイトデータ送信,dataは16進数をASCII文字で入力\r\n"); _pc->printf(" RDRS : RSSI値読み出し\r\n"); _pc->printf(" STPO 送信出力 : 1~3で入力, 1:0.1mW, 2:1mW, 3:10mW\r\n"); _pc->printf(" RDPO : 送信出力読み出し\r\n"); _pc->printf(" STRT 速度値 : 無線通信速度設定, 1:高速(50kbps), 2:長距離(1.25kbps)\r\n"); _pc->printf(" RDRT : 無線通信速度を読み出す\r\n"); _pc->printf(" RDVR : 製品バージョンの読み出し\r\n"); _pc->printf(" ERPT : 簡易中継ON\r\n"); _pc->printf(" DRPT : 簡易中継OFF\r\n"); _pc->printf(" RPRM : パラメータ一括読み出し\r\n"); _pc->printf(" SRST : ソフトウェアリセット\r\n"); _pc->printf(" PCLR : パラメータクリア\r\n"); _pc->printf("-----------------------\r\n"); } void IM920::interactiveMode(){ AS = INTERACTIVE_STRING; //interactiveFlag = 1; int current = 0; static char buf[IM920_BUFF_SIZE] = {'\0'}; memset(buf, '\0', IM920_BUFF_SIZE); _pc->printf("Start Interactive mode!!\r\n"); printFormat(); while(1){ if(_pc->readable()){ char ccc = _pc->getc(); if(ccc == '@'){ _pc->printf("Interactive mode finish!!\r\n"); break; } if(ccc == '\r'){ _pc->printf("\r\n"); buf[current] = '\0'; ser->printf("%s\r\n", buf); current = 0; memset(buf, '\0', IM920_BUFF_SIZE); wait(1.0); printFormat(); while(_pc->readable()){ _pc->getc();} } else if(ccc != '\n'){ _pc->printf("%c", ccc); buf[current] = ccc; current++; if(current >= 160){ current = 0; memset(buf, '\0', IM920_BUFF_SIZE); } } } } AS = DATA_STRING; return; }