Skip to content

Neurotech-Hub/Hublink-BEAM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

128 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hublink BEAM Arduino Library

An Arduino library for the Hublink BEAM ESP32-S3 data logging device. This library provides functionality for sensor monitoring and SD card data logging.

Installation

  1. In Arduino IDE, you use Boards Manager to install the Espressif esp32 board package.

  2. Install the Hublink-BEAM library from Arduino IDE. Alternatively (but not recommended), clone or download this repository to the libraries folder in the Arduino IDE, (or use Sketch -> Include Library -> Add .ZIP Library).

  3. Ensure the dependencies are installed for library.properties and https://github.com/Neurotech-Hub/Hublink-Node:

  • RTClib
  • Adafruit MAX1704X
  • Adafruit BME280 Library
  • Adafruit VEML7700 Library
  • Adafruit NeoPixel
  • ESP32Time
  • Preferences

meta.json File Contents BEAM must have a meta.json file present to control timing parameters (if deviating from the sketch defaults) and sync with Hublink. Several Hublink parameters are disregarded because of BEAM's deep sleep cycling: advertise_every, advertise_for, and reconnect settings are not utilized but can still be placed in the hublink structure.

json
{
  "hublink": {
    "advertise": "HUBLINK",
    "advertise_every": 120,
    "advertise_for": 30,
    "try_reconnect": false,
    "reconnect_attempts": 2,
    "reconnect_every": 30,
    "upload_path": "/BEAM",
    "append_path": "device:id",
    "disable": false
  },
  "beam": {
    "log_every_minutes": 1,
    "sync_every_minutes": 3,
    "sync_for_seconds": 30,
    "new_file_on_boot": true,
    "inactivity_period_seconds": 40,
    "randomize_alarm_minutes": 1
  },
  "subject": {
    "id": "",
    "strain": "",
    "sex": "F"
  },
  "experiment": {
    "name": ""
  },
  "device": {
    "id": "001"
  }
}

Testing

  1. Ensure the power switch is in the ON position.

  2. If the device has been previously flashed, it may be in a deep sleep state and will not connect to the serial port. To enter boot mode, hold the Boot button and toggle the Reset button (then release the Boot button).

  3. If the Arduino IDE does not indicate that it is connected to "Adafruit Feather ESP32-S3 2MB PSRAM", click Tools -> Board -> esp32 -> Adafruit Feather ESP32-S3 2MB PSRAM (you will need to download the esp32 board package (by espressif) from the Arduino IDE).

Debug Mode

You may enable debugging mode by placing the A switch down. This will reduce the PIR sensor initialization period and introduce delays before Serial statements so they can be read by a serial terminal. These delays are useful for debugging, but should be removed for normal operation.

RTC Setting

Setting the RTC is performed using the compilation time of the sketch. This is not always accurate and typically requires a clearing of your sketch cache to ensure correctness.

Clear Arduino IDE Cache:

On MacOS:

rm -rf /Users/<username>/Library/Caches/arduino/sketches

On Windows:

rmdir /s "%LOCALAPPDATA%\Arduino15\packages\esp32\tools\esptool_py\*\cache"
del /s /q "%TEMP%\arduino_*"

On Linux:

rm -rf ~/.arduino15/packages/esp32/tools/esptool_py/*/cache
rm -rf /tmp/arduino_*

Alternative RTC Setting Methods:

  1. Manual RTC Setting (more accurate):

    // Set RTC to specific date/time
    beam.adjustRTC(DateTime(2024, 1, 15, 10, 30, 0)); // Year, Month, Day, Hour, Minute, Second
  2. Unix Timestamp Setting:

    // Set RTC using Unix timestamp
    beam.adjustRTC(1705315800); // Unix timestamp
  3. Ensure Fresh Compilation:

    • Close Arduino IDE completely
    • Clear cache as shown above
    • Reopen IDE and compile/upload immediately for most accurate compilation time

Hardware Assembly

For detailed hardware assembly instructions, including the required low-power modification, see docs/assembly.md.

LED Indicators

These indicators may be temporary during operations or flash continuously if stuck in a loop.

  • Blue: Starting up
  • Red: Error (SD card or sensor failure)
  • Green: Motion detected (during data logging)
  • Purple: Low battery
  • White: Hublink sync on boot (attempt is ongoing)
  • Off: Normal operation

Battery Protection

The device implements intelligent battery protection to prevent over-discharge while maintaining operational reliability:

Low Battery Threshold: 3.7V

First Boot/Power-On:

  • Battery < 3.7V: Device will not start (purple LED, initialization failure)
  • Protects battery from deep discharge damage
  • Switch A down (debug mode): Bypasses protection for development/testing

Wake from Deep Sleep:

  • Battery < 3.7V: Device continues operation (logs low battery state)
  • Ensures continuous data collection even if battery drops during use
  • Allows device to complete current logging cycle and save data

Benefits:

  • Prevents battery damage from over-discharge on startup
  • Maintains data integrity during normal operation
  • Clear visual indicators (purple LED) for low battery state
  • Debug override available for development work

Data Logging

CSV Format

Each log entry contains the following columns:

  • datetime: Current date and time (YYYY-MM-DD HH:MM:SS)
  • millis: Milliseconds since last boot
  • device_id: Device identifier (3-character alphanumeric)
  • library_version: Library version string
  • battery_voltage: Battery voltage in volts (-1.0 if sensor failed)
  • temperature_c: Temperature in Celsius (-273.15 if sensor failed)
  • pressure_hpa: Atmospheric pressure in hPa (-1.0 if sensor failed)
  • humidity_percent: Relative humidity percentage (-1.0 if sensor failed)
  • lux: Light level in lux (-1.0 if sensor failed)
  • activity_count: Number of motion events since last log
  • activity_percent: Fraction of time PIR was active (0-1)
  • inactivity_period_s: Configured inactivity period in seconds
  • inactivity_count: Number of complete inactivity periods
  • inactivity_percent: Fraction of possible inactivity periods (0-1)
  • min_free_heap: Minimum free heap memory in bytes
  • reboot: 1 if entry is from fresh boot, 0 if from wake from sleep

File Creation Behavior

Files are named in the format /BEAM_YYYYMMDDXX.csv where:

  • YYYY: Year
  • MM: Month (01-12)
  • DD: Day (01-31)
  • XX: Sequence number (00-99)

For a detailed flowchart of the filename selection logic, see docs/filename_logic.md.

The sequence number handling can be controlled with the setNewFileOnBoot() method:

beam.setNewFileOnBoot(false); // false to continue using same file if it's the same day
  • When true (default): Creates a new file with incremented sequence number on each boot
  • When false: Continues using the same file if it's from the same day

If the SD card is cleared or files are deleted:

  1. The system scans for existing files matching today's date
  2. Uses the next available sequence number (00-99)
  3. Creates a new file regardless of any stored filename in preferences
  4. This ensures proper sequencing even after data is wiped

Startup Sequence

On power-up or reset, the device:

  1. Stops any running ULP program to free GPIO pins
  2. Initializes pins and I2C power
  3. Checks battery voltage (purple LED and initialization failure if battery < 3.7V on first boot)
  4. Initializes SD card (must be present)
  5. Sets up sensors and RTC
  6. Creates a new log file with today's date and next available number

Deep Sleep Operation

The device uses the ESP32's ULP (Ultra Low Power) coprocessor to monitor motion while the main processor is in deep sleep. See docs/flowchart.md for a detailed flow diagram.

Inactivity Period Configuration

The inactivity period can be set using the setInactivityPeriod() method:

beam.setInactivityPeriod(40); // 40 seconds of immobility indicates sleep

The 40-second threshold is based on research by Brown et al. (2017) which demonstrated that extended immobility of >40 seconds provides a reliable indicator of sleep, correlating well with EEG-defined sleep (Pearson's r >0.95, n=4 mice).

Alarm Randomization

To prevent multiple devices from syncing simultaneously (which can cause network collisions), the library supports alarm randomization:

beam.setAlarmRandomization(1); // Randomize alarm timing by ±1 minute

Configuration via meta.json:

{
  "beam": {
    "randomize_alarm_minutes": 1
  }
}

How it works:

  • Each device generates a unique, consistent delay based on its MAC address
  • Random delay ranges from 0 to (2 × randomize_alarm_minutes) minutes
  • Applied during device initialization after successful sensor setup
  • Same device always uses the same delay (deterministic based on hardware)
  • Default value of 0 disables randomization (backward compatible)
  • Debug mode (Switch A down) skips the delay for faster development

Example with randomize_alarm_minutes: 1:

  • Device A (MAC: AA:BB:CC...): Always delays 23 seconds on boot
  • Device B (MAC: 11:22:33...): Always delays 47 seconds on boot
  • Device C (MAC: FF:EE:DD...): Always delays 8 seconds on boot

This spreads sync operations across a 0-2 minute window, eliminating collisions when multiple devices wake simultaneously.

ULP Operation

  • ULP program continuously monitors the PIR sensor
  • Increments PIR count when motion is detected
  • Tracks inactivity periods based on configured duration
  • Maintains counters in RTC memory
  • Main processor reads counters upon waking

Sleep Process

  • Configures ULP program with current settings
  • Disables sensors and peripherals to save power
  • Enters deep sleep for specified duration
  • Wakes on timer expiration to log data
  • Calculates activity metrics upon wake

Examples

See the examples folder for detailed usage examples:

  • BasicLogging: Demonstrates basic data logging functionality

Low Power Addons

  • Idle SD card by immediately checking for /x.txt
  • Two-stage deep sleep for optimal power usage
  • VEM7700 has low power modes (in library); reduces from ~13µA to ~5µA
  • BME280 has low power modes (in library); reduces from ~650µA to ~10µA
  • MAX17048 has hibernation mode (in library); reduces from ~23µA to ~4µA
  • SD card draws ~1200µA; could optimize
  • SD card detent pull-up could be ~60-160µA when card is present; consider toggling pull-up to check
  • ZDP323 draws ~8µA (no low power mode)
  • consider rtc_gpio_isolate(GPIO_NUM_12); from esp-idf/examples/system/ulp/ulp_fsm/ulp/main/ulp_example_main.c at v5.4 · espressif/esp-idf

License and Copyright

Copyright © 2024 Neurotech Hub at Washington University in St. Louis. All rights reserved.

This software is proprietary and confidential. The source code is the property of the Neurotech Hub at Washington University in St. Louis and is protected by intellectual property laws. No part of this software may be deployed, copied, modified, or distributed in any form or by any means without the prior written permission from the Neurotech Hub at Washington University in St. Louis.

For licensing inquiries, please contact the Neurotech Hub at Washington University in St. Louis.

About

Provides functionality for sensor monitoring and SD card data logging for the Hublink BEAM device.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors