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 traceback
|
||||
import argparse
|
||||
@ -16,7 +16,7 @@ def main():
|
||||
help='COM port for the Modbus connection')
|
||||
parser.add_argument('--slave_id', type=int, default=1,
|
||||
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')
|
||||
args = parser.parse_args()
|
||||
|
||||
@ -26,14 +26,17 @@ def main():
|
||||
|
||||
while True:
|
||||
try:
|
||||
instrument = minimalmodbus.Instrument(com_port, slave_id)
|
||||
instrument.serial.baudrate = 9600
|
||||
instrument.serial.bytesize = 8
|
||||
instrument.serial.parity = minimalmodbus.serial.PARITY_NONE
|
||||
instrument.serial.stopbits = 1
|
||||
instrument.serial.timeout = 1
|
||||
client = ModbusSerialClient(
|
||||
port=com_port,
|
||||
baudrate=57600,
|
||||
bytesize=8,
|
||||
parity='N',
|
||||
stopbits=1,
|
||||
timeout=1
|
||||
)
|
||||
client.connect()
|
||||
time.sleep(3)
|
||||
hardware = Hardware(instrument)
|
||||
hardware = Hardware(client, slave_id)
|
||||
|
||||
while True:
|
||||
start_time = time.time()
|
||||
@ -55,6 +58,9 @@ def main():
|
||||
print(f"Error: {e}")
|
||||
print(traceback.format_exc())
|
||||
time.sleep(5)
|
||||
finally:
|
||||
if 'client' in locals():
|
||||
client.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1 +1 @@
|
||||
minimalmodbus==1.0.2
|
||||
pymodbus==3.1.0
|
||||
@ -1,2 +1,3 @@
|
||||
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:
|
||||
def __init__(self, instrument):
|
||||
self.instrument = instrument
|
||||
self.relay_0_address = 0
|
||||
self.relay_1_address = 1
|
||||
self.button_0_address = 0
|
||||
self.button_1_address = 1
|
||||
def __init__(self, client, slave_id):
|
||||
self.client = client
|
||||
self.slave_id = slave_id
|
||||
self.relay_0 = False
|
||||
self.relay_1 = False
|
||||
self.button_0 = False
|
||||
self.button_1 = False
|
||||
|
||||
|
||||
def update(self):
|
||||
self.instrument.write_bit(self.relay_0_address, self.relay_0, functioncode=5)
|
||||
self.instrument.write_bit(self.relay_1_address, self.relay_1, functioncode=5)
|
||||
self.button_0 = self.instrument.read_bit(self.button_0_address, functioncode=2)
|
||||
self.button_1 = self.instrument.read_bit(self.button_1_address, functioncode=2)
|
||||
try:
|
||||
self.client.write_coils(0, [self.relay_0, self.relay_1], slave=self.slave_id)
|
||||
input_response = self.client.read_discrete_inputs(0, 2, slave=self.slave_id)
|
||||
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):
|
||||
self.relay_0 = value
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
from src.buttons_timers_and_relays import ButtonsTimersAndRelays
|
||||
|
||||
buttons_timers_relays = ButtonsTimersAndRelays()
|
||||
|
||||
def loop(hardware):
|
||||
hardware.set_relay_0(hardware.get_button_0() != hardware.get_button_1())
|
||||
hardware.set_relay_1(hardware.get_button_0() and hardware.get_button_1())
|
||||
buttons_timers_relays.loop(hardware)
|
||||
@ -1,6 +1,6 @@
|
||||
#include <ModbusSerial.h>
|
||||
|
||||
#define BAUD_RATE 9600
|
||||
#define BAUD_RATE 57600
|
||||
#define SLAVE_ID 1
|
||||
#define COIL_COUNT 4
|
||||
#define COIL_START 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user