Skip to content

Repository files navigation

ProtoCentral tinyGSR Arduino Library

Arduino Lint Compile Examples

Arduino library for the ProtoCentral tinyGSR electrodermal-activity (EDA / galvanic skin response) breakout — every hardware revision, one library.

Don't have one? Buy it here

ProtoCentral tinyGSR

Links

🛒 Product page https://protocentral.com/product/protocentral-tinygsr-gsr-eda-digital-output-sensor-board-qwiic-stemma-qt/
🔧 Hardware design files https://github.com/Protocentral/protocentral_tinygsr_hardware
🐍 MicroPython driver https://github.com/Protocentral/protocentral-micropython-tinygsr
📄 ADC datasheet (TI TLA2022) https://www.ti.com/lit/ds/symlink/tla2022.pdf
📄 Front-end op-amp (TI OPA2333) https://www.ti.com/lit/ds/symlink/opa2333.pdf

Current boards report an absolute skin conductance in microsiemens (µS) with no per-unit calibration, from a research-standard 0.5 V DC constant-voltage transimpedance front end. The original v1 board streamed a relative, hand-trimmed proxy instead, and is supported here in ADC-count mode.

How it works

One electrode sits at GND; the other is pinned at V_exc = 0.5 V by a zero-drift op-amp (OPA2333) in a transimpedance loop. The skin draws I = V_exc · G_skin, which a precision feedback resistor R_f = 39.2 kΩ converts to a voltage. The ADC reads it differentially (AIN0 = V_out, AIN1 = V_exc), so the 0.5 V pedestal is subtracted in hardware and only the conductance-proportional term I·R_f is digitised:

G[µS] = V_diff / (V_exc · R_f) × 1e6      V_exc ≈ 0.5007 V, R_f = 39.2 kΩ

Because V_exc and R_f are known precision quantities, counts map to µS deterministically — two boards agree with each other, and a reading taken today is comparable with one from next month.

Hardware revisions

Revision begin() argument Front end ADC address Reports
v3 (current) · v2 TINYGSR_REV_V3 (default) OPA2333 constant-voltage TIA, R_f 39.2 kΩ 0.1 % 0x48 absolute µS + resistance, Rcal self-check
v1 (original) TINYGSR_REV_V1 LMV324 with a 200 kΩ trimpot 0x49 relative ADC counts only

The revision cannot be detected at runtime — both boards present the same TLA2022, and either one's ADDR jumper can be moved — so you state it at begin(). Leave the constructor's address at its default and begin() resolves 0x48 or 0x49 to match; pass an address explicitly and that always wins.

On a v1 board readConductance(), readResistance() and readFiltered() return NAN. Its gain is set by a trimpot turned by hand, so nothing maps counts to microsiemens, and returning a plausible-looking number that means nothing would be worse than saying so. Use readCounts() / readCountsFiltered() — the signal shape EDA analysis actually uses is unaffected. v1 owners still gain from this library: it replaces the old TLA20xx + FIR dependency pair with one self-contained install.

Features

  • Absolute skin conductance in microsiemens (µS) and resistance in ohms
  • Built-in 8-tap moving-average smoothing — no external filter library
  • One-point self-calibration against the board's on-board 100 kΩ 0.1 % Rcal (= 10.00 µS)
  • No-contact and over-range flags so a bad electrode is visible in software
  • Raw voltage and raw ADC-count escape hatches for power users
  • ADC-agnostic transfer function (conductanceFromVoltage) for a 16-bit ADS111x front end
  • Supports every tinyGSR revision from one library
  • Standalone — depends= is empty; nothing else to install
  • I²C / Qwiic / STEMMA QT — Arduino, ESP32, Nano 33 BLE, RP2040 and other 3.3 V or 5 V hosts

Installation

Arduino Library Manager (Recommended)

  1. Open the Arduino IDE
  2. Go to Sketch → Include Library → Manage Libraries
  3. Search for "ProtoCentral tinyGSR"
  4. Click Install

Manual Installation

  1. Download or clone this repository
  2. Copy it into your Arduino libraries folder (~/Documents/Arduino/libraries/)
  3. Restart the Arduino IDE

Hardware Setup

tinyGSR pin Arduino connection Pin function
VCC 3.3 V or 5 V Power supply (3.3 V – 5 V)
GND GND Ground
SDA A4 (or the board's SDA pin) I²C data
SCL A5 (or the board's SCL pin) I²C clock

Or skip the wiring entirely: plug a Qwiic / STEMMA QT cable into either of the board's two connectors. I²C pull-ups are on board, and the second connector daisy-chains the next device.

Attach Ag/AgCl electrodes to the supplied 3.5 mm snap lead and place them on two fingers of the same hand, or on the thenar and hypothenar of the palm. Non-polarizable Ag/AgCl electrodes are required for a stable DC baseline — dry or steel contacts drift.

Quick Start

#include <Wire.h>
#include "protocentral_TinyGSR.h"

TinyGSR gsr;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  gsr.begin();                 // v2/v3 board; pass TINYGSR_REV_V1 for an original v1
}

void loop() {
  Serial.println(gsr.readFiltered(), 3);   // smoothed conductance in µS
  delay(100);
}

A relaxed tonic level is typically ~1–20 µS. A deep breath, a sudden sound, or mental arithmetic should produce a phasic bump (SCR) rising within ~1–3 s.

Using a custom I²C bus or address

TinyGSR gsr(0x49);             // explicit address always wins over the revision default
gsr.begin(TINYGSR_REV_V1);

Self-check and one-point calibration

The v2/v3 board carries a precision Rcal = 100 kΩ (= 10.00 µS) behind the jumper marked SHORT FOR CAL (open in normal use). To verify or calibrate:

  1. Remove the subject and close the jumper
  2. Call calibrate() — the reading should be 10.00 µS, and the scale factor is stored so R_f, V_exc and ADC-gain tolerances are folded out
  3. Open the jumper before measuring a subject

See the 02-Self-Check-Calibration example. There is no Rcal on a v1 board, so calibrate() is a no-op there.

API Reference

Constructor and lifecycle

Method Description
TinyGSR(addr = TINYGSR_ADDR_AUTO, wire = &Wire) Constructor. AUTO lets begin() pick the address for the revision.
begin(rev = TINYGSR_REV_V3) Configure the ADC for the revision; returns false if it does not ACK.
isConnected() Whether the ADC ACKs on the bus.
revision() / address() What begin() selected.

Reading the signal

Method Returns Description
readConductance() float Absolute skin conductance, µS. NAN on v1.
readFiltered() float 8-tap moving-average conductance, µS. NAN on v1.
readResistance() float Skin resistance, ohms (INFINITY when open). NAN on v1.
readVoltage() float Raw differential front-end voltage, V.
readCounts() int16_t Signed 12-bit ADC result — every revision.
readCountsFiltered() float 8-tap moving-average ADC counts — every revision.
conductanceFromVoltage(v) float µS from a differential voltage (custom / 16-bit front end).

Diagnostics and calibration

Method Returns Description
isContact() bool Electrodes appear connected.
isOverRange() bool Reading is saturating near full scale.
calibrate(known_us) void One-point cal against the on-board Rcal. No-op on v1.
setCalibration(scale) / getCalibration() Get or set the stored scale factor.
setExcitation(v) / setFeedbackResistor(ohms) Override the front-end constants.

Constants

Constant Value Description
TINYGSR_REV_V3 / TINYGSR_REV_V1 0 / 1 Board revision passed to begin()
TINYGSR_ADDR_AUTO 0xFF Resolve the I²C address from the revision
TINYGSR_DEFAULT_ADDRESS_V3 / _V1 0x48 / 0x49 Per-revision ADC address
TINYGSR_RCAL_US 10.0 On-board calibration resistor, in µS
TINYGSR_VEXC_DEFAULT 0.5007 Excitation voltage, V
TINYGSR_RF_DEFAULT 39200.0 TIA feedback resistor, Ω

Examples

Example Description
01-Basic-Conductance-Read Print absolute µS and resistance with contact / over-range flags
02-Self-Check-Calibration Verify against the on-board Rcal and store a one-point calibration
03-OpenView Stream to the OpenView app — select "tinyGSR Breakout" from the Board dropdown
04-V1-Legacy-Board Read an original v1 board in ADC-count mode

The OpenView example emits the ProtoCentral v3 frame (0x0A 0xFA | LEN | 0x02 | 8-byte payload | 0x00 0x0B) over USB serial at 57600 baud — deliberately different from the 115200 the other examples use. Its payload's resistance slot is an int16 in ohms, which EDA skin resistance overflows, so it is left at 0 and the ADC count carries the signal; absolute µS stays available through the API.

Notes

  • Ag/AgCl electrodes are strongly recommended; the biggest real-world accuracy limits are electrode half-cell offset and E1-node leakage, not the circuit.
  • EDA bandwidth is DC – ~5 Hz (phasic SCRs ~0.05 – 1 Hz); the front end low-passes at ~18 Hz.
  • Safety: 0.5 V, ≤ 50 µA into skin. Non-medical — for research and education only.

Related

Hardware design files (CERN-OHL-P v2) https://github.com/Protocentral/protocentral_tinygsr_hardware
MicroPython / Raspberry Pi driver https://github.com/Protocentral/protocentral-micropython-tinygsr
OpenView companion app https://github.com/Protocentral/protocentral_openview
Getting-started guide https://protocentral.com/product/protocentral-tinygsr-gsr-eda-digital-output-sensor-board-qwiic-stemma-qt/docs/getting-started/

License

MIT — see LICENSE. The tinyGSR hardware design files are licensed CERN-OHL-P v2.

Copyright (c) 2026 ProtoCentral Electronics.

About

Arduino library for the ProtoCentral tinyGSR electrodermal activity (GSR/EDA) sensor breakout — absolute skin conductance in microsiemens over I2C, all hardware revisions

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages