Fish Posted June 2, 2016 Share Posted June 2, 2016 Hi guys. I am a low tech biologist user of DAQFactory. I have previously used it to control aeration and degassing of water based on input from gas probes. I am thinking about doing an experiment where I want to have daily variations in oxygen levels in a tank. I can hook up my Labjack with input from an oxygen probe and control if I want to keep levels above or below a certain threshold. Is it possible in that little bit of code to integrate time as a variable, so that I can ramp down oxygen levels to a set minimum value during the night, after which it slowly climbs back up? Any help would be greatly appreciated. My desired levels are illustrated in the attached image. Cheers Link to comment Share on other sites More sharing options...
AzeoTech Posted June 2, 2016 Share Posted June 2, 2016 Of course. But this is more a programming problem than a DAQFactory problem. Use systime() % 86400 to get the current time of day in seconds. From there, its a matter of figuring out the desired level based on time of day. Do you have a formula for this? Or is it more random, in which case a lookup table will be needed? Link to comment Share on other sites More sharing options...
Fish Posted June 2, 2016 Author Share Posted June 2, 2016 12 minutes ago, AzeoTech said: Of course. But this is more a programming problem than a DAQFactory problem. Use systime() % 86400 to get the current time of day in seconds. From there, its a matter of figuring out the desired level based on time of day. Do you have a formula for this? Or is it more random, in which case a lookup table will be needed? Thanks. I don't have a formula per se. I was thinking more that time could be part of the event code; adding several lines along the line of "if systime(>7200, but <14400) AND if input channel 1 (> xx volts), then output channel = 5 volts" and then just add the required number of lines. I apologize, I know this is probably a total rookie question... Link to comment Share on other sites More sharing options...
AzeoTech Posted June 2, 2016 Share Posted June 2, 2016 You can do that, though you'll want to store the time of day in a private variable: private tod = systime() % 86400 you don't want to use systime() straight up because that's absolute time, and you really want the time of day. You can use a bunch of ifs(), but its more efficient to use a lookup table. The quickest and easiest is to have a value for every hour of the day. Something like: private outLevel = {60, 40, 30, 40, etc....} you'd have 24 values inside the {}, starting with the value for midnight, then 1am, etc. Then you can lookup the value by doing: private hod = floor(tod / 3600) private actualOut = outLevel[hod] private nextHour = hod+1 if (nextHour == 24) nextHour = 0 endif private nextOut = outLevel[nextHour] // now extrapolate between them: private decimalHour = (tod - hod * 3600) / 3600 private finalOut = nextOut * decimalHour + actualOut * (1 - decimalHour) If you don't care about the linear interpolation, you can just use the first two lines above and use the actualOut value to set your output (after scaling of course to Volts). The rest does linear interpolation between hours. Note: I did this off the cuff, so there might be a typo... Link to comment Share on other sites More sharing options...
Fish Posted June 2, 2016 Author Share Posted June 2, 2016 Thanks so much. I will give it a try! Link to comment Share on other sites More sharing options...
Fish Posted October 8, 2016 Author Share Posted October 8, 2016 On 2/6/2016 at 10:17 PM, AzeoTech said: You can do that, though you'll want to store the time of day in a private variable: private tod = systime() % 86400 you don't want to use systime() straight up because that's absolute time, and you really want the time of day. You can use a bunch of ifs(), but its more efficient to use a lookup table. The quickest and easiest is to have a value for every hour of the day. Something like: private outLevel = {60, 40, 30, 40, etc....} you'd have 24 values inside the {}, starting with the value for midnight, then 1am, etc. Then you can lookup the value by doing: private hod = floor(tod / 3600) private actualOut = outLevel[hod] private nextHour = hod+1 if (nextHour == 24) nextHour = 0 endif private nextOut = outLevel[nextHour] // now extrapolate between them: private decimalHour = (tod - hod * 3600) / 3600 private finalOut = nextOut * decimalHour + actualOut * (1 - decimalHour) If you don't care about the linear interpolation, you can just use the first two lines above and use the actualOut value to set your output (after scaling of course to Volts). The rest does linear interpolation between hours. Note: I did this off the cuff, so there might be a typo... Hi again, I haven't been looking at this over the summer, but am now getting back to it, and I think perhaps my questions was misunderstood, or just poorly formuulated. I am thinking the sequence above gives me a time dependant variable output? In my setup, I can either have a solenoid open to add nitrogen gas to the water for the purpose of bringing down the oxygen saturation level of the water, or it can be closed. Its a NC valve, meaning normally closed, i.e. if there is no voltage on the output channel. My input channel is from an oxygen probe with a 0-5V output representing the range from 0-100% saturation. It runs through a conversion - value*20. At different times of the day I want to deoxygenate the water to different levels, as illustrated in the figure of the original post. In table form it looks something like this, with TOD = 0 being midnight and so on TOD O2 saturation 0 52 1 46 2 39 3 34 4 30 5 26 6 22 7 20 8 23 9 34 10 53 11 66 12 81 13 92 14 99 15 100 16 100 17 98 18 88 19 78 20 72 21 66 22 60 23 55 So, for example at midnight (TOD=0), the solenoid on Ch4 should switch on if O2 saturation increases above 52%, at 1 am it should switch on if O2 saturation is above 46%, and so on. At midnight it should repeat the loop. If there was also a way to implement a hysteresis of e.g. 2% below the setpoint that would be great. The is no oxygenation to the tank, but there is a constant supply of oxygenated water that will slowly bring up the O2 level in the morning hours. Thanks Link to comment Share on other sites More sharing options...
AzeoTech Posted October 10, 2016 Share Posted October 10, 2016 No, your question was good and the answer I still believe addresses what you are trying to do. At the end of the sequence I posted, the finalOut variable will have the desired output based on TOD extrapolated between the hours. You then just need to add code that actually uses that value to control the output. You probably just want a big loop: while(1) private tod = systime() % 86400 private outLevel = {60, 40, 30, 40, etc....} private hod = floor(tod / 3600) private actualOut = outLevel[hod] private nextHour = hod+1 if (nextHour == 24) nextHour = 0 endif private nextOut = outLevel[nextHour] // now extrapolate between them: private decimalHour = (tod - hod * 3600) / 3600 private finalOut = nextOut * decimalHour + actualOut * (1 - decimalHour) if (o2Saturation[0] > finalout) ch4solenoid = 1 endif if (o2Saturation[0] < finalOut * 0.98) ch4solenoid = 0 endif delay(1) endwhile The while() and delay(1) just gets it to loop forever, analyzing every second. The first chunk is the code I posted originally. Then there are the two ifs at the bottom that actually control the valve based on the result of the calculation. Of course adjust for whatever you named your channels, and update the outlevel array with the values, where the first value is from midnight to 1, etc. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.