Initial commit, missing cycle time

This commit is contained in:
Geens 2024-08-03 16:28:08 +02:00
commit 6a1183ccf5
7 changed files with 169 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
__pycache__/
.vscode/

60
main.py Normal file
View File

@ -0,0 +1,60 @@
import minimalmodbus
import time
import traceback
import argparse
import serial.tools.list_ports
from src.hardware import Hardware
from src.logic import loop
def get_first_available_com_port():
ports = list(serial.tools.list_ports.comports())
return ports[0].device if ports else 'COM3'
def main():
parser = argparse.ArgumentParser(description='UNO Relay Modbus Controller')
parser.add_argument('--com_port', type=str, default=get_first_available_com_port(),
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,
help='Cycle time in seconds for the main loop')
args = parser.parse_args()
com_port = args.com_port
slave_id = args.slave_id
cycle_time = args.cycle_time
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
time.sleep(3)
hardware = Hardware(instrument)
while True:
start_time = time.time()
hardware.update()
loop(hardware)
execution_time = time.time() - start_time
if execution_time > cycle_time:
print(f"Warning: Loop execution time ({execution_time:.4f}s) exceeded cycle time ({cycle_time:.4f}s)")
sleep_time = max(0, cycle_time - execution_time)
time.sleep(sleep_time)
except KeyboardInterrupt:
print("Stopped by user")
break
except Exception as e:
print(f"Error: {e}")
print(traceback.format_exc())
time.sleep(5)
if __name__ == "__main__":
main()

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
minimalmodbus==1.0.2

2
src/__init__.py Normal file
View File

@ -0,0 +1,2 @@
from .hardware import Hardware
from .logic import loop

31
src/hardware.py Normal file
View File

@ -0,0 +1,31 @@
import minimalmodbus
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
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)
def set_relay_0(self, value):
self.relay_0 = value
def set_relay_1(self, value):
self.relay_1 = value
def get_button_0(self):
return self.button_0
def get_button_1(self):
return self.button_1

3
src/logic.py Normal file
View File

@ -0,0 +1,3 @@
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())

70
uno_relay_modbus.ino Normal file
View File

@ -0,0 +1,70 @@
#include <ModbusSerial.h>
#define BAUD_RATE 9600
#define SLAVE_ID 1
#define COIL_COUNT 4
#define COIL_START 1
#define COIL_0 4
#define COIL_1 5
#define COIL_2 6
#define COIL_3 7
#define STATUS_0 12
#define STATUS_1 11
ModbusSerial mb (Serial, SLAVE_ID);
void setup() {
Serial.begin (BAUD_RATE);
while (! Serial);
mb.config(BAUD_RATE);
mb.addCoil (0);
mb.addCoil (1);
mb.addCoil (2);
mb.addCoil (3);
mb.addIsts(0);
mb.addIsts(1);
pinMode(COIL_0, OUTPUT);
pinMode(COIL_1, OUTPUT);
pinMode(COIL_2, OUTPUT);
pinMode(COIL_3, OUTPUT);
pinMode(STATUS_0, INPUT_PULLUP);
pinMode(STATUS_1, INPUT_PULLUP);
}
void loop() {
mb.task();
readCoilValues();
writeStatusValues();
}
void readCoilValues() {
digitalWrite(COIL_0, mb.coil(0));
digitalWrite(COIL_1, mb.coil(1));
digitalWrite(COIL_2, mb.coil(2));
digitalWrite(COIL_3, mb.coil(3));
}
void writeStatusValues() {
mb.setIsts(0, !digitalRead(STATUS_0));
mb.setIsts(1, !digitalRead(STATUS_1));
}