modbus driver for ESP32 fix, INPUT&HANDLE REGISTERS

This commit is contained in:
2021-03-22 03:49:08 +03:00
parent 0d231345c2
commit 3d03aa661d
2 changed files with 82 additions and 45 deletions

View File

@@ -25,7 +25,7 @@ struct reg_t
struct serial_t
{
const char verb[4];
const uint16_t mode;
const serialParamType mode;
};
#define PAR_I16 1
@@ -55,37 +55,40 @@ const reg_t regSize_P[] PROGMEM =
const serial_t serialModes_P[] PROGMEM =
{
{ "8E1", (uint16_t) SERIAL_8E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN },
{ "8N1", (uint16_t) SERIAL_8N1},
{ "8E2", (uint16_t) SERIAL_8E2},
{ "8N2", (uint16_t) SERIAL_8N2},
{ "8O1", (uint16_t) SERIAL_8O1},
{ "8O2", (uint16_t) SERIAL_8O2},
{ "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", (uint16_t) SERIAL_7E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN },
{ "7N1", (uint16_t) SERIAL_7N1},
{ "7E2", (uint16_t) SERIAL_7E2},
{ "7N2", (uint16_t) SERIAL_7N2},
{ "7O1", (uint16_t) SERIAL_7O1},
{ "7O2", (uint16_t) SERIAL_7O2}
{ "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)
uint16_t str2SerialParam(char * str)
serialParamType str2SerialParam(char * str)
{ debugSerial<<str<<F(" =>");
for(uint8_t i=0; i<serialModesNum && str;i++)
if (strcmp_P(str, serialModes_P[i].verb) == 0)
{
debugSerial<< i << F(" ") << pgm_read_word_near(&serialModes_P[i].mode)<< endl;
//debugSerial<< i << F(" ") << pgm_read_word_near(&serialModes_P[i].mode)<< endl;
if (sizeof(serialModesNum)==4)
return pgm_read_dword_near(&serialModes_P[i].mode);
else
return pgm_read_word_near(&serialModes_P[i].mode);
}
debugSerial<< F("Default serial mode N81 used");
return static_cast<uint16_t> (SERIAL_8N1);
return static_cast<serialParamType> (SERIAL_8N1);
}
int str2regSize(char * str)
{
@@ -123,13 +126,19 @@ bool out_Modbus::getConfig()
aJsonObject * baudObj=aJson.getObjectItem(templateObj, "baud");
if (baudObj && baudObj->type == aJson_Int && baudObj->valueint) store->baud = baudObj->valueint;
else store->baud = 9600;
modbusSerial.begin(store->baud, store->serialParam);
aJsonObject * pollObj=aJson.getObjectItem(templateObj, "poll");
if (pollObj && pollObj->type == aJson_Object)
{
store->pollingRegisters=aJson.getObjectItem(pollObj, "regs");
store->pollingInterval =aJson.getObjectItem(pollObj, "delay")->valueint;
store->pollingIrs=aJson.getObjectItem(pollObj, "irs");
aJsonObject * delayObj= aJson.getObjectItem(pollObj, "delay");
if (delayObj) store->pollingInterval = delayObj->valueint;
else store->pollingInterval = 1000;
}
else {store->pollingRegisters=NULL;store->pollingInterval = 1000;}
else {store->pollingRegisters=NULL;store->pollingInterval = 1000;store->pollingIrs=NULL;}
store->parameters=aJson.getObjectItem(templateObj, "par");
return true;
@@ -209,13 +218,19 @@ return (result == node.ku8MBSuccess);
int out_Modbus::findRegister(int registerNum, int posInBuffer)
int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
{
aJsonObject * paramObj = store->parameters->child;
bool is8bit = false;
while (paramObj)
{
aJsonObject *regObj = aJson.getObjectItem(paramObj, "reg");
aJsonObject *regObj;
switch (regType) {
case MODBUS_HOLDING_REG_TYPE: regObj = aJson.getObjectItem(paramObj, "reg");
break;
case MODBUS_INPUT_REG_TYPE: regObj = aJson.getObjectItem(paramObj, "ir");
}
if (regObj && regObj->valueint ==registerNum)
{
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
@@ -301,24 +316,12 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer)
return is8bit;
}
int out_Modbus::Poll(short cause)
{
if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && isTimeOver(store->timestamp,millis(),store->pollingInterval))
{
debugSerial<<F("Poll ")<< item->itemArr->name << endl;
modbusBusy=1;
//store->serialParam=(USARTClass::USARTModes) SERIAL_8N1;
#if defined (__SAM3X8E__)
modbusSerial.begin(store->baud, static_cast <USARTClass::USARTModes> (store->serialParam));
#elif defined (ARDUINO_ARCH_ESP8266)
modbusSerial.begin(store->baud, static_cast <SerialConfig>(store->serialParam));
#else
modbusSerial.begin(store->baud, (store->serialParam));
#endif
debugSerial<< store->baud << F("---")<< store->serialParam<<endl;
node.begin(item->getArg(0), modbusSerial);
aJsonObject * reg = store->pollingRegisters->child;
void out_Modbus::pollModbus(aJsonObject * reg, int regType)
{
if (!reg) return;
reg=reg->child;
//aJsonObject * reg = store->pollingRegisters->child;
while (reg)
{
switch (reg->type)
@@ -326,9 +329,10 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i
case aJson_Int:
{
int registerNum = reg->valueint;
if (readModbus(registerNum,MODBUS_HOLDING_REG_TYPE,1))
//if (readModbus(registerNum,MODBUS_HOLDING_REG_TYPE,1))
if (readModbus(registerNum,regType,1))
{
findRegister(registerNum,0);
findRegister(registerNum,0,regType);
// data = node.getResponseBuffer(j);
}
}
@@ -339,11 +343,12 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i
int registerFrom=aJson.getArrayItem(reg, 0)->valueint;
int registerTo=aJson.getArrayItem(reg, 1)->valueint;
if (readModbus(registerFrom,MODBUS_HOLDING_REG_TYPE,registerTo-registerFrom+1))
//if (readModbus(registerFrom,MODBUS_HOLDING_REG_TYPE,registerTo-registerFrom+1))
if (readModbus(registerFrom,regType,registerTo-registerFrom+1))
{
for(int i=registerFrom;i<=registerTo;i++)
{
findRegister(i,i-registerFrom);
findRegister(i,i-registerFrom,regType);
}
//data = node.getResponseBuffer(j);
}
@@ -353,6 +358,31 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i
}
reg = reg->next;
}
}
int out_Modbus::Poll(short cause)
{
if ((store->pollingRegisters || store->pollingIrs) && !modbusBusy && (Status() == CST_INITIALIZED) && isTimeOver(store->timestamp,millis(),store->pollingInterval))
{
debugSerial<<F("Poll ")<< item->itemArr->name << endl;
modbusBusy=1;
//store->serialParam=(USARTClass::USARTModes) SERIAL_8N1;
#if defined (__SAM3X8E__)
modbusSerial.begin(store->baud, static_cast <USARTClass::USARTModes> (store->serialParam));
#elif defined (ARDUINO_ARCH_ESP8266)
modbusSerial.begin(store->baud, static_cast <SerialConfig>(store->serialParam));
#elif defined (ESP32)
//modbusSerial.begin(store->baud, store->serialParam);
//delay(100);
modbusSerial.updateBaudRate (store->baud); //Some terrible error in ESP32 core with uart reinit
#else
modbusSerial.begin(store->baud, (store->serialParam));
#endif
debugSerial<< store->baud << F("---")<< store->serialParam<<endl;
node.begin(item->getArg(0), modbusSerial);
pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE);
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
store->timestamp=millisNZ();
debugSerial<<F("endPoll ")<< item->itemArr->name << endl;

View File

@@ -4,6 +4,11 @@
#include <abstractout.h>
#include <item.h>
#if defined(ESP32)
#define serialParamType uint32_t
#else
#define serialParamType uint16_t
#endif
class mbPersistent : public chPersistent {
@@ -11,10 +16,11 @@ public:
// int addr
int8_t driverStatus;
int baud;
uint16_t serialParam;
serialParamType serialParam;
uint16_t pollingInterval;
uint32_t timestamp;
aJsonObject * pollingRegisters;
aJsonObject * pollingIrs;
aJsonObject * parameters;
};
@@ -36,6 +42,7 @@ public:
protected:
mbPersistent * store;
bool getConfig();
int findRegister(int registerNum, int posInBuffer);
int findRegister(int registerNum, int posInBuffer, int regType);
void pollModbus(aJsonObject * reg, int regType);
};
#endif