Hello,
I have a 3-phase AC voltage multimeter with Modbus RTU RS485 interface (Electrex Femto D4). I want to read 3 voltages and display in the serial monitor, but I get a mix of random characters and other strings.
Connections:
Arduino Uno
TTL-RS485 module
RE-DE to pin 2 and 3
DI-RX
RO-TX
Address: 27
Baudrate 38400 8N2
Here is my code, which is a modified version of the example provided in the library ModbusMaster;
/*
RS485_HalfDuplex.pde - example using ModbusMaster library to communicate
with .......... using a half-duplex RS485 transceiver.
Library:: ModbusMaster
Author:: Marius Kintel <marius at kintel dot net>
Copyright:: 2009-2016 Doc Walker
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <ModbusMaster.h>
/*!
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE 3
#define MAX485_RE_NEG 2
// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 115200 baud
Serial.begin(38400, SERIAL_8N2);
// Modbus slave ID 1
node.begin(27, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop()
{
uint8_t result;
uint16_t data[6];
// Read 3 registers starting at 0x220)
result = node.readInputRegisters(0x220, 3);
if (result == node.ku8MBSuccess)
{
Serial.print("V1: ");
Serial.println(node.getResponseBuffer(0x01));
Serial.print("V2: ");
Serial.println(node.getResponseBuffer(0x02));
Serial.print("V3:");
Serial.println(node.getResponseBuffer(0x03));
} else Serial.println("fail");
delay(500);
}
First thing I don't understand: I must be using two serial ports (one for the RS485 and one for the serial monitor), but in the source code seems that there is only one serial port! :o
Second: who is writing in the crap in the serial monitor? (see attached screen-shot)
Third: I failed to succeed using all the libraries for modbus RS485 I could find around. On which one shall I focus on? Which modbus master library would you recommend?
you later use the same serial interface for debugging output. That doesn't work as you get all the binary ModBus stuff to the same serial interface.
TTL-RS485 module
Post a link to that hardware as there are dozens of them.
First thing I don't understand: I must be using two serial ports (one for the RS485 and one for the serial monitor), but in the source code seems that there is only one serial port!
Depending on the hardware you're using you might give out some debugging text to the serial interface while the RS-485 driver is deactivated but then it's your responsibility to distinguish between the debugging text and the binary codes of the ModBus protocol. The example of the ModbusMaster library is not wisely chosen in this regard.
Third: I failed to succeed using all the libraries for modbus RS485 I could find around. On which one shall I focus on? Which modbus master library would you recommend?
That depends on your needs. I use the ModBus Master-Slave library because it supports both master and slave modes and I need both. None of the libraries I found doesn't have some drawbacks so you have to choose yourself.
I want to read the voltage measurements from the Modbus multimeter, and display in the computer serial monitor. I would like to use two serial interfaces: one for debug (pin 0 an 1 on the arduino uno), and one for the RS485. Is it possible?
I understood that if I want to use RS485 instead of RS232 with the library Modbus-Master-Slave-for-Arduino on the Uno I must use the serial port pins 0 an 1. This pins also belong to the FTDI chip.
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* u8serno : serial port (use 0 for Serial)
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus master(0); // this is master and RS-232 or USB-FTDI via software serial
in my case:
Modbus master(0, 0, 2);
Address of master: 0
Serial port: 0 (pin 0 an 1 of arduino Uno)
DE-RE pins: to pin 2 of the arduino Uno.
On the UNO I only have one serial port (is it 0?). This means I will have a mix of RS485 and Serial.print stuff in the serial terminal. But, the serial terminal is empty
I want to read the voltage measurements from the Modbus multimeter, and display in the computer serial monitor. I would like to use two serial interfaces: one for debug (pin 0 an 1 on the arduino uno), and one for the RS485. Is it possible?
Not with the UNO. If you want to use it this way. get a Mega2560 (4 serial interfaces) or a Leonardo (Serial is a virtual USB serial interface, while Serial1 is a hardware serial interface on pin 0 and 1).
Are D3 and D4 for the RS485?
Where shall the DE and RE pin be connected to the Arduino Uno?
Forget SoftwareSerial in your setup. It might work up to 9600 baud but only if you use 8N1 (it doesn't support any other mode). And SoftwareSerial is crippled piece of software that you should never use in a productive environment.
This pins also belong to the FTDI chip.
The UNO doesn't have an FTDI chip, it has an ATmega16U2 coprocessor for the USB2Serial task.
On the UNO I only have one serial port (is it 0?). This means I will have a mix of RS485 and Serial.print stuff in the serial terminal. But, the serial terminal is empty
Ok, I will drop the use of the SoftwareSerial, and use an LCD to display what I hope to read with the RS485 connected on the RX-TX of arduino UNO. Merry Christmas