mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
modbus driver for ESP32 fix, INPUT&HANDLE REGISTERS
This commit is contained in:
@@ -25,7 +25,7 @@ struct reg_t
|
|||||||
struct serial_t
|
struct serial_t
|
||||||
{
|
{
|
||||||
const char verb[4];
|
const char verb[4];
|
||||||
const uint16_t mode;
|
const serialParamType mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PAR_I16 1
|
#define PAR_I16 1
|
||||||
@@ -55,37 +55,40 @@ const reg_t regSize_P[] PROGMEM =
|
|||||||
|
|
||||||
const serial_t serialModes_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 },
|
{ "8E1", (serialParamType) SERIAL_8E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN },
|
||||||
{ "8N1", (uint16_t) SERIAL_8N1},
|
{ "8N1", (serialParamType) SERIAL_8N1},
|
||||||
{ "8E2", (uint16_t) SERIAL_8E2},
|
{ "8E2", (serialParamType) SERIAL_8E2},
|
||||||
{ "8N2", (uint16_t) SERIAL_8N2},
|
{ "8N2", (serialParamType) SERIAL_8N2},
|
||||||
{ "8O1", (uint16_t) SERIAL_8O1},
|
{ "8O1", (serialParamType) SERIAL_8O1},
|
||||||
{ "8O2", (uint16_t) SERIAL_8O2},
|
{ "8O2", (serialParamType) SERIAL_8O2},
|
||||||
// { "8M1", SERIAL_8M1},
|
// { "8M1", SERIAL_8M1},
|
||||||
// { "8S1", SERIAL_8S1},
|
// { "8S1", SERIAL_8S1},
|
||||||
{ "7E1", (uint16_t) SERIAL_7E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN },
|
{ "7E1", (serialParamType) SERIAL_7E1},//(uint16_t) US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_EVEN },
|
||||||
{ "7N1", (uint16_t) SERIAL_7N1},
|
{ "7N1", (serialParamType) SERIAL_7N1},
|
||||||
{ "7E2", (uint16_t) SERIAL_7E2},
|
{ "7E2", (serialParamType) SERIAL_7E2},
|
||||||
{ "7N2", (uint16_t) SERIAL_7N2},
|
{ "7N2", (serialParamType) SERIAL_7N2},
|
||||||
{ "7O1", (uint16_t) SERIAL_7O1},
|
{ "7O1", (serialParamType) SERIAL_7O1},
|
||||||
{ "7O2", (uint16_t) SERIAL_7O2}
|
{ "7O2", (serialParamType) SERIAL_7O2}
|
||||||
// { "7M1", SERIAL_7M1},
|
// { "7M1", SERIAL_7M1},
|
||||||
// { "7S1", SERIAL_7S1}
|
// { "7S1", SERIAL_7S1}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
#define serialModesNum sizeof(serialModes_P)/sizeof(serial_t)
|
#define serialModesNum sizeof(serialModes_P)/sizeof(serial_t)
|
||||||
|
|
||||||
uint16_t str2SerialParam(char * str)
|
serialParamType str2SerialParam(char * str)
|
||||||
{ debugSerial<<str<<F(" =>");
|
{ debugSerial<<str<<F(" =>");
|
||||||
for(uint8_t i=0; i<serialModesNum && str;i++)
|
for(uint8_t i=0; i<serialModesNum && str;i++)
|
||||||
if (strcmp_P(str, serialModes_P[i].verb) == 0)
|
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;
|
||||||
return pgm_read_word_near(&serialModes_P[i].mode);
|
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");
|
debugSerial<< F("Default serial mode N81 used");
|
||||||
return static_cast<uint16_t> (SERIAL_8N1);
|
return static_cast<serialParamType> (SERIAL_8N1);
|
||||||
}
|
}
|
||||||
int str2regSize(char * str)
|
int str2regSize(char * str)
|
||||||
{
|
{
|
||||||
@@ -123,13 +126,19 @@ bool out_Modbus::getConfig()
|
|||||||
aJsonObject * baudObj=aJson.getObjectItem(templateObj, "baud");
|
aJsonObject * baudObj=aJson.getObjectItem(templateObj, "baud");
|
||||||
if (baudObj && baudObj->type == aJson_Int && baudObj->valueint) store->baud = baudObj->valueint;
|
if (baudObj && baudObj->type == aJson_Int && baudObj->valueint) store->baud = baudObj->valueint;
|
||||||
else store->baud = 9600;
|
else store->baud = 9600;
|
||||||
|
|
||||||
|
modbusSerial.begin(store->baud, store->serialParam);
|
||||||
aJsonObject * pollObj=aJson.getObjectItem(templateObj, "poll");
|
aJsonObject * pollObj=aJson.getObjectItem(templateObj, "poll");
|
||||||
if (pollObj && pollObj->type == aJson_Object)
|
if (pollObj && pollObj->type == aJson_Object)
|
||||||
{
|
{
|
||||||
store->pollingRegisters=aJson.getObjectItem(pollObj, "regs");
|
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");
|
store->parameters=aJson.getObjectItem(templateObj, "par");
|
||||||
return true;
|
return true;
|
||||||
@@ -209,14 +218,20 @@ 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;
|
aJsonObject * paramObj = store->parameters->child;
|
||||||
bool is8bit = false;
|
bool is8bit = false;
|
||||||
while (paramObj)
|
while (paramObj)
|
||||||
{
|
{
|
||||||
aJsonObject *regObj = aJson.getObjectItem(paramObj, "reg");
|
aJsonObject *regObj;
|
||||||
if (regObj && regObj->valueint ==registerNum)
|
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");
|
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
|
||||||
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
||||||
@@ -301,24 +316,12 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer)
|
|||||||
return is8bit;
|
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)
|
while (reg)
|
||||||
{
|
{
|
||||||
switch (reg->type)
|
switch (reg->type)
|
||||||
@@ -326,9 +329,10 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i
|
|||||||
case aJson_Int:
|
case aJson_Int:
|
||||||
{
|
{
|
||||||
int registerNum = reg->valueint;
|
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);
|
// data = node.getResponseBuffer(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,11 +343,12 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i
|
|||||||
int registerFrom=aJson.getArrayItem(reg, 0)->valueint;
|
int registerFrom=aJson.getArrayItem(reg, 0)->valueint;
|
||||||
int registerTo=aJson.getArrayItem(reg, 1)->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++)
|
for(int i=registerFrom;i<=registerTo;i++)
|
||||||
{
|
{
|
||||||
findRegister(i,i-registerFrom);
|
findRegister(i,i-registerFrom,regType);
|
||||||
}
|
}
|
||||||
//data = node.getResponseBuffer(j);
|
//data = node.getResponseBuffer(j);
|
||||||
}
|
}
|
||||||
@@ -353,6 +358,31 @@ if (store->pollingRegisters && !modbusBusy && (Status() == CST_INITIALIZED) && i
|
|||||||
}
|
}
|
||||||
reg = reg->next;
|
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();
|
store->timestamp=millisNZ();
|
||||||
debugSerial<<F("endPoll ")<< item->itemArr->name << endl;
|
debugSerial<<F("endPoll ")<< item->itemArr->name << endl;
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
#include <abstractout.h>
|
#include <abstractout.h>
|
||||||
#include <item.h>
|
#include <item.h>
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
#define serialParamType uint32_t
|
||||||
|
#else
|
||||||
|
#define serialParamType uint16_t
|
||||||
|
#endif
|
||||||
|
|
||||||
class mbPersistent : public chPersistent {
|
class mbPersistent : public chPersistent {
|
||||||
|
|
||||||
@@ -11,10 +16,11 @@ public:
|
|||||||
// int addr
|
// int addr
|
||||||
int8_t driverStatus;
|
int8_t driverStatus;
|
||||||
int baud;
|
int baud;
|
||||||
uint16_t serialParam;
|
serialParamType serialParam;
|
||||||
uint16_t pollingInterval;
|
uint16_t pollingInterval;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
aJsonObject * pollingRegisters;
|
aJsonObject * pollingRegisters;
|
||||||
|
aJsonObject * pollingIrs;
|
||||||
aJsonObject * parameters;
|
aJsonObject * parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,6 +42,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
mbPersistent * store;
|
mbPersistent * store;
|
||||||
bool getConfig();
|
bool getConfig();
|
||||||
int findRegister(int registerNum, int posInBuffer);
|
int findRegister(int registerNum, int posInBuffer, int regType);
|
||||||
|
void pollModbus(aJsonObject * reg, int regType);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user