Modbus TCP/IP on RaspberryPi wit PyModBus - raspberry-pi4

I need to communicate with several modules and devices using the ModBus Protocol and the Raspberry Pi.
I am using PyModBus on Raspberry Pi to read/write Modbus function codes. (https://pymodbus.readthedocs.io/en/latest/readme.html)
I was able to communicate Modbus RTU over RS485 with the device but now that I am trying to communicate ModbusTCP over a Ethernet cable and keep running into the following error:
import pymodbus
from pymodbus.client.sync import ModbusTcpClient
client = ModbusTcpClient('127.0.0.1')
connection = client.connect()
Output:
ERROR.pymodbus.client.sync: Conection to (127.0.0.1, 502) failed: [Errno 111] connection refused
Any tips or explanation for the error?

127.0.0.1 is a loopback address; this means that ModbusTcpClient('127.0.0.1') will attempt to establish a connection to the Pi iteslf. Unless there is a Modbus server running on the Pi the error you received is to be expected.
"I am trying to communicate ModbusTCP over a Ethernet cable" indicates you are communicating with another device which should have it's own IP address. You need to work out what that address is and use that when attempting to connect (as well as ensuring your network setup is valid). The method used to set/determine a devices address varies from device to device so you would need to check the documentation (you did not specify what the device is).

Related

Serial port on Raspberry Pi disconnects after several minutes and cannot be reconnected (IOError, pyserial)

I have a device with a RS-232 DB9 port connected to my Raspberry Pi over a USB-to-serial cable.
Initially, I am able to communicate with the device without issue using pyserial.
However, after some variable length of time, I can no longer receive messages from the device.
If I close the serial port and attempt to open a new one, using the same code I normally use:
import serial
ser = serial.Serial(
serial_path,
9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE
)
I get:
File "/opt/venv/lib/python3.8/site-packages/serial/serialposix.py", line 713, in _update_dtr_state
fcntl.ioctl(self.fd, TIOCMBIS, TIOCM_DTR_str)
OSError: [Errno 5] Input/output error
I have no way to get around this error and re-establish communication with the device unless I physically unplug and replug the USB port.
In case it's relevant, the RS-232 device is connected to my RaspBerry Pi via an intermediate USB Hub and a USB extension cable.
I also tried setting rtscts=True and dsrdtr=True when creating the pyserial object. The IOError no longer occurs; however the serial device remains uncommunicative.
What might be the underlying issue here? Any guidance would be appreciated. Is there any way to detect the issue and reset the serial port via the shell, without requiring physical intervention?

ESP8266 connection to a Arduino Nano

I am trying to connect a WiFi module (ESP8266) to a "funduino" development board (Arduino Nano) but I have no success. Since I tried so much schematics I've found on the internet about the connection between them two, I kindly ask here if is anyone who succeed in "pairing" this two devices.
I am asking for the schematic and a functional source code.
Regards
The ESP-01 by default comes with nonOS SDK bootloader that communicated via AT commands, you can find the complete command set from Expressif here. This is designed for an MCU (like Arduino Nano) to use it purely as an WiFi module rather than using it as a stand-alone MCU (for which it will require NodeMCU SDK).
If you ever upload an Arduino sketch up to the ESP-01, it will erase the AT Command firmware.
Assuming your ESP-01 is still having the AT Command firmware. What #Ben provided is a sketch that allows you to type AT commands via the Serial Monitor to internact with the ESP-01, it is manual, and good for testing if ESP-01 is working (you type AT and press return on Serial Monitor, the ESP-01 will ack with Ok) but not practical as a real application. The minimum commands required to established an WiFi connection with ESP-01 is listed below.
AT+CIPMUX=1 - Enable single (0) or multiple connection (1) to the web server.
Multiple connection is a good option if you are repeatedly sending
out or reading data from the Internet.
AT+CWMODE=3 - Set WiFi mode: 1 is station mode (ESP8266 is client), 2 is AP mode
(ESP8266 acts like a WiFi router where your phone or PC can connect),
3 is AP+station mode (make the ESP8266 do both)
AT+CWJAP=“<your-ssid>”,”<your-pw>” - Connect to your WiFi. Provide your SSID name
and password inside the double qoutes.
AT+CIFSR - This returns the IP address of the module, indicating that it has
successfully connected to your WiFi router.
Once the WiFi connection is established, you can further communicate with the ESP-01 via the connection, like accessing a website for example:
AT+CIPSTART=0,"TCP", "www.example.com","80” - Start TCP or UDP connection. The
0 is the id of the connection.
AT+CIPSEND=0,16 - Command to tell the module data is ready to be sent. 0 is the
connection id, and 16 is the length of the data to be sent.
After this command, the ESP8266 will reply with the “>”
character to tell us that it will be waiting for the data to be
sent. If successful, the module will reply with “SEND OK”
GET / HTTP/1.1 - Send the http header, and other data, etc...
You can write your own sketch to automate those AT commands for interacting with with ESP-01 once you understand the AT commands required for establish a WiFi connection.
Here are two resources that I personally found extremely useful for doing more than connecting to WiFi.
STM32-ESP-01 Web Server - although this is for interfacing with STM32, the main difference is the pin assignment, so you should be able to port to Arduino easily.
MQTT via ESP-01
As for hardware interface, please noted that what #Ben provided is correct in principle, but you need to be aware that the ESP-01(ESP8266 to be precise) is a 3V3 MCU, so the connection is depended on what kind of host board you are using. If you are using Arduino Uno/Nano, both are having a 5V MCU, you will need a voltage divider (two resistors to drop the voltage to 3v3 before connecting to ESP-01) or a level shifter chip at least for the ESP-01 Rx pin to avoid the potential damage to the ESP-01.

Pymodbus Failed to Connect with PLC Slave and Raspberry Pi Master

I am trying to use a Raspberry Pi 3 Model B to read values from an Allen Bradly PLC. I'm using the Pymodbus Modbus TCP protocol to communicate between them.
When I run a test client I get the following error:
pi#raspberrypi:/var $ python test1.py
Got here 1
Traceback (most recent call last):
File "test1.py", line 12, in <module>
request = client.read_holding_registers(0,1)
File "build/bdist.linux-armv7l/egg/pymodbus/client/common.py", line 109, in read_holding_registers
File "build/bdist.linux-armv7l/egg/pymodbus/client/sync.py", line 82, in execute
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Failed to connect[10.0.0.237:502]
Here is the code for the test client:
from pymodbus.client.sync import ModbusTcpClient
#modbus connection
client = ModbusTcpClient(host='10.0.0.237')
connection = client.connect()
#test print
print "Got here 1"
#read register
request = client.read_holding_registers(0,1)
print request
client.close()
I can ping the IP address of the PLC's ethernet card (10.0.0.237) just fine. (The PLC is on and shows up in RSLinx and RSLogix5000.) But when I try to check port 502 (which Modbus uses) with the command:
telnet 10.0.0.237 502
I get the error:
Trying 10.0.0.237...
telnet: Unable to connect to remote host: Connection refused
The research I've done told me to check whether that port is open, but that is for PCs, I don't know how you check/configure the ports on a PLC.
In addition, I am wondering if the problem is that I am trying to just use Modbus to go between the Raspbery Pi and PLC. I have found prosoft gateways that do the interfacing. But I couldn't find any information on whether those were just another option or whether they were required.
I am new to PLCs and networking, so any help would be appreciated.
I have not used Allen Bradley myself but I do use a multitude of other PLCs though and they all work more or less the same.
You dont open the port as you would in a router but rather activate modbus connectivity in the PLC. Most often its a setting but if Allen Bradley use their own proprietary bus system (e.g Saia S-Bus) you sometimes need a specific function block to enable modbus.
A quick google search for example showed that in micrologix 1400 theres a checkbox to enable modbus tcp under some channel setting.
Check in the PLC if there is a setting to enable modbus master/client (master=serial or RTU, client=TCP but sometimes manufacturers dont differentiate them).
To test the Raspberry Pi you can download a modbus server simulator and poll that.
To test the PLC with something other then the Pi you could download a modbus client/master. I personally use QmodMaster which is free and works well for testing purposes (search google).
Also, make sure youre polling using the right function code. This can be confusing as holding registers (which are addressed 4xxxx) use function code 03. Input registers (which are addressed 3xxxx) use function code 04.
A modbus gateway is used to enable serial modbus (RTU or ASCII) to communicate via TCP.
If both devices do have modbus tcp theres no need for a gateway. If for example you have a device which only has wired modbus (RS232/485/422) you can connect that to a gateway and the gateway to TCP.

Developing my own modem

I would like to develop my own modem for a custom communication network that will be detectable on the serial port by PC automatically. What I'm uncertain about is the protocol part of the AT commands and how to make it work seamlessly so that computer will detect the modem automatically.
I plan to use ftdi UART to USB converter to interface my microcontroller with the PC using standard serial interface. The PC will then use AT commands to communicate with the microcontroller that will in turn connect to another microcontroller over radio tranceiver and establish a two way serial connection over radio. The idea is that the PC on the other end will run PPPD and listen on it's own modem connection for incoming call and then bridge the connection with it's other internet interface that is connected to internet. The first computer will get it's own IP address using PPPD and will be connected to internet over this custom microcontroller based modem.
But how do I implement the communication protocol between my controller and PC? What commands do I absolutely need to implement? How do I make sure that the computer recognises my controller which is connected over ftdi usb to serial adapter as a functional modem?
Where can I find a speciffication of the minimum command set that is required of a modem?
In practice linux usually discovers a 3G modem automatically for example. Does that have to do with the actual USB identifier of the modem? Is it possible to have linux automatically discover an ordinary serial port modem? I'm thinking that the modem will be sending an AT idle ping repeatedly when it's plugged in so that linux should be able to detect it.

Cisco switch and router programming using Arduino?

So, this topic is very similar to this Cisco Switch/Router programming using Arduino?.
I have an Arduino ATmega2560 and Ethernet Shield plus a Cisco 1751 router. I want to configure the router via the console or AUX port using Arduino.
Fast search gave the following results: you could connect to the router using RJ45 to Serial or RJ45 to RJ45 connectors; the protocol is very similar to Telnet (actually works like serial port with text-based commands).
So the main question is - am I able to control the router via a console or AUX port using Ethernet Shield (and an Ethernet library) or do I have to use a serial port connection using something like RS-232?
Update: I've noticed one thing - the DB9 port is just an option for easy communicating with a PC so it seems that my idea is not so bad:) See Cabling and Adapter Setups that Work.
As you have pointed out the console and aux ports on Cisco devices are serial ports not network ports so you need to connect to them using RS232, this is an entirely different type of interface from Ethernet.

Resources