Before beginning I would like to say that I am somewhat familiar with Modbus RTU but completely new to Modbus TCP and ethernet communication in general.
I am attempting to create a Modbus TCP communication between my computer running ModbusTool.exe (V.1.1.1.0) and an Arduino Machine Control.
Hardware: Computer + Ethernet cable + Portenta Machine Control
This is my sketch thus far:
#include <Arduino_MachineControl.h>
#include <Ethernet.h>
#include <PortentaEthernet.h>
#include <SPI.h>
#include <ArduinoRS485.h>
#include <ArduinoModbus.h>
using namespace machinecontrol;
EthernetServer ethServer(502);
ModbusTCPServer modbusTCPServer;
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// The IP address will be dependent on your local network:
byte mac[] = {
0x90, 0x2E, 0x16, 0xF4, 0xED, 0xB4
};
IPAddress ip(xxx, xxx, xx, xxx);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial) {
// wait for serial port to connect. Needed for native USB port only
}
Ethernet.begin(mac, ip);
// start the Ethernet connection:
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin() == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware.");
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
}
// print your local IP address:
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
if (!modbusTCPServer.begin()) {
Serial.println("Failed to start Modbus TCP Server!");
while (1);
}
modbusTCPServer.configureCoils(0x00, 1);
}
void loop() {
// put your main code here, to run repeatedly:
// listen for incoming clients
EthernetClient client = ethServer.available();
if (client) {
// a new client connected
Serial.println("new client");
// let the Modbus TCP accept the connection
modbusTCPServer.accept(client);
while (client.connected()) {
// poll for Modbus TCP requests, while client connected
modbusTCPServer.poll();
}
Serial.println("client disconnected");
}
}
I think the sketch is working as the ip address is printed and none of the error messages that would indicate a lack of communication appear.
I can also see this in windows control panel:
This makes me think some sort of ethernet communication is indeed going on.
However when I use ModbusTool.exe and try to connect the program ends up idling in "connecting" forever. Here are my settings:
I also noticed in windows cmd >> ipconfig/all that the IPv4 address changes each time I upload the sketch, so I tried connecting with both the old address shown in the print statement in the serial monitor and also the new address shown in cmd or control panel - but without success.
Am I missing something or is there some mistake in my code?
Would very much appreciate if someone could point me in the right direction!
If I understand it correctly this segment of the code creates a new IP address for the program after I already specify one in IPAdress ip( ); ?
Have you tried to ping the Arduino IP?
No, I will learn about this and try it out
Does your PC use the same network as your Arduino?
I do not quite understand this question... I am not connect to wifi via the PMC and the only similar communication is between the PMC and the PC with the ethernet cable.
(where you replace <IP_of_the_Arduino> by the IP address the Arduino got, of course).
Post the output you get (no pictures please).
So you connect the Arduino directly by an Ethernet cable. That works only if your PC has auto-MDI/MDI-X capabilites. Otherwise you need a cross-over cable for that connection.
Hello again pylon and thank you for your info & guidance.
I tried removing the part of the code you suggested but was not able to connect ModbusTool.exe.
On the command line do:
Are you here reffering to the windows cmd or the Arduino CLI. I have not use the CLI previously but am ofc open to downloading it and using it
I think I now roughly understand the importance of auto-MDI/MD-X and what it is, however I am unsure how to know if my own computer has it.
I have tried looking around the web a little for tutorials and also had a look in ipconfig (windows cmd), lenovo vantage, the "about" section in settings, and device manager, but could not find any info. Someone in a forum wrote that the computer doesnt know about these layer 1 processes (?).
How would I go about determining if my pc has auto-MDI/MD-X capabilities?
A command line, under Windows that the "DOS window" or the newer Powershell, under Mac OS and Linux it's usually simply called Terminal.
The arduino-cli is an Arduino version for above mentioned command line, it's not a command line itself.
If you have a cross-over cable you can eliminate the need for auto-MDI/MDI-X.
You haven't told us yet what actual IP addresses you use on your computer as well as on the Arduino. That's no critical information you can post it here without any problems. I got the impression that you might have chosen the wrong one there too. That would explain your problems.
So if I understand you correctly I should try using the windows command prompt for the line?
Here is all I get:
C:\Users\einar> ping <IP_of_the_Arduino>
The syntax of the command is incorrect.
If you have a cross-over cable you can eliminate the need for auto-MDI/MDI-X.
Understood. However then I must order this cable which will take some time shipping, so it would also be nice If I could determine in some way if my pc has this capability...
That's no critical information you can post it here without any problems.
Ok so the ip address that Im feeding into the IPConfig IP ( ); function is currently:
169.254.97.226
I get this from "Ethernet Adapter Ethernet" in windows cmd ipconfig/all.
However it seems to change each time I upload...
Read my post again. I told you that you have to replace part of that command with a value I don't know.
Do you get a link on the PC when the Arduino is connected? A link is usually shown by an LED at the connector, although some modern Notebooks even eliminated those LEDs.
Without the LEDs your OS might tell you the link status but I don't know your operating system well enough to help you there.
Rather bad choice. That's a link local IP address which is used to connect two PCs directly. This link local address uses a network mask of 255.255.0.0 (class B network) while the default network mask of the Arduino Ethernet library is 255.255.255.0 (class C network). There may be other restrictions on a Windows PC using these addresses but I don't know them.
I recommend to use a class C network from the private range, p.e. 192.168.200.x. So use 192.168.200.20 on your Arduino and configure your PC's ethernet interface to use 192.168.200.10 (network mask 255.255.255.0). You don't have to specify a gateway or DNS server as they won't be used anyway.
Ok, here is the response I get when I ping the ip address I've fed to the Arduino program:
Pinging 169.254.0.175 with 32 bytes of data:
Reply from 169.254.0.175: bytes=32 time=6ms TTL=255
Reply from 169.254.0.175: bytes=32 time=1ms TTL=255
Reply from 169.254.0.175: bytes=32 time=2ms TTL=255
Reply from 169.254.0.175: bytes=32 time=2ms TTL=255
Ping statistics for 169.254.0.175:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 1ms, Maximum = 6ms, Average = 2ms
Do you get a link on the PC when the Arduino is connected? A link is usually shown by an LED at the connector, although some modern Notebooks even eliminated those LEDs.
No LED exists physically on the PC end however the Arduino PMC is blinking its LEDs at the ethernet connector point. I am using windows 10.
while the default network mask of the Arduino Ethernet library is 255.255.255.0 (class C network)
Ok, understood
I recommend to use a class C network from the private range, p.e. 192.168.200.x.
I understand where the 192.168. came from, but where did the .200. come from? Is this the default private address on a 255.255.255.0 submask?
Anyhow I will follow your instructions and get back! Thanks
No, that's just a network not commonly used by home routers. This is to limit the chance that you collide with other networks in your home if there is a connection you forgot to mention...
I guess you did change the IP address in your ModbusTool too...
Can you try the ping command using the new IP addressof the Arduino?
I'm concerned about the "Preferred" here. Please try to get rid of the Autoconfiguration IPv4 address. Tell your PC that you want to set the IPv4 manually.
Currently I have just copied the DNS info from ipconfig/all, but looking at that information gateway is blank, so not sure what to put there...
Cheers / Einar
Both are not needed but should get values inside the network, so use 192.168.200.1 (for both). Don't set an alternative DNS.
If you cannot ping the address on the same host it wasn't actually set up. Windows can be very disgusting in such thing, unfortunately (that's why I'm using it only if I'm forced to).
Ok thanks for your help so far though!
(I learnt a lot )
Do you have any good resources you would recommend to learn more about Ethernet and Modbus TCP?
Kind regards / Einar