diff --git a/build-flags/build_flags_esp32-wifi b/build-flags/build_flags_esp32-wifi index 91926d7..a3cdb86 100644 --- a/build-flags/build_flags_esp32-wifi +++ b/build-flags/build_flags_esp32-wifi @@ -14,3 +14,12 @@ #-DUSE_1W_PIN=16 #-DW5500_CS_PIN=15 #-DPID_DISABLE + +#Define pins for Serial1. Default - 9/10 is utilized by ESP flash +#-DRX1=15 +#-DTX1=2 + +-DMODBUS_UART_RX_PIN=15 +-DMODBUS_UART_TX_PIN=2 +-DmodbusSerial=Serial1 + diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 33f1673..8ea231a 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -49,6 +49,7 @@ e-mail anklimov@gmail.com #include "modules/out_pwm.h" #include "modules/out_pid.h" #include "modules/out_multivent.h" +#include "modules/out_uartbridge.h" short modbusBusy = 0; bool isPendedModbusWrites = false; @@ -183,6 +184,13 @@ void Item::Parse() { // debugSerial<name << F(" T:") << itemType << F(" =") << getArg() << endl; @@ -1871,7 +1879,7 @@ return false; */ int Item::checkModbusDimmer() { if (modbusBusy) return -1; - if (checkModbusRetry()) return -2; + //if (checkModbusRetry()) return -2; short numpar = 0; if ((itemArg->type != aJson_Array) || ((numpar = aJson.getArraySize(itemArg)) < 2)) { diff --git a/lighthub/item.h b/lighthub/item.h index dcb369e..f6f8aa9 100644 --- a/lighthub/item.h +++ b/lighthub/item.h @@ -53,6 +53,7 @@ e-mail anklimov@gmail.com #define CH_MOTOR 12 #define CH_PID 13 #define CH_MBUS 14 +#define CH_UARTBRIDGE 15 #define CH_MULTIVENT 18 //#define CHANNEL_TYPES 13 diff --git a/lighthub/modules/out_modbus.cpp b/lighthub/modules/out_modbus.cpp index af380a4..4dd364c 100644 --- a/lighthub/modules/out_modbus.cpp +++ b/lighthub/modules/out_modbus.cpp @@ -22,11 +22,13 @@ struct reg_t const uint8_t id; }; +/* struct serial_t { const char verb[4]; const serialParamType mode; }; +*/ #define PAR_I16 1 #define PAR_I32 2 @@ -53,6 +55,7 @@ const reg_t regSize_P[] PROGMEM = } ; #define regSizeNum sizeof(regSize_P)/sizeof(reg_t) +/* const serial_t serialModes_P[] PROGMEM = { { "8E1", (serialParamType) SERIAL_8E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN }, @@ -90,6 +93,8 @@ serialParamType str2SerialParam(char * str) debugSerial<< F("Default serial mode N81 used"); return static_cast (SERIAL_8N1); } +*/ + int str2regSize(char * str) { for(uint8_t i=0; ibaud, static_cast (store->serialParam)); #elif defined (ARDUINO_ARCH_ESP8266) modbusSerial.begin(store->baud, static_cast (store->serialParam)); + #elif defined (ARDUINO_ARCH_ESP32) + modbusSerial.begin(store->baud, (store->serialParam),MODBUS_UART_RX_PIN,MODBUS_UART_TX_PIN); #else modbusSerial.begin(store->baud, (store->serialParam)); #endif @@ -375,6 +382,7 @@ if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() = modbusSerial.begin(store->baud, static_cast (store->serialParam)); #elif defined (ARDUINO_ARCH_ESP8266) modbusSerial.begin(store->baud, static_cast (store->serialParam)); + Serial1.begin() #elif defined (ESP32) //modbusSerial.begin(store->baud, store->serialParam); //delay(100); diff --git a/lighthub/modules/out_modbus.h b/lighthub/modules/out_modbus.h index 334eb9d..7a6030c 100644 --- a/lighthub/modules/out_modbus.h +++ b/lighthub/modules/out_modbus.h @@ -4,12 +4,9 @@ #include #include #include "itemCmd.h" +#include + -#if defined(ESP32) -#define serialParamType uint32_t -#else -#define serialParamType uint16_t -#endif class mbPersistent : public chPersistent { diff --git a/lighthub/modules/out_uartbridge.cpp b/lighthub/modules/out_uartbridge.cpp new file mode 100644 index 0000000..a5be807 --- /dev/null +++ b/lighthub/modules/out_uartbridge.cpp @@ -0,0 +1,222 @@ +#ifdef UARTBRIDGE_ENABLE + +#include "modules/out_uartbridge.h" +#include "Arduino.h" +#include "options.h" +#include "utils.h" +#include "Streaming.h" + +#include "item.h" +#include +#include "main.h" +#include + +extern aJsonObject *modbusObj; +extern ModbusMaster node; +extern short modbusBusy; +extern void modbusIdle(void) ; + +/* +struct reg_t +{ + const char verb[4]; + const uint8_t id; +}; + + +#define PAR_I16 1 +#define PAR_I32 2 +#define PAR_U16 3 +#define PAR_U32 4 +#define PAR_I8H 5 +#define PAR_I8L 6 +#define PAR_U8H 7 +#define PAR_U8L 8 +#define PAR_TENS 9 + +const reg_t regSize_P[] PROGMEM = +{ + { "i16", (uint8_t) PAR_I16 }, + { "i32", (uint8_t) PAR_I32 }, + { "u16", (uint8_t) PAR_U16 }, + { "u32", (uint8_t) PAR_U32 }, + { "i8h", (uint8_t) PAR_I8H }, + { "i8l", (uint8_t) PAR_I8L }, + { "u8h", (uint8_t) PAR_U8H }, + { "u8l", (uint8_t) PAR_U8L }, + { "x10", (uint8_t) PAR_TENS } +} ; +#define regSizeNum sizeof(regSize_P)/sizeof(reg_t) + +int str2regSize(char * str) +{ + for(uint8_t i=0; iitemArg || (item->itemArg->type != aJson_Object)) + { + errorSerial<itemArg<itemArg->type != aJson_Object)<itemArg, "serial"); + if (serialParamObj && serialParamObj->type == aJson_String) store->serialParam = str2SerialParam(serialParamObj->valuestring); + else store->serialParam = SERIAL_8N1; + + aJsonObject * baudObj=aJson.getObjectItem(item->itemArg, "baud"); + if (baudObj && baudObj->type == aJson_Int && baudObj->valueint) store->baud = baudObj->valueint; + else store->baud = 9600; + + #if defined (__SAM3X8E__) + MODULE_UATRBRIDGE_UARTA.begin(store->baud, static_cast (store->serialParam)); + MODULE_UATRBRIDGE_UARTB.begin(store->baud, static_cast (store->serialParam)); + #elif defined (ARDUINO_ARCH_ESP8266) + MODULE_UATRBRIDGE_UARTA.begin(store->baud, static_cast (store->serialParam)); + MODULE_UATRBRIDGE_UARTA.begin(store->baud, static_cast (store->serialParam)); + #elif defined (ARDUINO_ARCH_ESP32) + MODULE_UATRBRIDGE_UARTA.begin(store->baud, (store->serialParam),MODULE_UATRBRIDGE_UARTA_RX_PIN,MODULE_UATRBRIDGE_UARTA_TX_PIN); + MODULE_UATRBRIDGE_UARTB.begin(store->baud, (store->serialParam),MODULE_UATRBRIDGE_UARTB_RX_PIN,MODULE_UATRBRIDGE_UARTB_TX_PIN); + #else + MODULE_UATRBRIDGE_UARTA.begin(store->baud, (store->serialParam)); + MODULE_UATRBRIDGE_UARTB.begin(store->baud, (store->serialParam)); + #endif + + return true; + } + + +int out_UARTbridge::Setup() +{ +abstractOut::Setup(); +if (!store) store= (ubPersistent *)item->setPersistent(new ubPersistent); +if (!store) + { errorSerial<timestamp=millisNZ(); +if (getConfig()) + { + infoSerial<itemArr->name<driverStatus = CST_INITIALIZED; + return 1; + } +else + { errorSerial<driverStatus = CST_FAILED; + return 0; + } + +} + +int out_UARTbridge::Stop() +{ +Serial.println("UARTbridge De-Init"); + +delete store; +item->setPersistent(NULL); +store = NULL; +return 1; +} + +int out_UARTbridge::Status() +{ +if (store) + return store->driverStatus; +return CST_UNKNOWN; +} + +int out_UARTbridge::Poll(short cause) +{ + int chA; + int chB; + + while (MODULE_UATRBRIDGE_UARTA.available()) + { + chA=MODULE_UATRBRIDGE_UARTA.read(); + MODULE_UATRBRIDGE_UARTB.write(chA); + debugSerial<")<<_HEX(chB); + } + +return 1;//store->pollingInterval; +}; + +int out_UARTbridge::getChanType() +{ + return CH_MODBUS; +} + + +//!Control unified Modbus item +// Priority of selection sub-items control to: +// 1. if defined standard suffix Code inside cmd +// 2. custom textual subItem +// 3. non-standard numeric suffix Code equal param id + +int out_UARTbridge::Ctrl(itemCmd cmd, char* subItem, bool toExecute) +{ +//int chActive = item->isActive(); +//bool toExecute = (chActive>0); +//itemCmd st(ST_UINT32,CMD_VOID); + +int suffixCode = cmd.getSuffix(); + +// aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type"); +// aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map"); +// aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2); +// uint16_t data = node.getResponseBuffer(posInBuffer); + + + +if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it + +switch(suffixCode) +{ +case S_NOTFOUND: + // turn on and set +toExecute = true; +debugSerial< +#include +#include "itemCmd.h" +#include "utils.h" + +#if defined(ESP32) +#define serialParamType uint32_t +#else +#define serialParamType uint16_t +#endif + +#ifndef MODULE_UATRBRIDGE_UARTA +#define MODULE_UATRBRIDGE_UARTA Serial1 +#endif + +#ifndef MODULE_UATRBRIDGE_UARTB +#define MODULE_UATRBRIDGE_UARTB Serial2 +#endif + +#ifndef MODULE_UATRBRIDGE_UARTA_RX_PIN +#define MODULE_UATRBRIDGE_UARTA_RX_PIN 15 +#endif + +#ifndef MODULE_UATRBRIDGE_UARTA_TX_PIN +#define MODULE_UATRBRIDGE_UARTA_TX_PIN 2 +#endif + +#ifndef MODULE_UATRBRIDGE_UARTB_RX_PIN +#define MODULE_UATRBRIDGE_UARTB_RX_PIN -1 +#endif + +#ifndef MODULE_UATRBRIDGE_UARTB_TX_PIN +#define MODULE_UATRBRIDGE_UARTB_TX_PIN -1 +#endif + +class ubPersistent : public chPersistent { + +public: +// int addr + int8_t driverStatus; + int baud; + serialParamType serialParam; + //uint16_t pollingInterval; + //uint32_t timestamp; + //aJsonObject * pollingRegisters; + //aJsonObject * pollingIrs; + //aJsonObject * parameters; +}; + + + +class out_UARTbridge : public abstractOut { +public: + + out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();}; + int Setup() override; + int Poll(short cause) override; + int Stop() override; + int Status() override; + int getChanType() override; + int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override; + int getDefaultStorageType(){return ST_INT32;}; + //int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override; + +protected: + ubPersistent * store; + bool getConfig(); +// int findRegister(int registerNum, int posInBuffer, int regType); +// void pollModbus(aJsonObject * reg, int regType); +}; +#endif diff --git a/lighthub/options.h b/lighthub/options.h index 9d50b9c..929f921 100644 --- a/lighthub/options.h +++ b/lighthub/options.h @@ -158,6 +158,7 @@ #define DEFAULT_INC_STEP 5 + #if defined(ARDUINO_ARCH_AVR) //All options available #ifdef CONTROLLINO @@ -172,8 +173,14 @@ #endif #if defined(__SAM3X8E__) +#ifndef modbusSerial #define modbusSerial Serial2 +#endif + +#ifndef AC_Serial #define AC_Serial Serial3 +#endif + #define dmxout DmxDue1 #define dmxin DmxDue1 #endif @@ -193,10 +200,16 @@ #define _espdmx #endif +#ifndef modbusSerial #define modbusSerial Serial1 +#endif + +#ifndef AC_Serial #define AC_Serial Serial1 #endif +#endif + #if defined(ARDUINO_ARCH_ESP32) #undef _dmxin //#undef _modbus @@ -206,10 +219,25 @@ #endif //#undef _dmxout //#undef modbusSerial +#ifndef modbusSerial #define modbusSerial Serial2 +#endif + +#ifndef AC_Serial #define AC_Serial Serial2 #endif + +#ifndef MODBUS_UART_RX_PIN +#define MODBUS_RX_PIN -1 +#endif + +#ifndef MODBUS_UART_TX_PIN +#define MODBUS_TX_PIN -1 +#endif + +#endif + #ifndef _dmxout #undef _artnet #endif diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index 7b2766b..b047ec4 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -26,6 +26,8 @@ e-mail anklimov@gmail.com #include "item.h" #include +#include + extern int8_t configLocked; extern int8_t ethernetIdleCount; extern PubSubClient mqttClient; @@ -683,6 +685,49 @@ unsigned long millisNZ(uint8_t shift) return now; } +struct serial_t +{ + const char verb[4]; + const serialParamType mode; +}; + +const serial_t serialModes_P[] PROGMEM = +{ + { "8E1", (serialParamType) SERIAL_8E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN }, + { "8N1", (serialParamType) SERIAL_8N1}, + { "8E2", (serialParamType) SERIAL_8E2}, + { "8N2", (serialParamType) SERIAL_8N2}, + { "8O1", (serialParamType) SERIAL_8O1}, + { "8O2", (serialParamType) SERIAL_8O2}, +// { "8M1", SERIAL_8M1}, +// { "8S1", SERIAL_8S1}, + { "7E1", (serialParamType) SERIAL_7E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN }, + { "7N1", (serialParamType) SERIAL_7N1}, + { "7E2", (serialParamType) SERIAL_7E2}, + { "7N2", (serialParamType) SERIAL_7N2}, + { "7O1", (serialParamType) SERIAL_7O1}, + { "7O2", (serialParamType) SERIAL_7O2} +// { "7M1", SERIAL_7M1}, +// { "7S1", SERIAL_7S1} +} ; + +#define serialModesNum sizeof(serialModes_P)/sizeof(serial_t) + +serialParamType str2SerialParam(char * str) +{ debugSerial<"); + for(uint8_t i=0; i (SERIAL_8N1); +} #pragma message(VAR_NAME_VALUE(debugSerial)) #pragma message(VAR_NAME_VALUE(SERIAL_BAUD)) diff --git a/lighthub/utils.h b/lighthub/utils.h index 91aaf0f..209b6f7 100644 --- a/lighthub/utils.h +++ b/lighthub/utils.h @@ -43,6 +43,12 @@ enum topicType { T_OUT = 3 }; +#if defined(ESP32) +#define serialParamType uint32_t +#else +#define serialParamType uint16_t +#endif + void PrintBytes(uint8_t* addr, uint8_t count, bool newline); void SetBytes(uint8_t* addr, uint8_t count, char * out); void SetAddr(char * out, uint8_t* addr); @@ -67,3 +73,4 @@ bool executeCommand(aJsonObject* cmd, int8_t toggle = -1); bool executeCommand(aJsonObject* cmd, int8_t toggle, itemCmd _itemCmd); itemCmd mapInt(int32_t arg, aJsonObject* map); unsigned long millisNZ(uint8_t shift=0); +serialParamType str2SerialParam(char * str);