Skip to content

Instantly share code, notes, and snippets.

@kiraind
Last active August 1, 2020 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiraind/adc6b6387c77f61ef3e1f2bf82a2c888 to your computer and use it in GitHub Desktop.
Save kiraind/adc6b6387c77f61ef3e1f2bf82a2c888 to your computer and use it in GitHub Desktop.
#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