Raspberry 3 + Arduino Uno USB + MODBus RTU

  • marv-nene

    marv-nene - 2016-05-03

    I'm using the following setup:
    - Raspberrry Pi 3 (Modbus RTU Master)
    - Codesys Runtime (Current Version)
    - Arduino UNO (Modbus RTU Slave)

    The Raspberry Pi controls the logic and the Arduino uno is for the periphery. They're connected per USB. Communication over modbus rtu works between these two and I testet it with different bitrates.
    Modbus RTU works after every code upload quite well.
    But after every cold boot, codesys does not recognize the Arduino as Slave.
    In this case, a "cold reboot" helps to fix the the problem in most cases.

    Have anyone an idea where the problem is or a guess how to fix it?

  • eschwellinger

    eschwellinger - 2016-05-04

    I would recommend to check:
    1. If the startup is done and the communication stucks with modbus rtu, Login with CODESYS and check the device tree
    - which components have a green\red sign (Modbus Master / Modbus Slave / Modbus Comport)
    - Then add the name of the slave (the name in the devicetree) to the watchwindow and check the communications states, if there is an slave error you should see this
    Maybe you give us a few screenshots of these states to see what happens

  • marcys

    marcys - 2016-05-28

    Hello marv_nene,

    Would You like to post screen how you connect raspberry with arduino and how you configure it?
    I want to do the same to control my home


  • marv-nene

    marv-nene - 2016-05-31

    @Edwin, thanks for your response, but I figured out a solution:

    IF (xInit = FALSE) THEN
       Modbus_Slave_COM_Port.xReset := FALSE;
    xInit := TRUE;
    IF Modbus_Slave_COM_Port.xError THEN
       Modbus_Slave_COM_Port.xReset := TRUE;
       Modbus_Master_COM_Port.xResetComPort := TRUE;
       Modbus_Master_COM_Port.xStop := TRUE;
       Modbus_Slave_COM_Port.xReset := FALSE;
       Modbus_Master_COM_Port.xResetComPort := FALSE;
       Modbus_Master_COM_Port.xStop := FALSE;

    I guess, the problem is the following: When the raspberry boots, the COM port for the arduino is initialized after the start of the codesys runtime, or it seems it needs longer then expected. So, the automatic reconnection doesn't work for me. When I do it manually, it works. This code is executed every 5 seconds.

    I will respond you later.

  • marcys

    marcys - 2016-06-01

    Hi marv_nene,

    Ok, Thank You. I will wait for response.

  • marv-nene

    marv-nene - 2016-06-09

    Hello Marcys,
    so, first you have to configure the USB Com Port of your connected Arduino described in thishttp://forum.codesys.com/viewtopic.php?f=21&t=6755&p=14284&hilit=modbus+rtu#p14284

    For ModBus on Arduino, you can use the ModBusIno Library from stephane @[url]https://github.com/stephane/modbusino
    [/url]. It works for me with
    Baud : 38400
    Parity: none
    Data Bits: 8
    Stop bits: 2

    In Codesys add a Com-Port-> Modbus RTU Master-> Modbus Slave

    In the Modbus Master deactivate the "auto reconnect" and use my code above.
    A good idea is, to create a task for it, which circles all 30 sec.

    Hope, this will help you.

  • marcys

    marcys - 2016-06-10

    Hello marv_nene,

    Would you like to post some screenshot and code example. I did what you wrote but it does not work for me:-(


  • sandro66

    sandro66 - 2016-07-15

    You need to set .xResetComPort and .xStop flags for a minimun of 5 sec.

    Hope, this will help you.


  • alverman

    alverman - 2017-05-17

    I tried inserting the code in a task to check the status of the arduino connection but it does not work automatically.
    When I unplug the arduino usb cable I can not see Modbus_Slave_COM_Port.xError switched from FALSE to TRUE so when connecting the cable the connection is not restored.
    If I force the state of xError to TRUE and then put it back to FALSE the connection re-establishes.

    Where am I wrong?

    Thank you, Alberto

    IMG: CSYS_2.png

    IMG: CSYS_1.png

  • elconfa

    elconfa - 2018-11-22

    Hi, I'm trying to connect Raspberry 3 B + to Arduino Mega via USB cable. In Arduino I loaded the sample program of the Modbusino library. I added the inscription:

    Linux.Devicefile = / dev / ttyUSB
    portnum: = COM.SysCom.SYS_COMPORT1;

    in the CODESYSControl.cfg file.

    Arduino is programmed directly by Raspberry and the Arduino IDE sees the card connected on the /dev/ttyUSB0 port.
    I tried at various speeds, but I can not read or write anything.

    Could someone post a sample code for Arduino and for Raspberry Codesys to try?

    In next post I will submit all my project.

    Thanks in advance to everyone that would help me.


    [SOLVED] Now it work. From Raspberry to Arduino Mega it is possible to control all Input and Output

    The code for Arduino:

    * Modbus slave example 2:
    * The purpose of this example is to link the Arduino digital and analog
    * pins to an external device.

    * Recommended Modbus Master: QModbus
    * http://qmodbus.sourceforge.net/

    * Editado al español por LuxARTS

    //Incluye la librería del protocolo Modbus
    #include <modbusrtu.h>
    #define ID 1</modbusrtu.h>

    //Crear instancia
    Modbus slave(ID, 0, 0); //ID del nodo. 0 para el master, 1-247 para esclavo
    //Puerto serie (0 = TX: 1 - RX: 0)
    //Protocolo serie. 0 para RS-232 + USB (default), cualquier pin mayor a 1 para RS-485
    boolean led;
    int8_t state = 0;
    unsigned long tempus;

    uint16_t au16data[8]; //La tabla de registros que se desea compartir por la red

    Configuración del programa
    void setup() {
    io_setup(); //configura las entradas y salidas

    slave.begin(19200); //Abre la comunicación como esclavo
    tempus = millis() + 100; //Guarda el tiempo actual + 100ms
    digitalWrite(13, HIGH ); //Prende el led del pin 13 (el de la placa)

    Inicio del programa
    void loop() {
    //Comprueba el buffer de entrada
    state = slave.poll( au16data, 8 ); //Parámetros: Tabla de registros para el intercambio de info
    // Tamaño de la tabla de registros
    //Devuelve 0 si no hay pedido de datos
    //Devuelve 1 al 4 si hubo error de comunicación
    //Devuelve mas de 4 si se procesó correctamente el pedido

    if (state > 4) { //Si es mayor a 4 = el pedido fué correcto
    tempus = millis() + 50; //Tiempo actual + 50ms
    digitalWrite(13, HIGH);//Prende el led
    if (millis() > tempus) digitalWrite(13, LOW );//Apaga el led 50ms después

    //Actualiza los pines de Arduino con la tabla de Modbus

    void io_setup() {
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH ); //Led del pin 13 de la placa

    Enlaza la tabla de registros con los pines
    void io_poll() {

    au16data[0] = au16data[4] + au16data[5];
    au16data[1] = au16data[6] + au16data[7];
    au16data[2] = au16data[4] + au16data[6];
    au16data[3] = au16data[5] + au16data[7];

    TestModbus.projectarchive [477.66 KiB]


Log in to post a comment.