Multiple serials with Arduino Uno and Modbus package

Hello,

I am trying to connect an Energy meter (see datasheet in the attachments) via a RS485 to an Arduino Uno and show the response in the serial monitor on the PC. The connections between Arduino and RS485 are:

RS485 ===========> Arduino UNO
RO ==============> pin 0 (RX)
DE ================> pin 9
RE ================> pin 8
DI ===============> pin 1 (TX)

and A and B of RS485 are connected to A B from meter.

I am using ModbusMaster.h library So far, the best result I could get was with this code:

// Include the libraries
#include <ModbusMaster.h>

// Parameters to read
#define volt 30001
#define current 30007
#define power 30051
#define pin_DE 9
#define pin_RE 8

//Decimals to show
int dec=3;

// instantiate ModbusMaster object
ModbusMaster node;

//Set up ModbusMaster library
/*
int modbus_volt,modbus_curr,modbus_power;
*/
float modbus_volt,modbus_curr,modbus_power;
int status_volt,status_curr,status_power;
uint32_t i;


void setup()
{

  
  // Use Serial (port 0); initialize Modbus communication baud rate 
  // Also need to select 19200 in the meter front panel (see pag. 6 of the 
  // meter datasheet)yes
  Serial.begin(19200,SERIAL_8E1);
/*
  // init vars
  modbus_volt=0;
  modbus_curr=0;
  modbus_power=0;
*/
  i = 0;
 
  
  // communicate with Modbus slave ID 10 over Serial (port 0)
  node.begin(10, Serial);
  delay(100);
  
  //Serial to show data in screen
  Serial.begin(9600);
  
  // Print hello message
  Serial.println("Energy Meter output");
  Serial.println("Voltage Current Watt");
  delay(100);
}
a

void loop() {
  
  static uint32_t i;
  
  // read modbus data
  uint8_t j, result;
  uint16_t data[2];

  i++;

  // set word 0 of TX buffer to least-significant word of counter (bits 15..0)
  node.setTransmitBuffer(0, lowWord(i));

  // set word 1 of TX buffer to most-significant word of counter (bits 31..16)
  node.setTransmitBuffer(1, highWord(i));


  //04 Read input Registers => Read content of read only location ( 3X )
  // slave: read (2) 16-bit registers starting at register 1 to RX buffer
  // Two consecutive 16 bit registers represent one parameter

  //voltage
  result = node.readInputRegisters(volt, 2);
  if (result == node.ku8MBSuccess) {
        for (j = 0; j < 2; j++)
        {
          data[j] = node.getResponseBuffer(j);
        }
      uint32_t lw = (uint32_t)data[0] + (uint32_t)data[1]*65536;
      modbus_volt = *((float*)&lw);
  }
  status_volt = result;

  //current
  result = node.readInputRegisters(current, 2);
  if (result == node.ku8MBSuccess) {
        for (j = 0; j < 2; j++)
        {
          data[j] = node.getResponseBuffer(j);
        }
      uint32_t lw = (uint32_t)data[0] + (uint32_t)data[1]*65536;
      modbus_curr = *((float*)&lw);
  }
  status_curr = result;

    //power
  result = node.readInputRegisters(power, 2);
  if (result == node.ku8MBSuccess) {
        for (j = 0; j < 2; j++)
        {
          data[j] = node.getResponseBuffer(j);
        }
      uint32_t lw = (uint32_t)data[0] + (uint32_t)data[1]*65536;
      modbus_power = *((float*)&lw);
  }
  status_power = result;

  //Show the result
  Serial.print(modbus_volt);
  Serial.print("\t");
  Serial.print(modbus_curr);
  Serial.print("\t");
  Serial.println(modbus_power);

  delay(1000);
}

and it only shows lines of ?@’?0.00 0.00 0.00

Searching around I found out that the problem is that the Arduino UNO can not handle two Serial at the same time (Arduino Mega o Leonardo do, but I don’t have them). So I tried to debug the response in the serial monitor with SoftwareSerial.h and AltSoftSerial.h libraries. The problem is that I think SoftwareSerial can not be used with the Arduino USB (it is connected to the PC via USB) as you need to specify TX/RX pins, and I read here that Modbus library does not work well with AltSolfSerial. How can I show the response of the meter in the monitor?

Also, I would like to know if I have to initialize pins 8 and 9 (connected to RE and DE) in the code to make it work.

em13xx_manual_good.pdf (1.98 MB)

  Serial.begin(19200,SERIAL_8E1);

... 

  // communicate with Modbus slave ID 10 over Serial (port 0)
  node.begin(10, Serial);
  delay(100);

  //Serial to show data in screen
  Serial.begin(9600);

I hope you see that you're using the same resource (the hardware serial interface) for two different tasks. This simply cannot work. The second Serial.begin() overwrites the first call.

If you must communicate with the Modbus device and the PC, an UNO is the wrong Arduino for the job. You need a board with at least one hardware serial interface independent from the connection to the PC. A Leonardo or a Mega2560 are two boards that would fulfill this requirement.

Thank you Pylon for the response. Yes, I noticed I am overlapping the Serial, but is there no way to use a library or something with Arduino UNO yo solve the problem. Or is it possible to record the data from de Modbus in a file (e.g. a txt) instead of showing it on the monitor without any Serial issue?

Mpedrosab: So I tried to debug the response in the serial monitor with SoftwareSerial.h and AltSoftSerial.h libraries. The problem is that I think SoftwareSerial can not be used with the Arduino USB (

That is indeed not on. No comment on why modbus cannot be used with software serial but, yes, you could either: Record data onto SD using the SPI bus for later use or Send data direct to a proper PC terminal programme like RealTerm via Bluetooth on software serial.

The later offers timestamping, which you may find useful.

No comment on why modbus cannot be used with software serial

Because Modbus (strictly by the standard) devices use parity and SoftwareSerial doesn't support that.

Yes, I noticed I am overlapping the Serial, but is there no way to use a library or something with Arduino UNO yo solve the problem

Nick_Pyner suggested some ways. Another one may be to use the UNO solely as a USB-to-serial adapter (it's onboard ATmega16U2 is doing that) and use libmodbus on the PC to decode that Modbus messages. As you didn't told us yet what you're planning to do with the data on the PC it's hard to give you recommendations.

Thank you all for your responses.

pylon: Nick_Pyner suggested some ways. Another one may be to use the UNO solely as a USB-to-serial adapter (it's onboard ATmega16U2 is doing that) and use libmodbus on the PC to decode that Modbus messages. As you didn't told us yet what you're planning to do with the data on the PC it's hard to give you recommendations.

I want to have the data in the PC because I want to send it later to the cloud. What is the process to use the arduino as a USB/serial converter and then libmodbus?. Sorry but I am quite new to these Modbus protocols

Mpedrosab: I want to send it later to the cloud.

This loose language. You may want to use internet of things, whereby you send the send the data now, as it is generated, rather than later - and no PC required.

And possibly no Arduino either, a Node-MCU talks to the world via WiFi. All you need do is ensure that Modbus will talk sensibly with Node-MCU.

Thank you Nick_Pyner. Sorry for my "loose language" but as I said I am not am expert in this. And is is possible to use a ES32 with Modbus? That way data can be sent directly via WiFi

I don’t know anything about Modbus but, if it is a serial device, it should talk via hardware or software serial like any other serial device. I don’t know how there could be a problem and my caution in reply #6 is only in the light of a potential problem in your original post concerning the Modbus library. I have since had a quick look and all I can conclude is that the other guy adwsystems hasn’t the faintest idea about what he is doing. It could be that this Modbus thing has a fixed baud rate that is more than a software serial can handle but I saw no mention of that, and hardware serial should handle that OK anyway.

I assume you are now alluding to the ESP32. This is essentially an advanced form of the Node-MCU. I believe it comes in varying forms and should be just fine. Mine is a dev board by Heltec, and comes with an on-board display.

While I talk Node-MCU, you may find you an get by with the most basic ESP8266, costing about $3.

And is is possible to use a ES32 with Modbus?

Yes, it is, the bigger problem usually is to get an RS-485 adapter that runs on 3V3 (as the ESPs do).

I did a deeper check of the EM13XX manual. You can change both, the baud rate and the parity setting over the display. If you set it to 9600 baud and no parity you might use SoftwareSerial (or better AltSoftSerial but note that this one is fixed to pins 8/9).

Ok. Thank all of you very much