I want to connect 2 MCU (ESP32 with STM) via Uart using Modbus. I saw implementations with a RS485-modul, but that is kinda overkill for my Project. I simply want to connect TX/RX Pins and communicate via Modbus.
The implementations you saw were for Modbus over RS-485. Using RS-485 allows you to connect more than 2 devices together - aka a multi-drop bus.
If you simply want ONLY 2 devices to communicate then you can normally use the TX/RX pins providing that they are not being used for other purposes such as a serial-USB interface. This is ok for short distances, but for longer distances you really should consider some sort of line driver.
Hey @markd833
it is for short distance only. They are both connected via a serial line on a circuit board and it is not planned to add any others MCU's.
Well i have to implement Modbus. I do an internship for a company and they told me to implement Modbus as a communication between 2 MCU. I researched about my topic. As far as i saw, there is no library for modbus communicatino without rs-xxx modules.
I think i have to deal with every single packet which is about to be send via the serial line.
Or do you have any recommendations? It sounds like you are more experienced with modbus on Arduino
As you are only using 2 devices, you can skip over all the RS-485 module stuff.
You can connect the UARTS so MCU #1 Tx -> MCU #2 Rx and MCU #1 Rx -> MCU #2 Tx.
The Modbus libraries will usually reference signals called RE (received enable) & DE (transmit enable). These 2 signals are used to enable/disable the Tx & Rx interface inside a MAX485 (for example). As you are using direct comms, you can either remove (or comment out) the code that drives these pins, or declare a couple of unused pins as being connected to RE & DE instead.
The rest of the Modbus library code should function as is.
I'm not sure what you mean by this? Are you listening in to the Modbus messages? I think there are 2 Modbus protocols over serial. There's an ASCII version (which uses printable characters) and a binary version, which I think is called Modbus-RTU.
Note that in order to have a debug serial console output as well as a Modbus, you need 2 serial interfaces. Either 2 hardware UARTS or 1 hardware and 1 software UART. You shouldn't use the same serial port for both Modbus and debug.
for this example code provided by the Library creater:
/*
RS485_HalfDuplex.pde - example using ModbusMaster library to communicate
with EPSolar LS2024B controller using a half-duplex RS485 transceiver.
This example is tested against an EPSolar LS2024B solar charge controller.
See here for protocol specs:
http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf
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(115200);
// Modbus slave ID 1
node.begin(1, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
bool state = true;
void loop()
{
uint8_t result;
uint16_t data[6];
// Toggle the coil at address 0x0002 (Manual Load Control)
result = node.writeSingleCoil(0x0002, state);
state = !state;
// Read 16 registers starting at 0x3100)
result = node.readInputRegisters(0x3100, 16);
if (result == node.ku8MBSuccess)
{
Serial.print("Vbatt: ");
Serial.println(node.getResponseBuffer(0x04)/100.0f);
Serial.print("Vload: ");
Serial.println(node.getResponseBuffer(0xC0)/100.0f);
Serial.print("Pload: ");
Serial.println((node.getResponseBuffer(0x0D) +
node.getResponseBuffer(0x0E) << 16)/100.0f);
}
delay(1000);
}
I send the Message to a USB-Serial-interface so i can see the incoming message via PUTTY.
Ah! The Arduino IDE serial monitor can't display binary so you get the "weird" characters. You need a terminal program that can display binary. I think termite can do that, but there are others.