Time restrictions for an FR1 task

231 views
Skip to first unread message

Lex Kravitz

unread,
Dec 5, 2021, 9:59:07 AM12/5/21
to FEDforum
I received a question through email that I wanted to post here.  The user asked if it was possible to modify an FR1 session to also restrict the hours that the FED3 was active.

The answer is yes!  I'm attaching a script that does this.  It operates like the normal FR1 task but only during certain hours.  If you hold down both pokes at startup it will enter a small edit menu where you can set the number of the device and set the hours that the FED3 is active, stored in the variables timedStart and timedEnd. The attached script makes use of these variables to set the times that FED3 is active.  This same approach can be used for any task.  

To give some background on how time restrictions work:
There is a variable in the FED3 library called fed3.currentHour that can be queried  at any time to get the current hour.  So if you want FED3 to dispense on a Left poke only after 5PM, you can make that part of the contingency for whether a Left poke is registered.  ie:
if (fed3.Left and fed3.currentHour >= 17 ) {           
  fed3.Feed();
}

Hope this is helpful!  -Lex
FixedRatio1_time_restricted.ino

Nora Ahmed

unread,
Mar 2, 2022, 10:27:30 PM3/2/22
to FEDforum
Could it also be adapted if I wanted to set the minutes in which the FED 3 was active? For example, I would like to have the device active for only 20 minutes upon turning it on. 

FEDforum

unread,
Mar 2, 2022, 11:18:19 PM3/2/22
to FEDforum
Hi! There is not currently a variable in the FED3 library that returns the current minute in the same way as the current hour.  I can add this to the to-do list for a future release (which is getting long BTW!)

However in the meantime you can do this in the high-level Arduino script by starting a millis() timer when you start your program (ie: something like "Starttime = millis()"), and then only dispensing if less than 20 minutes has elapsed since the program started.  If you post your code I can show you what to add.  Hope this helps! -Lex

David Mallet

unread,
Jun 16, 2023, 5:03:57 AM6/16/23
to FEDforum
Hello,

I would like my FED3 to be active during the night, from 7pm to 7am the next day.

I'd like to use the if (fed3.currentHour >= 19 && fed3.currentHour < 7) fonction.

However, in the literal sense, there is no number greater than 7 and smaller than 19, so my device will never be activated.
Do I need to specify 2 activation slots? From 19 to 24 then from 0 to 7?

Thank you for your help,
David

Lex

unread,
Jun 16, 2023, 1:22:55 PM6/16/23
to David Mallet, FEDforum
Hi David, you should be able to do this with an OR statement, ie:
if ((fed3.currentHour >= 19) || (fed3.currentHour < 7))

Please post back if that works! 

--
You received this message because you are subscribed to the Google Groups "FEDforum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fedforum+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fedforum/815ca80b-0f4f-45ef-a8e5-72050ed1a5ecn%40googlegroups.com.

David Mallet

unread,
Jun 19, 2023, 3:09:17 AM6/19/23
to FEDforum
Hi Lex,

Thank you for your help.
I tried it this weekend and it works perfectly!

Thanks
David

Vander LeKites

unread,
Aug 31, 2023, 2:25:48 PM8/31/23
to FEDforum
Hi all,

Do you know if it is possible to activate then inactivate the machine hourly on an FR1 pellet delivery? Hoping to incorporate lights to show when the device is on, and then sounds to play when the device is inactive and tries to nosepoke for a pellet.

I've tried playing with the lights but am unable to have them turn off when the nosepokes are no longer active, wondering if it has to do with the 'disableSleep' function. Please get back to me as soon as possible.

César Vargas

unread,
Aug 31, 2023, 3:35:41 PM8/31/23
to Vander LeKites, FEDforum
Hi Vander,

Do you mean like having one hour sessions or just on the hour? If it's the latter, I've written a perioding food restriction (you determine every x number of hours that food is delivered) that you might be able to modify and just add the stimulus function(s) when the desired time or interval occurs.

Vander LeKites

unread,
Aug 31, 2023, 4:06:19 PM8/31/23
to FEDforum
Hi Cesar,

Unfortunately it's the former, one hour active followed by one hour inactive and carry that process. I think that I can make that happen, but am struggling to do it with the lights being on only when the device is active. We are trying to install a go signal only using visual cues showing the mouse that the device is active and can poke to receive pellets.

Lex

unread,
Sep 1, 2023, 7:09:11 AM9/1/23
to Vander LeKites, FEDforum
Hi Vander,
For a strategy to accomplish this, in your void loop() you can call fed3.currentHour % 2 and assign the result (this will be either 0 for the even hours, or 1 for the odd hours) to a variable called FED3Active.  Then you can turn all of the pixels on if FED3Active == 1, and turn them off if FED3Active == 0.  And also only allow the ConditiondStimulus() and Feed() functions to go when FED3Active == 1.  

Here is a loop that may do what you want, I haven't tested it but hopefully it works or at least points you in the right direction!  Best, -Lex

int  FED3Active = 1;
 
void loop() {
  if (fed3.currentHour % 2 == 0) {
    FED3Active = 0;
    fed3.pixelsOff(); 
  }
  if (fed3.currentHour % 2 == 1)  {
    FED3Active = 1;
    fed3.pixelsOn(2, 2, 2, 2); 
  }

  fed3.run();                                           //Call fed.run at least once per loop
  if (fed3.Left) {                                      //If left poke is triggered
    fed3.logLeftPoke();                           //Log left poke
    if (FED3Active == 1) {                        // Test if FED3Active == 1
      fed3.ConditionedStimulus();           //Deliver conditioned stimulus (tone and lights for 200ms)
      fed3.Feed();                                       //Deliver pellet
    }
  }
  if (fed3.Right) {                                       //If right poke is triggered
    fed3.logRightPoke();                           //Log right poke
  }
}



Rose Presby

unread,
Jun 26, 2024, 4:33:38 PMJun 26
to FEDforum
Hi All,

I'm trying to modify the Free Feeding task so that it runs for 40 minutes every 3 hours. The FED box will be placed in the home cage and used as the food source for the animal. We previously had a script written that accomplished this but when I went to set the experiment up again, the script had magically disappeared. :( I was not the one who wrote the script and my RA who did is no longer in the lab. I have been banging my head against this for a while now and trying to use AI tools to help (I'm terrible at coding) but have had no success. The latest script that I have seems like it should work (based on my limited understanding) but when it is uploaded to the FED, the startup screen will initiate and then the screen turns off. Any help/advice would be really appreciated. Below is the script I just mentioned:

#include <FED3.h> // Include the FED3 library

String sketch = "FreeFeed"; // Unique identifier text for each sketch (this will show up on the screen and in log file)
FED3 fed3(sketch); // Start the FED3 object

const long runDuration = 40 * 60 * 1000; // Run duration in milliseconds (40 minutes)
const int feedHours[] = {7, 10, 13, 16, 19, 22}; // Feeding start hours
unsigned long startMillis = 0;
bool isFeeding = false;

void setup() {
  fed3.begin(); // Setup the FED3 hardware
  fed3.DisplayPokes = false; // Customize the DisplayPokes option to 'false' to not display the poke indicators
}

void loop() {
  int currentHour = fed3.currentHour; // Assuming fed3.currentHour gives the current hour
  unsigned long currentMillis = millis();

  // Check if it's time to start feeding
  for (int i = 0; i < sizeof(feedHours)/sizeof(feedHours[0]); i++) {
    if (currentHour == feedHours[i] && !isFeeding) {
      startMillis = currentMillis;
      isFeeding = true;
      break;
    }
  }

  // Check if it's time to stop feeding
  if (isFeeding && (currentMillis - startMillis >= runDuration)) {
    isFeeding = false;
  }

  // Run feeding logic if feeding time
  if (isFeeding) {
    fed3.run(); // Call fed.run at least once per loop
    fed3.Feed(); // Drop pellet
    fed3.Timeout(2); // 2s timeout
  }
}

Christine Liu

unread,
Jun 27, 2024, 12:33:28 PMJun 27
to FEDforum
Hi Rose,

Try putting the fed3.run() line of code outside the if(isFeeding) statement, for example as the very last line of code in the void loop outside of any conditional statements. Good luck!

Rose Presby

unread,
Jun 28, 2024, 10:34:33 AMJun 28
to FEDforum
Thanks Christine!

That solved the issue with the box turning off. Now I have another issue. It seems like the FED is not continuously checking the time. If I turn the box on during a time it is not supposed to be feeding, it does not start feeding/releasing pellets until one of the specified times but then does not stop releasing pellets. I thought I might run into this issue with the 40 minute time frame, thinking it would run the whole hour and stop once it hit a time it was not supposed to be feeding, but that is not the case. It just continues releasing pellets. I appreciate the help everyone!

Christine Liu

unread,
Jun 29, 2024, 12:26:05 PMJun 29
to FEDforum
Hi Rose,

Can you tell us more about how long the FED continues to feed? To me it looks like the reason why the FED keeps feeding is because the startMillis is allowed to reset within a feeding hour after the 40min runDuration. For example I imagine that 40 minutes after the last minute in the hour, you'd stop seeing feeding? For example the device would allow feeding to start at 7:00am - 7:40am. But at 7:40am it could reset and allow another 40minutes of feeding until 8:20am. One way to fix this would be to set specific feeding minutes in addition to the hour to lock it in to 7:00-7:40, or you could use nested conditional statements.


Rose Presby

unread,
Jul 9, 2024, 1:12:04 PMJul 9
to FEDforum
Hi Christine,

Thanks for the response and I apologize for not getting back sooner. The timing varies. It ranges from running for 90 minutes to stopping 10 minutes before the next start time. For example, the box started at 10am, ran until 12:10 (supposed to stop at 10:40am), started again at 1pm and stopped again at 2:35pm (supposed to stop at 1:40). It always starts when it is supposed to. It is just getting it to stop 40 minutes after the start.

You stated that I could set specific feeding minutes, can you explain how to do that? Or how to make nested conditional statements? Do you think one is better than another based on my problem?

Thanks!

Lex

unread,
Jul 9, 2024, 4:40:44 PMJul 9
to Rose Presby, FEDforum
Hi Rose,
Can you try disabling sleep?  The millis() timer stops when FED sleeps so that could explain the funny timing you're seeing.  -Lex

Rose Presby

unread,
Jul 12, 2024, 4:15:53 PMJul 12
to FEDforum
Hi Lex,

Thanks! That did fix the wonky timing. Now it is specifically doing what Christine said with it running an extra 40 minutes and then stopping. I understand that because it is within the given feed hour it is allowed to restart. Should I remove the runDuration line and add a feedMinutes line instead? As previously stated, very bad at this type of thing...

Thanks,
Rose

Christine Liu

unread,
Jul 14, 2024, 4:40:02 PM (12 days ago) Jul 14
to FEDforum
Hi Rose,

Good to know that disabling sleep allows mills() to function properly, I hadn't realized that could be a problem before! However, in my experience, disabling sleep also drains the battery much faster so I'd agree that you should go about it by avoiding the use of millis() altogether by removing runDuration so that you can let the FED sleep.

Mainly, you can edit this line:

    if (currentHour == feedHours[i] && !isFeeding) {

To something like this after creating a currentMinutes variable:
    if (currentHour == feedHours[i] && !isFeeding && currentMinutes < 40) {

This should restrict feeding to minutes 0 to minute 40 for each one of your feedHours.
Hope that works!
Christine

Rose Presby

unread,
Jul 15, 2024, 3:27:44 PM (11 days ago) Jul 15
to FEDforum
It works!!

Thank you Christine and Lex for all the help. Below is the code if anyone ever wants to try it out or modify to fit their needs:

#include <FED3.h> // Include the FED3 library

String sketch = "40minFreeFeed"; // Unique identifier text for each sketch (this will show up on the screen and in log file)
FED3 fed3(sketch); // Start the FED3 object

const int feedHours[] = {7, 10, 13, 16, 19, 22}; // Feeding start hours
const int feedMinutes[] = {40}; // Feeding Minutes
unsigned long startMillis = 0;
bool isFeeding = false;

void setup() {
  fed3.begin(); // Setup the FED3 hardware
  fed3.disableSleep(); // Disable Sleep
  fed3.DisplayPokes = false; // Customize the DisplayPokes option to 'false' to not display the poke indicators
}

void loop() {
  int currentHour = fed3.currentHour; // Assuming fed3.currentHour gives the current hour
  int currentMinute = fed3.currentMinute; // Assuming fed3.currentMinute gives the current minute
  unsigned long currentMillis = millis();
  fed3.run(); // Call fed.run at least once per loop

  // Check if it's time to start feeding
  for (int i = 0; i < sizeof(feedHours)/sizeof(feedHours[0]); i++) {
    if (currentHour == feedHours[i] && !isFeeding && currentMinute < 40) {
      startMillis = currentMillis;
      isFeeding = true;
      break;
    }
  }

  // Check if it's time to stop feeding
  if (isFeeding && (currentMillis - startMillis >= currentMinute)) {
    isFeeding = false;
  }

  // Run feeding logic if feeding time
  if (isFeeding) {

Lex

unread,
Jul 15, 2024, 3:51:10 PM (11 days ago) Jul 15
to Rose Presby, FEDforum
Wonderful!!! Thanks for posting the update!

Reply all
Reply to author
Forward
0 new messages