Добавляем базовый класс для работы с Serial

This commit is contained in:
2023-11-16 22:28:17 +03:00
parent 9dec0ab11d
commit d53b197a53
2 changed files with 134 additions and 0 deletions

34
include/classes/IoTUart.h Normal file
View File

@@ -0,0 +1,34 @@
#pragma once
#include <Arduino.h>
#include "classes/IoTItem.h"
#ifdef ESP8266
#include <SoftwareSerial.h>
#else
#include <HardwareSerial.h>
#endif
class IoTUart : public IoTItem {
public:
IoTUart(const String& parameters);
~IoTUart();
virtual void uartHandle();
virtual void loop();
void uartPrintStrInUTF16(const char *strUTF8, int length);
void uartPrintln(const String& msg);
void uartPrint(const String& msg);
void uartPrintHex(const String& msg);
virtual IoTValue execute(String command, std::vector<IoTValue> &param);
protected:
#ifdef ESP8266
SoftwareSerial* _myUART;
#else
HardwareSerial* _myUART;
#endif
};

100
src/classes/IoTUart.cpp Normal file
View File

@@ -0,0 +1,100 @@
#include "Global.h"
#include "classes/IoTUart.h"
IoTUart::IoTUart(const String& parameters) : IoTItem(parameters) {
int _tx, _rx, _speed, _line;
jsonRead(parameters, "rx", _rx);
jsonRead(parameters, "tx", _tx);
jsonRead(parameters, "speed", _speed);
jsonRead(parameters, "line", _line);
#ifdef ESP8266
_myUART = new SoftwareSerial(_rx, _tx);
_myUART->begin(_speed);
#endif
#ifdef ESP32
_myUART = new HardwareSerial(_line);
_myUART->begin(_speed, SERIAL_8N1, _rx, _tx);
#endif
}
void IoTUart::loop() {
uartHandle();
}
void IoTUart::uartHandle() {}
IoTUart::~IoTUart() {}
void IoTUart::uartPrintStrInUTF16(const char *strUTF8, int length) {
// очень жесткий но быстрый способ конвертирования UTF-8 в UTF-16, но с поддержкой только кириллицы и двух байт в UTF-8
// не определяются исключения по формату UTF-8
for (int i=0; i < length; i++) {
if (strUTF8[i] < 176) { // если байт соответствует коду ASCII, значит берем как есть, но расширяем до двух байт
_myUART->write(0x00);
_myUART->write(strUTF8[i]);
} else { // иначе понимаем, что имеем дело с двумя байтами (да UTF8 может иметь и больше, но это ограничение наше)
_myUART->write(0x04); // указываем номер диапазона символов кириллицы первым байтом на выходе
if (strUTF8[i] == 208) { // если первый байт символа в первом диапазоне
if (strUTF8[i+1] == 129) _myUART->write(0x01); // исключение для символа 'ё'
else _myUART->write(strUTF8[i+1] - 128); // применяем смещение 128 и отправляем второй байт
}
if (strUTF8[i] == 209) { // если первый байт символа во втором диапазоне
if (strUTF8[i+1] == 145) _myUART->write(0x51); // исключение для символа 'Ё'
else _myUART->write(strUTF8[i+1] - 64); // применяем смещение 64 и отправляем второй байт
}
i++; // пропускаем второй байт входной строки
}
}
}
void IoTUart::uartPrintln(const String& msg) {
if (_myUART) {
_myUART->println(msg);
}
}
void IoTUart::uartPrint(const String& msg) {
if (_myUART) {
_myUART->print(msg);
}
}
void IoTUart::uartPrintHex(const String& msg) {
if (!_myUART) return;
unsigned char Hi, Lo;
uint8_t byteTx;
const char* strPtr = msg.c_str();
while ((Hi = *strPtr++) && (Lo = *strPtr++)) {
byteTx = (ChartoHex(Hi) << 4) | ChartoHex(Lo);
_myUART->write(byteTx);
}
}
IoTValue IoTUart::execute(String command, std::vector<IoTValue> &param) {
if (command == "println") {
if (param.size() == 1) {
//if (param[0].isDecimal) uartPrintln((String)param[0].valD);
//else uartPrintln(param[0].valS);
uartPrintln(param[0].valS);
}
} else if (command == "print") {
if (param.size() == 1) {
//if (param[0].isDecimal) uartPrint((String)param[0].valD);
//else uartPrint(param[0].valS);
uartPrintln(param[0].valS);
}
} else if (command == "printHex") {
if (param.size() == 1) {
uartPrintHex(param[0].valS);
}
}
return {};
}