yaacov / arduinomodbusslave Goto Github PK
View Code? Open in Web Editor NEWModbus slave library for Arduino
License: ISC License
Modbus slave library for Arduino
License: ISC License
Is there a possibility to integrate 1-wire sensors (ds18b20), I2C sensors (BME280) and PWM in your code?
I can't compile last one version oof library for mega2560, where I use Serial1.
Problem was header file at line 140. I must change SERIAL_BUFFER_SIZE to SERIAL_RX_BUFFER_SIZE
Hi,
Thank you for sharing your library that seems very interesting as it is the only one I have found that use callback functions. I cannot imagine implementing a Modbus slave that copy the values of the registers at each iteration of the loop.
Nevertheless, I did not manage to use your simple.ino
example with a baudrate higher than 9600, using qmodbus as the Master, while it works well with other libraries like this one at 19200 or 115200 baud.
I have tried to change the timeout defined in Modbus::setT35
without any success.
On qmodbus, I have the following error:
Slave threw exception "Connection timed out" or function not implemented.
I have tested it on Arduino UNO and Arduino MEGA.
Let me know if you have already encountered that issue or have any ideas.
Romain
The SERIAL_TX_BUFFER_SIZE define does not exist in the SAMD platform. Instead SERIAL_BUFFER_SIZE should be used. A switch should be build in to detect and correct this.
Looking at the code:
https://github.com/yaacov/ArduinoModbusSlave/blob/master/src/ModbusSlave.h#L45
enum {
CB_MIN = 0,
CB_READ_COILS = CB_MIN,
CB_READ_DISCRETE_INPUTS,
CB_READ_HOLDING_REGISTERS,
CB_READ_INPUT_REGISTERS,
CB_WRITE_COILS,
CB_WRITE_HOLDING_REGISTERS,
CB_READ_EXCEPTION_STATUS,
CB_MAX
};
The CB_READ_COILS = CB_MIN
assignment looks very wrong to me. as they are compared in the poll
function with the FC_xxx
values.
With the code currently in master, the arduino code only return errors for any request I made from the master (I use QModMaster Windows app) whose packets are correct.
Is master tested or am I missing something? The (very) old library worked nicely but I needed to remove the CTRL pin because of a new RS485 adapter.
Hey Yaacov,
Let me first say thank you for writing this library. Saved a lot of my time here.
However, broadcast messages are not captured. These type of messages are very useful to change a holding register network-wide and are usually sent with slave id 0
.
Unfortunately, however, this library only captures messages with message slave id equal to the configured slave id and ignores messages with slave id 0
.
This can be fixed easily and I can submit a PR. However, I think you should decide IF and how we should inform the user of the library about these type of messages as the current implementation of the callback method is not capable of that.
Hello,
Getting bizzaro complier errors, probably a Teensy issue, but I never can tell because I'm not good at this stuff.
The simple.ino code won't compile on the Teensy 3.x and LC unless the "USB Type" includes a "keyboard"
Doesn't work under regular serial, doesn't work under NO USB. Only seems to work if Keyboard is in the mix. Here's the horrendous error:
Linking everything together...
"C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-gcc" -O2 -Wl,--gc-sections,--relax,--defsym=__rtc_localtime=1549453279 "-TC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy3/mk20dx256.ld" -lstdc++ -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -o "C:\\Users\\andy\\AppData\\Local\\Temp\\arduino_build_341405/simple.ino.elf" "C:\\Users\\andy\\AppData\\Local\\Temp\\arduino_build_341405\\sketch\\simple.ino.cpp.o" "C:\\Users\\andy\\AppData\\Local\\Temp\\arduino_build_341405\\libraries\\ArduinoModbusSlave\\ModbusSlave.cpp.o" "C:\\Users\\andy\\AppData\\Local\\Temp\\arduino_build_341405/..\\arduino_cache_695210\\core\\core_teensy_avr_teensy31_usb_serial,speed_96,opt_o2std,keys_en-us_4939f5412a75a8560acb0f9e98268f02.a" "-LC:\\Users\\andy\\AppData\\Local\\Temp\\arduino_build_341405" -larm_cortexM4l_math -lm
c:/program files (x86)/arduino/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7e-m\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x12): undefined reference to `_write'
collect2.exe: error: ld returned 1 exit status
Using library ArduinoModbusSlave at version 2.0.0 in folder: C:\Users\andy\OneDrive\Documents\Arduino\libraries\ArduinoModbusSlave
Error compiling for board Teensy 3.2 / 3.1.
So it's all about this keyboard thing.
I tried compiling in the Arduino IDE 1.8.8 / TeensyDuino 1.45
Also in Platform.io / Visual Code with the same results.
Dear Mr Dr. Yaacov,
I would like to know if is it possible to change parity in comunication.
For example, I can connect with 9600-8-N-1, but if I want to connect with 9600-8-O-1 (odd parity), how I can do it?
I look forward to hearing from you soon.
Thanks.
Kind regards,
Javier
EDIT: mr=>dr :-)
Hi,
I'm using this library on arduino in order to make it as a Modbus Slave, the slave consists in a ATMEGA328P with a bunch of neopixel leds (8) attached, periodically - every 250ms - , the master (Library: ModbusMaster) will change the led colors, generating some random colors.
The speed is: 57600-8E1
I was experiencing very often a slave timeout on the master (226 error), even if the master timeout limit is not reached (2000ms).
After some experiments, i've found that if i add to the slave a small delay(10) at the end of the write register function, the problem almost disappears (the timeout errors will appear very few times, like one every 100 writes)
This is weird, i mean: is this a normal behavior? i need to slow down the response of my slave in order to get it work?
I found that the slave is responding to bad packets when it sees a command it does not recognise. This is causing collisions on the bus and corruption when other slaves are present.
The problem is that the Validate function does not check the CRC first, only after it has decoded the message. If during the decoding the validate function finds a Modbus function code it does not handle it sends a STATUS_ILLEGAL_FUNCTION message back but this is done BEFORE the CRC is checked and so could very well be due to a packet not addressed to us at all. I am seeing errors from the master where a response was received from the WRONG slave.
Moving the CRC check and adding an address check to the beginning of the validate function fixes the problem and I see no more errors reported by the master..
`bool Modbus::validateRequest()
{
// IanA - Moved CRC check so we do not attempt to dscipher any invalid messages
// Check the crc, and if it isn't correct ignore the request.
uint16_t crc = readCRC(_requestBuffer, _requestBufferLength);
if (Modbus::calculateCRC(_requestBuffer, _requestBufferLength - MODBUS_CRC_LENGTH) != crc)
{
return false;
}
// Check that the message was addressed to us
if (!Modbus::relevantAddress(_requestBuffer[MODBUS_ADDRESS_INDEX]))
{
return false;
}
// IanA - End
// The minimum buffer size (1 x Address, 1 x Function, n x Data, 2 x CRC).
uint16_t expected_requestBufferSize = MODBUS_FRAME_SIZE;
// Check the validity of the data based on the function code.
switch (_requestBuffer[MODBUS_FUNCTION_CODE_INDEX])
{
case FC_READ_EXCEPTION_STATUS:
// Broadcast is not supported, so ignore this request.
if (isBroadcast())
{
return false;
}
break;
case FC_READ_COILS: // Read coils (digital read).
case FC_READ_DISCRETE_INPUT: // Read input state (digital read).
case FC_READ_HOLDING_REGISTERS: // Read holding registers (analog read).
case FC_READ_INPUT_REGISTERS: // Read input registers (analog read).
// Broadcast is not supported, so ignore this request.
if (isBroadcast())
{
return false;
}
// Add bytes to expected request size (2 x Index, 2 x Count).
expected_requestBufferSize += 4;
break;
case FC_WRITE_COIL: // Write coils (digital write).
case FC_WRITE_REGISTER: // Write registers (digital write).
// Add bytes to expected request size (2 x Index, 2 x Count).
expected_requestBufferSize += 4;
break;
case FC_WRITE_MULTIPLE_COILS:
case FC_WRITE_MULTIPLE_REGISTERS:
// Add bytes to expected request size (2 x Index, 2 x Count, 1 x Bytes).
expected_requestBufferSize += 5;
if (_requestBufferLength >= expected_requestBufferSize)
{
// Add bytes to expected request size (n x Bytes).
expected_requestBufferSize += _requestBuffer[6];
}
break;
default:
// Unknown function code.
Modbus::reportException(STATUS_ILLEGAL_FUNCTION);
return false;
}
// If the received data is smaller than what we expect, ignore this request.
if (_requestBufferLength < expected_requestBufferSize)
{
return false;
}
// Set the length to be read from the request to the calculated expected length.
_requestBufferLength = expected_requestBufferSize;
// This is now done at the start of the function so it is no longer needed.
// Check the crc, and if it isn't correct ignore the request.
// uint16_t crc = readCRC(_requestBuffer, _requestBufferLength);
// if (Modbus::calculateCRC(_requestBuffer, _requestBufferLength - MODBUS_CRC_LENGTH) != crc)
// {
// return false;
// }
return true;
}
`
Hi there,
I wonder that can I use this library on ESP32 module?
Have you ever tried that?
Regards.
Erkan
Using an Arduino MKRZero I get stuck in row 190 calling flush() when using Serial1. If I send dummy byte on the Serial1 before calling .begin() it works.
Seems the blame is in Arduino Core.
https://github.com/arduino/ArduinoCore-samd/blob/ad95d3c204d43bee789bb0c116afbec135e6ace5/cores/arduino/SERCOM.cpp
void SERCOM::flushUART()
{
// Skip checking transmission completion if data register is empty
// if(isDataRegisterEmptyUART())
// return;
// Wait for transmission to complete
while(!sercom->USART.INTFLAG.bit.TXC);
}
Hello
How i can change SLAVE_ID in void loop or void setup?
I have a project use Arduino as Master to read and write data for about 30 slave(R485) but Currently, I have not found a solution yet
Cordial greetings.
I have made an implementation for my degree project and my teacher asks if the communication is ASCII or RTU and because I do not find in the documentation the answer, I have created this ISSUE.
Hi guys, what i would like to do is change the SLAVE_ID during the void setup. This because i would like to set the slave address with 5 dip switch. At the moment the SLAVE_ID is declared at the beginning and i don't kwon how to solve this problem.
The SLAVE_DIP is the int variable that i want to use as a SLAVE_ID
Below my code:
//Testato con QModMaster
//https://github.com/yaacov/ArduinoModbusSlave
// https://en.wikipedia.org/wiki/Modbus
#include <ModbusSlave.h>
#include <SoftwareSerial.h>
SoftwareSerial RS485Serial(10, 11); // RX, TX
#define SLAVE_ID 10 // The Modbus slave ID, change to the ID you want to use.
#define SERIAL_BAUDRATE 9600 // Change to the baudrate you want to use for Modbus communication.
// Comment out the following line if your not using RS485
#define RS485_CTRL_PIN 2 // Change to the pin the RE/DE pin of the RS485 controller is connected to.
#define command_open 8
#define command_close 9
#define command_rocking 12
#define feedback_open 3
#define feedback_close 4
#define WatchDog 5
#define DIP_1 A0
#define DIP_2 A1
#define DIP_3 A2
#define DIP_4 A3
#define DIP_5 A4
boolean SET_1;
boolean SET_2;
boolean SET_3;
boolean SET_4;
boolean SET_5;
// Modbus object declaration
Modbus slave(RS485Serial, SLAVE_ID, RS485_CTRL_PIN);
void setup() {
// RS485 control pin must be output
pinMode(2, OUTPUT);
//OUTPUT
pinMode(command_open, OUTPUT);
pinMode(command_close, OUTPUT);
pinMode(command_rocking, OUTPUT);
//INPUT
pinMode(feedback_open, INPUT);
pinMode(feedback_close, INPUT);
pinMode(WatchDog, INPUT);
//DIPSWITCH
pinMode(DIP_1, INPUT);
pinMode(DIP_2, INPUT);
pinMode(DIP_3, INPUT);
pinMode(DIP_4, INPUT);
pinMode(DIP_5, INPUT);
SET_1 = digitalRead(DIP_1);
SET_2 = digitalRead(DIP_2);
SET_3 = digitalRead(DIP_3);
SET_4 = digitalRead(DIP_4);
SET_5 = digitalRead(DIP_5);
int SLAVE_DIP = (SET_1*1)+(SET_2*2)+(SET_3*4)+(SET_4*8)+(SET_5*16)+1;
Serial.println(SLAVE_DIP);
// Register functions to call when a certain function code is received.
slave.cbVector[CB_WRITE_COILS] = writeDigitalOut;
slave.cbVector[CB_READ_DISCRETE_INPUTS] = readDigitalIn;
// Set the serial port and slave to the given baudrate.
RS485Serial.begin(SERIAL_BAUDRATE);
slave.begin(SERIAL_BAUDRATE);
Serial.begin(9600);
}
void loop() {
/* listen for modbus commands con serial port.
*
* on a request, handle the request.
* if the request has a user handler function registered in cbVector.
* call the user handler function.
*/
slave.poll();
}
/**
* Handle Force Single Coil (FC=05) and Force Multiple Coils (FC=15)
* set digital output pins (coils).
*
* Dalla pagina di wikipedia addr: Coil Read-write 1 bit 00001 - 09999
*/
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length) {
Serial.print("FC= ");
Serial.println(fc);
Serial.print("ADDRES= ");
Serial.println(address);
Serial.print("LENGHT= ");
Serial.println(length);
if (address == 3) {
digitalWrite(command_open, slave.readCoilFromBuffer(0));
digitalWrite(command_close, slave.readCoilFromBuffer(1));
digitalWrite(command_rocking, slave.readCoilFromBuffer(2));
}
return STATUS_OK;
}
// Handle the function code Read Input Status (FC=02) and write back the values from the digital input pins (discreet input).
uint8_t readDigitalIn(uint8_t fc, uint16_t address, uint16_t length)
{
Serial.print("FC= ");
Serial.println(fc);
Serial.print("ADDRES= ");
Serial.println(address);
Serial.print("LENGHT= ");
Serial.println(length);
if (address == 0) {
// Write the state of the digital pin to the response buffer.
slave.writeCoilToBuffer(0, digitalRead(feedback_open));
// Write the state of the digital pin to the response buffer.
slave.writeCoilToBuffer(1, digitalRead(feedback_close));
// Write the state of the digital pin to the response buffer.
slave.writeCoilToBuffer(2, digitalRead(WatchDog));
}
return STATUS_OK;
}
Thanks
Pietro
ArduinoModbusSlave/src/ModbusSlave.cpp
Line 836 in 3a09303
This line crash everything!!! ;( ... I dont check any other lines changed with this merge but I think you shoudl verify it...
Please fix it ASAP becouse now your all great work is totally not working!!!
Hello
If I use Write Single Register 0x06, I can not send DATA to another Register. Always DATA is saved at Register 0.
If I use Write Multiple Registers 0x10, is all ok!
Is there an error in the library?
Hi Yaacov Zamir.
Sorry yet a new issue.
I made a simple example sketch from which you can easily see how the problem occurs, i did the "// EXAMPLES" commas tell the editing section.
In addition, it is custom edited by the full_Examples.ino sketch
Sincerely, Rauno Finland
I have a very specific feature request for a product our company has produced. I implemented it (and changing the Unit ID) easily enough, but thought I would add an issue. I can issue a PR with my version of it if needed.
The ability to turn communication on and off with a function call. Our product doesn't communicate at start up until a digital in is raised, then it talks on ID 1. When the digital in is lowered, it switches to a different ID according to a register. This allows us daisy chain multiple units together without having to pre-configure them; the master gives them each an address in turn.
My fix was a simple private bool, and some methods to toggle it. If the bool is false, processing of packets would stop before checking the unit Id.
Ok, now, this might be a little picky. After all, a lot of these problems might not be so obvious when working with the library. But I was just checking the source code and decided it is best to report them here. Even tho I hope I can find some time to fix these myself; it's always better to know which parts can use improvements if I failed to do so.
micros( ) > timeout + last_receive_time
should be replaced with micros( ) - last_receive_time ) > timeout
and type to uint64_t
to prevent overflowlengthIn
or reject it altogether; this should be changed so requests are processed completely at least after 1.5T silence. (half the timeout)pin 8 max485 should go to vcc. color of the wire is correct, but its look like you swapped with pin 5.
can any body tell me which modbus simulator software is better to use with this library , i have used "Simply Modbus Master " simulator and tried writing/reading data to register number 40001 , didn't get any response or anything
Hi,
I am trying the library on Arduino Mega 2560. Receiving the queries works ok but writeRegisterToBuffer doesn't write the response to any Serial. I tried all the serials but none works.
I tried HoldingRegisters function ans also InputRegisters.
It does enter the function to handel the queries but no write to serial is being done.
Any idea?
Thanks
Hi Yaacov Zamir
Thanks to the excellent Full modbus Arduino skelets you made.
I've added the NTC10 temperature calculation and PID control everything works as well and I can apply set values in EEPROM memory ..
My only problem is the INPUT registers query
30001 = PID adjustment value (360-359 value)
30002 = NTC10 Temperature (22.6 - 22.7 C)
30003 = Blank
30004 = PWM calculation value (55-56%)
30005 = Blank
This would be my desired morbus register list.
But when I ask for one of the INPUT registers eg 30004 (57) I always get 30001 (360) value in the register.
I have tried to make the INPUT FC = 04 offset settings where I could get the correct value of it but I failed.
This writeRegisterToBuffer command confuses because I do not want to write the value directly to something I want in the registry. Do you need a new FUNKTION here?
You could look at my appendix pictures if they better tell you what it is all about.
Can you tell me how should I act to get the modbus register functions to work correctly?
I am a novice in these matters, and yet the desire is hard to understand programming and other technology packages .. Big thank you Modbus excellent program for you.
Sincerely, Rauno Finland
full_TESTI.zip
I'm looking for a Modbus RTU slave implementation for a Blue Pill and would be interested if there's any user feedback on using this lib with STM32F1XX devices.
Thanks!
I had successfully implemented this library with Arduino as an I2c slave. So one arduino modbus slave + I2c slave works. But right now I have interfaced a I2C sensor with arduino, and modbus is not working, not able to scan registry on a modbus master end. Arduino modbus slave + I2C master won't work. I have tried with some flags but still not working. Any ideas on what might be the issue?
Out of curiosity, why is it that the Stream interface is not started at the set baudrate inside the begin() function? If it is included it is one less step you can forget while using this library.
ArduinoModbusSlave/examples/full/full.ino
Line 135 in a9559f9
EEPROM.get(address + i * 2, value);
example->full.ino @line 144 "return;" should be change to "return STATUS_OK;" right?
Can i use this library for RP2040 or Raspberry pi pico?
while trying the example "simple" using "Simply Modbus" software as a master and an Arduino UNO as slave, i'm getting "Exception Response" & "Illegal Data Address"
can anybody tell me why this is happening ??
Hi,
I have a codesys controlwin softplc configured as modbus master. Communication only works if i use a arduino leonardo as slave hardware. The exact same project on a arduino uno or arduino duemilanove does not work.
Is this a know problem (and maybe a solution/workaround)?
Hi,
i have following example on a atmega 4808 running and try with my linux usb-ftdi rs485 to read the registers.
include #define SLAVE_ID 33 // The Modbus slave ID, change to the ID you want to use. #define SERIAL_BAUDRATE 9600 // Change to the baudrate you want to use for Modbus communication. #define SERIAL_PORT Serial // Serial port to use for RS485 communication, change to the port you're using. // Comment out the following line if your not using RS485 #define RS485_CTRL_PIN PIN_PF6 // Change to the pin the RE/DE pin of the RS485 controller is connected to. // The position in the array determines the address. Position 0 will correspond to Coil, Discrete input or Input register 0. uint8_t analog_pins[] = {PIN_PD0, PIN_PD1, PIN_PD2}; // Add the pins you want to read as a Input register. uint8_t analog_pins_size = sizeof(analog_pins) / sizeof(analog_pins[0]); // Get the size of the analog_pins array #ifdef RS485_CTRL_PIN // Modbus object declaration Modbus slave(SERIAL_PORT, SLAVE_ID, RS485_CTRL_PIN); #else Modbus slave(SERIAL_PORT, SLAVE_ID); #endif void setup() { // Set the defined analog pins to input mode. for (int i = 0; i < analog_pins_size; i++) { pinMode(analog_pins[i], INPUT); } slave.cbVector[CB_READ_INPUT_REGISTERS] = readAnalogIn; // Set the serial port and slave to the given baudrate. SERIAL_PORT.begin(SERIAL_BAUDRATE); slave.begin(SERIAL_BAUDRATE); } void loop() { // Listen for modbus requests on the serial port. // When a request is received it's going to get validated. // And if there is a function registered to the received function code, this function will be executed. slave.poll(); } // Modbus handler functions // The handler functions must return an uint8_t and take the following parameters: // uint8_t fc - function code // uint16_t address - first register/coil address // uint16_t length/status - length of data / coil status // Handle the function code Read Input Registers (FC=04) and write back the values from analog input pins (input registers). uint8_t readAnalogIn(uint8_t fc, uint16_t address, uint16_t length) { // Check if the requested addresses exist in the array if (address > analog_pins_size || (address + length) > analog_pins_size) { return STATUS_ILLEGAL_DATA_ADDRESS; } // Read the analog inputs for (int i = 0; i < length; i++) { // Write the state of the analog pin to the response buffer. slave.writeRegisterToBuffer(i, analogRead(analog_pins[address + i])); } return STATUS_OK; }
on the linux machine not sure if the Parity is none but tried the other both as well
# mbpoll /dev/ttyUSB0 -m rtu -a 33 -r 1 -c 10 -b 9600 -P none -vv debug enabled debug enabled Set device=/dev/ttyUSB0 mbpoll 1.0-0 - FieldTalk(tm) Modbus(R) Master Simulator Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; type 'mbpoll -w' for details. Opening /dev/ttyUSB0 at 9600 bauds (N, 8, 1) Set response timeout to 1 sec, 0 us Protocol configuration: Modbus RTU Slave configuration...: address = [33] start reference = 1, count = 10 Communication.........: /dev/ttyUSB0, 9600-8N1 t/o 1.00 s, poll rate 1000 ms Data type.............: 16-bit register, output (holding) register table -- Polling slave 33... Ctrl-C to stop) [21][03][00][00][00][0A][C2][AD] Waiting for a confirmation... ERROR Connection timed out: select Read output (holding) register failed: Connection timed out <00>-- Polling slave 33... Ctrl-C to stop) [21][03][00][00][00][0A][C2][AD] Waiting for a confirmation... ERROR Connection timed out: select Read output (holding) register failed: Connection timed out ^C<00>--- /dev/ttyUSB0 poll statistics --- 2 frames transmitted, 0 received, 2 errors, 100.0% frame loss everything was closed.
maybe you can help me to understand what settings i need to use on the modpoll
many thanks
This is not an issue but just a question.
What are, on your opinion, the best options to copy a string between the master and the slave?
Apparently, but I am not a modbus expert, it looks like the Read/Write File Record (0x14 / 0x15) are the best option in the specs.
Should I implement these services? What do you think?
For a project I would like to use ModbusTCP. For this I looked into using your TCP lib, but this only accepts a ESP8266 and is about 3 years old. Would it be worth the effort to fix that library, or would it be better to change this one to also accept TCP messages?
Would like to know your vision on this problem.
Dear Kobi Zamir,
Hi
Please accept my thanks for your very use full Library for ARDUINO modbus slave.
i successfully uploaded full.ino code in example of library and successfully :
1.Read/Write digital pins.
2.Read Analog pins.
3.Read EEPROM registers.
and problem is here that i want to write in EEPROM using function 06(Write_Single_Register) because some Limitations.
Thanks for your support.
#include <ModbusSlave.h>
#include <SoftwareSerial.h>
SoftwareSerial RS485Serial(10, 11); // RX, TX
Modbus slave(RS485Serial, 1, 2);
int led = 12;
int dl_ro = 2;
void setup() {
pinMode(dl_ro, OUTPUT);
pinMode(led, OUTPUT);
slave.cbVector[CB_WRITE_COILS] = writeDigitalOut;
RS485Serial.begin(9600);
slave.begin(9600);
}
void loop() {
slave.poll();
}
uint8_t writeDigitalOut(uint8_t fc, uint16_t address, uint16_t length) {
Serial.print("FC=05: ");
Serial.println(fc);
Serial.println(address);
Serial.println(length);
if (address == led) {
digitalWrite(12, slave.readCoilFromBuffer(0));
}
return STATUS_OK;
}
The double default declaration (.cpp and .h) of the ModbusSlave unitaddress gives compiling errors.
Hello
I have problem..
Every few minutes, no communication via rs485. How to reset the arduino is ok, again for about 5 minutes.
There is some command to reset only the library
Some splush? or reset port?
How can I read the data at 40001. how should i edit the code please help me
Modbus :: createResponse ();
If there is no delay (1)
or Serial.println ("")
before calling the function, it does not work properly.
communication:rs232
baudrate:9600
dataBits:8
Parity:None
StopBits:1
uint8_t Modbus::poll()
{
.....
// Validate the incoming request.
if (!Modbus::validateRequest())
{
Serial.println("notvalid");
return 0;
}
//Serial.println("valid");
//delay(1);
// Execute the incoming request and create the response.
uint8_t status = Modbus::createResponse();
}
Hello I have described an Arduino pro mini ATmega328p with the full.ino in Arduino IDE. Now my problem I can not choose between digital inputs and outputs, the holding register always shows 255 when reading but writing does not always result in error: timeout with QModMaster and the digital pins stay on output.
There are problems to compile the library for the new Arduino Nano Every target.
They declared that Arduino Nano Every is compatible with Arduino Nano but that's not true.
It seems the Arduino Nano Every doesn't suppport software serial but only hardware serial.
Could it possible to modifiy the library for supporting the Arduino Nano Every too?
Hi,
I would like to see the CB_READ_COILS function being split into CB_READ_COILS and CB_READ_DISCRETE_INPUTS.
The same for CB_READ_REGISTERS. This one should be split into CB_READ_INPUT_REGISTERS and CB_READ_HOLDING_REGISTERS.
I think this would make the programming of the slave code a lot more intuitive. Is there a reason why this is not done in the first place?
so i create this
https://github.com/yanzixiang/ArduinoModbusSlaveAsyncTCPAndRTU
is there any solution to change Slave_ID in void_setup?
i want to set Slave_ID with dip switch
In my opinion this function is confusingly named as a String is typically a set of characters. I would suggest to change it to writeArrayToBuffer() as this better covers the intended purpose. This would mean a minor functionality break, but would help with readability.
Also wouldn't it be more logical to support uint16_t array's as Modbus is 16 bit values based?
Hi,
First thank you for great work. I did test various libraries and this is the one library that work here.
I have a question:
Is possible change the start address or set a especific address using function 04? I need put data in address 4121 becouse i have one app that read data in this address and i cant change this.
Thank you one more time.
EDIT: I dont use analog in. I get one value per modbus function 03 from a equipment.
I thought to do:
uint8_t [4200] analog_pins;
and:
slave.writeRegister Buffer (4121, 1234);
Would be the solution, but it didn't work.
Hi !
I tried the last release of the library and it looks broken.
I used the examples supplied with both ArduinoModbusSlave (full.ino) and node-modbus-serial (polling_RTU.js), and I wasn't able to make the communication work.
I only tried the ReadHoldingRegister function.
I used the following code :
#include "ModbusSlave.h"
#define SLAVE_ID 4
#define CTRL_PIN 8
#define BAUDRATE 9600
Modbus slave(SLAVE_ID, CTRL_PIN);
uint16_t value = 1234;
void setup() {
pinMode(CTRL_PIN, OUTPUT);
slave.cbVector[CB_READ_HOLDING_REGISTERS] = readMemory;
Serial.begin( BAUDRATE );
slave.begin( BAUDRATE );
Serial.println("NEW_MODBUS_LIBRARY");
}
void loop() {
if (slave.poll() != 0) {
Serial.println(value);
}
}
uint8_t readMemory(uint8_t fc, uint16_t address, uint16_t length) {
slave.writeRegisterToBuffer(0, value);
return STATUS_OK;
}
Here is a console record when starting the master :
As soon as I swap the new release with the previous one, everything works fine :
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.