We will now look at P1AM Arduino Modbus TCP communication to the C-More EA9 Series HMI. This will be communicating Ethernet Modbus TCP protocol. The P1AM will be the server (slave) and the EA9-RHMI the client (master).
We will explain how to connect a headless C-more HMI to our P1AM-ETH Industrial Arduino Ethernet Shield.
The P1AM Example from Automation Direct on GitHub will be used.
P1AM-Examples/tree/master/P1AM-100_ModbusTCP_Server_HMI
We will be using the remote android and windows app to connect to the C-More EA9 HMI. This will display the information from our Arduino P1AM on our headless unit. Let’s get started.
Previous posts in this Productivity Open Arduino Compatible Industrial Controller Series
A full list can be obtained at the following location:
Productivity Open (P1AM-100) Arduino Controller
Productivity Open Arduino Controller Hardware
– Starter Kit Unboxing Video
– Powering Up Video
Installing the Software – Video
First Program – Video
Program Structure – Video
Variables Data Types – Video
Serial Monitor COM – Video
Program Control – Video
Operators – Video
GPIO Inputs and Outputs – Video
Math Instructions – Video
Time Instructions – Video
P1000 Expansion Analog Combination Module – Video
P1000 Expansion Digital Inputs and Outputs Part 1 – Video
P1000 Expansion Digital Inputs and Outputs Part 2 – Video
Watchdog Timer – Video
P1000 Expansion Thermocouple Module – Video
PID Control – Video
P1AM Arduino Modbus TCP to C-More Micro EA3 – Video
Watch the video below to see a sample program (sketch) of the P1AM-ETH Modbus TCP Server communicating to our C-More EA9 Modbus TCP client HMI.
Arduino P1AM-ETH Shield
Specifications
The P1AM-ETH is an industrially rated MKR format shield based on the WIZnet W5500 chip that adds ethernet connectivity to the P1AM-100. The P1AM-ETH uses SPI to communicate with the P1AM-100 or other MKR format CPU. The P1AM-ETH uses the Arduino Ethernet library which comes standard with the Arduino IDE.
The MAC (Media Access Control) address is the physical hardware identification number. This is printed on the right-hand side label of our P1AM-ETH unit.
We will need this number for our program.
Modbus TCP Server (Slave)
Our sketch (program) comes from the sample on GitHub that will turn our P1AM-ETH into a Modbus TCP Server and give access to our P1 (Productivity 1000) input and output modules.
Libraries Required for Arduino Program (Sketch)
The first thing that we must do is to ensure that the libraries (dependencies) that we need are installed on our Arduino IDE.
https://github.com/arduino-libraries/ArduinoModbus
https://github.com/arduino-libraries/ArduinoRS485
Note: The Arduino Modbus Library depends on the Arduino RS485 so both must be installed.
Call up the library by using the main menu | Sketch | Include Library | Manage Libraries… Alternatively, you can use the short cut of Ctrl+Shift+I.
Type in ArduinoModbus on the top line to call up the library functions available.
If it is not installed then select the latest version and install.
Type in ArduinoRS485 on the top line to call up the library functions available.
If it is not installed then select the latest version and install.
Select close to close the library manager window.
Note: Both libraries appear when typing Arduino RS485 because of the dependency between them.
Modbus TCP Server Sample Program (Sketch)
A Modbus server will do nothing until a client asks for information. The server program will create variables that are available for the client to read or write. There are four types of variables in Modbus.
Discrete Output Coils 0xxxx
Discrete Input Contacts 1xxxx
Analog Input Registers 3xxxx
Analog Output Holding Registers 4xxxx
This sample program is the exact same as the sample on GitHub. The purpose is to create a Modbus TCP server for the P1AM-ETH with access to productivity 1000 (P1) input and output modules.
In our example, we have two P1 modules to the right-hand side of the P1AM CPU. The P1-08SIM (8 point simulator input card) and P1-16TR (16 point relay output card).
This sketch creates a Modbus TCP Server for up to 8 connections. Slot1 Inputs are mapped to Modbus Input Bits 100001 to 100008. Slot2 Outputs are controlled by Modbus Coil Bits 000001 to 000008. Modbus Holding Register 400001 is always incrementing.
Here is the sample program (sketch):
We have ensured that the MAC address is set according to the physical card and the IP is set according to our network.
/* Modbus TCP Server for P1AM-ETH with access to P1 Input/Output Modules This sketch creates a Modbus TCP Server for up to 8 connections. Slot1 Inputs are mapped to Modbus Input Bits 100001 to 100008. Slot2 Outputs are controlled by Modbus Coil Bits 000001 to 000008. Modbus Holding Register 400001 is always incrementing. The P1AM-100 cpu will require external 24vdc power for the IO modules to function. This example uses Serial.print() to display status information. The Serial Monitor must be running for the sketch to start. Required Libraries which need to be installed. https://github.com/arduino-libraries/ArduinoModbus https://github.com/arduino-libraries/ArduinoRS485 */
#include #include #include #include // ArduinoModbus depends on the ArduinoRS485 library #include byte mac[] = { //Use the �Reserved MAC� printed on the right-side label of your P1AM-ETH. 0x60, 0x52, 0xD0, 0x06, 0x69, 0x86 }; IPAddress ip(192, 168, 1, 177); //IP Address of the P1AM-ETH module. boolean MB_C[16]; //Modbus Coil Bits boolean MB_I[16]; //Modbus Input Bits int MB_HR[16]; //Modbus Holding Registers int MB_IR[16]; //Modbus Input Registers EthernetServer server(502); EthernetClient clients[8]; ModbusTCPServer modbusTCPServer; int client_cnt; void setup() { Serial.begin(115200); while (!Serial){}// wait for serial port to connect. Serial.println("Modbus TCP Server and Module I/O Example"); while (!P1.init()){} ; //Wait for P1 Modules to Sign on Ethernet.begin(mac, ip); server.begin(); // start the server to begin listening if (!modbusTCPServer.begin()) { // start the Modbus TCP server Serial.println("Failed to start Modbus TCP Server!"); while (1); //If it can't be started no need to continue, stay here forever. } modbusTCPServer.configureCoils(0x00, 16); //Coils modbusTCPServer.configureDiscreteInputs(0x00, 16); //Discrete Inputs modbusTCPServer.configureHoldingRegisters(0x00, 16); //Holding Register Words modbusTCPServer.configureInputRegisters(0x00, 16); //Input Register Words Serial.println("Done with setup()"); } void loop() { EthernetClient newClient = server.accept(); //listen for incoming clients if (newClient) { //process new connection if possible for (byte i = 0; i < 8; i++) { //Eight connections possible, find first available. if (!clients[i]) { clients[i] = newClient; client_cnt++; Serial.print("Client Accept:"); //a new client connected Serial.print(newClient.remoteIP()); Serial.print(" , Total:"); Serial.println(client_cnt); break; } } } //If there are packets available, receive them and process them. for (byte i = 0; i < 8; i++) { if (clients[i].available()) { //if data is available modbusTCPServer.accept(clients[i]); //accept that data modbusTCPServer.poll();// service any Modbus TCP requests, while client connected } } for (byte i = 0; i < 8; i++) { // Stop any clients which are disconnected if (clients[i] && !clients[i].connected()) { clients[i].stop(); client_cnt--; Serial.print("Client Stopped, Total: "); Serial.println(client_cnt); } } //Read from P1-08SIM Input Module and then write into Modbus memory int Slot1_Inputs = P1.readDiscrete(1,0); //Read from P1-08SIM Input Simulator Module for (int i=0;i<8;i++){ MB_I[i]=Slot1_Inputs&(1<<i); } updateInputs(); //Write current state of the Modbus Inputs into MB_I[] //Read from Analog Input Modules and then write into Modbus memory updateInputRegisters(); //Write current state of the Modbus Inputs into MB_IR[] updateCoils(); //Read current state of the Modbus Coils into MB_C[] for (int i=0;i<8;i++){ P1.writeDiscrete(MB_C[i],2,i+1);//Data,Slot,Channel ... Channel is one-based. } updateHoldingRegisters(); //Read current state of the Modbus Registers into MB_HR[] MB_HR[0]++; //TestApp, increment the Modbus Register 400000 just to have data changing. modbusTCPServer.holdingRegisterWrite(0,MB_HR[0]); } void updateCoils() {//Read the Coil bits from the Modbus Library for (int i=0;i<16;i++){ MB_C[i] = modbusTCPServer.coilRead(i); } } void updateInputs() { //Write the Input bits to the Modbus Library for (int i=0;i<16;i++){ modbusTCPServer.discreteInputWrite(i,MB_I[i]); } } void updateHoldingRegisters() {//Read the Holding Register words from the Modbus Library for (int i=0;i<16;i++){ MB_HR[i] = modbusTCPServer.holdingRegisterRead(i); } } void updateInputRegisters() { //Write the Input Registers to the Modbus Library for (int i=0;i<16;i++){ modbusTCPServer.inputRegisterWrite(i,MB_IR[i]); } }
We now have our completed Modbus server program for our industrial Arduino.
Verify the program.
Upload the program.
We can now move onto the Modbus client.
C-More EA9
Our complete cmore series can be found here. This will take you through all of the features of this versatile human-machine interface. (HMI)
Our HMI program comes from the sample on GitHub. We will modify the P1AM Driver Cmore V6.52.eap9 to the latest software and change the HMI unit to the EA9-RHMI headless.
The latest EA9 HMI programming software can be downloaded free of charge here.
Once the C-More programming software has been installed, open up the file downloaded from GitHub.
The program will be converted to the new version of the software. Click yes to make a copy of the original project.
Here is what our project looks like. We will have one screen (Screen 1) that is called the P1AM driver.
Select panel manager. You can do this by the main menu | Setup | Panel Manager…
This can also be found under the Setup in the function tab of the navigation window.
Change the panel type to an EA9-RHMI. The project resolution will be SD – 720×480.
Select display large keypad on the panel. This is ideal for use on the remote apps.
Select DEV001 under the Ethernet port on the panel manager window.
The PLC protocol is set for Modicon Modbus TCP/IP Ethernet. Set the PLC IP address to the same number on the P1AM.
Select OK
We can now move around the indicator lights, pushbutton switches, numeric display, and entry to fit the new screen size.
Here is our completed screen.
Tag Name Database
The tag database can be seen by selecting the tag name database under the database in the function tab of the navigation window. You can also call this up by using the main menu | Database | Tag Name Database…
C-More EA9 Remote Access Setup
Call up the panel network window by using the main menu | Setup | Panel Network…
Panel network can also be accessed by selecting the menu under the setup option in the function tab of the navigation window.
We will name our panel P1AM Client. It is a good practice to name the device on the network. Select Ethernet Port.
The enabled IP address to be changed from the software is on as a default. Once you have set up the IP address then this can be unchecked. Select Web Server.
We will enable the webserver function and password option. The Account name will be “ACC” and the password will be “acca”. The web server is necessary in order to download the windows based software. Once this has been downloaded, the webserver can be turned off.
Select remote access.
Select remote access server function. We will leave port number 11102 as the default number. Under the logon information select permission as full control. This will allow the user to view, change pages, and modify the parameters.
The account name and password will be the same as the webserver.
We can have up to 5 users on this account at the same time. In our case, we are limiting this account to 3 users.
Note: We can have up to 15 users altogether for the three accounts on the panel.
Select OK.
Remote access has now been set up.
We can now transfer this program over to our EA9-RHMI.
Additional information on remote control apps on the EA9 can be found here.
We can use the simulator to test our program before downloading to the HMI.
Select start.
Download the C-More EA9 program into the EA9-RHMI screen.
We can now run our programs together.
Watch the video below to see the operation of our productivity open industrial Arduino controller communicating Modbus TCP to our C-More unit.
Download the P1AM-100 sample sketch and Productivity Block program here.
Productivity Open Arduino Compatible Links:
Product Hardware
– Productivity Open (Automation Direct)
– P1AM-100 Specifications
– Productivity Open User Manual
– Configure a Productivity Open Arduino-based Controller
– Open Source Controllers (Arduino-Compatible)
– Productivity Open Documentation (Facts Engineering)
– P1AM Design Files
Software
– Arduino IDE (Integrated Development Environment)
– P1AM-100 library (Easy Interface for controlling P1000 Modules)
– Productivity Blocks (Development Timesaver)
– Productivity Blocks Documentation (Wiki)
Community
– Automation Direct Forum – Open Source Devices
Modbus Learning Links:
Simply Modbus Frequently Asked Questions
Modbus TCP/IP Overview – Real-Time Automation
All You Need to Know About Modbus RTU – Video
Next time we will look at programming the webserver with our Ethernet industrial shield on our P1AM-100 Arduino Industrial Controller.
Watch on YouTube: Productivity Open P1AM Industrial Arduino Modbus TCP to C-More EA9
If you have any questions or need further information please contact me.
Thank you, Garry
If you’re like most of my readers, you’re committed to learning about technology. Numbering systems used in PLC’s are not difficult to learn and understand. We will walk through the numbering systems used in PLCs. This includes Bits, Decimal, Hexadecimal, ASCII and Floating Point. To get this free article, subscribe to my free email newsletter. Use the information to inform other people how numbering systems work. Sign up now.
The ‘Robust Data Logging for Free’ eBook is also available as a free download. The link is included when you subscribe to ACC Automation.