Switched modbus implementation and added state machine
This commit is contained in:
parent
6a1183ccf5
commit
09ac0bda50
24
main.py
24
main.py
@ -1,4 +1,4 @@
|
|||||||
import minimalmodbus
|
from pymodbus.client import ModbusSerialClient
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import argparse
|
import argparse
|
||||||
@ -16,7 +16,7 @@ def main():
|
|||||||
help='COM port for the Modbus connection')
|
help='COM port for the Modbus connection')
|
||||||
parser.add_argument('--slave_id', type=int, default=1,
|
parser.add_argument('--slave_id', type=int, default=1,
|
||||||
help='Slave ID for the Modbus device')
|
help='Slave ID for the Modbus device')
|
||||||
parser.add_argument('--cycle_time', type=float, default=0.01,
|
parser.add_argument('--cycle_time', type=float, default=0.05,
|
||||||
help='Cycle time in seconds for the main loop')
|
help='Cycle time in seconds for the main loop')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@ -26,14 +26,17 @@ def main():
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
instrument = minimalmodbus.Instrument(com_port, slave_id)
|
client = ModbusSerialClient(
|
||||||
instrument.serial.baudrate = 9600
|
port=com_port,
|
||||||
instrument.serial.bytesize = 8
|
baudrate=57600,
|
||||||
instrument.serial.parity = minimalmodbus.serial.PARITY_NONE
|
bytesize=8,
|
||||||
instrument.serial.stopbits = 1
|
parity='N',
|
||||||
instrument.serial.timeout = 1
|
stopbits=1,
|
||||||
|
timeout=1
|
||||||
|
)
|
||||||
|
client.connect()
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
hardware = Hardware(instrument)
|
hardware = Hardware(client, slave_id)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
@ -55,6 +58,9 @@ def main():
|
|||||||
print(f"Error: {e}")
|
print(f"Error: {e}")
|
||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
finally:
|
||||||
|
if 'client' in locals():
|
||||||
|
client.close()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
@ -1 +1 @@
|
|||||||
minimalmodbus==1.0.2
|
pymodbus==3.1.0
|
||||||
@ -1,2 +1,3 @@
|
|||||||
from .hardware import Hardware
|
from .hardware import Hardware
|
||||||
from .logic import loop
|
from .logic import loop
|
||||||
|
from .buttons_timers_and_relays import ButtonsTimersAndRelays
|
||||||
79
src/buttons_timers_and_relays.py
Normal file
79
src/buttons_timers_and_relays.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
from enum import Enum
|
||||||
|
import time
|
||||||
|
|
||||||
|
class ButtonsTimersAndRelays:
|
||||||
|
class State(Enum):
|
||||||
|
RELAY_0_LOW = 0
|
||||||
|
RELAY_0_HIGH = 1
|
||||||
|
BUTTON_1_PRESSED = 2
|
||||||
|
RELAY_1_HIGH_1 = 3
|
||||||
|
RELAY_1_LOW = 4
|
||||||
|
RELAY_1_HIGH_2 = 5
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.current_state = self.State.RELAY_0_LOW
|
||||||
|
self.state_change_time = time.time()
|
||||||
|
self.time_in_current_state = 0
|
||||||
|
|
||||||
|
def loop(self, hardware):
|
||||||
|
next_state = self.current_state
|
||||||
|
|
||||||
|
# State transitions
|
||||||
|
match self.current_state:
|
||||||
|
case self.State.RELAY_0_LOW:
|
||||||
|
if hardware.get_button_0():
|
||||||
|
next_state = self.State.RELAY_0_HIGH
|
||||||
|
elif hardware.get_button_1():
|
||||||
|
next_state = self.State.BUTTON_1_PRESSED
|
||||||
|
case self.State.RELAY_0_HIGH:
|
||||||
|
if not hardware.get_button_0() and hardware.get_button_1():
|
||||||
|
next_state = self.State.BUTTON_1_PRESSED
|
||||||
|
case self.State.BUTTON_1_PRESSED:
|
||||||
|
if hardware.get_button_0():
|
||||||
|
next_state = self.State.RELAY_0_HIGH
|
||||||
|
elif not hardware.get_button_1():
|
||||||
|
next_state = self.State.RELAY_1_HIGH_1
|
||||||
|
case self.State.RELAY_1_HIGH_1:
|
||||||
|
if hardware.get_button_0():
|
||||||
|
next_state = self.State.RELAY_0_HIGH
|
||||||
|
elif self.time_in_current_state > 1:
|
||||||
|
next_state = self.State.RELAY_1_LOW
|
||||||
|
case self.State.RELAY_1_LOW:
|
||||||
|
if hardware.get_button_0():
|
||||||
|
next_state = self.State.RELAY_0_HIGH
|
||||||
|
elif self.time_in_current_state > 1:
|
||||||
|
next_state = self.State.RELAY_1_HIGH_2
|
||||||
|
case self.State.RELAY_1_HIGH_2:
|
||||||
|
if hardware.get_button_0():
|
||||||
|
next_state = self.State.RELAY_0_HIGH
|
||||||
|
elif self.time_in_current_state > 1:
|
||||||
|
next_state = self.State.RELAY_0_LOW
|
||||||
|
|
||||||
|
# Time calculation
|
||||||
|
if next_state != self.current_state:
|
||||||
|
self.state_change_time = time.time()
|
||||||
|
self.time_in_current_state = 0
|
||||||
|
else:
|
||||||
|
self.time_in_current_state = time.time() - self.state_change_time
|
||||||
|
self.current_state = next_state
|
||||||
|
|
||||||
|
# Outputs
|
||||||
|
match self.current_state:
|
||||||
|
case self.State.RELAY_0_LOW:
|
||||||
|
hardware.set_relay_0(False)
|
||||||
|
hardware.set_relay_1(False)
|
||||||
|
case self.State.RELAY_0_HIGH:
|
||||||
|
hardware.set_relay_0(True)
|
||||||
|
hardware.set_relay_1(False)
|
||||||
|
case self.State.BUTTON_1_PRESSED:
|
||||||
|
hardware.set_relay_0(False)
|
||||||
|
hardware.set_relay_1(False)
|
||||||
|
case self.State.RELAY_1_HIGH_1:
|
||||||
|
hardware.set_relay_0(False)
|
||||||
|
hardware.set_relay_1(True)
|
||||||
|
case self.State.RELAY_1_LOW:
|
||||||
|
hardware.set_relay_0(False)
|
||||||
|
hardware.set_relay_1(False)
|
||||||
|
case self.State.RELAY_1_HIGH_2:
|
||||||
|
hardware.set_relay_0(False)
|
||||||
|
hardware.set_relay_1(True)
|
||||||
@ -1,22 +1,23 @@
|
|||||||
import minimalmodbus
|
from pymodbus.exceptions import ModbusException
|
||||||
|
|
||||||
class Hardware:
|
class Hardware:
|
||||||
def __init__(self, instrument):
|
def __init__(self, client, slave_id):
|
||||||
self.instrument = instrument
|
self.client = client
|
||||||
self.relay_0_address = 0
|
self.slave_id = slave_id
|
||||||
self.relay_1_address = 1
|
|
||||||
self.button_0_address = 0
|
|
||||||
self.button_1_address = 1
|
|
||||||
self.relay_0 = False
|
self.relay_0 = False
|
||||||
self.relay_1 = False
|
self.relay_1 = False
|
||||||
self.button_0 = False
|
self.button_0 = False
|
||||||
self.button_1 = False
|
self.button_1 = False
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.instrument.write_bit(self.relay_0_address, self.relay_0, functioncode=5)
|
try:
|
||||||
self.instrument.write_bit(self.relay_1_address, self.relay_1, functioncode=5)
|
self.client.write_coils(0, [self.relay_0, self.relay_1], slave=self.slave_id)
|
||||||
self.button_0 = self.instrument.read_bit(self.button_0_address, functioncode=2)
|
input_response = self.client.read_discrete_inputs(0, 2, slave=self.slave_id)
|
||||||
self.button_1 = self.instrument.read_bit(self.button_1_address, functioncode=2)
|
if not input_response.isError():
|
||||||
|
self.button_0 = input_response.bits[0]
|
||||||
|
self.button_1 = input_response.bits[1]
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Modbus error: {e}")
|
||||||
|
|
||||||
def set_relay_0(self, value):
|
def set_relay_0(self, value):
|
||||||
self.relay_0 = value
|
self.relay_0 = value
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
from src.buttons_timers_and_relays import ButtonsTimersAndRelays
|
||||||
|
|
||||||
|
buttons_timers_relays = ButtonsTimersAndRelays()
|
||||||
|
|
||||||
def loop(hardware):
|
def loop(hardware):
|
||||||
hardware.set_relay_0(hardware.get_button_0() != hardware.get_button_1())
|
buttons_timers_relays.loop(hardware)
|
||||||
hardware.set_relay_1(hardware.get_button_0() and hardware.get_button_1())
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#include <ModbusSerial.h>
|
#include <ModbusSerial.h>
|
||||||
|
|
||||||
#define BAUD_RATE 9600
|
#define BAUD_RATE 57600
|
||||||
#define SLAVE_ID 1
|
#define SLAVE_ID 1
|
||||||
#define COIL_COUNT 4
|
#define COIL_COUNT 4
|
||||||
#define COIL_START 1
|
#define COIL_START 1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user