node-modbus icon indicating copy to clipboard operation
node-modbus copied to clipboard

[Question] crcMismatch error when using with ArduinoModbus

Open patryk-zielinski93 opened this issue 1 year ago • 1 comments

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.

patryk-zielinski93 avatar May 03 '23 09:05 patryk-zielinski93

Hey @patryk-zielinski93

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

stefanpoeter avatar May 08 '23 06:05 stefanpoeter