mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
105
src/classes/IoTUart.cpp
Normal file
105
src/classes/IoTUart.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#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
|
||||
if (_line >= 0) {
|
||||
_myUART = new HardwareSerial(_line);
|
||||
((HardwareSerial*)_myUART)->begin(_speed, SERIAL_8N1, _rx, _tx);
|
||||
} else {
|
||||
_myUART = new SoftwareSerial(_rx, _tx);
|
||||
((SoftwareSerial*)_myUART)->begin(_speed);
|
||||
}
|
||||
#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> ¶m) {
|
||||
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 {};
|
||||
}
|
||||
@@ -1,47 +1,149 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
#include "classes/IoTUart.h"
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <SoftwareSerial.h>
|
||||
#else
|
||||
#include <HardwareSerial.h>
|
||||
#endif
|
||||
|
||||
class DwinI : public IoTItem {
|
||||
class DwinI : public IoTUart {
|
||||
private:
|
||||
#ifdef ESP8266
|
||||
SoftwareSerial* _myUART;
|
||||
#else
|
||||
HardwareSerial* _myUART;
|
||||
#endif
|
||||
uint8_t _headerBuf[260]; // буфер для приема пакета dwin
|
||||
int _headerIndex = 0; // счетчик принятых байт пакета
|
||||
|
||||
public:
|
||||
DwinI(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 doByInterval() {
|
||||
Serial.println("ddddddddddddd");
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m) { // будет возможным использовать, когда сценарии запустятся
|
||||
DwinI(String parameters) : IoTUart(parameters) {
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void uartHandle() {
|
||||
if (!_myUART) return;
|
||||
|
||||
if (_myUART->available()) {
|
||||
_headerBuf[_headerIndex] = _myUART->read();
|
||||
|
||||
// ищем валидный заголовок пакета dwin, проверяя каждый следующий байт
|
||||
if (_headerIndex == 0 && _headerBuf[_headerIndex] != 0x5A ||
|
||||
_headerIndex == 1 && _headerBuf[_headerIndex] != 0xA5 ||
|
||||
_headerIndex == 2 && _headerBuf[_headerIndex] == 0 ||
|
||||
_headerIndex == 3 && _headerBuf[_headerIndex] == 0x82 ) {
|
||||
_headerIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_headerIndex == _headerBuf[2] + 2) { // получили все данные из пакета
|
||||
// Serial.print("ffffffff");
|
||||
// for (int i=0; i<=_headerIndex; i++)
|
||||
// Serial.printf("%#x ", _headerBuf[i]);
|
||||
// Serial.println("!!!");
|
||||
|
||||
String valStr, id = "_";
|
||||
if (_headerIndex == 8) { // предполагаем, что получили int16
|
||||
valStr = (String)((_headerBuf[7] << 8) | _headerBuf[8]);
|
||||
}
|
||||
|
||||
char buf[5];
|
||||
hex2string(_headerBuf + 4, 2, buf);
|
||||
id += (String)buf;
|
||||
|
||||
IoTItem* item = findIoTItemByPartOfName(id);
|
||||
if (item) {
|
||||
//Serial.printf("received data: %s for VP: %s for ID: %s\n", valStr, buf, item->getID());
|
||||
generateOrder(item->getID(), valStr);
|
||||
}
|
||||
|
||||
_headerIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_headerIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
void onRegEvent(IoTItem* eventItem) {
|
||||
if (!_myUART || !eventItem) return;
|
||||
int indexOf_;
|
||||
String printStr = "";
|
||||
|
||||
printStr = eventItem->getID();
|
||||
indexOf_ = printStr.indexOf("_");
|
||||
uint8_t sizeOfVPPart = printStr.length() - indexOf_ - 1;
|
||||
if (indexOf_ == -1 || !_myUART || sizeOfVPPart < 4 || indexOf_ == 0) return; // пропускаем событие, если нет признака _ или признак пустой
|
||||
|
||||
char typeOfVP = sizeOfVPPart == 5 ? printStr.charAt(indexOf_ + 5) : 0;
|
||||
String VP = printStr.substring(indexOf_ + 1, indexOf_ + 5);
|
||||
|
||||
if (typeOfVP == 0) { // если не указан тип, то додумываем на основании типа данных источника
|
||||
if (eventItem->value.isDecimal)
|
||||
typeOfVP = 'i';
|
||||
else
|
||||
typeOfVP = 's';
|
||||
}
|
||||
|
||||
if (typeOfVP == 'i') {
|
||||
_myUART->write(0x5A);
|
||||
_myUART->write(0xA5);
|
||||
_myUART->write(0x05); // размер данных отправляемых с учетом целых чисел int
|
||||
_myUART->write(0x82); // требуем запись в память
|
||||
uartPrintHex(VP); // отправляем адрес в памяти VP
|
||||
|
||||
if (!eventItem->value.isDecimal) {
|
||||
eventItem->value.valD = atoi(eventItem->value.valS.c_str());
|
||||
}
|
||||
|
||||
_myUART->write(highByte((int)eventItem->value.valD));
|
||||
_myUART->write(lowByte((int)eventItem->value.valD));
|
||||
}
|
||||
|
||||
if (typeOfVP == 's') {
|
||||
if (eventItem->value.isDecimal) {
|
||||
eventItem->value.valS = eventItem->getValue();
|
||||
}
|
||||
|
||||
// подсчитываем количество символов отличающихся от ASCII, для понимания сколько символов состоит из дух байт
|
||||
int u16counter = 0;
|
||||
const char* valSptr = eventItem->value.valS.c_str();
|
||||
for (int i=0; i < eventItem->value.valS.length(); i++) {
|
||||
if (valSptr[i] > 200) u16counter++;
|
||||
}
|
||||
|
||||
_myUART->write(0x5A);
|
||||
_myUART->write(0xA5);
|
||||
_myUART->write((eventItem->value.valS.length() - u16counter) * 2 + 5); // подсчитываем и отправляем размер итоговой строки + служебные байты
|
||||
_myUART->write(0x82); // требуем запись в память
|
||||
uartPrintHex(VP); // отправляем адрес в памяти VP
|
||||
uartPrintStrInUTF16(eventItem->value.valS.c_str(), eventItem->value.valS.length()); // отправляем строку для записи
|
||||
_myUART->write(0xFF); // терминируем строку, чтоб экран очистил все остальное в элементе своем
|
||||
_myUART->write(0xFF);
|
||||
|
||||
//Serial.printf("fffffffff %#x %#x %#x %#x \n", Data[0], Data[1], Data[2], Data[3]);
|
||||
}
|
||||
|
||||
if (typeOfVP == 'f') {
|
||||
_myUART->write(0x5A);
|
||||
_myUART->write(0xA5);
|
||||
_myUART->write(0x07); // размер данных отправляемых с учетом дробных чисел dword
|
||||
_myUART->write(0x82); // требуем запись в память
|
||||
uartPrintHex(VP); // отправляем адрес в памяти VP
|
||||
|
||||
byte hex[4] = {0};
|
||||
if (!eventItem->value.isDecimal) {
|
||||
eventItem->value.valD = atof(eventItem->value.valS.c_str());
|
||||
}
|
||||
|
||||
byte* f_byte = reinterpret_cast<byte*>(&(eventItem->value.valD));
|
||||
memcpy(hex, f_byte, 4);
|
||||
|
||||
_myUART->write(hex[3]);
|
||||
_myUART->write(hex[2]);
|
||||
_myUART->write(hex[1]);
|
||||
_myUART->write(hex[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void onModuleOrder(String &key, String &value) {
|
||||
if (key == "uploadUI") {
|
||||
//SerialPrint("i", F("DwinI"), "Устанавливаем UI: " + value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
~DwinI(){
|
||||
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"menuSection": "screens",
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"name": "LCD Dwin экран",
|
||||
"type": "Reading",
|
||||
"subtype": "DwinI",
|
||||
@@ -10,11 +9,11 @@
|
||||
"widget": "",
|
||||
"page": "",
|
||||
"descr": "",
|
||||
"int": 15,
|
||||
"TX": 17,
|
||||
"RX": 16,
|
||||
"tx": 17,
|
||||
"rx": 16,
|
||||
"line": 2,
|
||||
"speed": 115200
|
||||
"speed": 9600,
|
||||
"btn-uploadUI": ""
|
||||
}
|
||||
],
|
||||
"about": {
|
||||
@@ -28,28 +27,50 @@
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"moduleDesc": "Позволяет выводить на графические экраны фирмы Dwin информацию от элементов конфигурации в автоматическом режиме.",
|
||||
"propInfo": {
|
||||
"int": ""
|
||||
},
|
||||
"subTypes": [
|
||||
"DwinI"
|
||||
],
|
||||
"title": "Экраны от компании Dwin",
|
||||
"funcInfo": [
|
||||
{
|
||||
"name": "rrrr",
|
||||
"descr": "rrrr",
|
||||
"params": []
|
||||
}
|
||||
]
|
||||
"moduleDesc": "Позволяет выводить на графические экраны фирмы Dwin информацию от элементов конфигурации в автоматическом режиме. Отправляться будут события тех элементов, которые имеют суффикс в ИД с указанием адреса VP для записи значения, например ID_5000. Для вывода числа используется суффикс i, для дробных - f, для строк - s",
|
||||
"propInfo": {
|
||||
"tx": "TX пин",
|
||||
"rx": "RX пин",
|
||||
"speed": "Скорость UART",
|
||||
"line": "Актуально только для ESP32: номер линии hardUART. =2 rx=16 tx=17",
|
||||
"btn-uploadUI": "Формирует автоматически графический интерфейс на базе конфигурации и выгружает в экран. Занимает продолжительное время! (в разработке)"
|
||||
}
|
||||
},
|
||||
"defActive": false,
|
||||
"defActive": true,
|
||||
"usedLibs": {
|
||||
"esp32_4mb": [],
|
||||
"esp32_4mb3f": [],
|
||||
"esp32cam_4mb": [],
|
||||
"esp8266_4mb": [],
|
||||
"esp8266_1mb": [],
|
||||
"esp8266_1mb_ota": [],
|
||||
"esp8285_1mb": [],
|
||||
"esp8285_1mb_ota": []
|
||||
"esp32_4mb": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp32_4mb3f": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp32cam_4mb": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8266_4mb": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8266_1mb": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8266_1mb_ota": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8266_2mb": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8266_2mb_ota": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8285_1mb": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
],
|
||||
"esp8285_1mb_ota": [
|
||||
"plerup/EspSoftwareSerial"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTUart.h"
|
||||
#include "classes/IoTItem.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
@@ -8,40 +9,19 @@
|
||||
#ifdef ESP8266
|
||||
SoftwareSerial* myUART = nullptr;
|
||||
#else
|
||||
HardwareSerial* myUART = nullptr;
|
||||
Stream* myUART = nullptr;
|
||||
#endif
|
||||
|
||||
class IoTmUART : public IoTItem {
|
||||
class IoTmUART : public IoTUart {
|
||||
private:
|
||||
int _eventFormat = 0; // 0 - нет приема, 1 - json IoTM, 2 - Nextion
|
||||
char _inc;
|
||||
String _inStr = ""; // буфер приема строк в режимах 0, 1, 2
|
||||
uint8_t _headerBuf[260]; // буфер для приема пакета dwin
|
||||
int _headerIndex = 0; // счетчик принятых байт пакета
|
||||
|
||||
#ifdef ESP8266
|
||||
SoftwareSerial* _myUART = nullptr;
|
||||
#else
|
||||
HardwareSerial* _myUART = nullptr;
|
||||
#endif
|
||||
|
||||
public:
|
||||
IoTmUART(String parameters) : IoTItem(parameters) {
|
||||
int _tx, _rx, _speed, _line;
|
||||
jsonRead(parameters, "tx", _tx);
|
||||
jsonRead(parameters, "rx", _rx);
|
||||
jsonRead(parameters, "speed", _speed);
|
||||
jsonRead(parameters, "line", _line);
|
||||
IoTmUART(String parameters) : IoTUart(parameters) {
|
||||
jsonRead(parameters, "eventFormat", _eventFormat);
|
||||
|
||||
#ifdef ESP8266
|
||||
myUART = _myUART = new SoftwareSerial(_rx, _tx);
|
||||
_myUART->begin(_speed);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
myUART = _myUART = new HardwareSerial(_line);
|
||||
_myUART->begin(_speed, SERIAL_8N1, _rx, _tx);
|
||||
#endif
|
||||
myUART = _myUART;
|
||||
}
|
||||
|
||||
// проверяем формат и если событие, то регистрируем его
|
||||
@@ -72,47 +52,9 @@ class IoTmUART : public IoTItem {
|
||||
|
||||
void uartHandle() {
|
||||
if (!_myUART) return;
|
||||
|
||||
if (_myUART->available()) {
|
||||
if (_eventFormat == 3) { // третий режим, значит ожидаем бинарный пакет данных от dwin
|
||||
_headerBuf[_headerIndex] = _myUART->read();
|
||||
|
||||
// ищем валидный заголовок пакета dwin, проверяя каждый следующий байт
|
||||
if (_headerIndex == 0 && _headerBuf[_headerIndex] != 0x5A ||
|
||||
_headerIndex == 1 && _headerBuf[_headerIndex] != 0xA5 ||
|
||||
_headerIndex == 2 && _headerBuf[_headerIndex] == 0 ||
|
||||
_headerIndex == 3 && _headerBuf[_headerIndex] == 0x82 ) {
|
||||
_headerIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_headerIndex == _headerBuf[2] + 2) { // получили все данные из пакета
|
||||
// Serial.print("ffffffff");
|
||||
// for (int i=0; i<=_headerIndex; i++)
|
||||
// Serial.printf("%#x ", _headerBuf[i]);
|
||||
// Serial.println("!!!");
|
||||
|
||||
String valStr, id = "_";
|
||||
if (_headerIndex == 8) { // предполагаем, что получили int16
|
||||
valStr = (String)((_headerBuf[7] << 8) | _headerBuf[8]);
|
||||
}
|
||||
|
||||
char buf[5];
|
||||
hex2string(_headerBuf + 4, 2, buf);
|
||||
id += (String)buf;
|
||||
|
||||
IoTItem* item = findIoTItemByPartOfName(id);
|
||||
if (item) {
|
||||
//Serial.printf("received data: %s for VP: %s for ID: %s\n", valStr, buf, item->getID());
|
||||
generateOrder(item->getID(), valStr);
|
||||
}
|
||||
|
||||
_headerIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_headerIndex++;
|
||||
|
||||
if (_eventFormat == 3) { // третий режим, значит ожидаем бинарный пакет данных от dwin оставлен для совместимости с предыдущей версией модуля
|
||||
// используйте новый модуль для dwin DwinI
|
||||
} else {
|
||||
_inc = _myUART->read();
|
||||
if (_inc == 0xFF) {
|
||||
@@ -148,7 +90,6 @@ class IoTmUART : public IoTItem {
|
||||
case 2: // формат событий для Nextion ID=Value0xFF0xFF0xFF
|
||||
printStr += eventItem->getID();
|
||||
indexOf_ = printStr.indexOf("_");
|
||||
//Serial.println(printStr + " fff " + indexOf_);
|
||||
if (indexOf_ == -1) return; // пропускаем событие, если нет используемого признака типа данных - _txt или _vol
|
||||
|
||||
if (printStr.indexOf("_txt") > 0) {
|
||||
@@ -168,114 +109,25 @@ class IoTmUART : public IoTItem {
|
||||
|
||||
uartPrintFFF(printStr);
|
||||
break;
|
||||
|
||||
case 3: // формат событий для Dwin
|
||||
printStr = eventItem->getID();
|
||||
indexOf_ = printStr.indexOf("_");
|
||||
uint8_t sizeOfVPPart = printStr.length() - indexOf_ - 1;
|
||||
if (indexOf_ == -1 || !_myUART || sizeOfVPPart < 4 || indexOf_ == 0) return; // пропускаем событие, если нет признака _ или признак пустой
|
||||
|
||||
char typeOfVP = sizeOfVPPart == 5 ? printStr.charAt(indexOf_ + 5) : 0;
|
||||
String VP = printStr.substring(indexOf_ + 1, indexOf_ + 5);
|
||||
|
||||
if (typeOfVP == 0) { // если не указан тип, то додумываем на основании типа данных источника
|
||||
if (eventItem->value.isDecimal)
|
||||
typeOfVP = 'i';
|
||||
else
|
||||
typeOfVP = 's';
|
||||
}
|
||||
|
||||
if (typeOfVP == 'i') {
|
||||
_myUART->write(0x5A);
|
||||
_myUART->write(0xA5);
|
||||
_myUART->write(0x05); // размер данных отправляемых с учетом целых чисел int
|
||||
_myUART->write(0x82); // требуем запись в память
|
||||
uartPrintHex(VP); // отправляем адрес в памяти VP
|
||||
|
||||
if (!eventItem->value.isDecimal) {
|
||||
eventItem->value.valD = atoi(eventItem->value.valS.c_str());
|
||||
}
|
||||
|
||||
_myUART->write(highByte((int)eventItem->value.valD));
|
||||
_myUART->write(lowByte((int)eventItem->value.valD));
|
||||
}
|
||||
|
||||
if (typeOfVP == 's') {
|
||||
if (eventItem->value.isDecimal) {
|
||||
eventItem->value.valS = eventItem->getValue();
|
||||
}
|
||||
|
||||
// подсчитываем количество символов отличающихся от ASCII, для понимания сколько символов состоит из дух байт
|
||||
int u16counter = 0;
|
||||
const char* valSptr = eventItem->value.valS.c_str();
|
||||
for (int i=0; i < eventItem->value.valS.length(); i++) {
|
||||
if (valSptr[i] > 200) u16counter++;
|
||||
}
|
||||
|
||||
_myUART->write(0x5A);
|
||||
_myUART->write(0xA5);
|
||||
_myUART->write((eventItem->value.valS.length() - u16counter) * 2 + 5); // подсчитываем и отправляем размер итоговой строки + служебные байты
|
||||
_myUART->write(0x82); // требуем запись в память
|
||||
uartPrintHex(VP); // отправляем адрес в памяти VP
|
||||
uartPrintStrInUTF16(eventItem->value.valS.c_str(), eventItem->value.valS.length()); // отправляем строку для записи
|
||||
_myUART->write(0xFF); // терминируем строку, чтоб экран очистил все остальное в элементе своем
|
||||
_myUART->write(0xFF);
|
||||
|
||||
//Serial.printf("fffffffff %#x %#x %#x %#x \n", Data[0], Data[1], Data[2], Data[3]);
|
||||
}
|
||||
|
||||
if (typeOfVP == 'f') {
|
||||
_myUART->write(0x5A);
|
||||
_myUART->write(0xA5);
|
||||
_myUART->write(0x07); // размер данных отправляемых с учетом дробных чисел dword
|
||||
_myUART->write(0x82); // требуем запись в память
|
||||
uartPrintHex(VP); // отправляем адрес в памяти VP
|
||||
|
||||
byte hex[4] = {0};
|
||||
if (!eventItem->value.isDecimal) {
|
||||
eventItem->value.valD = atof(eventItem->value.valS.c_str());
|
||||
}
|
||||
|
||||
byte* f_byte = reinterpret_cast<byte*>(&(eventItem->value.valD));
|
||||
memcpy(hex, f_byte, 4);
|
||||
|
||||
_myUART->write(hex[3]);
|
||||
_myUART->write(hex[2]);
|
||||
_myUART->write(hex[1]);
|
||||
_myUART->write(hex[0]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void 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 и отправляем второй байт
|
||||
}
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m) {
|
||||
if (command == "printFFF") {
|
||||
if (param.size() == 2) {
|
||||
String strToUart = "";
|
||||
strToUart = param[0].valS;
|
||||
|
||||
if (strUTF8[i] == 209) { // если первый байт символа во втором диапазоне
|
||||
if (strUTF8[i+1] == 145) _myUART->write(0x51); // исключение для символа 'Ё'
|
||||
else _myUART->write(strUTF8[i+1] - 64); // применяем смещение 64 и отправляем второй байт
|
||||
}
|
||||
|
||||
i++; // пропускаем второй байт входной строки
|
||||
if (param[1].valD)
|
||||
uartPrintFFF("\"" + strToUart + "\"");
|
||||
else
|
||||
uartPrintFFF(strToUart);
|
||||
}
|
||||
} else { // не забываем, что переопределяем execute и нужно проверить что в базовом классе проверяется
|
||||
return IoTUart::execute(command, param);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void loop() {
|
||||
uartHandle();
|
||||
return {};
|
||||
}
|
||||
|
||||
void uartPrintFFF(const String& msg) {
|
||||
@@ -286,67 +138,6 @@ class IoTmUART : public IoTItem {
|
||||
_myUART->write(0xff);
|
||||
}
|
||||
}
|
||||
|
||||
void uartPrintln(const String& msg) {
|
||||
if (_myUART) {
|
||||
_myUART->println(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void uartPrint(const String& msg) {
|
||||
if (_myUART) {
|
||||
_myUART->print(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void 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 execute(String command, std::vector<IoTValue> ¶m) {
|
||||
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);
|
||||
}
|
||||
} else if (command == "printFFF") {
|
||||
if (param.size() == 2) {
|
||||
String strToUart = "";
|
||||
// if (param[0].isDecimal)
|
||||
// strToUart = param[0].valD;
|
||||
// else
|
||||
// strToUart = param[0].valS;
|
||||
strToUart = param[0].valS;
|
||||
|
||||
if (param[1].valD)
|
||||
uartPrintFFF("\"" + strToUart + "\"");
|
||||
else
|
||||
uartPrintFFF(strToUart);
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void* getAPI_UART(String subtype, String param) {
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
extern SoftwareSerial* myUART;
|
||||
#else
|
||||
#include <HardwareSerial.h>
|
||||
extern HardwareSerial* myUART;
|
||||
extern Stream* myUART;
|
||||
#endif
|
||||
@@ -37,7 +37,7 @@
|
||||
"rx": "RX пин",
|
||||
"speed": "Скорость UART",
|
||||
"line": "Актуально только для ESP32: номер линии hardUART. =2 rx=16 tx=17",
|
||||
"eventFormat": "Выбор формата обмена сообщениями с другими контроллерами. =0 - не указан формат, значит не следим за событиями, =1 - формат событий IoTM с использованием json, =2 - формат событий для Nextion отправка событий: ID.val=Value0xFF0xFF0xFF прием ордеров: ID=Value. Отправляться будут события тех элементов, которые имеют суффикс в ИД _val или _txt, которые влияют на передаваемый формат, =3 - формат событий для экранов Dwin. Отправляться будут события тех элементов, которые имеют суффикс в ИД с указанием адреса VP для записи значения, например ID_5000. Пока поддерживается только вывод целых чисел, значения кнопки и текст."
|
||||
"eventFormat": "Выбор формата обмена сообщениями с другими контроллерами. =0 - не указан формат, значит не следим за событиями, =1 - формат событий IoTM с использованием json, =2 - формат событий для Nextion отправка событий: ID.val=Value0xFF0xFF0xFF прием ордеров: ID=Value. Отправляться будут события тех элементов, которые имеют суффикс в ИД _val или _txt, которые влияют на передаваемый формат."
|
||||
},
|
||||
"retInfo": "Содержит полученное последнее по UART сообщение.",
|
||||
"funcInfo": [
|
||||
|
||||
Reference in New Issue
Block a user