I have watched some general Modbus information I could find on Youtube, read the Modbus protocol, and read various explanatory articles. However I am still unsure about the practical "how-to" of Modbus. Most information talks about the format (function codes, registers numbers, error codes, bla bla bla) of Modbus communication and not how to go about setting Modbus communication up. I did find a few videos on Youtube but either they use old libraries that I can not get to work (Recording Arduino Modbus Slave - YouTube) or had long code with little to no explanation of the content (Arduino Modbus RTU Slave Simple Example How to try modbus algorithm with arduino - YouTube).
I have previously got two Arduino's (a Nano and Uno) to communicate with each other via Modbus (following this guide: RS485 Serial Communication between two Arduino boards) but that's the extent of my success.
Disclaimer: I am quite the Noob when it comes to programming -all my knowledge comes from Paul McWhorter's Arduino tutorial series.
All help would be appreciated; articles, explanations, videos, libraries with user guides, etc.
Hi Pylon, thank you for you reply.
perhaps my schematic is not visible?
Let me know if that's the case...
As to my goal:
The Arduino should be a slave.
Now what I'm trying to achieve is this: I'm part of a business which is constructing a coffee roaster where the Arduino is the controlling unit for temperature sensors, stepper motors, fans, etc.
The Arduino should be connected to a computer where you can run a program to control the "roast profile" of your coffee beans. However we want the customer to be able to use their choice of program (artisan, etc) and since Modbus is the standard industrial communication protocol it allows us to achieve this goal.
So for instance instead of: x program adopted for Arduino --> Arduino
we can use: x, y, z program adopted for Modbus --> Modbus hardware --> Arduino.
That doesn't do the same. It waits for 120ms before sending the IR sequence while the original code sends the IR sequence and then waits for 120ms.
The picture is visible although it's not schematics in my opinion. But it gives a rough overview how you plan to wire it.
Yes, it did, thank you.
I used this library as a slave implementation of the Modbus protocol for one of my projects (I actually modified it slightly to fit my rather specific needs). The library comes with examples of how to use it.
Using Modbus in a rather complex setup is probably not the best way start programming. Many beginners struggle with the concept of strict master/slave. The slave doesn't have a chance to tell the master anything, the master always have to ask exactly for everything.
Using Modbus in a rather complex setup is probably not the best way start programming.
Would you consider this setup "complex":
[coffee roasting program --> (via Modbus) arduino --> temperature gauge / fan / vent, etc.]
?
I do not really struggle too much with the theoretical aspects of Modbus having read the protocol and having watched and read a decent number of videos and articles, however what I struggle with is the practical part.
I think the most helpful resources for me would be project guides and how to (specifically with Arduino) information to get familiar with the specifics of actually establishing the Modbus communication.
I will check out the library you suggested and have a look at the examples
-Einar
P.S.
The picture is visible although it's not schematics in my opinion
I have fixed it so that it is no longer referred to as a schematics
Yes, the inclusion of Modbus made it already complex. Although the protocol is quite well documented, the implementations often realize only part of it and don't go in every detail (timing is an often seen problem).
you have to go through some basics because there are different function codes depending of if you want to write a coil (a relay), read an input, or set a variable.
so the first thing is to bring the API of your machine on paper, describing in detail what functions you want to have available on Modbus. Then you can find out which function codes are needed and you can assign the registers.
After all this paperwork is done you can chose a library.
you have to go through some basics because there are different function codes depending of if you want to write a coil (a relay), read an input, or set a variable.
Yeah I know some of the basics of the Modbus communication structure like function code, address, data, etc. As I have mentioned I've read the Modbus protocol and tried to educate myself through articles and videos.
so the first thing is to bring the API of your machine on paper, describing in detail what functions you want to have available on Modbus. Then you can find out which function codes are needed and you can assign the registers.
I don't really understand this part of your response.
I skimmed through this (What is an Application Programming Interface (API)? | IBM) briefly and to my understanding Modbus is a API?
What do you mean by bringing the API of my machine on paper? You mean the machine(s) that will be connected to the Arduino (fan, temperature reader, etc)?
Right now I'm just trying to get the first part of the puzzle solved, so setting up the Arduino as a slave with Modbus. So for now I'm ignoring the further equipment that will be attached and just focusing on getting this working.
What I'm struggling with the most right now is this:
As I understand it, the Arduino has no built in registers since it is does not come equipped for Modbus by the manufacturer.
Therefore you have to write your own registers in the Arduino after downloading a Modbus library.
Then you can use a standard Modbus program, such as QModBus, to address the Arduino as a slave.
Is this overall conception correct??
If so, how do I do this? where can I learn to write registers?
I hope these questions give you a better idea about where I am in terms of understanding Modbus.
partly. You design your API with Modbus. But for the complete API you should have a clear description what you want to control via Modbus. If you know the WHAT - you can define the necessary function codes and you can define the registers.
It makes a difference if you want to control a relay or if you want to read a sensor.
Yes. You have to "program" all function codes and valid registers to make the Arduino working as slave.
Again, first you have to define what function code - which register - than you can add the necessary functionality in your sketch.
I have written a "simple" Modbus Slave (server) library. It comes with several examples for each supported function code and several advanced examples. I assume I could help you with a sketch but you will need a clear picture of WHAT you want your slave to do. https://werner.rothschopf.net/microcontroller/202112_arduino_modbus_server.htm
But for the complete API you should have a clear description what you want to control via Modbus. If you know the WHAT - you can define the necessary function codes and you can define the registers.
hmmm I was not aware that you could program function codes. I thought that the function codes are defined by the Modbus protocol (ex. read coil status is 0x01)?
If you know the WHAT - you can define the necessary function codes and you can define the registers.
It makes a difference if you want to control a relay or if you want to read a sensor.
I can give two examples of things I want to do via the Arduino:
Read a temperature sensor.
Control a stepper motor.
I will now check out the library you have created and read the guide to try to increase my understanding.
No, it's a protocol. The library implementing the protocol offers an API.
noiasca meant that you should know what the Modbus slave should be able to do to be able to select the correct library. There are quite a few libraries available and each has it's advantages and disadvantages.
The registers of Modbus are a logical concept. Almost no Modbus device implements the registers in hardware.
The registers are usually implemented by the library you just have to define (using the API) what registers you need and what type they have.
The au16date holds the Modbus registers. The numbers on that line are the initialization values they get at startup.
Thanks for your response pylon,
You will have to forgive me for some extreme n00b questions here:
The registers of Modbus are a logical concept. Almost no Modbus device implements the registers in hardware.
Do you think you could expand on this? What do you mean by a "logical concept"?
For instance I have a variable frequency driver which comes ready to be used with Modbus; would that also use a library?
.
.
No, it's a protocol. The library implementing the protocol offers an API.
So how does a protocol differ from an API? According to this (What is an Application Programming Interface (API)? | IBM) website an API is "a set of defined rules that explain how computers or applications communicate with one another."
This sounds like what Modbus is too me...
.
.
you just have to define (using the API) what registers you need and what type they have.
What do you mean by "what type they have"?
.
.
The numbers on that line are the initialization values they get at startup.
What are initialization values? Are they arbitrary?
Would the slave in this example have 16 registers? if so how come multiple numbers are 0?
Hope I am not annoying you with my large amount of questions; this is just the way I learn the best and I really want/need to understand this topic better...
Hi Noiasca,
I have now used this (GitHub - smarmengol/Modbus-Master-Slave-for-Arduino: Modbus Master-Slave library for Arduino) library to establish a Modbus connection between my computer and an Uno with the RS485_slave example and am receiving some data when I read a coil from start address 0.
My next goal is to control a red LED and to turn it on/off through QModBus.
How would I go about doing this?
I do also not know what & how many registers the library has created, how do I know this?
/**
* Modbus slave example 3:
* The purpose of this example is to link a data array
* from the Arduino to an external device through RS485.
*
* Recommended Modbus Master: QModbus
* http://qmodbus.sourceforge.net/
*/
#include <ModbusRtu.h>
// assign the Arduino pin that must be connected to RE-DE RS485 transceiver
#define TXEN 4
// data array for modbus network sharing
uint16_t au16data[16] = {
3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, -1 };
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* port : serial port
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus slave(1,Serial,TXEN); // this is slave @1 and RS-485
void setup() {
Serial.begin( 19200 ); // baud-rate at 19200
slave.start();
}
void loop() {
slave.poll( au16data, 16 );
}
When I send a request to readCoils(0x01) through QModBus I get the return message 01 01 01 00 51 88 and no error messages so I assume everything is working.
But to "control" a LED you should use something with FC5 Write Single Coil .
You have to study the library / library description how to define "coils" and how to access them. I haven't found a quick example for that in this library but based on the source code - that should be able with this library.
Hi Noiasca,
what about that message lets me know it's holding registers that I've created?
But to "control" a LED you should use something with FC5 Write Single Coil .
Yeah that makes sense.
You have to study the library / library description how to define "coils" and how to access them. I haven't found a quick example for that in this library but based on the source code - that should be able with this library.
If I understand it correctly (?): is not the library.h file a code to get the library itself to function, and not something that you use to learn to write code?
.h is usually a header file only. But in this library it also contains the full c++ code.
It's the complete implementation.
the keyword.txt is only a file for the Arduino IDE which does the keyword highlightning.
Additionally there are some examples. These are the starting points for "learning" how to use code.
On your PC you will find also the folder "documentation" in the library folder ... this should contain a human readable description of the library. Open the index.html.
PS: I'm not here to judge others work, but after reading the documentation of that and other libraries you might understand why I have decided to write my own Modbus library, my own description, my own examples. Example "0215_Modbus_Server_FC1_FC5_FC15_Read_Write_Coils" demonstrates how to write to four (or any other number of defined) outputs.
Noiasca,
How is a library separate from a header file? Should I understand it that the header file is a subspecies of a library?
going off these definitions:
Additionally there are some examples. These are the starting points for "learning" how to use code.
I've had a look at these and in my opinion the "simple" ones are not very informative/detailed and the advanced ones are not even in English!
On your PC you will find also the folder "documentation" in the library folder ... this should contain a human readable description of the library. Open the index.html.
PS: I'm not here to judge others work, but after reading the documentation of that and other libraries you might understand why I have decided to write my own Modbus library, my own description, my own examples. Example "0215_Modbus_Server_FC1_FC5_FC15_Read_Write_Coils" demonstrates how to write to four (or any other number of defined) outputs.
I understand this totally, I had a look at the library you posted and the description and explanations were much clearer although it was somewhat above my expertise level (had to go learn about callback functions etc).