yaacov / node-modbus-serial

A pure JavaScript implemetation of MODBUS-RTU (and TCP) for NodeJS
ISC License
640 stars 241 forks source link

Modbus-RTU via GPIO RPi3 #107

Closed philesgilles closed 7 years ago

philesgilles commented 7 years ago

Good day, I'm trying to connect Modbus Via GPIO ttyAMA0. When I check with an oscilloscope the RX pin, the message return well. So I've made a few research and it seems that there is a glitch so we receive a <0> front of the message.

I don’t know if you can change something in your code for fixing that?

=> https://github.com/stephane/libmodbus/issues/302

I don’t know how to test it… But seems basically after a ‘modbus connect’, it need to to be added :

if(value == 0) { modbus_flush(ctx); }

best,

yaacov commented 7 years ago

hi, thanks 👍

a. can you write a test program that fails because of this ? b. can you write a pull request that fix this, so the test program will not fail ?

philesgilles commented 7 years ago

a) I have a test program that fails (I think) because of this. I have the right response from the Modbus devices reading with an oscilloscope on the RX pin but there is a little glitch. I think it's the cause and it creates a <00> in front. Using a USB to RS485, it works great. As soon I switch to ttyAMA0, I can't receive anything.

b) no... I don't know how to do that.

yaacov commented 7 years ago

I do not fully understand what is the problem ...

a. the extra byte comes from the master ( computer running nodejs ) for example a request looks like that 00 11 01 0013 0025 0E84 instead of that 11 01 0013 0025 0E84

or

b. the extra byte comes from the slave ( controller ) for example a response looks like that 00 11 01 05 CD6BB20E1B 45E6 instead of that 11 01 05 CD6BB20E1B 45E6

?

philesgilles commented 7 years ago

it's in the response. it adds a 00 in front of it. (b)

yaacov commented 7 years ago

it's in the response.

Ahh.. We have the buffered rtu for this :-)

// create an empty modbus client
var ModbusRTU = require("modbus-serial");
var client = new ModbusRTU();

// open connection to a serial port
client.connectRTUBuffered("/dev/ttyUSB0", { baudrate: 9600 });
client.setID(1);

// read the values of 10 registers starting at address 0
// on device number 1. and log the values to the console.
setInterval(function() {
    client.readHoldingRegisters(0, 10, function(err, data) {
        console.log(data.data);
    });
}, 1000);
yaacov commented 7 years ago

@philesgilles did the RTUBuffered helped ?

philesgilles commented 7 years ago

no, with the RTU i had a CRC error code and RTU-buffered i have a "empty" then timeout

yaacov commented 7 years ago

Using a USB to RS485, it works great. As soon I switch to ttyAMA0, I can't receive anything.

Using a USB to RS485 a. you have an rs485 connection ( two wires ) on the controller, and a rs485 to usb module [1] on the computer, did I understand correctly ? b. this works ?

switch to ttyAMA0 a. does your controller has a ttl out legs ? b. is it the same voltage 3.3 / 5v ? c. is the clock/boud sync ?

[1] http://www.ebay.co.uk/bhp/usb-to-rs485-converter

philesgilles commented 7 years ago

Hi !

With a USB to RS485 (2wires) no problem. I was making all the tests with that one.

I bought a stratopi board (this one: https://www.sferalabs.cc/product/strato-pi-ups-board/) When i request a register on a modbus client i have the TX and RX leds working. I checked with oscilloscope on the RX to see the reply and it seems totally ok. (If I write it's working.) it's just that there is a problem between the RX and the software. I don't understant...

philesgilles commented 7 years ago

I think it's the exact same problem as here: https://github.com/stephane/libmodbus/issues/302

With USB to RS485 pi@raspberrypi ~/SW-QT5/ModbusProjekt/ModbusProjekt/libmodbus-master/rpi-test $ sudo ./test sec_to=0 usec_to=500000 Rpi RTU enabled. BCM Pin set as 18. RPI pin exported and pin direction configured successfully. Opening /dev/ttyUSB0 at 9600 bauds (N, 8, 1) [01][04][00][00][00][01][31][CA] GPIO18 written : 1 successfully ! GPIO18 written : 0 successfully ! Waiting for a confirmation... <01><04><02><03><28> Date received is : 808 RPI BCM Pin Unexported successfully.

with GPIO pi@raspberrypi ~/libmodbus-master/rpi-test $ sudo ./test sec_to=0 usec_to=500000 Rpi RTU enabled. BCM Pin set as 18. RPI pin exported and pin direction configured successfully. Opening /dev/ttyAMA0 at 9600 bauds (N, 8, 1) [01][04][00][00][00][01][31][CA] GPIO18 written : 1 successfully ! GPIO18 written : 0 successfully ! Waiting for a confirmation... ERROR Connection timed out: select <00><01><04><02><03><25><78><1B>Bytes flushed (0) Date received is : 0 RPI BCM Pin Unexported successfully.

Is there a way to flush the buffer on port opening ?

yaacov commented 7 years ago

When i request a register on a modbus client i have the TX and RX leds working

a. their are lots of things that can fail on ttl communication [ boud, voltage, direction ... ] you need to be very careful when connecting two hardware devices using ttl, did you try just to send "hello world" message between your two devices ?

b. who is the master (the computer running nodejs) - the raspberry pi (strato pi) , a laptop ? c. who is the client (controller) - commercial controller, arduino, the raspberry pi (strato pi), other raspberry ?

d. what hardware is connected to the other side of the rx/tx ? e. can you post here the rpi-test code ?

philesgilles commented 7 years ago

pi is master, connected via the stratopi RS485 port to a countis counter and a arduino for testing write functions. The code up is not mine it's from the topic linked.

I'll try to make a fresh install and see if something i did before is the problem.

yaacov commented 7 years ago

pi is master, connected via the stratopi RS485 port to a countis counter and a arduino for testing write functions.

a. As best practice you should not connect raspberry pi to an arduino using ttl ... a. raspberry is 3.3v and arduino is 5v b. ttl is sensitive to interaptions c. you may fry you device, if you coincidently connect it wrong :-)

b. You can write a small program in your arduino that send data, listen to it on your pi (write some code that open port and listen), and see if you get that extra 0x00 ...

c. Post here the code that fails using modbus-serial, maybe we can add the missing flush command in your code.

yaacov commented 7 years ago

@philesgilles any news ?

yaacov commented 7 years ago

@philesgilles closing, if you have new info, just post it here ( we can re-open if needed )

surbhigup commented 6 years ago

I'm trying to connect Modbus Via GPIO ttyAMA0. But it gives modbus.c:6:20: fatal error: modbus.h: No such file or directory compilation terminated. please suggest me what can I do.

yaacov commented 6 years ago

@surbhigup hi, thanks for your comment, can you give more content, what are you trying to do, why and how ?

This library has no files named modbus.c or modbus.h it also does not use the c programming language, so from your comment it looks like your error has no connection to this library.

Please give as much information as you can about what you are doing, so we can try to help.

surbhigup commented 6 years ago

hey yaacov Actually i want to implement RS485 via Modbus RTU protocol interfacing with Raspberry PI3 model. I am using libmodbus library but didn't get any success. Could you suggest me what i need to use by hardware side as well code side.

surbhigup commented 6 years ago

I want to do this by serial ports of Raspberry Pi. Any more information needed? Please suggest me!!

yaacov commented 6 years ago

Actually i want to implement RS485 via Modbus RTU protocol interfacing with Raspberry PI3 model.

a. the raspberry will be the master ? b. what controllers are you using ?

Could you suggest me what i need to use by hardware side

The easiest way to connect raspberry to a rs485 line will be using a usb to rs485 connector: https://www.sparkfun.com/products/9822 https://www.ebay.com/sch/i.html?_nkw=USB+to+Rs485

as well code side.

well you are asking here ... this library is called node-modbus-serial and it requires node-js.

surbhigup commented 6 years ago

ya raspberry is the master. I am simply using MAX485 IC for RS485 PORT not anything else.

I got success by usb to rs485 connector but i want it to do with GPIO pins. By using node-modbus-serial , will i get success? There is no library other than this one? I want to read the holding registers of slave device.

yaacov commented 6 years ago

I am simply using MAX485 IC

max485 requires manual direction control view pins de and re, how do you control this pins ?

By using node-modbus-serial , will i get success?

node-modbus-serial does not support manual direction control (pins RE and DE in max485), you will need to implement electronics for automatic direction control ( for example here: https://www.google.com/search?q=max485+direction+control+from+tx ) or add the missing support to the serialport library code (modbus-serial uses serialport so the support need to be their first).

There is no library other than this one?

The only one that may have manual support is libmodbus but I never tried it ... I will be very happy if you can add the support for manual direction control to this lib :-)

philesgilles commented 6 years ago

Have you made the modifications to activate the right serial port on the Pi 3? I had lot of problems using the default mini UART.

=> https://www.raspberrypi.org/documentation/configuration/uart.md

If all is working with an usb adapter, then the problem is the port on the Pi.

Satprod Philippe Gilles Sound engineer, Product developer

Think about the planet before printing this mail !

CONFIDENTIALITY CAUTION:

This message is intended only for the use of the individual or entity to whom it is addressed and contains information that is privileged and confidential. If you, the reader of this message, are not the intended recipient, you should not disseminate, distribute or copy this communication. If you have received this communication in error, please notify us immediately by return email and delete the original message. Thank you.

Le 25 mai 2018 à 13:52, surbhigup notifications@github.com a écrit :

I want to read the holding registers of the slave.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

surbhigup commented 6 years ago

@yaacov
Ya MAX485 require manual direction control of DE and RE, but i am not understood with it that how to control it. I think because of this, didnt get success. It is not possible to give only port in the code like dev/ttyAMA0 or dev/serial0 or any thing? Is it must to add the RE and DE pins.

I only try the example which is given in libmodbus library.

surbhigup commented 6 years ago

@philesgilles I did all the modifications which is given in the document => https://www.raspberrypi.org/documentation/configuration/uart.md

but cant understand they are right or wrong.

yaacov commented 6 years ago

Is it must to add the RE and DE pins.

yes, max485 can not transmit unless you force the re and de pins.

It is not possible to give only port in the code like dev/ttyAMA0 or dev/serial0 or any thing?

yes, you can give only rx and tx from the rpi, but only if you implement the electronics that control the re and de pins for you automatically, like the usb modules do.

surbhigup commented 6 years ago

@yaacov OK I will do it. https://electronics.stackexchange.com/questions/286263/is-there-any-way-to-use-half-duplex-rs485-without-using-a-dedicated-controller-p Is it work?

surbhigup commented 6 years ago

@philesgilles serial0 -> ttyS0 serial1 -> ttyAMA0

My Rpi shows this configuration of serial ports. They are right ?

yaacov commented 6 years ago

Is it work?

Never tried it, so I don't know ... should work in low baudrate ...

ghost commented 6 years ago

Someone has experienced it with success and has an example of how to use MAX485 chip on ttyAMA0 port?

yaacov commented 6 years ago

using drain [1] and flush we can know when transmit is ending and control some gpio pin to signal transmit/receive to max485, a pull request testing that option is welcome.

[1] https://node-serialport.github.io/node-serialport/BaseBinding.html#drain

RobertSmart commented 5 years ago

I was just about to try this same thing. Best thing to do would to probably be to raise events for data transmission end and start (or beforeStart) so the logic to control the pins can be handled outside of this module (using the raspberry pi GPIO module). that would keep this module more generic then.