Home Forums Assembly/Setup Reprogramming P3 and P4 on the Chi.bio

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #841
    aliceboo
    Participant

    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?

    #842
    harrison
    Keymaster

    Hi 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…

    #883
    gstan
    Participant

    Hi 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

    #888
    harrison
    Keymaster

    Interesting. 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).

    #892
    gstan
    Participant

    This 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.

    • This reply was modified 5 years ago by gstan.
    • This reply was modified 5 years ago by gstan.
    #895
    harrison
    Keymaster

    OK, maybe post your PumpModulation function (if that is the only thing you edited) and I will see

    #896
    aliceboo
    Participant

    def 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 sysDevices

    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’:
    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
    return

    sysDevices[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):
    return

    Time1=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’]=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(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()
    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();

    #897
    harrison
    Keymaster

    OK, 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]:

Viewing 8 posts - 1 through 8 (of 8 total)
  • You must be logged in to reply to this topic.
Log in/Register
Scroll to top