I all,
I am trying to implement the Modbus master library (from Doc Walter) on an project, however I am experiencing some issues such as the code running slowly and erroneous readings when I am trying to read more than one register at a time.
In the code bellow, if I call only one of the "read" functions in the loop, the refreshing rate is very fast (<500 ms). If I call more than one function, the refreshing rate is slow (1 sec. aprox) and only one variable returns the correct value, the other readings are erroneous (value remains 0). When I add the delays in between the functions call (in the loop) the readings are correct, however they “block” the code.
Even though I don't need a very fast refreshing rate, I can't afford "blocking" delays. I have tried calling the functions sequentially using "non-blocking delays" (timing them using the millis function) however my code still runs very slowly and "blocks" other functions (e.g. slows down other readings, or slows down button click reaction)
I have tried it on arduino Uno and Mega boards, using various TTL to RS485 converter boards, however the problem persists will all of them. I have hooked some pull up and pull down resistors (392 ohms) between the A and VCC terminal and between B and GND terminal of the RS485 module, as well as 120 omhs termination resistors between A and B but didn't notice any change.
I would be very grateful if you could give me an insight on that.
Thanks in advance,
Aurel
#include <ModbusMaster.h>
//#include <SPI.h>
//#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x3F
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
#define baudRate 9600
ModbusMaster node; // instantiate ModbusMaster object
LiquidCrystal_I2C lcd (0x3F, 2, 1, 0, 4, 5, 6, 7); // set the LCD address to 0x27 for a 16 chars and 2 line display // Set the LCD I2C address
String modbusStatusMessage;
int modbusStatus;
float fluidMfcCapacity;
float fluidMfcTemp;
float fluidMfcFlow;
float fluidMfcCounterValue;
unsigned long fluidMfcValveOutput;
void setup() {
lcd.begin(20, 4); // initialize the lcd for 24 chars 4 lines, turn on backlight
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.setBacklight(HIGH); // Switch on the backlight
lcd.home (); // go home
Serial.begin(baudRate, SERIAL_8E1); // use Serial (port 0); initialize Modbus communication baud rate
node.begin(1, Serial); // communicate with Modbus slave ID 1 over Serial (port 0)
}
void loop() {
readMfcFlow ();
//delay (250);
readMfcCapacity();
//delay (250);
readMfcCounterValue ();
//delay (250);
readMfcFluidTemp ();
//delay (250);
readMfcValveOutput ();
//delay (250);
statusModbus();
printMfcParameters ();
}
void readMfcFluidTemp (){
uint8_t result;
union {
float temp;
uint16_t t[2];
} unitedTempVar;
result = node.readHoldingRegisters(41272, 2);
if (result == node.ku8MBSuccess)
{
unitedTempVar.t [0] = node.getResponseBuffer(0x01);
unitedTempVar.t [1] = node.getResponseBuffer(0x00);
}
fluidMfcTemp= unitedTempVar.temp;
modbusStatus=result;
}
void readMfcCapacity (){
uint8_t result;
union {
float capacity;
uint16_t cap[2];
} unitedVar;
result = node.readHoldingRegisters(33128, 2);
if (result == node.ku8MBSuccess)
{
unitedVar.cap [0] = node.getResponseBuffer(0x01);
unitedVar.cap [1] = node.getResponseBuffer(0x00);
fluidMfcCapacity= unitedVar.capacity;
}
modbusStatus=result;
}
void readMfcFlow (){
uint8_t result;
union {
float flow;
uint16_t b[2];
} unitedVar;
result = node.readHoldingRegisters(41216, 2);
if (result == node.ku8MBSuccess) {
unitedVar.b [0] = node.getResponseBuffer(0x01);
unitedVar.b [1] = node.getResponseBuffer(0x00);
}
fluidMfcFlow= unitedVar.flow;
modbusStatus=result;
}
void readMfcCounterValue (){
uint8_t result;
union {
float counterValue;
uint16_t b[2];
} unitedVar;
result = node.readHoldingRegisters(59400, 2);
if (result == node.ku8MBSuccess)
{
unitedVar.b [0] = node.getResponseBuffer(0x01);
unitedVar.b [1] = node.getResponseBuffer(0x00);
}
fluidMfcCounterValue= unitedVar.counterValue;
modbusStatus=result;
}
void readMfcValveOutput (){
uint8_t result;
union {
unsigned long valveOutput;
uint16_t b[2];
} unitedVar;
result = node.readHoldingRegisters(61960, 2);
if (result == node.ku8MBSuccess)
{
unitedVar.b [0] = node.getResponseBuffer(0x01);
unitedVar.b [1] = node.getResponseBuffer(0x00);
}
fluidMfcValveOutput= unitedVar.valveOutput;
modbusStatus=result;
}
void statusModbus() {
if (modbusStatus == node.ku8MBIllegalFunction) {
modbusStatusMessage = "Modbus Illegal Func.";
} else if (modbusStatus == node.ku8MBIllegalDataAddress) {
modbusStatusMessage = "Modbus Illegal Addr.";
} else if (modbusStatus == node.ku8MBIllegalDataValue) {
modbusStatusMessage = "Modbus Illegal Value";
} else if (modbusStatus == node.ku8MBSlaveDeviceFailure) {
modbusStatusMessage = "Modbus lave failure ";
} else if (modbusStatus == node.ku8MBInvalidSlaveID) {
modbusStatusMessage = "Modbus Inval.slaveID";
} else if (modbusStatus == node.ku8MBInvalidFunction) {
modbusStatusMessage = " Modbus Inval.Func. ";
} else if (modbusStatus == node.ku8MBResponseTimedOut) {
modbusStatusMessage = " Modbus timed out ";
} else if (modbusStatus == node.ku8MBInvalidCRC) {
modbusStatusMessage = " Modbus Invalid CRC ";
} else {
modbusStatusMessage = " Modbus succes ";
}
}
void printMfcParameters (){
lcd.setCursor(0,0);
lcd.print(modbusStatusMessage);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("t:");
lcd.print(fluidMfcTemp,2);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print("Cap:");
lcd.print(fluidMfcCapacity,2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print ("FL:");
lcd.print(fluidMfcFlow,2);
lcd.print(" ");
lcd.setCursor(10,1);
lcd.print("V");
lcd.print(fluidMfcValveOutput,1);
if (fluidMfcValveOutput <100){
lcd.print(" ");
}else lcd.print(" ");
lcd.setCursor(10,2);
lcd.print("CV:");
lcd.print(fluidMfcCounterValue);
lcd.print(" ");
}