Update xdrv_08_serial_bridge.ino

SerialBridge revisited
This commit is contained in:
Theo Arends 2019-02-09 16:08:09 +01:00
parent b3d6857f6a
commit cc8c13b240

View File

@ -31,12 +31,13 @@
enum SerialBridgeCommands { CMND_SSERIALSEND, CMND_SBAUDRATE }; enum SerialBridgeCommands { CMND_SSERIALSEND, CMND_SBAUDRATE };
const char kSerialBridgeCommands[] PROGMEM = D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE; const char kSerialBridgeCommands[] PROGMEM = D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE;
TasmotaSerial *SerialBridgeSerial; TasmotaSerial *SerialBridgeSerial = NULL;
uint8_t serial_bridge_active = 1;
uint8_t serial_bridge_in_byte_counter = 0;
unsigned long serial_bridge_polling_window = 0; unsigned long serial_bridge_polling_window = 0;
char *serial_bridge_buffer = NULL; char *serial_bridge_buffer = NULL;
int serial_bridge_in_byte_counter = 0;
bool serial_bridge_active = true;
bool serial_bridge_raw = false;
void SerialBridgeInput(void) void SerialBridgeInput(void)
{ {
@ -44,25 +45,37 @@ void SerialBridgeInput(void)
yield(); yield();
uint8_t serial_in_byte = SerialBridgeSerial->read(); uint8_t serial_in_byte = SerialBridgeSerial->read();
if (serial_in_byte > 127) { // binary data... if ((serial_in_byte > 127) && !serial_bridge_raw) { // Discard binary data above 127 if no raw reception allowed
serial_bridge_in_byte_counter = 0; serial_bridge_in_byte_counter = 0;
SerialBridgeSerial->flush(); SerialBridgeSerial->flush();
return; return;
} }
if (serial_in_byte) { if (serial_in_byte || serial_bridge_raw) { // Any char between 1 and 127 or any char (0 - 255)
if ((serial_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && (serial_in_byte != Settings.serial_delimiter)) { // add char to string if it still fits
if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ...
((isprint(serial_in_byte) && (128 == Settings.serial_delimiter)) || // Any char between 32 and 127
(serial_in_byte != Settings.serial_delimiter) || // Any char between 1 and 127 and not being delimiter
serial_bridge_raw)) { // Any char between 0 and 255
serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte; serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte;
serial_bridge_polling_window = millis(); // Wait for more data serial_bridge_polling_window = millis(); // Wait for more data
} else { } else {
serial_bridge_polling_window = 0; // Publish now serial_bridge_polling_window = 0; // Publish now
break; break;
} }
} }
} }
if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) { if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) {
serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // serial data completed serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer); if (!serial_bridge_raw) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\"%s\"}"), serial_bridge_buffer);
} else {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_SSERIALRECEIVED "\":\""));
for (int i = 0; i < serial_bridge_in_byte_counter; i++) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%02x"), mqtt_data, serial_bridge_buffer[i]);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s\"}"), mqtt_data);
}
MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED));
// XdrvRulesProcess(); // XdrvRulesProcess();
serial_bridge_in_byte_counter = 0; serial_bridge_in_byte_counter = 0;
@ -73,15 +86,18 @@ void SerialBridgeInput(void)
void SerialBridgeInit(void) void SerialBridgeInit(void)
{ {
serial_bridge_active = 0; serial_bridge_active = false;
if ((pin[GPIO_SBR_RX] < 99) && (pin[GPIO_SBR_TX] < 99)) { if ((pin[GPIO_SBR_RX] < 99) && (pin[GPIO_SBR_TX] < 99)) {
serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFFER_SIZE)); SerialBridgeSerial = new TasmotaSerial(pin[GPIO_SBR_RX], pin[GPIO_SBR_TX]);
if (serial_bridge_buffer != NULL) { if (SerialBridgeSerial->begin(Settings.sbaudrate * 1200)) { // Baud rate is stored div 1200 so it fits into one byte
SerialBridgeSerial = new TasmotaSerial(pin[GPIO_SBR_RX], pin[GPIO_SBR_TX]); if (SerialBridgeSerial->hardwareSerial()) {
if (SerialBridgeSerial->begin(Settings.sbaudrate * 1200)) { // Baud rate is stored div 1200 so it fits into one byte ClaimSerial();
serial_bridge_active = 1; serial_bridge_buffer = serial_in_buffer; // Use idle serial buffer to save RAM
SerialBridgeSerial->flush(); } else {
serial_bridge_buffer = (char*)(malloc(SERIAL_BRIDGE_BUFFER_SIZE));
} }
serial_bridge_active = true;
SerialBridgeSerial->flush();
} }
} }
} }
@ -100,18 +116,19 @@ bool SerialBridgeCommand(void)
serviced = false; // Unknown command serviced = false; // Unknown command
} }
else if ((CMND_SSERIALSEND == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) { else if ((CMND_SSERIALSEND == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) {
if (XdrvMailbox.data_len > 0) { // "Hello Tiger\n" serial_bridge_raw = (XdrvMailbox.index > 3);
if (XdrvMailbox.data_len > 0) {
if (1 == XdrvMailbox.index) { if (1 == XdrvMailbox.index) {
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len); SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len); // "Hello Tiger"
SerialBridgeSerial->write("\n"); SerialBridgeSerial->write("\n"); // "\n"
} }
else if ((2 == XdrvMailbox.index) || (4 == XdrvMailbox.index)) { // "Hello Tiger" or "A0" else if ((2 == XdrvMailbox.index) || (4 == XdrvMailbox.index)) {
SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len); SerialBridgeSerial->write(XdrvMailbox.data, XdrvMailbox.data_len); // "Hello Tiger" or "A0"
} }
else if (3 == XdrvMailbox.index) { // "Hello\f" else if (3 == XdrvMailbox.index) { // "Hello\f"
SerialBridgeSerial->write(Unescape(XdrvMailbox.data, &XdrvMailbox.data_len), XdrvMailbox.data_len); SerialBridgeSerial->write(Unescape(XdrvMailbox.data, &XdrvMailbox.data_len), XdrvMailbox.data_len);
} }
else if (5 == XdrvMailbox.index) { // "AA004566" as hex values else if (5 == XdrvMailbox.index) {
char *p; char *p;
char stemp[3]; char stemp[3];
uint8_t code; uint8_t code;
@ -122,7 +139,7 @@ bool SerialBridgeCommand(void)
while (size > 0) { while (size > 0) {
snprintf(stemp, sizeof(stemp), codes); snprintf(stemp, sizeof(stemp), codes);
code = strtol(stemp, &p, 16); code = strtol(stemp, &p, 16);
SerialBridgeSerial->write(code); SerialBridgeSerial->write(code); // "AA004566" as hex values
size -= 2; size -= 2;
codes += 2; codes += 2;
} }
@ -159,7 +176,7 @@ bool Xdrv08(uint8_t function)
SerialBridgeInit(); SerialBridgeInit();
break; break;
case FUNC_LOOP: case FUNC_LOOP:
SerialBridgeInput(); if (SerialBridgeSerial) { SerialBridgeInput(); }
break; break;
case FUNC_COMMAND: case FUNC_COMMAND:
result = SerialBridgeCommand(); result = SerialBridgeCommand();