Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 67 additions & 27 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@


application = Flask(__name__)
application.config.from_pyfile('config/chibio_default.cfg', silent=True)
application.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 #Try this https://stackoverflow.com/questions/23112316/using-flask-how-do-i-modify-the-cache-control-header-for-all-output/23115561#23115561

lock=Lock()
Expand All @@ -34,6 +35,7 @@
'presentDevices' : { 'M0' : 0,'M1' : 0,'M2' : 0,'M3' : 0,'M4' : 0,'M5' : 0,'M6' : 0,'M7' : 0},
'Version' : {'value' : 'Turbidostat V3.0'},
'DeviceID' : '',
'DeviceName': '',
'time' : {'record' : []},
'LEDA' : {'WL' : '395', 'default': 0.1, 'target' : 0.0, 'max': 1.0, 'min' : 0.0,'ON' : 0},
'LEDB' : {'WL' : '457', 'default': 0.1, 'target' : 0.0, 'max': 1.0, 'min' : 0.0,'ON' : 0},
Expand Down Expand Up @@ -370,10 +372,9 @@ def initialise(M):
scanDevices(M)
if(sysData[M]['present']==1):
turnEverythingOff(M)
print(str(datetime.now()) + " Initialised " + str(M) +', Device ID: ' + sysData[M]['DeviceID'])
print(str(datetime.now()) + " Initialised " + str(M) + ', (' + sysData[M]['DeviceName'] + ') Device ID: '
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove device name feature

+ sysData[M]['DeviceID'])




def initialiseAll():
# Initialisation function which runs at when software is started for the first time.
Expand All @@ -382,6 +383,11 @@ def initialiseAll():
time.sleep(2.0) #This wait is to allow the watchdog circuit to boot.
print(str(datetime.now()) + ' Initialising devices')

check_config_value(config_key='TWO_PUMPS_PER_DEVICE', default_value=False)
check_config_value(config_key='NUMBER_OF_OD_MEASUREMENTS', default_value=4)
check_config_value(config_key='DEVICE_COMM_FAILURE_THRESHOLD', default_value=10)


for M in ['M0','M1','M2','M3','M4','M5','M6','M7']:
initialise(M)
scanDevices("all")
Expand All @@ -405,7 +411,13 @@ def turnEverythingOff(M):

I2CCom(M,'DAC',0,8,int('00000000',2),int('00000000',2),0)#Sets all DAC Channels to zero!!!
setPWM(M,'PWM',sysItems['All'],0,0)
setPWM(M,'Pumps',sysItems['All'],0,0)

if application.config['TWO_PUMPS_PER_DEVICE']:
chibios_to_shut_down = [0, 1, 2, 3]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's call the variable chibios_w_pumps

else:
chibios_to_shut_down = [0, 1, 2, 4, 5, 6, 7]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

number 3 is missing!

if int(M[1]) in chibios_to_shut_down:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use f-string instead! printf(f'M{number}') in number

setPWM(M=M, device='Pumps', channels=sysItems['All'], fraction=0, ConsecutiveFails=0)

SetOutputOn(M,'Stir',0)
SetOutputOn(M,'Thermostat',0)
Expand Down Expand Up @@ -584,12 +596,12 @@ def SetOutputOn(M,item,force):
if (force==1):
sysData[M][item]['ON']=1
SetOutput(M,item)
return ('', 204)
return ('', 204)

elif(force==0):
sysData[M][item]['ON']=0;
SetOutput(M,item)
return ('', 204)
return ('', 204)

#Elsewise this is doing a flip operation (i.e. changes to opposite state to that which it is currently in)
if (sysData[M][item]['ON']==0):
Expand Down Expand Up @@ -681,7 +693,27 @@ def PumpModulation(M,item):
global sysData
global sysItems
global sysDevices


if application.config['TWO_PUMPS_PER_DEVICE']:
pump_mapping = {'M4': 'M0', 'M5': 'M1', 'M6': 'M2', 'M7': 'M3'}
if int(M[1]) in [0, 1, 2, 3]:
if item == 'Pump1' or item == 'Pump2':
MB = M
itemB = item
elif item == 'Pump3' or item == 'Pump4':
sysData[M][item]['ON'] = 0
return
else:
if item == 'Pump1' or item == 'Pump2':
MB = pump_mapping[M]
itemB = 'Pump' + str(int(item[4])+2)
elif item == 'Pump3' or item == 'Pump4':
sysData[M][item]['ON'] = 0
return
else:
MB = M
itemB = item

sysDevices[M][item]['threadCount']=(sysDevices[M][item]['threadCount']+1)%100 #Index of the particular thread running.
currentThread=sysDevices[M][item]['threadCount']

Expand All @@ -690,10 +722,10 @@ def PumpModulation(M,item):

if (abs(sysData[M][item]['target']*sysData[M][item]['ON'])!=1 and currentThread==sysDevices[M][item]['threadCount']): #In all cases we turn things off to begin
sysDevices[M][item]['active']=1
setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0)
sysDevices[M][item]['active']=0
if (sysData[M][item]['ON']==0):
return
Expand All @@ -711,23 +743,23 @@ def PumpModulation(M,item):

if (sysData[M][item]['target']>0 and currentThread==sysDevices[M][item]['threadCount']): #Turning on pumps in forward direction
sysDevices[M][item]['active']=1
setPWM(M,'Pumps',sysItems[item]['In1'],1.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In1'],1.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0)
sysDevices[M][item]['active']=0
elif (sysData[M][item]['target']<0 and currentThread==sysDevices[M][item]['threadCount']): #Or backward direction.
sysDevices[M][item]['active']=1
setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In2'],1.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In2'],1.0*float(sysData[M][item]['ON']),0)
sysDevices[M][item]['active']=0

time.sleep(Ontime)

if(abs(sysData[M][item]['target'])!=1 and currentThread==sysDevices[M][item]['threadCount']): #Turning off pumps at appropriate time.
sysDevices[M][item]['active']=1
setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(M,'Pumps',sysItems[item]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In1'],0.0*float(sysData[M][item]['ON']),0)
setPWM(MB,'Pumps',sysItems[itemB]['In2'],0.0*float(sysData[M][item]['ON']),0)
sysDevices[M][item]['active']=0

Time2=datetime.now()
Expand Down Expand Up @@ -1336,7 +1368,7 @@ def I2CCom(M,device,rw,hl,data1,data2,SMBUSFLAG):

global sysDevices
if(sysData[M]['present']==0): #Something stupid has happened in software if this is the case!
print(str(datetime.now()) + ' Trying to communicate with absent device - bug in software!. Disabling hardware and software!')
print(str(datetime.now()) + ' Trying to communicate with M%s absent device - bug in software!. Disabling hardware and software!' % M)
sysItems['Watchdog']['ON']=0 #Basically this will crash all the electronics and the software.
out=0
tries=-1
Expand Down Expand Up @@ -1420,11 +1452,12 @@ def I2CCom(M,device,rw,hl,data1,data2,SMBUSFLAG):
out=0
sysData[M]['present']=0
tries=-1
if tries>10: #In this case something else has gone wrong, so we panic.
if tries >= application.config['DEVICE_COMM_FAILURE_THRESHOLD']: #In this case something else has gone wrong, so we panic.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this!

sysItems['Watchdog']['ON']=0 #Basically this will crash all the electronics and the software.
out=0
sysData[M]['present']=0
print('Failed to communicate to a device 10 times. Disabling hardware and software!')
print('Failed to communicate to a device %d times. Disabling hardware and software!' %
application.config['DEVICE_COMM_FAILURE_THRESHOLD'])
tries=-1
os._exit(4)

Expand Down Expand Up @@ -2066,13 +2099,13 @@ def runExperiment(M,placeholder):

sysData[M]['OD']['Measuring']=1 #Begin measuring - this flag is just to indicate that a measurement is currently being taken.

#We now meausre OD 4 times and take the average to reduce noise when in auto mode!
ODV=0.0
for i in [0, 1, 2, 3]:
# We now measure OD N times and take the average to reduce noise when in auto mode!
ODV = 0.0
for _ in range(0, application.config['NUMBER_OF_OD_MEASUREMENTS']):
MeasureOD(M)
ODV=ODV+sysData[M]['OD']['current']
time.sleep(0.25)
sysData[M]['OD']['current']=ODV/4.0
sysData[M]['OD']['current'] = ODV/float(application.config['NUMBER_OF_OD_MEASUREMENTS'])

MeasureTemp(M,'Internal') #Measuring all temperatures
MeasureTemp(M,'External')
Expand Down Expand Up @@ -2187,7 +2220,14 @@ def runExperiment(M,placeholder):
addTerminal(M,'Experiment Stopped')



def check_config_value(config_key, default_value, critical=False):
if config_key not in application.config.keys():
if critical:
raise ValueError('config value for %s was not found, it must be set for safe operations' % config_key)
application.config[config_key] = default_value
application.logger.warning('config value %s was not found and set to default: %d' % (config_key, default_value))
else:
application.logger.info('config found: %s=%s' % (config_key, application.config[config_key]))

if __name__ == '__main__':
initialiseAll()
Expand Down
4 changes: 4 additions & 0 deletions config/chibio_default.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
NUMBER_OF_OD_MEASUREMENTS = 4
TWO_PUMPS_PER_DEVICE = False
DEVICE_COMM_FAILURE_THRESHOLD = 10
CONTINUOUS_STIRRING = False