diff --git a/Arduino/SenderTrial2/BluetoothESP32.cpp b/Arduino/SenderTrial2/BluetoothESP32.cpp index 8452215..fda3e31 100644 --- a/Arduino/SenderTrial2/BluetoothESP32.cpp +++ b/Arduino/SenderTrial2/BluetoothESP32.cpp @@ -19,22 +19,38 @@ sRxLine RxLine; bool Bluetooth_ATCommand(const char* cmd); -const int BTRates[] = { - 9600, 38400, 115200, 19200, 57600, 2400, 4800, 1200 -}; -bool bHC05Available = false; +// Search for a HC-05 BlueTooth adapter, trying the more common baud rates first. +// As we cannot power up with the key pin high we are at the mercy of the baud rate +// stored in the module. +// **IMPORTANT** +// We must use a HC-05 module that uses a 3 pin 3.3V regulator (NOT 5 pin). +// On those modules, the EN input drive pin 34 and can be used to switch to AT +// command mode from data mode by raising EN high. +// ** BEWARE** +// The other style modules (with a 5 pin regulator) will disable the HC-05's power +// when the EN pin is low!!!! +// +// Once in command mode we can start interrogating using a simple "AT" command and +// checking for a response. +// If no response, try another baud rate till we do find a response. +// We can then proceed and configure the device's name, and force 9600 data rate void Bluetooth_Init() { + const int BTRates[] = { + 9600, 38400, 115200, 19200, 57600, 2400, 4800, 1200 + }; + RxLine.clear(); + + // attach to the SENSE line from the HC-05 module + // this line goes high when a BT client is connected :-) + pinMode(HC05_Sense, INPUT); - // search for BlueTooth adapter, trying the common baud rates, then less common - // as the device cannot be guaranteed to power up with the key pin high - // we are at the mercy of the baud rate stored in the module. - digitalWrite(KeyPin, HIGH); - delay(5000); - Serial2.begin(9600, SERIAL_8N1, Rx2Pin, Tx2Pin); // need to explicitly specify pins for pin multiplexer!); + digitalWrite(KeyPin, HIGH); // request HC-05 module to enter command mode + // Open Serial2, explicitly specify pins for pin multiplexer!); + Serial2.begin(9600, SERIAL_8N1, Rx2Pin, Tx2Pin); DebugPort.println("\r\n\r\nAttempting to detect HC-05 Bluetooth module..."); @@ -44,88 +60,85 @@ void Bluetooth_Init() DebugPort.print(" @ "); DebugPort.print(BTRates[BTidx]); DebugPort.print(" baud... "); - Serial2.begin(BTRates[BTidx], SERIAL_8N1, Rx2Pin, Tx2Pin); // open serial port at a certain baud rate + Serial2.begin(BTRates[BTidx], SERIAL_8N1, Rx2Pin, Tx2Pin); // open serial port at a std.baud rate + delay(10); + Serial2.print("\r\n"); // clear the throat! delay(100); - Serial2.print("\r\n"); Serial2.setTimeout(100); - if(Bluetooth_ATCommand("AT\r\n")) { - DebugPort.println(" OK."); - break; - } - if(Bluetooth_ATCommand("AT\r\n")) { + if(Bluetooth_ATCommand("AT\r\n")) { // probe with a simple "AT" + DebugPort.println(" OK."); // got a response - woo hoo found the module! + break; + } + if(Bluetooth_ATCommand("AT\r\n")) { // sometimes a second try is good... DebugPort.println(" OK."); break; } + // failed, try another baud rate DebugPort.println(""); Serial2.flush(); Serial2.end(); - delay(1000); + delay(100); } DebugPort.println(""); if(BTidx == maxTries) { - DebugPort.println("FAILED to detect HC-05 Bluetooth module :-("); + // we could not get anywhere with teh AT commands, but maybe this is the other module + // plough on and assume 9600 baud, but at the mercy of whatever the module name is... + DebugPort.println("FAILED to detect a HC-05 Bluetooth module :-("); + // leave the EN pin high - if other style module keeps it powered! + + // assume it is 9600, and just (try to) use it like that... + // we will sense the STATE line to prove a client is hanging off the link... + DebugPort.println("ASSUMING a HC-05 module @ 9600baud (Unknown name)"); + Serial2.begin(9600, SERIAL_8N1, Rx2Pin, Tx2Pin); } else { -/*// if(BTRates[BTidx] == 115200) { - if(BTRates[BTidx] == 9600) { -// DebugPort.println("HC-05 found and already set to 115200 baud, skipping Init."); - DebugPort.println("HC-05 found and already set to 9600 baud, skipping Init."); - bHC05Available = true; - } - else*/ { - do { - DebugPort.println("HC-05 found"); + // found a HC-05 module at one of its supported baud rates. + // now program it's name and force a 9600 baud data interface. + // this is the defacto standard as shipped! - DebugPort.print(" Setting Name to \"Diesel Heater\"... "); - if(!Bluetooth_ATCommand("AT+NAME=\"Diesel Heater\"\r\n")) { - DebugPort.println("FAILED"); - break; - } - DebugPort.println("OK"); + DebugPort.println("HC-05 found"); -// DebugPort.print(" Setting baud rate to 115200N81..."); -// if(!Bluetooth_ATCommand("AT+UART=115200,1,0\r\n")) { - DebugPort.print(" Setting baud rate to 9600N81..."); - if(!Bluetooth_ATCommand("AT+UART=9600,1,0\r\n")) { - DebugPort.println("FAILED"); - break; - }; - DebugPort.println("OK"); + do { // so we can break! + DebugPort.print(" Setting Name to \"Diesel Heater\"... "); + if(!Bluetooth_ATCommand("AT+NAME=\"Diesel Heater\"\r\n")) { + DebugPort.println("FAILED"); + break; + } + DebugPort.println("OK"); -// Serial2.begin(115200, SERIAL_8N1, Rx2Pin, Tx2Pin); - Serial2.begin(9600, SERIAL_8N1, Rx2Pin, Tx2Pin); - bHC05Available = true; + DebugPort.print(" Setting baud rate to 9600N81..."); + if(!Bluetooth_ATCommand("AT+UART=9600,1,0\r\n")) { + DebugPort.println("FAILED"); + break; + }; + DebugPort.println("OK"); - } while(0); + Serial2.begin(9600, SERIAL_8N1, Rx2Pin, Tx2Pin); - } + // leave HC-05 command mode, return to data mode + digitalWrite(KeyPin, LOW); + } while (0); // yeah lame, allows break prior though :-) } - digitalWrite(KeyPin, LOW); // leave HC-05 command mode - delay(500); - - if(!bHC05Available) - Serial2.end(); // close serial port if no module found + delay(50); DebugPort.println(""); } void Bluetooth_Check() -{ +{ // check for data coming back over Bluetooth - if(bHC05Available) { - if(Serial2.available()) { - char rxVal = Serial2.read(); - if(isControl(rxVal)) { // "End of Line" - Command_Interpret(RxLine.Line); - RxLine.clear(); - } - else { - RxLine.append(rxVal); // append new char to our Rx buffer - } + if(Serial2.available()) { + char rxVal = Serial2.read(); + if(isControl(rxVal)) { // "End of Line" + Command_Interpret(RxLine.Line); + RxLine.clear(); + } + else { + RxLine.append(rxVal); // append new char to our Rx buffer } } } @@ -134,39 +147,42 @@ void Bluetooth_Check() void Bluetooth_SendFrame(const char* pHdr, const CProtocol& Frame, bool lineterm) { DebugPort.print(millis()); - DebugReportFrame(pHdr, Frame, lineterm ? "\r\n" : " "); + DebugPort.print("ms "); +// DebugReportFrame(pHdr, Frame, lineterm ? "\r\n" : " "); + DebugReportFrame(pHdr, Frame, " "); - if(bHC05Available) { + if(digitalRead(HC05_Sense)) { if(Frame.verifyCRC()) { - digitalWrite(LED, !digitalRead(LED)); // toggle LED + // send data frame to HC-05 Serial2.print(pHdr); Serial2.write(Frame.Data, 24); + // toggle LED + digitalWrite(LED, !digitalRead(LED)); // toggle LED } else { DebugPort.print("Bluetooth data not sent, CRC error "); - DebugPort.println(pHdr); } } else { - DebugPort.println("No Bluetooth client"); + DebugPort.print("No Bluetooth client"); + // force LED off digitalWrite(LED, 0); } + if(lineterm) + DebugPort.println(""); } // local function, typically to perform Hayes commands with HC-05 bool Bluetooth_ATCommand(const char* cmd) { -// if(bHC05Available) { - Serial2.print(cmd); - char RxBuffer[16]; - memset(RxBuffer, 0, 16); - int read = Serial2.readBytesUntil('\n', RxBuffer, 16); // \n is not included in returned string! - if((read == 3) && (0 == strcmp(RxBuffer, "OK\r")) ) { - return true; - } - return false; -// } -// return false; + Serial2.print(cmd); + char RxBuffer[16]; + memset(RxBuffer, 0, 16); + int read = Serial2.readBytesUntil('\n', RxBuffer, 16); // \n is not included in returned string! + if((read == 3) && (0 == strcmp(RxBuffer, "OK\r")) ) { + return true; + } + return false; } #else // ESP32_USE_HC05 diff --git a/Arduino/SenderTrial2/SenderTrial2.ino b/Arduino/SenderTrial2/SenderTrial2.ino index 6522a40..9fa657c 100644 --- a/Arduino/SenderTrial2/SenderTrial2.ino +++ b/Arduino/SenderTrial2/SenderTrial2.ino @@ -1,4 +1,4 @@ - /* + /* Chinese Heater Half Duplex Serial Data Sending Tool Connects to the blue wire of a Chinese heater, which is the half duplex serial link. @@ -68,12 +68,9 @@ #include "NVStorage.h" #include "debugport.h" -#define BLUETOOTH #define DEBUG_BTRX -#ifdef BLUETOOTH #include "Bluetooth.h" -#endif #if defined(__arm__) // Required for Arduino Due, UARTclass is derived from HardwareSerial @@ -117,7 +114,7 @@ CProtocol HeaterFrame1; // data packet received from heater in response t CProtocol HeaterFrame2; // data packet received from heater in response to our packet CProtocol DefaultBTCParams(CProtocol::CtrlMode); // defines the default parameters, used in case of no OEM controller long lastRxTime; // used to observe inter character delays -int hasController = 0; +bool hasOEMController = false; // setup Non Volatile storage // this is very much hardware dependent, we can use the ESP32's FLASH @@ -170,9 +167,7 @@ void setup() DefaultBTCParams.setFan_Min(1680); DefaultBTCParams.setFan_Max(4500); -#ifdef BLUETOOTH Bluetooth_Init(); -#endif // create pointer to CHeaterStorage // via the magic of polymorphism we can use this to access whatever @@ -202,9 +197,7 @@ void loop() } } -#ifdef BLUETOOTH Bluetooth_Check(); // check for Bluetooth activity -#endif // Handle time interval where we send data to the blue wire if(CommState.is(CommStates::BTC_Tx)) { @@ -223,17 +216,11 @@ void loop() // have not seen any receive data for a second. // OEM controller is probably not connected. // Skip state machine immediately to BTC_Tx, sending our own settings. - hasController = 0; + hasOEMController = false; CommState.set(CommStates::BTC_Tx); bool isBTCmaster = true; TxManage.PrepareFrame(DefaultBTCParams, isBTCmaster); // use our parameters, and mix in NV storage values TxManage.Start(timenow); -#ifdef BLUETOOTH -// Bluetooth_SendFrame("[BTC]", TxManage.getFrame(), false); // BTC => Bluetooth Controller :-) -// Bluetooth_SendFrame("[BTC]", TxManage.getFrame(), true); // BTC => Bluetooth Controller :-) -#else - DebugReportFrame("BTC ", OEMCtrlFrame, " "); -#endif } // precautionary action if all 24 bytes were not received whilst expecting them @@ -264,7 +251,7 @@ void loop() if( CommState.is(CommStates::Idle) && (RxTimeElapsed > 100)) { DebugPort.print(RxTimeElapsed); DebugPort.println(" OEM Controller re-sync"); - hasController = 1; + hasOEMController = true; CommState.set(CommStates::OEMCtrlRx); } @@ -296,23 +283,15 @@ void loop() if( CommState.is(CommStates::OEMCtrlReport) ) { // filled controller frame, report -#ifdef BLUETOOTH // echo received OEM controller frame over Bluetooth, using [OEM] header Bluetooth_SendFrame("[OEM]", OEMCtrlFrame, true); -#else - DebugReportFrame("OEM ", OEMCtrlFrame, " "); -#endif CommState.set(CommStates::HeaterRx1); } else if(CommState.is(CommStates::HeaterReport1) ) { // received heater frame (after controller message), report -#ifdef BLUETOOTH // echo heater reponse data to Bluetooth client Bluetooth_SendFrame("[HTR]", HeaterFrame1); -#else - DebugReportFrame("Htr1 ", HeaterFrame1, "\r\n"); -#endif if(digitalRead(ListenOnlyPin)) { bool isBTCmaster = false; @@ -328,20 +307,21 @@ void loop() else if( CommState.is(CommStates::HeaterReport2) ) { // received heater frame (after our control message), report delay(5); -#ifdef BLUETOOTH - if(!hasController) { + if(!hasOEMController) { Bluetooth_SendFrame("[BTC]", TxManage.getFrame(), true); // BTC => Bluetooth Controller :-) Bluetooth_SendFrame("[HTR]", HeaterFrame2); // pin not grounded, suppress duplicate to BT } -#else - DebugReportFrame("Htr2 ", HeaterFrame2, "\r\n"); -#endif + else { + DebugReportFrame("Htr2 ", HeaterFrame2, "\r\n"); + } // if(!digitalRead(ListenOnlyPin)) { // } CommState.set(CommStates::Idle); +#ifdef SHOW_HEAP Serial.print("Free heap "); Serial.println(ESP.getFreeHeap()); +#endif } } // loop diff --git a/Arduino/SenderTrial2/pins.h b/Arduino/SenderTrial2/pins.h index fce6f39..00ebf6c 100644 --- a/Arduino/SenderTrial2/pins.h +++ b/Arduino/SenderTrial2/pins.h @@ -5,4 +5,4 @@ const int Tx1Pin = 18; const int Rx1Pin = 19; const int Tx2Pin = 16; const int Rx2Pin = 17; - +const int HC05_Sense = 4;