Last active
August 1, 2020 13:35
-
-
Save kiraind/adc6b6387c77f61ef3e1f2bf82a2c888 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SoftwareSerial.h> | |
#include <SimpleTimer.h> | |
#define LED 13 | |
#define BT_POWER 12 | |
#define BT_RX 11 | |
#define BT_TX 10 | |
SoftwareSerial bluetoothPort(BT_TX, BT_RX); | |
SimpleTimer timer; | |
namespace CommandReader | |
{ | |
#define BUFFER_SIZE 32 | |
#define MSG_TIMEOUT 200 | |
SoftwareSerial *serialPortPtr; | |
int timeoutTimer; | |
char msgBuffer[BUFFER_SIZE]; | |
char msgLength; | |
typedef void (*callback_t)(const char *); | |
struct Handler | |
{ | |
char *prefix; | |
char prefixLength = 0; | |
callback_t callback; | |
} handlers[5]; | |
char handlersLength; | |
void setup(SoftwareSerial &serialPort) | |
{ | |
serialPortPtr = &serialPort; | |
msgLength = 0; | |
handlersLength = 0; | |
} | |
void run() | |
{ | |
if (serialPortPtr->available()) | |
{ | |
// cancel end message parse | |
timer.deleteTimer(timeoutTimer); | |
char ch = serialPortPtr->read(); | |
// save сhar | |
msgBuffer[msgLength] = ch; | |
msgLength += 1; | |
// wait for end of message | |
timeoutTimer = timer.setTimeout(MSG_TIMEOUT, []() { | |
// add zero terminator | |
msgBuffer[msgLength] = 0; | |
msgLength += 1; | |
// parse message | |
Serial.write("Parsing \""); | |
Serial.write(msgBuffer); | |
Serial.write("\"...\n"); | |
// find prefix & execute fitting | |
for (char handlerI = 0; handlerI < handlersLength; handlerI += 1) | |
{ | |
bool equals = true; | |
char charJ = 0; | |
for (; charJ < handlers[handlerI].prefixLength && charJ < msgLength; charJ += 1) | |
{ | |
if (msgBuffer[charJ] != handlers[handlerI].prefix[charJ]) | |
{ | |
// Serial.write("Not equal for \""); | |
// Serial.write(handlers[handlerI].prefix); | |
// Serial.write("\" at "); | |
// Serial.println((int)charJ); | |
equals = false; | |
break; | |
} | |
} | |
if (equals) | |
{ | |
Serial.write("Calling callback...\n"); | |
handlers[handlerI].callback(msgBuffer + charJ); | |
break; | |
} | |
} | |
// cleanup for next message | |
msgLength = 0; | |
}); | |
} | |
} | |
on(const char *prefix, callback_t callback) | |
{ | |
handlers[handlersLength].prefix = prefix; | |
handlers[handlersLength].prefixLength = strlen(prefix); | |
handlers[handlersLength].callback = callback; | |
handlersLength += 1; | |
} | |
} // namespace CommandReader | |
void setup() | |
{ | |
pinMode(LED, OUTPUT); | |
pinMode(BT_POWER, OUTPUT); | |
Serial.begin(9600); | |
digitalWrite(BT_POWER, HIGH); | |
bluetoothPort.begin(9600); | |
CommandReader::setup(bluetoothPort); | |
timer.setTimeout(1000, []() { | |
Serial.write("Setting up name...\n"); | |
bluetoothPort.write("AT+NAMEArduino\n"); | |
bluetoothPort.write("AT+PIN1234\n"); | |
}); | |
timer.setTimeout(1500, []() { | |
Serial.write("Setting up pin...\n"); | |
bluetoothPort.write("AT+PIN1234\n"); | |
}); | |
CommandReader::on("PING", []() { | |
bluetoothPort.write("PONG\n"); | |
}); | |
CommandReader::on("LED_ON", []() { | |
digitalWrite(LED, HIGH); | |
}); | |
CommandReader::on("LED_OFF", []() { | |
digitalWrite(LED, LOW); | |
}); | |
CommandReader::on("ECHO", [](const char* payload) { | |
bluetoothPort.write(payload); | |
bluetoothPort.write("\n"); | |
}); | |
} | |
void loop() | |
{ | |
timer.run(); | |
CommandReader::run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment