Open Celldom-Han opened 3 years ago
` class PneumaticsController: def init(self, arduino_port="COM4", baud=9600, reg_blocks=1): self.arduino_port = arduino_port self.baud = baud self.reg_blocks = reg_blocks
# =============== Set Physical Parameters ===============
self.valid_pressures = {'loaderLoadMin': -180,
'loaderLoadMax': 0,
'loaderSqueezeMin': -1000,
'loaderSqueezeMax': 0,
'ctrlBoxLoadMin': -1000,
'ctrlBoxLoadMax': 0,
'ctrlBoxSqueezeMin': -1000,
'ctrlBoxSqueezeMax': 0}
# =============== Sensor Properties ===============
# the pressure is linearly proportional to the sensor reading
# following the equation y = m * x + b
# x is the arduino_mega output [0, 1023]
# m is the slope and b is the intercept
self.voltage_supply = 5 # voltage of analog pins and given to sensor
self.Patm = 1000 # define atmospheric pressure
self.Prange = 160 # define sensor pressure differential range
self.Pmax = self.Patm # maximum sensor inlet pressure (mBar abs)
self.Pmin = self.Patm - self.Prange # minimum sensor inlet pressure (mBar abs)
# =============== Controller Properties ===============
# These variables define the pressures for the different loading steps in mbar
# and the times for each loading step in milliseconds
# global count
# global load_state
# global squeeze_pressure
# global squeeze_time
# self.loadState = False
# count = 0
self.load_pressure = -50
self.squeeze_pressure = -1000
self.squeeze_time = 1000
self.zero_pressure = 0
self.PWM_to_pressure_factor = -965
self.PWM_to_pressure_offset = 5
self.load_PWM = (self.load_pressure-self.PWM_to_pressure_offset) / self.PWM_to_pressure_factor
# =============== Handshake with arduino_mega ===============
try:
arduino_mega = pf.ArduinoMega(self.arduino_port)
iterator = pf.util.Iterator(arduino_mega)
iterator.start()
time.sleep(0.1)
# self.logger.info("Connected to "+str(arduino_mega))
except Exception as error:
# self.logger.info("Failed to connect to arduino_mega.")
print('Failed to connect to arduino_mega. {}'.format(error))
# =============== Configure pins for regulators ===============
# PneumaticsController alwways has at least one regulator block
# Assign pins for first regulator block
# self.LEDpin = arduino_mega.get_pin('d:13:p') # Pin for built-in LED
self.b1ps1 = arduino_mega.get_pin('a:7:i') # Pin to connect to pressure sensor 1
self.b1ps2 = arduino_mega.get_pin('a:6:i') # Pin to connect to pressure sensor 2
self.b1ps3 = arduino_mega.get_pin('a:5:i') # Pin to connect to pressure sensor 3
self.b1ps4 = arduino_mega.get_pin('a:4:i') # Pin to connect to pressure sensor 4
self.b1ps5 = arduino_mega.get_pin('a:3:i') # Pin to connect to pressure sensor 5
self.b1ps6 = arduino_mega.get_pin('a:2:i') # Pin to connect to pressure sensor 6
self.b1r1 = arduino_mega.get_pin('d:13:p') # Pin to connect to regulator, PWM mode
self.b1r2 = arduino_mega.get_pin('d:12:p') # Pin to connect to regulator, PWM mode
self.b1r3 = arduino_mega.get_pin('d:11:p') # Pin to connect to regulator, PWM mode
self.b1r4 = arduino_mega.get_pin('d:10:p') # Pin to connect to regulator, PWM mode
self.b1r5 = arduino_mega.get_pin('d:9:p') # Pin to connect to regulator, PWM mode
self.b1r6 = arduino_mega.get_pin('d:8:p') # Pin to connect to regulator, PWM mode
self.b1 = {# Name Input Output
'r1': {'i': self.b1ps1, 'o': self.b1r1},
'r2': {'i': self.b1ps2, 'o': self.b1r2},
'r3': {'i': self.b1ps3, 'o': self.b1r3},
'r4': {'i': self.b1ps4, 'o': self.b1r4},
'r5': {'i': self.b1ps5, 'o': self.b1r5},
'r6': {'i': self.b1ps6, 'o': self.b1r6}
}
if self.reg_blocks == 2:
# This PneumaticsController has two regulator blocks
# Assign more pins for second regulator block
self.b2ps1 = arduino_mega.get_pin('a:13:i') # Pin to connect to pressure sensor 1
self.b2ps2 = arduino_mega.get_pin('a:12:i') # Pin to connect to pressure sensor 2
self.b2ps3 = arduino_mega.get_pin('a:11:i') # Pin to connect to pressure sensor 3
self.b2ps4 = arduino_mega.get_pin('a:10:i') # Pin to connect to pressure sensor 4
self.b2ps5 = arduino_mega.get_pin('a:9:i') # Pin to connect to pressure sensor 5
self.b2ps6 = arduino_mega.get_pin('a:8:i') # Pin to connect to pressure sensor 6
self.b2r1 = arduino_mega.get_pin('d:7:p') # Pin to connect to regulator, PWM mode
self.b2r2 = arduino_mega.get_pin('d:6:p') # Pin to connect to regulator, PWM mode
self.b2r3 = arduino_mega.get_pin('d:5:p') # Pin to connect to regulator, PWM mode
self.b2r4 = arduino_mega.get_pin('d:4:p') # Pin to connect to regulator, PWM mode
self.b2r5 = arduino_mega.get_pin('d:3:p') # Pin to connect to regulator, PWM mode
self.b2r6 = arduino_mega.get_pin('d:2:p') # Pin to connect to regulator, PWM mode
self.b2 = {# Name Input Output
'r1': {'i': self.b2ps1, 'o': self.b2r1},
'r2': {'i': self.b2ps2, 'o': self.b2r2},
'r3': {'i': self.b2ps3, 'o': self.b2r3},
'r4': {'i': self.b2ps4, 'o': self.b2r4},
'r5': {'i': self.b2ps5, 'o': self.b2r5},
'r6': {'i': self.b2ps6, 'o': self.b2r6}
}
`
Hardware setup: Two Arduino Megas 2560 are connected to my PC (COM5, COM6) over USB, they take up two USB plugs on a 4:1 USB dock.
Software setup: -Both Megas have standardFirmata.c loaded onto them. -Pyfirmata package used in my python code to, at 1s intervals, do an analog read from 12 analog input pins on each mega (24 reads total per second) -In case this has any relevance, the code is displaying these analog reads on a dash app, and there's a callback at 1s intervals in the dash python code to do the analog reads
Issue: When I have just one of the two Megas connected, I get expected readings. However when both are connected via USB, one mega (COM5) seems to repeatedly give the first reading it gave, and never really changes from that reading (exact same voltage reading down to the 3rd decimal place). It's almost like it's unable to give a new reading or just keeps dumping the same first reading to the serial port buffer. I know the reading update function is correctly written because when I disconnect the COM6 Arduino and rerun the dash app, all of a sudden COM5 reads as expected and does change according to sensor input and noise.
I'm wondering if there's some quirk with pyfirmata that requires some minimum time delay before reading from one COM vs a second COM port?
For further context, both Megas can be connected at the same time and the digital write functions work perfectly fine for both simultaneously.