Skip to content

mccutcheonlab/FED_RT

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

REALTIME and REMOTE FED3(RTFED)

Banner Image

This branch (main) of the repository contains all the information you need to run the RTFED(BASIC) on Windows for online and remote data collection from FED3 devices, if you prefer to use the full-featured RTFED on Raspberry Pi, please visit the other branch RTFEDPi.

What is RTFED?

RTFED_HOME

RTFED is a software that enables you to collect data from FED3 remotely and online. RTFED stores data locally and also sends it to a Google spreadsheet and this process does not require any additional hardware change to FED3 units. With RTFED you can synchronize the time on all of your FEDs and set the modes on each of your FED3 devices via your computer instead of poking. Here I share a walkthrough of the process of setting up RTFED and incorporating a Google Apps Script with your spreadsheet to send you an alarm email in case your FED3 fails to deliver a pellet (e.g. jamming happens).

Since you need to have your FED3 connected to a computer via a USB cable all the time, this solution works best for labs who do not place the FED3 inside the mouse cage or can protect the FED3 and cable from the mice.

A video tutorial

Watch the video

▶️ Click on the thumbnail above to watch a walkthrough of RTFED

Upgrade V2 (NOV 2024):

RTFED now handles interruptions in your internet connection by caching the data on RAM and periodically checking the connection

Upgrade V3 (Dec 2024)

RTFED now comes with a GUI (zip file in /source), dynamically detects FED3 devices connected to your computer. Plug and Play! Just setup your Google spreadsheet and get the JSON file and connect your FED3s and run your experiment.

Upgrade V4 (Dec 2024)

RTFED has port indicator for each FED3 device connected to it, in case you have many FED3s connected and can not find which port receives data from which FED3, you can make right poke to see a tiny indicator blinking next to the active port

Upgrade V5 ( Dec 2024)

RTFED handles reconnecting FED3 devices during a running experiment, e.g. you can switch off a FED to fix jamming and then reconnect it and RTFED keeps logging the data from the device.

Upgrade V6 (Dec 2024)

RTFED GUI handles multiple FED3 units better than before. Some issues are also fixed for FR vs Free Feeding modes.

Upgrade V7 (Dec 2024)

Device number is now identified when RTFED runs and sheets will be named based on device number.

Upgrade V8 (Dec 2024)

Dark mode toggle added to the GUI in addition to some more instructions and hints for users

Upgrade V9 (Dec 2024)

Sync FED3 Time: A new feature added to the GUI which synchronizes the clock of your FED3 units based on your host computer. This is especially good for people who are having issues with the coin battery of clocks or need very accurate Timed Feeding across their FED3 devices.

Upgrade V10 (March 2025)

Device Identification function added and RTS library updated to listen to a command to trigger poke when the user sends a poke request. This feature helps the user easily identify many devices once all the FED units are mounted and cages are ready to go online!

Upgrade V11 (April_May 2025)

Now the users can select modes directly from their computer, once the FEDs are plugged and identified by RTFED, you can choose which FED (or all FEDs) you want to change the modes on and RTFED handles it by restarting the FEDs with the new mode. Additionally, new modes are included in the .ino file, that includes Deterministic Bandit, Bandit (80/20), ProbReversal and ClosedEconomy_PR2

Upgrade V12 (October 2025)

Enhanced GUI experience and added Offline mode after reviewers' comments"

DOWNLOAD THE RTFED_GUI.ZIP and run the RTFED.exe from /dist.

The first time you run the RTFED.exe file you might face a security error, to fix it, right click on the RTFED icon and go to properties, under the General tab you will find an Unblock option.

EXE

If your IT Security issues persist, you can run the code under the hood by running the RTFED.py or the notebook RTFED.ipynb file from ../scripts/ folder, but you need to make sure that you have installed the packages on your environment, to find more information, please look at the Extra section at the bottom of this page.

Step by step instructions for setting up RTFED

Step -1: Update FED3 library with NEW FILES and flash the board

The process of flashing FED3 is explained in detail on the original FED3 repository, the only process you need to follow is to go to your Arduino library folder, find the FED3 library and in folder /src replace the FED3.h and FED3.cpp files with files provided here RTFED_Library.

How to find my Arduino Library folder?

It depends on your arduino installation settings, for example on my computer FED library is located in C:\Arduino_lib\libraries\FED3\src or on a Mac it is located in /Users/your_user_name/Documents/Arduino/libraries but the easiest way to find it is to go to File menu in your Arduino IDE and then select Preference, there you will find the pathway to your libraries.

Arduino_0 Arduino_1

After replacing the files, connect your FED3 to your computer(Not via the charging port rather use the one on the feather board inside the FED body), put it on boot loader mode(Double-press the tiny button on feather board) and flash it just as explained in the original FED3 repository. FED_BOOT Use the port indicated on the image to flash your FED otherwise your computer won't detect any device

Note: You should remove the initial files including FED3.h and FED3.cpp and replace them with update files, you can save those files in a safe place in case you want to revert the changes later*

You are recommended to also flash your board with a new "Classic_FED3_Bandits.ino" file available here, this file includes Closed_economy_PR2, DetBandit, Bandit8020 and ProbReversal modes in addition to previous modes included in original ClassicFED3.

IMPORTANT Notes There are some changes in this new update of library

  1. When the device fails to deliver a pellet, it will just try 5 times in "Jam clearing" state and then stops clearing the jam
  2. As soon as the JAM is logged, the device is frozen and does not log any new activity, however it will just display the time when jamming happened on the screen.
  3. The baud rate is set at 115200 to enable FED3 to log events with millisecond resolution
  4. These changes are not necessary to establish the remote data acquisition and one can try to increase the number of motor turns to clear a jam

Hint

RTFED_FLASHED To make sure you have properly flashed your FED3 with RTFED library, check the screen of your FED3 unit, it should display RTT to the left of the battery icon.

Step 0: Create a Google spreadsheet in your Google Drive, we will get back to it later

Step 1: Create a project

To automatically send data from a local script to a specific Google Spreadsheet we need to get Google Service Account credentials which enables your python script to authenticate as a specific account without needing user interaction each time.

  1. Go to this link to create a new project on you Google Cloud Console, as shown on the screenshot, assign a name to it and press create. create_project

As soon as you create the project you will be prompted to project control panel, if not see notifications on the right corner bell, click on the notification icon and click on the last notification which says "project is created".

notification

Step 2: Set up Service Account Credentials (Get JSON file)

Once in the control panel of your project, form the left side panel go to API and Services and then select Library.

Control_panel

A new link will open in the search bar look for Google Drive API. Select the Google Drive API (probably the first item) and then ENABLE it. It will open a new link where you can control parameters of your Google Drive API.

API_SEARCH API_ENABLE

After enabling your Google Drive API you will be prompted back to APIs and services, click on Credentials in the left panel menu and then select + CREATE CREDENTIALS and from the menu select Service Account API_CONTROL_PANEL API_SERVICE_ACOUNT

Enter a service account name(choose your preferred name) and Service ID will be filled automatically, then press Create and Continue or you can optionally add more users to your project or just press DONE (You can manage it later if needed) API_SERVICE_ACOUNT

Now on the dashboard of your APIs and Services of your project, in Credentials tab from the left panel, you will find Service Account created. Under Action click on the edit icon (pen icon) API_SERVICE_ACOUNT

Click on KEYS PRESS_KEY

Now click on ADD KEY and then Create Key and then select JSON file.

JSON

As soon as you create the JSON key a file is downloaded, take that file and copy it to your preferred location(e.g. where your python script or project folder is located on your computer), we will use this file location in the python script. This JSON file contains information that enables you to interact with the python script and spreadsheet.

Step 3: Enable the Google Sheets API

On the APIs & Services > Credentials page, go to the Library section and search for Google Sheets API. API_SEARCH

API_SEARCH

Select Google Sheets API and then click Enable to activate it for your project.

GOOGLESHEETS_API

Step 4: Critical step - get the email address from JSON file

Now to allow the Service Account access the Google spreadsheet we need to share the Google spreadsheet with the email associated with your Service account (Go to the JSON file)

  1. Open the JSON file that you just downloaded, it can be opened in any editor(like notepad or VSCode).
  2. In the JSON file you will find the "client email", copy that email address(the quotation mark is not needed)
  3. Go to your Google spreadsheet on your Google drive , click on Share icon on the far right of the screen, Paste the email address from the JSON file, set General Access to "Anyone with the link" and click done, you can edit different levels of access for other people as well (For example View only or Editor).

Step 5: Setup the Alarm system(email notification for events)

  1. While in your Google Spreadsheet, from menu Extensions, select Apps Script and clear any existing code. App_script

  2. Paste the code below, make necessary changes described below in Critical sub-step and then press the "save" icon.

Critical sub-step:

After flashing your FED3 using the .cpp and .h files provided in this repository, you will have two extra columns in your FED files for Humidity and Temperature, those columns will remain blank if you do not have those sensors installed on your FED units, however this will not interfere with your data logging, just make sure correct column number are passed to the Apps Script code

Also to receive a email alerts for JAM and Pellets Consumed, you need to add your own email address to the last snippet of the code where it indicates: var emailAddress. You can also change the variable var pelletThreshold to set a threshold in case you want to receive emails when certain amounts of pellets are consumed by mice

    ////##### in the trigger settings, I recommend to choose Time driven under Select event source , and maybe run every 5 min?/// also Failure notification settings is better to be set on Weekly////

    function checkForJam() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheets = ss.getSheets();

    // 1-based columns
    var COL = { timestamp: 1, device: 6, event: 10, pellet: 14 };

    // Tunables, change the numbers if you wish to have different settings
    var PELLET_THRESHOLD = 100;   // this one triggers the daily pellet alert
    var TAIL_ROWS = 500;        // how many most-recent rows to scan each time

    var props = PropertiesService.getScriptProperties();
    var tz = Session.getScriptTimeZone(); // keep in sync with script’s timezone (in my case it is set to Europe/Oslo in File > Project settings if needed, not sure necessary at all!)

    sheets.forEach(function(sheet) {
        var sheetName = sheet.getName();
        var lastRow = sheet.getLastRow();
        if (lastRow < 2) return; // header only / empty

        var startRow = Math.max(2, lastRow - TAIL_ROWS + 1);
        var lastCol  = Math.max(COL.timestamp, COL.device, COL.event, COL.pellet);
        var values   = sheet.getRange(startRow, 1, lastRow - startRow + 1, lastCol).getValues();

        values.forEach(function(r, idx) {
        var rowNum = startRow + idx;

        var event  = String(r[COL.event  - 1] || "").trim();
        var device = String(r[COL.device - 1] || "").trim();
        var pellet = Number(r[COL.pellet - 1]);

        // Parse timestamp -> yyyy-MM-dd (daily key)
        var tsCell = r[COL.timestamp - 1];
        var ts = (tsCell instanceof Date) ? tsCell : (tsCell ? new Date(tsCell) : null);
        var dayKey = ts ? Utilities.formatDate(ts, tz, "yyyy-MM-dd") : "(no-date)";

        // ############################
        // JAM alarm once per row (so this should make sure repeated jams in a day WILL alert again, in case the user fixes a JAM and again a JAM happens)
        // ######
        if (event === "JAM") {
            var jamRowKey = "JAMROW__" + sheetName + "__" + rowNum;
            if (!props.getProperty(jamRowKey)) {
            sendJamAlert(sheetName, rowNum, event, device || "(unknown)");
            props.setProperty(jamRowKey, "1");
            }
        }

        // -####-##-#-#-#-#-#-#
        // Pellet threshold: once per (sheet, device, day)
        //
        if (!device || isNaN(pellet)) return;

        if (pellet >= PELLET_THRESHOLD) {
            var pelletKey = "PELLET__" + sheetName + "__" + device + "__" + dayKey;
            if (!props.getProperty(pelletKey)) {
            sendPelletAlert(sheetName, device, pellet);
            props.setProperty(pelletKey, "1");
            }
        }
        });
    });
    }

    /******** EMAILS  ********/
    function sendJamAlert(sheetName, row, event, deviceNumber) {
    var email = "ENTER YOUR EMAIL ADDRESS HERE";
    var subject = "🚨 FED3 Device Alert: JAM Detected 🚨";
    var message = "🚧 A FED unit has failed.🚧\n\n" +
        "Details:\n" +
        "Sheet: " + sheetName + "\n" +
        "Row: " + row + "\n" +
        "Device Number: " + deviceNumber + "\n" +
        "Event: " + event + "\n" +
        "Please go and check your device! ";
    MailApp.sendEmail(email, subject, message);
    }

    function sendPelletAlert(sheetName, deviceNumber, pelletCount) {
    var email = "ENTER YOUR EMAIL ADDRESS HERE";
    var subject = "🧀🐭FED3 Device Alert: Pellet Threshold Reached🐭🧀";
    var message = "A FED unit has reached the pellet count threshold for today🧀🐁.\n\n" +
        "Details:\n" +
        "Sheet: " + sheetName + "\n" +
        "Device Number: " + deviceNumber + "\n" +
        "Pellet Count: " + pelletCount + "\n" +
        "This alert fires once per device per day.";
    MailApp.sendEmail(email, subject, message);#### you do not need to enter your email address here, it is calling the function not defining a parameter#####
    }
  1. To activate the Alarm email, in the Apps Script control panel, from the left panel menu, select Triggers and then right bottom corner select + Add Trigger

App_script

Set the settings according to the screenshot below:

Trigger_setup

After saving the trigger, a warning will show up -- image below Trigger_setup

Click on Advanced, then click on Go to your project then click on Allow


IMPORTANT NOTE: The RTFED ignores the timestamp data coming from FEDs and gets the timestamp from the mother computer, which means that all the FEDs connected to the main computer will be synchronized.

Extra (For expert users who want to make changes in the codes)

You can use either the .yml file to create a separate environment for your RTFED python code, or use the requirement.txt file from the same folder to get the required python packages. Follow the instructions on ANACONDA_CHEAT_SHEET, but basically download the above mentioned files and move them to your anaconda environments directory, open your anaconda terminal and navigate to to the directory where the RTFED.yml is located and run the command below:

            conda env create -f RTFED.yml

Alternatively you can use the requirement.txt file to either update packages in your base/current environment or making an env from the scratch,simply navigate to the directory where you have the requirements.txt located, and run the following command:

            pip install -r requirements.txt

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Author of this repository

Hamid Taghipourbibalan, Ph.D. student at McCutcheon_lab at UiT The Arctic University of Norway.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published