It is probably the wrong title, but here is my problem.
I have a system comprised of a microcontroller (MCU), a serial interface (SPI), a DAC (Digital / Analog converter), an electrode (E). Each element is defined as a class in my python modelization.
As a first step, I want to monitor the output on the electrode as I input something in the microcontroller.
Let's consider the following:
- Input: 2 mA on the electrode during 1 ms.
- MCU send the new DAC value via the SPI: 30 us
- DAC updates its register and output: 400 us
- MCU send a switch on command to the electrode: 1 us
- The electrode is now outputting.
- 1 ms later, send a switch off command to the electrode: 1us
- The electrode doesn't output anymore.
My 2 biggest issues are 1. How to take into account this time component and 2. How to monitor the SPI line to determine if something has to be done.
class Electrode:
def __init__(self, id):
self.id = id
self.switch = False
self.value = 0
def output(self):
if self.switch:
return self.value
else:
return 0
class SPI:
def __init__(self):
self.msg = None
class MCU:
def __init__(self):
self.name = "MicroController"
def send_SPI_msg(self, SPI, msg):
SPI.msg = msg
class DAC:
def __init__(id):
self.id = id
self.cs = 1
self.register = None
self.output = None
def read_SPI_msg(self, SPI):
message = SPI.msg
# update register and output
My system actually has 16 DACs and electrodes and a field-programmable gate array which are all listening to the same SPI. What I described above is a fairly simplified version.
Question is: How to have the components check the value in SPI.msg
regularly and act accordingly?
In reality, each component is doing its life. Thus actions are performed in parallel. Since I'm trying to simulate the timeline and the action performed, I do not mind doing everything serially with a timeline variable (attribute) for each element. I just have issues to figure out how to have my classes interact together.
i.e. I can't do the following in python or I will get stuck:
class DAC:
def __init__(id):
# init
def read_SPI_msg(self, SPI):
while True:
message = SPI.msg
# update register and output if needed
Maybe an event triggering could be used... But I don't know how.
Maybe with multithreading, defining one thread / element?
EDIT: Current state:
class SPI:
def __init__(self):
self.attached_dacs = []
self.attached_fpga = []
self.attached_mcu = []
def attach_device(self, device):
if type(device) == DAC:
self.attached_dacs.append(device)
elif type(device) == FPGA:
self.attached_fpga.append(device)
elif type(device) == MCU:
self.attached_mcu.append(device)
def send_message(self, msg):
for device in self.attached_dacs + self.attached_fpga:
device.on_spi_message(self, msg)
class SpiAttachableDevice:
def on_spi_message(self, SPI, message):
if self.cs:
self.execute_SPI_message(message)
else:
return None
class DAC(SpiAttachableDevice):
def __init__(self, id):
self.id = id
self.cs = False # Not listening
def execute_SPI_message(message):
# Do stuff
class FPGA(SpiAttachableDevice):
def __init__(self):
self.electrodes = list()
self.cs = False # Not listening
def execute_SPI_message(message):
# Do stuff
class MCU:
def __init__(self):
self.electrodes = list()