From an off the shelf sensor and an Arduino to wireless data in Excel — here’s exactly how to build it.
MobileCollect has connected digital gages to SPC software wirelessly for decades. Calipers, micrometers, indicators, height gages — if it has a Digimatic or compatible SPC output, MobileCollect handles it. But measurement data doesn’t only come from traditional gages.
OpenGage Mode changes what MobileCollect can connect to.
Introduced with the Mini Mobile Module EVO (M3E), OpenGage Mode is a selectable operating mode that enables any device communicating at 3V UART to transmit data wirelessly over MicroRidge’s RM2.4 industrial wireless protocol — the same 32-bit encrypted, 140-foot range network used by the entire MobileCollect product line.
If it speaks 3V UART at 9600-N-8-1, it speaks RM2.4.
In this post we’ll walk through one concrete example of what that unlocks: a wireless environmental monitoring node built from an Arduino Nano ESP32 and a Sensirion SHT45 temperature and humidity sensor. Every 40 seconds — or any time an operator presses the Read Button on the M3E — a combined temperature and humidity reading transmits wirelessly into any PC application with no additional software, drivers, or middleware required.
Thousands of devices — sensors, instruments, microcontrollers, test fixtures — output data as a simple serial stream at 3V logic levels. Barcode scanners, load cells, torque gauges, flow meters, ultrasonic distance sensors, custom Arduino-based test rigs. If it speaks 3V UART at 9600-N-8-1, OpenGage Mode can put it on RM2.4 industrial wireless and route it into any PC application you’re already using.
RM2.4 is MicroRidge’s purpose-built industrial wireless protocol — deterministic, 32-bit encrypted, and designed for the RF environment of a production floor rather than a consumer device. If you’re evaluating wireless data collection and Bluetooth has come up in that conversation, it’s worth understanding why RM2.4 and Bluetooth are fundamentally different animals before committing to either. The short version: Bluetooth is always-on frequency hopping designed for consumer devices. RM2.4 wakes on demand, transmits, and sleeps — which is why the M3E gets approximately one year of battery life on a CR2032 while Bluetooth gages need to be charged. For the full protocol breakdown, see the RM2.4 Wireless Protocol page.
That’s a broad capability. So rather than list everything it could do, let’s build something concrete.
Environmental monitoring is one of the most universally applicable starting points — every production floor, metrology room, and calibration lab has some requirement to track temperature and humidity. It’s also a great demonstration of the OpenGage Mode concept because the hardware is inexpensive, the wiring is simple, and the output is immediately useful the moment it starts running.
ISO 9001 Clause 7.1.5 requires organizations to determine and provide monitoring and measuring resources necessary to ensure valid and reliable results. For many quality teams that includes documented evidence that environmental conditions at the point of measurement are within acceptable limits — particularly in calibration environments where thermal expansion and instrument drift are real sources of measurement uncertainty. If environmental data collection is part of your path to meeting that requirement, this build is one way to get there without a dedicated environmental monitoring system.
The sensor we’re using — the Sensirion SHT45 — delivers ±0.1°C temperature accuracy and ±1.0% RH humidity accuracy. Paired with an M3E and an EVO Base Receiver, readings stream wirelessly into any PC application every 40 seconds, automatically, for approximately one year on a single CR2032 battery.
Item | Source | Approx. Cost |
|---|---|---|
Mini Mobile Module EVO (MC-MM-M3-EVO) | MicroRidge | $285 |
OpenGage UART Cable (MC-M3E-UNIV-24) | MicroRidge | $115 |
MobileCollect EVO Base Receiver (Example MicroBase EVO USB C | MC-MB-C-EVO) | MicroRidge | $450 |
Arduino Nano ESP32 | Arduino Store | $20 |
Adafruit SHT45 Breakout | Adafruit Store | $15 |
Jumper Wires (male-to-male) | Any | $5 |
USB-C Cable | Any | $5 |
Approx. Total Cost | $895 | |
A note on the SHT45: Adafruit offers two versions — standard and with PTFE membrane filter. For a clean indoor environment like a calibration room or metrology lab, the standard version without PTFE is appropriate. If you’re deploying in a machining environment, near coolant mist, or anywhere with airborne particulates, the PTFE version provides long-term protection against contamination of the sensor element.
Arduino libraries required — install both via Arduino IDE Library Manager (Tools → Manage Libraries):
When prompted to install dependencies, select Install All.
The Nano ESP32 is a 3.3V board — a direct match for the SHT45’s operating voltage range. No level shifter required. The Adafruit SHT45 breakout includes onboard pull-up resistors, so no external components are needed for the I²C lines. All three devices — SHT45, Arduino, and M3E cable — share a common ground. Connect SHT45 GND and the M3E blue wire to the same GND pin or breadboard ground rail.
SHT45 Pin | Arduino Nano ESP32 Pin |
|---|---|
VIN | 3.3V |
GND | GND (shared) |
SDA | A4 |
SCL | A5 |
Wire Color | Signal | Arduino Nano ESP32 Pin |
|---|---|---|
Green | Read Button | D2 |
White | Read Request | D3 |
Black | UART Data (TX) | D6 |
Blue | Ground | GND (shared) |
Once running, the system operates two trigger paths simultaneously.
Automatic (every 40 seconds): The Arduino pulls the Read Button line LOW for 25 milliseconds, signaling the M3E to initiate a read cycle. The M3E responds with a Read Request signal, the Arduino reads the latest cached sensor values and transmits a combined temperature and humidity packet. The M3E receives it over UART and transmits wirelessly to the EVO Base Receiver.
Manual (operator-initiated): The operator presses the Read Button on the M3E housing at any time. The M3E pulls Read Request LOW independently, the Arduino detects it and transmits immediately. The auto-trigger timer resets so there’s no duplicate transmission shortly after.
Both paths produce the same output — a single combined packet:
Temp F[TAB]72.7[TAB]RH %[TAB]48.3Each label and value lands in its own column, so the temperature and humidity values are immediately available for charting or formula reference in Excel without any text parsing.
The packet flows from the EVO Base Receiver into whatever PC application has focus in Keyboard Wedge mode — Excel, a web-based quality form, SPC software, or any active window. In USB Serial mode it routes to the configured COM port for software integration.
Before uploading, configure the M3E in OpenGage Mode (9600-N-8-1) using MobileCollect Xpress Setup or Extended Setup and pair it with an EVO Base Receiver. Each Arduino sketch must be saved in its own folder — Arduino IDE compiles all .ino files in a folder together.
// ============================================================
// OpenGage Mode — Environmental Monitor Example
// MicroRidge MobileCollect Mini Mobile Module EVO (M3E)
// Hardware: Arduino Nano ESP32 + Adafruit SHT45
//
// On each trigger event (auto every 40 seconds, or operator
// pressing the Read Button on the M3E), transmits a single
// combined packet:
// Temp F[TAB]72.7[TAB]RH %[TAB]48.3
//
// Each label and value lands in its own Excel column so values
// can be charted or referenced directly without text parsing:
// Col A: Temp F | Col B: 72.7 | Col C: RH % | Col D: 48.3
//
// Trigger modes:
// Auto — Arduino triggers a read every 40 seconds.
// 800,000 M3E readings at this interval ≈ 1 year
// of battery life on a single CR2032 coin cell.
// Manual — Operator presses the Read Button on the M3E.
// Resets the auto-trigger timer — no double-fire.
//
// Wiring (Arduino Nano ESP32):
// Pin D2 (OUTPUT) → Green wire → Read Button on M3E
// Pin D3 (INPUT) → White wire → Read Request from M3E
// Pin D6 (TX) → Black wire → UART Data to M3E
// Pin A4 (SDA) → SDA → SHT45 SDA
// Pin A5 (SCL) → SCL → SHT45 SCL
// 3.3V → VIN → SHT45 VIN
// GND → Blue wire + SHT45 GND → Common Ground
//
// Required Libraries (Arduino Library Manager):
// Adafruit SHT4x Library
// Adafruit BusIO
//
// Before running: configure M3E in OpenGage Mode (9600-N-8-1)
// using MobileCollect Xpress Setup or Extended Setup, and pair
// with an EVO series MobileCollect Base Receiver.
// ============================================================
#include
#include "Adafruit_SHT4x.h"
// ── Pin Definitions ──────────────────────────────────────────
#define READ_BUTTON_PIN 2 // OUTPUT: Pull LOW 25–50 ms to auto-trigger.
#define READ_REQUEST_PIN 3 // INPUT: M3E pulls LOW when ready to receive.
#define UART_TX_PIN 6 // Serial1 TX → Black wire → M3E UART input.
// ── End-of-Packet Byte ───────────────────────────────────────
#define END_OF_PACKET 0x0D // Carriage Return — required packet terminator.
// ── Timing ───────────────────────────────────────────────────
// 40-second interval: 800,000 M3E readings ≈ 1 year per CR2032.
// Adjust READ_INTERVAL_MS to trade battery life for sample rate.
const unsigned long READ_INTERVAL_MS = 40000;
const unsigned long READ_BUTTON_PULSE_MS = 25;
const unsigned long READ_REQUEST_TIMEOUT_MS = 500;
const unsigned long SENSOR_POLL_MS = 5000;
// ── State ────────────────────────────────────────────────────
unsigned long lastReadTime = 0;
unsigned long lastSensorPoll = 0;
bool sensorReady = false;
// ── Cached Sensor Values ─────────────────────────────────────
// SHT45 is polled every 5 seconds in the background.
// Transmit reads from cache — no blocking sensor reads during
// the time-sensitive Read Request response window.
float cachedTempF = 0.0;
float cachedHumidity = 0.0;
// ── SHT45 ────────────────────────────────────────────────────
Adafruit_SHT4x sht45;
// ── Setup ────────────────────────────────────────────────────
void setup() {
Serial1.begin(9600, SERIAL_8N1, -1, UART_TX_PIN);
Wire.begin();
if (!sht45.begin(&Wire)) {
while (1) delay(10); // Halt — sensor required.
}
sht45.setPrecision(SHT4X_HIGH_PRECISION);
pinMode(READ_BUTTON_PIN, OUTPUT);
digitalWrite(READ_BUTTON_PIN, HIGH);
pinMode(READ_REQUEST_PIN, INPUT_PULLUP);
}
// ── pollSensor() ─────────────────────────────────────────────
// Reads SHT45 and caches values. Called on SENSOR_POLL_MS
// interval. Non-blocking — does not affect M3E timing.
// ─────────────────────────────────────────────────────────────
void pollSensor() {
sensors_event_t humidityEvent, tempEvent;
if (sht45.getEvent(&humidityEvent, &tempEvent)) {
cachedTempF = (tempEvent.temperature * 9.0 / 5.0) + 32.0;
cachedHumidity = humidityEvent.relative_humidity;
sensorReady = true;
}
}
// ── transmit() ───────────────────────────────────────────────
// Sends combined temp + humidity packet to M3E via UART.
// Labels and values are tab-separated into individual columns
// so values can be graphed or referenced directly in Excel
// without any text parsing.
// Format: "Temp F[TAB]72.7[TAB]RH %[TAB]48.3" + 0x0D
//
// Excel column layout:
// Col A: Temp F | Col B: 72.7 | Col C: RH % | Col D: 48.3
// ─────────────────────────────────────────────────────────────
void transmit() {
if (!sensorReady) return;
String packet = "Temp F\t" + String(cachedTempF, 1) + "\t" +
"RH %\t" + String(cachedHumidity, 1);
Serial1.print(packet);
Serial1.write(END_OF_PACKET);
delay(150); // 150 ms minimum gap between M3E packets.
}
// ── Main Loop ────────────────────────────────────────────────
void loop() {
unsigned long now = millis();
// Background sensor poll — keeps cached values current.
if (now - lastSensorPoll >= SENSOR_POLL_MS) {
pollSensor();
lastSensorPoll = now;
}
// Path 1: Auto-trigger every 40 seconds.
if (now - lastReadTime >= READ_INTERVAL_MS) {
digitalWrite(READ_BUTTON_PIN, LOW);
delay(READ_BUTTON_PULSE_MS);
digitalWrite(READ_BUTTON_PIN, HIGH);
unsigned long waitStart = millis();
while (millis() - waitStart < READ_REQUEST_TIMEOUT_MS) {
if (digitalRead(READ_REQUEST_PIN) == LOW) {
transmit();
lastReadTime = millis();
break;
}
}
if (millis() - lastReadTime > READ_REQUEST_TIMEOUT_MS) {
lastReadTime = millis();
}
}
// Path 2: Manual trigger — operator presses Read Button on M3E.
// Resets auto-trigger timer to prevent duplicate transmission.
else if (digitalRead(READ_REQUEST_PIN) == LOW) {
transmit();
lastReadTime = millis();
}
}
Each trigger — automatic or manual — sends one packet. In Keyboard Wedge mode with the cursor active in Excel, each reading arrives as four values in adjacent columns — label, value, label, value — so the numeric columns can be selected directly for charting or referenced in formulas without any text manipulation:
Column A | Column B | Column C | Column D |
|---|---|---|---|
Temp F | 72.4 | RH % | 48.1 |
Temp F | 72.5 | RH % | 48.2 |
Temp F | 72.5 | RH % | 48.0 |
A new row arrives every 40 seconds automatically. Over an 8-hour shift that’s 720 data points — a complete environmental record with no manual data entry and no dedicated logging hardware.
The same output works in any application that accepts keyboard input: SPC software, web-based quality forms, Access databases, Google Sheets, or a homegrown inspection system. No driver installation, no middleware, no API integration required.
One node covers one location — but RM2.4 supports multiple paired transmitters on the same Base Receiver network simultaneously. That means you can place SHT45 nodes at several points around a calibration lab or production floor and capture location-specific temperature and humidity data from all of them in the same application, alongside whatever gage data is already flowing through MobileCollect. A caliper at one station, a micrometer at another, and environmental sensors throughout — one system, one data stream, no additional infrastructure.
The 40-second interval in this example wasn’t chosen arbitrarily. The M3E uses a wake-on-demand architecture — it sleeps between every reading regardless of whether the trigger is operator-initiated or timer-based. At a 40-second read rate, 800,000 M3E readings works out to approximately one year of battery life on a single CR2032.
That means this environmental monitoring node runs unattended for roughly a year before needing a battery change. No charging, no scheduled maintenance, no interruption to data collection.
For a detailed look at how M3E battery life scales across different read rates and inspection workflows — including a comparison against Bluetooth-based wireless systems.
This example uses one sensor, but OpenGage Mode isn’t limited to environmental monitoring. Any device outputting 3V UART at 9600-N-8-1 can transmit wirelessly over RM2.4 using the same M3E and EVO Base Receiver: torque gauges, load cells, barcode and RFID readers, custom microcontroller-based test fixtures, flow meters, ultrasonic distance sensors, and more.
For the complete protocol specification, cable wiring details, and additional code examples, see the OpenGage Mode Feature Guide.
Riley Tronson is President and owner of MicroRidge Systems, a role held since 2023. Riley brings a strong technical foundation to leadership in measurement solutions. An experienced entrepreneur, Riley has founded and grown multiple software companies, including a venture focused on developing iPhone applications, blending engineering expertise with innovative product development.