[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.

    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.

     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.

ReadLoadCell = node.readInputRegisters(3, 3);

Link to ModbusMaster Library ModbusMaster

Full code below.

//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);
      }


      
}

Does VS send any additional characters after your command string, like CR/LF? Try printing out each character you read in hex to the serial console.

In any case, you should read Robin2's guide to reading serial and restructure your sketch accordingly.

Trying to get a string at a time is typically not a good approach. (Well, I'd not do it that way.) You can't control when data will show up and how much. You could get a string fragment them drop out of your loop. Heck even sitting in a loop waiting for data to come in is somewhat iffy.

Parse each char, one at a time as you go through loop() looking for #. Then do your action.

Also, it would be better to use one of the built-in line endings. For example '\n'. This is what they are there for. And, when you use code like it was designed to be used it tends to give you less issues.

or not..

-jim lee

arduarn & jimlee

Thanks for the link to the Serial guide and all the advice, I will take the recommendations onboard for proper syntax going forwards.

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;

    // 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.