RN41/42 control lib. RN41/42 is bluetooth module with class 1 or 2.
Dependencies: StrLib myTimer RingBuffer
RN41.cpp
- Committer:
- AkinoriHashimoto
- Date:
- 2015-10-20
- Revision:
- 0:812e6b59aa54
- Child:
- 1:5ed110051e39
File content as of revision 0:812e6b59aa54:
#include "RN41.h" //#include "SerialBase.h" //extern void sendHC05(string); const int RN41::NG= 0; const int RN41::OK= 1; // PRIVATE const int RN41::findCmp12= 100; const int RN41::findCmp1= 101; const int RN41::findCmp2= 102; // PUBLIC const int RN41::ERR_AddrUnder12= 210; const int RN41::ERR_AddrOver12= 211; const int RN41::ERR_Connect= 220; const int RN41::FAIL_Connect= 221; const int RN41::ERR_EnterCmdMode= 230; const int RN41::ERR_Disconnect= 240; const int RN41::ERR_NameSize= 310; /* const int RN41::None= 10; const int RN41::Odd= 11; const int RN41::Even= 12; */ RN41::RN41(PinName TX, PinName RX, int baudrate, int bit, int parity, int stop, bool CRLN) : rn41(TX, RX) { rn41.baud(baudrate); /* Parity _parity= SerialBase::None; // enum if(parity == 'O') _parity= SerialBase::Odd; if(parity == 'E') _parity= SerialBase::Even; rn41.format(bit, _parity, stop); // 8bit, NonParity, 1stopbit */ // 力技 if (parity == SerialBase::Odd) rn41.format(bit, SerialBase::Odd, stop); else if (parity == SerialBase::Even) rn41.format(bit, SerialBase::Even, stop); // 8bit, NonParity, 1stopbit else// if (parity == SerialBase::None) rn41.format(bit, SerialBase::None, stop); // 8bit, NonParity, 1stopbit CR= '\r'; if(CRLN) CR= "\r\n"; } int RN41::connect(string addr) { timerLocal.reset(); timerLocal.start(); addr= toAlpanumeric(addr, true); int idx= addr.size(); // ex. 0006:66:72:6e05\r ->000666726e05. if(idx < 12) return ERR_AddrUnder12; if(idx > 12) return ERR_AddrOver12; if(!enterCMD()) return ERR_EnterCmdMode; // CMD入れず // sendHC05("test 100"); if(!disconnect()) return ERR_Disconnect; if(!enterCMD()) return ERR_EnterCmdMode; // CMD入れず // BT addr check success; sendCMD("C,"+ addr); int status; // wait(1.0);read();sendHC05("--"+ rxStr+ "**"); status= chkReply("TRYING\r", 1000, "ERR\r"); if(status == findCmp2) return ERR_Connect; else if(status == findCmp1) { // Trying to connect to remote Bluetooth dev. // wait(7.0); read(); sendHC05(rxStr); timerLocal.reset(); timerLocal.start(); status= chkReply("CONNECT,", 10000, "CONNECT failed\r"); // wait 10s // sendHC05("Time of Create-Connection: "+ I2A(timerLocal.read_ms())+ " ms."); if(status == findCmp1) return OK; else if(status == findCmp2) return FAIL_Connect; } else { // sendHC05("connect:"+ I2A(status)); } return 1234; } string RN41::getLine() { read(); // CRまでを返す //sendHC05("debug 10"); if(str4GetLine.size()==0 && rxStr.size()==0) return ""; // trying->Connect待ちをTickerにすると、そこんとの除外処理が必須。 // sendHC05("debug 20"); // rxStr.size() > 0 int idx= rxStr.rfind(CR); // sendHC05("rxStr: "+ rxStr); sendHC05("idxCR: "+ I2A(idx)); if(idx == string::npos) // not find CR! return str4GetLine; // ダメじゃね?? // sendHC05("debug 30"); // rxStr has CR. idx += CR.size(); // \rなら+1、\r\nは+2 string rtn= str4GetLine; rtn += rxStr.substr(0, idx); // 切り取り rxStr= rxStr.substr(idx); // sendHC05("debug 40"); return rtn; } int RN41::setDev_Name(string str, bool usingAddr) { int strSize= str.size(); if((strSize==0) || (20<=strSize) || (usingAddr && 15<=strSize)) return ERR_NameSize; // 特殊文字チェックは不要っぽい string cmd; if(usingAddr) cmd= "S-,"; else cmd= "SN,"; if(!enterCMD()) return ERR_EnterCmdMode; // CMD入れず sendCMD(cmd+ str); int status; // wait(1.0);read();sendHC05("--"+ rxStr+ "**"); status= chkReply("AOK\r", 1000); if(status == findCmp1) return OK; return NG; } void RN41::sendCMD(string str, bool addCR) { if(addCR) str += '\r'; rn41.printf(str.c_str()); return; } void RN41::sendLINE(string str, bool addCR) { if(addCR) str += "\r\n"; rn41.printf(str.c_str()); return; } bool RN41::enterCMD() { sendCMD("$$$", false); if(chkReply("CMD\r", 500) == findCmp1) { // 500ms // sendHC05("returned CMD."); return true; } sendCMD("\r", false); // 既にCMDモード if(chkReply("?\r", 500) == findCmp1) { // sendHC05("Already CmdMode."); return true; } return false; } bool RN41::disconnect() { // if(!enterCMD()) return false; // CMD入れず sendCMD("K,"); // rtn KILL ? / ERR ? int status; // wait(6.0); read(); sendHC05("in disconnect; \t"+ rxStr); status= chkReply("KILL\r", 500, "ERR\r"); if(status == findCmp2) { // 既に切断されている sendCMD("---"); // exit CMD mode. if(chkReply("END\r", 500) == findCmp1) return true; else// { leds.ON(4); return false; // どういう状況か不明 } else if(status == findCmp1) { // if(chkReply("DISCONNECT", 2000) == findCmp1) if(chkReply_woCR("DISCONNECT", 5000)) // CR無いかも? return true; else //{ leds.ON(3); return false; // どういう状況か不明 }// else { return false; } return false; } int RN41::chkReply(string cmp1, int timeout, string cmp2) { timerLocal.reset(); timerLocal.start(); int cmp2Size= cmp2.size(); int idxCR, idx1, idx2;//= string::npos; bool find1, find2; for(;;) { if(timerLocal.read_ms() > timeout) return NG; read(); idxCR= rxStr.find_first_of('\r'); if(idxCR != string::npos) { // CR found. idx1= idx2= string::npos; // -1 find1= find2= false; idx1= rxStr.find(cmp1); if(cmp2Size != 0) idx2= rxStr.find(cmp2); // idx1: 0< or npos, idx2: 0< or npos(notfined or size0) int idxCut; //idx1(~CR) -> idx2(~CR) if(idx1 != string::npos) if(idx1 < idxCR) find1= true; if(idx2 != string::npos) if(idx2 < idxCR) find2= true; //sendHC05("++"+ rxStr+ "**"); //sendHC05("idx1:"+cmp1+":"+ I2A(idx1)+ "\tidx2:"+cmp2+":"+ I2A(idx2)+ "\tidxCR:"+ I2A(idxCR)); // CRまで切り取り。findならば切り捨て、見つからなければコピー後切り捨て idxCut= idxCR+ 1; if(rxStr[idxCut] == '\n') idxCut++; // 切り捨てはidxからの切り取りを上書き。コピーは文字数なので、idxが-1まで。 if(!(find1 || find2)) str4GetLine= rxStr.substr(0, idxCut); rxStr= rxStr.substr(idxCut); // 切り取りは共通。 if(find1 && find2) // find1有、find2有 return findCmp12; if(find1) return findCmp1; if(find2) return findCmp2; // CR内にCMP無い場合は、ループへ } } // end for } bool RN41::chkReply_woCR(string cmp, int timeout) { timerLocal.reset(); timerLocal.start(); int idx; for(;;) { if(timerLocal.read_ms() > timeout) { // sendHC05("in chkReply; "+ rxStr); return false; } read(); idx= rxStr.find(cmp); if(idx != string::npos) { // めんどいから消去する。 idx= rxStr.find_first_of('\r'); if(idx == string::npos) rxStr= ""; else { idx++; if(rxStr[idx] == '\n') idx++; rxStr= rxStr.substr(idx); } // rxStr= ""; return true; } } } void RN41::read() { if(!rn41.readable()) return; // Bufferを吸い尽くす // char ch; for(;;) { // char ch= rn41.getc(); // 1文字取る // ch= rn41.getc(); // 1文字取る // rxStr += ch; // 上書き前に退避 rxStr += (char)rn41.getc(); if(!rn41.readable()) return; //break; // Bufferになくなった } // end for }