Time as a variable on output channels


Recommended Posts

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

 

Image1.jpg

Link to comment
Share on other sites

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

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

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

  • 4 months later...
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

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

Archived

This topic is now archived and is closed to further replies.