-
Notifications
You must be signed in to change notification settings - Fork 91
Dexter ModBus
There are two ways to connect to a ModBus device: Serial and TCP. In either case, the protocol needs to be processed.
If your job engine doesn't already have it, you will need to install support for ModBus protocol into Dexter. We have tested the modbus-serial NPM package. Despite the name, modbus-serial supports both serial and TCP connections.
You can do this directly if Dexter is connected to the internet by SSHing into Dexter and then:
cd /root/Documents/dde
npm install modbus-serial
Note: The install will take a while.
If your Dexter is NOT directly connected to your PC and does not have ModBus installed, you can try to install it locally, and then copy the files over into the node_modules folder and trigger the make in the node_modules/modbus-serial/node_modules/@serialport/bindings/build folder. This is not well documented. Hopefully you can get an updated image with the ModBus support pre-installed, or connect your Dexter to the internet for this process.
Once the module is installed, you can use it via node.js. Examples are found here:
https://github.com/yaacov/node-modbus-serial/tree/master/examples
To access the new module from DDE jobs, we need to update the core files SSHing into Dexter and then:
cd /root/Documents/dde
nano core/index.js
Scroll down to the global. section near the end and add the line:
var ModbusRTU = require("modbus-serial")
after the last var line above the global section, then below the other globals, add:
global.ModbusRTU = ModbusRTU
After this change, any of the methods allowed by the module should be available in a DDE job via the ModbusRTU object.
To access network modbus devices (other than you own PC), your Dexter will need to be connected to the network.
//var ModbusRTU = require("modbus-serial") //for node.js, not needed in DDE
var client = new ModbusRTU();
var plc = "192.168.1.24"; //change to the address of the remote device.
// open connection to remote device
client.connectTCP(plc, { port: 8502 })
.then(setClient)
.then(function() {
console.log("Connected"); })
.catch(function(e) {
console.log(e.message); });
function setClient() {
// set the client's unit id
client.setID(1); //change to the correct unit id
// set a timeout for requests default is null (no timeout)
client.setTimeout(1000);
// run program
run();
}
function run() {
// write to coil
client.writeCoil(5, true)
.then(function(d) {
console.log("Write true to coil 5", d); })
.catch(function(e) {
console.log(e.message); })
.then(writeRegisters);
}
function writeRegisters() {
// write 3 registers statrting at register 101
// negative values (< 0) have to add 65535 for Modbus registers
client.writeRegisters(101, [10, 9, 8, -20 + 65535, -10 + 65535])
.then(function(d) {
console.log("Write 10, 9, 8, -20, -10 to registers 101 to 105", d); })
.catch(function(e) {
console.log(e.message); })
.then(close);
}
function close() {
client.close();
}When working with ModBusTCP, it would be best for Dexter to be listening for a message all the time, and to start a job if a new message is recieved. This ability will be integrated into the onboard node web server in time.
Of course, accessing a serial modbus device requires a serial adapter, either one with built in RS485 support ^, or standard serial unit 1, 2 with a TTL to RS485 adapter 1. USB adapters based on the CP2102 or CP2104 are known to work with Dexter.
See Dexter-Serial-Peripherals for installation, testing and troubleshooting of serial adapters in general.
This example job connects to a serial adapter at /dev/ttyUSB0 and once the connection is established, it writes the values 0, 0xffff to registers starting at address 5 on device number 1, then reads the 2 registers starting at address 5.
// create an empty modbus client
// var ModbusRTU = require("modbus-serial"); //For node.js, not needed in DDE
var client = new ModbusRTU();
// open connection to a serial port
client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600 }, write);
function write() {
client.setID(1);
// write the values 0, 0xffff to registers starting at address 5
// on device number 1.
client.writeRegisters(5, [0 , 0xffff])
.then(read);
}
function read() {
// read the 2 registers starting at address 5
// on device number 1.
client.readHoldingRegisters(5, 2)
.then(console.log);
}To search the Wiki, use the main search box in the black bar at the top, then select WiKi to filter the results or go to https://github.com/HaddingtonDynamics/Dexter/search?type=Wikis&q= and then add your search terms to the end of the URL.
To report errors, or request additional data, please chat with us on discord and/or raise a new issue