Emon & modbus on arduino

Hi All,

running the code below on an arduino uno connects to a modbus master simulator with many timeouts and randomly changing values displayed in the modbus registers,mostly 0’s

Tried other modbus slave libraries for the uno with similar results

Can anyone explain why this is happening ?

Do I need 2 arduino’s ?

One to handle the voltage and current sampling and a second one as the modbus slave connected via UART ?

While testing,emoncms prints perfectly to serial monitor and the modbus slave code works perfectly when reading an analogue input pin on the uno when running by themselves,the issues start when combining them.

Thanks Dave

 /*
 * Copyright © 2011-2012 Stéphane Raimbault <[email protected]>
 * License ISC, see LICENSE for more details.
 * Read holding registers (0x03)
 */

#include <Modbusino.h>

#include <EmonLib.h>              // Include Emon Library

 EnergyMonitor emon1;              // Create an instance

/* Initialize the slave with the ID 1 */

ModbusinoSlave modbusino_slave(1);

/* Allocate a mapping of 10 values */

uint16_t tab_reg[10];


int actual = 0


;void setup() {  

    emon1.voltage(5, 151.33, 1.7);  // Voltage: input pin, calibration, phase_shift
    emon1.current(4, 60.6);        // Current: input pin, calibration.
    modbusino_slave.setup(9600);

 /* The transfer speed is set to 9600 bauds */
}

void loop() {

  int solarvalue = analogRead(A3);
  
  emon1.calcVI(20,2000);          // Calculate all. No.of crossings, time-out 
  
    /* Initialize the  registers to have a value to read - register offset */
  
    tab_reg[0] = (emon1.realPower);
    tab_reg[1] = (emon1.apparentPower);
    tab_reg[2] = (emon1.Vrms);
    tab_reg[3] = (emon1.Irms);
    tab_reg[4] = (emon1.powerFactor);
    //tab_reg[5] = 
    //tab_reg[7] =
    tab_reg[6] = (analogRead(A3));
    

   float voltage = solarvalue * (5.0 / 1023.0);
    
    actual = (voltage / 11);
    delay(10);
    actual = (voltage / 11);
    tab_reg[5] = (actual);
    delay(10);
    
  
    /* Launch Modbus slave loop with:
       - pointer to the mapping
       - max values of mapping */
     
    modbusino_slave.loop(tab_reg, 10);
}

I don’t see why that should be necessary.
One thing I notice immediately is there’s no delay in the main loop. This won’t be important if the modbus library doesn’t return control before it’s finished transmitting, but if it’s like the Arduino Serial library for example, and I don’t know the Modbus library, you need a delay to allow it to complete before launching calcVI( ).

So I suggest adding a significant delay (say 5 s) and see what happens.

Hi Robert,

Thanks for the reply,
I edited the sketch as below and tried delays from 3000 to 5000.
The modbus simulator shows many timeout errors and the register readings still are very erratic even with scan rate set at 10 seconds plus.
Please take a look at my code …

 /*
 * Copyright © 2011-2012 Stéphane Raimbault <[email protected]>
 * License ISC, see LICENSE for more details.
 * Read holding registers (0x03)
 */

#include <Modbusino.h>

#include <EmonLib.h>              // Include Emon Library

 EnergyMonitor emon1;              // Create an instance

/* Initialize the slave with the ID 1 */

ModbusinoSlave modbusino_slave(1);

/* Allocate a mapping of 10 values - edit in last line of code also*/

uint16_t tab_reg[10];

int actual = 0

;void setup() {

    /* The transfer speed is set to 9600 bauds */

    emon1.voltage(5, 151.33, 1.7);  // Voltage: input pin, calibration, phase_shift

    emon1.current(4, 60.6);        // Current: input pin, calibration.

    modbusino_slave.setup(9600);
}

void loop() {
  
 calc();
 
 modbus();
 
 delay (5000);

}

void calc () {
  
  emon1.calcVI(20,2000);          // Calculate all. No.of crossings, time-out 
  
}

  void modbus () {

    int solarvalue = analogRead(A3);
  
    /* Initialize the first register to have a value to read - register offset */
  
    tab_reg[0] = (emon1.realPower);
    tab_reg[1] = (emon1.apparentPower);
    tab_reg[2] = (emon1.Vrms);
    //tab_reg[2] = (vrms);
    tab_reg[3] = (emon1.Irms);
    tab_reg[4] = (emon1.powerFactor);
    tab_reg[6] = (analogRead(A3));
    

   float voltage = solarvalue * (5.0 / 1023.0);
    
    actual = (voltage / 11);
    delay(10);
    actual = (voltage / 11);
    tab_reg[5] = (actual);
    delay(10);
    
  
    /* Launch Modbus slave loop with:
       - pointer to the mapping
       - max values of mapping */
     
    modbusino_slave.loop(tab_reg, 10);
}

How often is the master polling the slave? Or maybe the question is: If the slave’s values don’t change, does the master read them correctly?

I tried polling rates from 5.5 seconds to 10 and 20 seconds.
Many timeout errors shown in the modbus simulator after polling the slave.
Even when the input values from sensors do not change,they are displayed as mostly zero’s in the modbus sim with an occasional value changing here and there ,but accurate reading not displayed and vary widely.
Any ideas ?

It’s been so many years since I did anything with Modbus that I’m struggling to remember much about it. And as I said, I don’t know the library you’re using.

When you write “Modbus simulator”, what is that? I’d expect you to be using a Modbus library in a PC or a real Modbus controller and to be polling data from the Modbus slaves. If you have timeout errors, does that mean that the slave didn’t respond quickly enough, or it’s not responding at all, or doesn’t it say which? Is the timeout value something you can set?

I’ve been guessing that the Modbus slave library is interrupt-driven. Instead of delay(…), you could try setting a timer and only branch into calling calc( ) and modbus( ) when the timer reaches 5000, the rest of the time loop( ) cycles doing nothing. But I’m not sure what delay( ) does internally.

Hi Robert,

I use the modbusino library in the arduino.
Modbus simulator is a modbus master simulator program running on my PC connected serially to the arduino.

This polls the arduino slave at a user configured rate and timeout value can be set, I have tried setting the timeout at over 3000 ms and still get errors.

The timeout error does not give any further info,just goes red and says timeout error,I am guessing the modbus slave is not responding after being polled.

I will fiddle further.

Regards

Sorry I can’t be a lot of help. It’s so long ago that I can’t even remember where I was working at the time, nor the equipment. The slave had to have been a commercial unit - probably a PLC, and I think the master was a PC and a modbus library - but don’t ask me whose. It must have been RS232. I was almost certainly controlling a process and extracting the data back to display to the operator.

I guess your next step will be to look at activity on the bus (if you can) and try to figure out whether the master is always sending the right question, whether the slave is responding correctly, and take it from there.

Experience taught me not to take it for granted that everybody interprets the spec in the same way. Are you able to run the Arduino slave against the Arduino master library - just to prove they work together? If they did, it would show that the slave and your master weren’t compatible, but it wouldn’t prove which was wrong.

Thanks for the suggestions,
I will see what can be done,
Regards Dave