Cloud-Automation / node-modbus

Modbus TCP Client/Server implementation for Node.JS
456 stars 169 forks source link

[Question] crcMismatch error when using with ArduinoModbus #325

Closed patryk-zielinski93 closed 1 month ago

patryk-zielinski93 commented 1 year ago

Hello, I am trying to establish stable connection between Controllino Mega Modbus slave and NodeJS master. Reading works without any problems but when it comes to writing I am receiving crcMismatch error.

Code uploaded to Controllino is example code from Arduino Modbus library adjusted to work with Controllino:

#include <Arduino.h>
#include <Controllino.h>
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

RS485Class rs485(Serial3, CONTROLLINO_RS485_TX, CONTROLLINO_RS485_DE, CONTROLLINO_RS485_nRE);

const int ledPin = CONTROLLINO_R0;

void setup() {
    Serial.begin(9600);

    Serial.println("Modbus RTU Server LED");

    // start the Modbus RTU server, with (slave) id 1
    if (!ModbusRTUServer.begin(rs485, 1, 19200)) {
        Serial.println("Failed to start Modbus RTU Server!");
        while (1);
    }

    // configure the LED
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, LOW);

    // configure a single coil at address 0x00
    ModbusRTUServer.configureCoils(0, 1);
}

void loop() {
    // poll for Modbus RTU requests
    int packetReceived = ModbusRTUServer.poll();

    if(packetReceived) {
        // read the current value of the coil
        int coilValue = ModbusRTUServer.coilRead(0x00);

        if (coilValue) {
            // coil value set, turn LED on
            digitalWrite(ledPin, HIGH);
        } else {
            // coil value clear, turn LED off
            digitalWrite(ledPin, LOW);
        }
    }
}

NodeJS code to write data:

import { errors, ModbusRTUClient } from 'jsmodbus';
import { SerialPort, SerialPortOpenOptions } from 'serialport';

const options: SerialPortOpenOptions<any> = {
    path: '/dev/cu.usbserial-AB0NKK4A',
    baudRate: 19200,
    dataBits: 8,
    stopBits: 1
};

const socket = new SerialPort(options);
const client = new ModbusRTUClient(socket, 1, 2500);

function test(prev = false) {
    client
        .writeSingleCoil(0, prev)
        .then(({ metrics, response }) => {
            console.log('Transfer Time: ' + metrics.transferTime);
            console.log('Response Function Code: ' + response.body.fc);
            setTimeout(() => {
                test(!prev);
            }, 500);
        })
        .catch((err) => {
            console.log(err);
            handleErrors(err);
        })
        .finally(() => socket.close());
}

socket.on('open', () => {
    test();
});

socket.on('error', function (err) {
    console.log(err);
});

function handleErrors(err: any) {
    console.log(err);
    if (errors.isUserRequestError(err)) {
        switch (err.err) {
            case 'OutOfSync':
            case 'Protocol':
            case 'Timeout':
            case 'ManuallyCleared':
            case 'ModbusException':
            case 'Offline':
            case 'crcMismatch':
                console.log(
                    'Error Message: ' + err.message,
                    'Error' + 'Modbus Error Type: ' + err.err
                );
                break;
        }
    } else if (errors.isInternalException(err)) {
        console.log(
            'Error Message: ' + err.message,
            'Error' + 'Error Name: ' + err.name,
            err.stack
        );
    } else {
        console.log('Unknown Error', err);
    }
}

It is worth mentioning that if the communication takes place directly between two Controllino Megas using the Arduino Modbus library, no errors occur.

I am newbie in RS485 and Modbus, so I will be very grateful if someone can tell me why there is a problem with the CRC check.

stefanpoeter commented 1 year ago

Hey @patryk-zielinski93

Can you provide some DEBUG Messages? You can trigger them by setting the DEBUG environment variable to debug.