Home › Forums › Assembly/Setup › Reprogramming P3 and P4 on the Chi.bio
- This topic has 7 replies, 3 voices, and was last updated 5 years ago by harrison.
-
AuthorPosts
-
October 29, 2019 at 2:18 pm #841alicebooParticipant
Hello,
We’re about to receive the Chi.bios soon and we bought 1 pumping platform for 2 turbidostats. This means that we need to repurpose pumps P3 and P4 to be used as an IN and OUT pumps for another Chi.bio. Do you have any idea how to do that?
October 29, 2019 at 3:02 pm #842harrisonKeymasterHi Alice,
That should be no problem. I think the best way to go about implementing that change would be in the PumpModulation function, as this will mean the data/interface in each reactor will reflect its current behaviour, despite the fact that it is using pumps potentially attached to another one.
A rough outline of the changes you might make are as follows:
1) Decide on how you are going to remap the pumps. Perhaps what you could do is for every odd index reactor, use the pumps for the reactor with previous index (i.e. M1 uses P3,4 from M0, M3 uses P3,4 from M2).
2) Add a new “if” statement to the top of PumpModulation. Inside this If statement you should catch each of the cases from step 1 independently. That is, case 1 is if you have an even index reactor, case 2 is odd index reactor. You can sort these by doing something like int(M[1])%2 to take the mod of the reactor index.
3) Set up new variables called MB and itemB which will be defined in a case-dependent manner in these if statements.
4) If case 1 and item==’Pump1′ or ‘Pump2′ then set MB=M and itemB=item. If case 1 and item==’Pump3’ or ‘Pump4’ then maybe just do sysData[M][item][‘ON’]=0 and then a return statement. This is to prevent the even index device from trying to control P3 or P4.
5) If case 2 and item==’Pump1 or ‘Pump2’ then set MB=’M’+str(int(M[1])-1) and itemB=’Pump’+str(int(item[3])+2). Basically what I intend to do here is map (for example) M1 to M0 and Pump1 to Pump3. Thus, we would be using the desired pump boards for the odd index reactor. Also do a similar statement to as above to set sysData[M][item][‘ON’]=0 if Pump3 or Pump4 are called in this case.
6) Now go through the PumpModulation function and update each incidence of setPWM(M,’Pumps’,sysItems[item] to setPWM(MB,’Pumps’,sysItems[itemB] Do not change the “M” in the next argument of the setPWM command.If you complete the above then the interface should basically work as before, but when you use pump 1,2 on an odd index reactor it routes the digital command to pumps 3,4 of a different reactor. It might be worthwhile implementing the above with print statements scattered throughout to ensure my logic was correct…
November 15, 2019 at 2:48 pm #883gstanParticipantHi Harry,
Together with Alice we have followed your instructions to repurpose pumps P3 and P4 to be used as an IN and OUT pumps for other Chi.bio turbidostats.
This works as long as all Chi.Bio turbidostats are still connected to pump boards. However, in this new configuration some of the Chi.Bio turbidostats will not (should not) be connected to any pump boards. Currently, this throws an error with a “Failed Pumps comms” error for the Chi.Bio turbidostats that are not connected to any pump boards.
What would be the best way to bypass the checks for connections to the pumps boards for the turbidostats that are not connected to any with the reconfiguration we have discussed above?
Cheers,
Guy
November 18, 2019 at 5:04 pm #888harrisonKeymasterInteresting. That error means those Reactors are still trying to send digital signals to their pump boards, despite the fact that the above code changes should (if they work perfectly) prevent that from ever happening. The error you are describing is therefore symptomatic of the changes I outlined not working as intended, and so I would recommend debugging that rather than disabling the connection check functionality. Disabling the connection check functionality might make it work to begin with, but may lead to problems down the line if signals arent actually going where they are meant to.
Does this error happen when you click on the pump controls in the software, or also when you start up the software and it goes through initialisation? Have you tried adding some print statements to “PumpModulation” to see when and where it is going wrong (i.e. when it is trying to control pumps on pump boards that aren’t connected).
November 18, 2019 at 8:51 pm #892gstanParticipantThis happens at the initialisation stage. Essentially, the system tries to connect to the pump board 10 times and says each time “Failed Pumps comms 1 times”, …, “Failed Pumps comms 10 times” and then aborts and quits the initialisation.
We do not want to deactivate the checks for everything. Only for the chambers that are not connected to pump boards.
We can send you the code we have made for you to have a look at if you can.
November 19, 2019 at 12:28 pm #895harrisonKeymasterOK, maybe post your PumpModulation function (if that is the only thing you edited) and I will see
November 19, 2019 at 12:39 pm #896alicebooParticipantdef PumpModulation(M,item):
#Responsible for turning pumps on/off with an appropriate duty cycle. They are turned on for a fraction of each ~1minute cycle to achieve low pump rates.
global sysData
global sysItems
global sysDevicesif 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’:
if int(M[1]) == 4:
MB = ‘M0’
elif int(M[1]) == 5:
MB = ‘M1’
elif int(M[1]) == 6:
MB = ‘M2’
elif int(M[1]) == 7:
MB = ‘M3’
itemB = ‘Pump’ + str(int(item[4])+2)
elif item == ‘Pump3’ or item == ‘Pump4’:
sysData[M][item][‘ON’] = 0
returnsysDevices[M][item][‘threadCount’]=(sysDevices[M][item][‘threadCount’]+1)%100 #Index of the particular thread running.
currentThread=sysDevices[M][item][‘threadCount’]while (sysDevices[M][item][‘active’]==1): #Idea is we will wait here if a previous thread on this pump is already running. Potentially all this ‘active’ business could be removed from this fuction.
time.sleep(0.02)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
# print(“MB: “+MB)
# print(“M: “+M)
# print(“itemB: “+itemB)
# print(“item: “+item)
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):
returnTime1=datetime.now()
cycletime=sysData[M][‘Experiment’][‘cycleTime’]*1.05 #We make this marginally longer than the experiment cycle time to avoid too much chaos when you come back around to pumping again.Ontime=cycletime*abs(sysData[M][item][‘target’])
if (item==”Pump1” and abs(sysData[M][item][‘target’])<0.3): #Ensuring we run Pump1 after Pump2.
waittime=cycletime*abs(sysData[M][‘Pump2’][‘target’]) #We want to wait until the output pump has stopped, otherwise you are very inefficient with your media since it will be pumping out the fresh media fromthe top of the test tube right when it enters.
time.sleep(waittime+1.0)if (sysData[M][item][‘target’]>0 and currentThread==sysDevices[M][item][‘threadCount’]): #Turning on pumps in forward direction
sysDevices[M][item][‘active’]=1
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(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’]=0time.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(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’]=0Time2=datetime.now()
elapsedTime=Time2-Time1
elapsedTimeSeconds=round(elapsedTime.total_seconds(),2)
Offtime=cycletime-elapsedTimeSeconds
if (Offtime>0.0):
time.sleep(Offtime)if (sysData[M][item][‘ON’]==1 and sysDevices[M][item][‘threadCount’]==currentThread): #If pumps need to keep going, this starts a new pump thread.
sysDevices[M][item][‘thread’]=Thread(target = PumpModulation, args=(M,item))
sysDevices[M][item][‘thread’].setDaemon(True)
sysDevices[M][item][‘thread’].start();November 19, 2019 at 2:23 pm #897harrisonKeymasterOK, I think that looks OK. It seems the issue may just be in initialisation.
Edit the function TurnEverythingOff:
Try putting the line:
setPWM(M,’Pumps’,sysItems[‘All’],0,0)Inside an if statement like:
if int(M[1]) in [0, 1, 2 , 3]: -
AuthorPosts
- You must be logged in to reply to this topic.