[SOLVED] ModbusMaster is blocking part of my code

Hello,

I am working on an application in visual studio 2019 to control a 50 tonne hydraulic press. So far I have got visual studio to connect to the Arduino mega over a COM port and sends strings with the end line character '#' to the Arduino, which then drives certain pins HIGH/LOW to control SSR's, that in turn control the press.

Code: [Select]

    while(Serial.available()>0)
      {
          c = Serial.read();
          SerialData += c;
      }
   
    if(c=='#')//if an End Line Character Received
      {
          if(SerialData=="ON#")
            {  digitalWrite(53, HIGH);
            }
            else if(SerialData=="OFF#"){

              digitalWrite(53, LOW);
            }

          c=0;
          SerialData="";
      }

On the Arduino I am using the ModbusMaster library to talk to a 50 tonne load cell over Modbus RTU, it pulls the readout from the press to the Arduino, which is then sent back over the comport to Visual studio, this is done over Serial1.

Code: [Select]

     ReadLoadCell = node.readInputRegisters(3, 3);
     
       if(ReadLoadCell == node.ku8MBSuccess)
      {
        Current_Pressure = node.getResponseBuffer(0x02);
        Serial.println(Current_Pressure);
      }

Both parts of the code work on their own, but when they are combined the Arduino does not respond to the end line character commands from Visual Studio. It is receiving them as the Rx LED is flashing in when the commands are sent.

I have gone through the code and have isolated the problem to this single line. I do not understand why this line of code is interfering with the end of line commands?

I have an SSR hooked up to pin 53 for testing and when the line below is commented out the LED on the SSR shows it is working as intended.

Code: [Select]

ReadLoadCell = node.readInputRegisters(3, 3);

Link to ModbusMaster Library ModbusMaster

Full code below.

Code: [Select]

//Global Variable

#include <ModbusMaster.h>               //Library for using ModbusMaster
ModbusMaster node;                    //object node for class ModbusMaster
uint8_t ReadLoadCell;
long Current_Pressure;
char c;
String SerialData;

void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
Serial1.begin(9600);             //Baud Rate as 9600
node.begin(1, Serial1);            //Slave ID as 1
pinMode(53,OUTPUT);
digitalWrite(53, LOW);

}

void loop() {
  // put your main code here, to run repeatedly:



   

    while(Serial.available()>0)
      {
          c = Serial.read();
          SerialData += c;
      }
   
    if(c=='#')//if an End Line Character Received
      {
          if(SerialData=="ON#")
            {  digitalWrite(53, HIGH);
            }
            else if(SerialData=="OFF#"){

              digitalWrite(53, LOW);
            }

          c=0;
          SerialData="";
      }

     //ReadLoadCell = node.readInputRegisters(0x30001, 03);
     ReadLoadCell = node.readInputRegisters(3, 3);
     
       if(ReadLoadCell == node.ku8MBSuccess)
      {
        Current_Pressure = node.getResponseBuffer(0x02);
        Serial.println(Current_Pressure);
      }


     
}

Hi !
Can you send your project Schematics ?

Hello,

Add a line of code that prints the contents of SerialData after each character is appended.

Your check for a # character assumes that you are only processing a single message per main loop.
My guess is that the delay introduced by readInputRegisters reduces the rate at which the Arduino processes incoming serial bytes so the Rx buffer fills up with multiple messages. You could end up with a SerialData string such as "ON#OFF#ON#OFF#" which will never match with your search for "ON#" or "OFF#".

I would add that executing a chain of rapid on/off commands is an easy way to destroy large machines because of their mechanical/electrical inertia. Every time you receive an "OFF#" command you need to set a timeout period during which you will ignore any "ON#" commands.

if not solved you can try this:

//c=0;

SerialData="";

Serial1.flush() // Waits for the transmission of outgoing [i]serial[/i] data to complete.

Thanks for all the suggestions everyone.

I was testing this system offline from the press, so it was not receiving any modbus data. I checked out ModbusMaster.H and found this line;

Code: [Select]

    // Modbus timeout [milliseconds]
    static const uint16_t ku16MBResponseTimeout          = 2000; ///< Modbus timeout [milliseconds]

I'm guessing it was putting the system into a constant delay state. I changed the delay to 1ms and everything is working together.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.