Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TCP socket connection #5

Closed
wants to merge 10 commits into from
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,4 @@ ENV/

# mypy
.mypy_cache/

# MacOS
.DS_Store
.DS_Store?
.vscode/settings.json
53 changes: 53 additions & 0 deletions examples/rtu_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Example Modbus RTU Client

This example shows how to communicate with a modbus server over RTU.

Written by FACTS Engineering
Copyright (c) 2023 FACTS Engineering, LLC
Licensed under the MIT license.

"""

import time
import board
import busio
from uModBus.serial import RTUClient
import p1am_200_helpers as helpers # For P1AM-SERIAL
from rs485_wrapper import RS485 # If using an RS485 transceiver

def clear_terminal():
print(chr(27) + "[2J")


# For P1AM-SERIAL using RS232
comm = helpers.get_serial(1, mode=232, baudrate=115200)

# For P1AM-SERIAL using RS485
# uart, de = helpers.get_serial(1, mode=485, baudrate=115200) # For P1AM-SERIAL
# comm = RS485(uart, de, auto_idle_time=.05) # If using an RS485 transceiver

# For generic RS232
# comm = busio.UART(board.TX1, board.RX1, baudrate=115200)

unit_id = 1 # ID of modbus unit
mb_client = RTUClient(comm, default_unit_id=unit_id) # Optionally specify a unit ID

counter = 0
while True:

counter += 1 # increment counter for register 4
if counter > 32767:
counter = 0 # reset counter

mb_client.write_single_register(4, counter, unit=unit_id)
current_states = mb_client.read_coils(0, 16, unit=unit_id)
holding_regs = mb_client.read_holding_registers(0, 3) # when unit is not specified, the default_unit_id is used

clear_terminal()
for i in range(len(current_states)):
print(f"Coil #{i} is {current_states[i]}")
for i in range(len(holding_regs)):
print(f"Register #{i} is {holding_regs[i]}")

time.sleep(1)
60 changes: 60 additions & 0 deletions examples/rtu_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Example Modbus RTU Server

This example shows how to configure a Modbus RTU server.

Written by FACTS Engineering
Copyright (c) 2023 FACTS Engineering, LLC
Licensed under the MIT license.

"""

import board
import digitalio
from uModBus.serial import RTUServer
import p1am_200_helpers as helpers # For P1AM-SERIAL
from rs485_wrapper import RS485 # If using an RS485 transceiver


led = digitalio.DigitalInOut(board.LED)
led.switch_to_output()
switch = digitalio.DigitalInOut(board.SWITCH)

# For P1AM-SERIAL using RS232
comm = helpers.get_serial(1, mode=232, baudrate=115200)

# For P1AM-SERIAL using RS485
# uart, de = helpers.get_serial(1, mode=485, baudrate=115200) # For P1AM-SERIAL
# comm = RS485(uart, de, auto_idle_time=.05) # If using an RS485 transceiver

# For generic RS232
# comm = busio.UART(board.TX1, board.RX1, baudrate=115200)

mb_server = RTUServer(
comm,
unit_addr=1,
number_coils=20,
number_input_registers=0xFF,
number_discrete_inputs=0x10,
number_holding_registers=10,
)

mb_server.input_registers[0:] = list(range(0xFF)) # set input registers 0-255 to 0-255

mb_server.discrete_inputs[5] = True # set input register 5 to True

mb_server.holding_registers.signed[1] = True # set holding register 1 to use 16-bit signed values

count = 0

while True:

mb_server.poll(timeout=.5) # Regularly poll the modbus server to handle incoming requests
mb_server.discrete_inputs[0] = switch.value # set discrete input 0 to switch value
mb_server.holding_registers[0] = count # set holding register 0 to count value
mb_server.holding_registers[1] = -count # set holding register 1 to negative count value
led.value = mb_server.coils[0] # set led to output value

count += 1
if count > 32767:
count = 0 # reset count
52 changes: 52 additions & 0 deletions examples/tcp_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Example Modbus TCP Client

This example shows how to communicate with a modbus server over TCP.

Written by FACTS Engineering
Copyright (c) 2023 FACTS Engineering, LLC
Licensed under the MIT license.

"""

import time
import board
import busio
import digitalio
import adafruit_connection_manager
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socketpool as socket
from uModBus.tcp import TCPClient

def clear_terminal():
print(chr(27) + "[2J")


cs = digitalio.DigitalInOut(board.D5)
spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
eth = WIZNET5K(spi_bus, cs, is_dhcp=True)
pool = adafruit_connection_manager.get_radio_socketpool(eth)
print(eth.pretty_ip(eth.ip_address))

client_ip = '192.168.1.101'
unit_id = 255
mb_client = TCPClient(pool, client_ip, default_unit_id=unit_id)

counter = 0
while True:

counter += 1 # increment counter for register 4
if counter > 32767:
counter = 0 # reset counter

mb_client.write_single_register(4, counter, unit=unit_id)
current_states = mb_client.read_coils(0, 16, unit=unit_id)
holding_regs = mb_client.read_holding_registers(0, 3) # when unit is not specified, the default_unit_id is used

clear_terminal()
for i in range(len(current_states)):
print(f"Coil #{i} is {current_states[i]}")
for i in range(len(holding_regs)):
print(f"Register #{i} is {holding_regs[i]}")

time.sleep(1)
71 changes: 71 additions & 0 deletions examples/tcp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""
Example Modbus TCP Server

This example shows how to configure a Modbus TCP server.

Written by FACTS Engineering
Copyright (c) 2023 FACTS Engineering, LLC
Licensed under the MIT license.

"""

import board
import busio
import digitalio
import p1am_200_helpers as helpers # For P1AM-ETH
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
from uModBus.tcp import TCPServer


led = digitalio.DigitalInOut(board.LED)
led.switch_to_output()
switch = digitalio.DigitalInOut(board.SWITCH)

# For P1AM-ETH
eth = helpers.get_ethernet(False) # DHCP False

# For generic ethernet
# cs = digitalio.DigitalInOut(board.D5)
# spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# eth = WIZNET5K(spi_bus, cs, is_dhcp=False)

IP_ADDRESS = (192, 168, 1, 177)
SUBNET_MASK = (255, 255, 248, 0)
GATEWAY_ADDRESS = (192, 168, 0, 1)
DNS_SERVER = (8, 8, 8, 8)
eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)

socket.set_interface(eth)
server_ip = eth.pretty_ip(eth.ip_address)
mb_server = TCPServer(
socket,
server_ip,
number_coils=0x20,
number_input_registers=0xFF,
number_discrete_inputs=0x10,
number_holding_registers=10,
)

mb_server.input_registers[0:] = list(range(0xFF)) # set input registers 0-255 to 0-255

mb_server.discrete_inputs[5] = True

mb_server.holding_registers.signed[1] = True # set holding register 1 to use 16-bit signed values

count = 0

while True:

try:
mb_server.poll(timeout=.1) # Regularly poll the modbus server to handle incoming requests
except RuntimeError as e:
pass # Ignore errors in case the client disconnects mid-poll
mb_server.discrete_inputs[0] = switch.value # set discrete input 0 to switch value
mb_server.holding_registers[0] = count # set holding register 0 to count value
mb_server.holding_registers[1] = -count # set holding register 1 to count value
led.value = mb_server.coils[0] # set led to output value

count += 1
if count > 32767:
count = 0 # reset count
105 changes: 0 additions & 105 deletions main.py

This file was deleted.

Loading