Connect Any 3V UART Device to the RM2.4 Industrial Wireless Network
Digital gages have always been the core of MobileCollect. Calipers, micrometers, indicators, height gages — if it has a Digimatic or compatible SPC output, MobileCollect has been connecting it to SPC software wirelessly for decades. But measurement data doesn’t only come from traditional gages. Production floors and lab environments are full of sensors, custom fixtures, and microcontroller-based test systems that generate measurement data — and historically, getting that data into an SPC or data collection system wirelessly required custom RF hardware, proprietary wireless modules, or manual entry.
OpenGage Mode changes that.
Introduced with the Mini Mobile Module EVO (M3E) on May 4, 2026, 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. No custom RF design. No proprietary data logger. No secondary wireless system to manage alongside your existing MobileCollect infrastructure.
If it speaks 3V UART at 9600-N-8-1, it speaks RM2.4.
For quality engineers, OpenGage Mode means non-standard measurement devices — sensors, custom fixtures, and test systems that don’t have a conventional gage connector — can now feed data into the same SPC software, MES, or ERP workflow as your traditional gages, with the same closed-loop per-reading confirmation and the same data integrity guarantees. For embedded and controls engineers, it means RM2.4 industrial wireless is accessible from any Arduino, ESP32, or UART-capable microcontroller without RF hardware design overhead.
OpenGage Mode operates on the M3E alongside all other MobileCollect transmitters on the same RM2.4 network. A standard digital gage M3E, a Command Mobile Module, and an M3E running OpenGage Mode can all pair to the same EVO Base Receiver simultaneously — feeding data from completely different device types into a single PC application or SPC software instance without additional hardware or configuration.
OpenGage Mode connects to any device that outputs data via UART at 9600-N-8-1 with 3V logic levels. This spans a wide range of device types across quality, embedded controls, and custom instrumentation applications.
Arduino and ESP32 boards are the most common rapid development platforms for custom measurement fixtures, EOL test systems, and industrial IoT prototypes. Both output 3V UART natively and communicate at 9600 baud with straightforward configuration. OpenGage Mode gives these platforms direct access to RM2.4 industrial wireless — meaning a custom Arduino-based measurement fixture built in days can transmit data wirelessly into SPC software on the same network as your production gage fleet, with no RF engineering required.
This is the entry point for embedded engineers who need industrial wireless capability without the overhead of designing and certifying custom radio hardware. The MC-M3E-UNIV-24 OpenGage UART Cable provides the physical interface between the development board and the M3E.
End-of-line test fixtures, automated inspection stations, and custom measurement systems built on microcontrollers represent one of the highest-value applications for OpenGage Mode. These fixtures are typically engineered in-house or by contract manufacturers to address specific measurement requirements — dimensional checks, electrical characterization, force or torque verification — that off-the-shelf gages don’t cover directly.
Historically, getting data out of these fixtures wirelessly required integrating a separate wireless module into the fixture design, with all the associated RF engineering, antenna design, and regulatory certification overhead. With OpenGage Mode, the M3E handles all of that. The fixture outputs its measurement result via UART, the M3E transmits it wirelessly over RM2.4, and the data arrives in the host application within a second of the read event — the same as any other MobileCollect gage.
For quality engineers, this means custom fixture data can now flow into the same SPC dataset as production gage data, supporting unified measurement system analysis and eliminating the parallel data collection processes that create audit gaps.
Torque measurement is a critical process control parameter in fastener assembly, valve and fitting installation, and any application governed by IATF 16949 process control requirements. Many digital torque gauges and bench-top torque transducers provide UART output as a standard or optional interface.
OpenGage Mode connects these instruments to RM2.4 wireless, enabling wireless torque data collection at the point of application without tethered cables that create ergonomic issues or create trip hazards in assembly environments. Torque readings transmit directly into SPC software for real-time process monitoring and Cpk tracking — supporting control plan requirements without manual transcription.
Temperature, humidity, and atmospheric pressure sensors are infrastructure monitoring devices explicitly addressed under ISO 9001 Clause 7.1.5 — the requirement that organizations determine and provide the monitoring and measuring resources necessary to ensure valid and reliable results. In calibration labs, metrology rooms, and climate-controlled storage areas, environmental conditions directly affect measurement uncertainty and must be documented.
UART-output environmental sensors connected via OpenGage Mode can transmit condition data wirelessly into the same data collection infrastructure used for dimensional measurement — eliminating the need for a separate environmental monitoring system and enabling correlated analysis between environmental conditions and measurement results.
Bench-top and fixture-mounted load cells with UART output cover tensile testing, compression testing, peel strength, and insertion/extraction force measurement applications. These are common in incoming inspection, product validation, and process qualification workflows across medical device, aerospace, and consumer electronics manufacturing.
OpenGage Mode enables wireless data collection from these instruments without modifying the fixture or routing signal cables to a data collection point — particularly valuable in test setups where the measurement point is inside an enclosure, at an ergonomically inconvenient location, or subject to vibration that makes cabled connections unreliable.
Pairing part identification with measurement data at the point of collection is a foundational traceability requirement under IATF 16949, AS9100, and 21 CFR Part 820. Barcode and RFID readers with UART output connected via OpenGage Mode can transmit part identifiers wirelessly into the same data collection session as the dimensional measurements taken on that part — enabling automated traceability linkage without operator manual entry of part numbers.
This is particularly relevant for first article inspection, receiving inspection, and any workflow where measurement records must be tied to a specific part serial number or lot identifier for downstream quality system use.
Inline process measurement devices — flow meters, level sensors, pressure transducers, and similar instruments with UART output — extend OpenGage Mode’s reach into process monitoring applications beyond traditional dimensional metrology. For manufacturers running SPC on process parameters alongside dimensional parameters, OpenGage Mode enables both data streams to flow through the same MobileCollect infrastructure into the same host application.
When a Mini Mobile Module EVO (M3E) is connected to a UART Host Device (Host), the M3E is waiting to receive data from Host via UART at 9600-N-8-1. Data Send events (Data packet sent from Host) can be initiated by either pushing the Read Button on the M3E or by the UART Host pulling the “Read Button” line low. The UART Host waits to receive the “Read Request” line low signal and then sends the Data Packet to M3E via UART @ 9600-N-8-1. The M3E will then send the Data Packet to a MobileCollect Base Receiver.
UART Host Device – Device sending data via UART
Receiving Device – MicroRidge MobileCollect Mini Mobile Module EVO (M3E)
If the Mini Mobile Module fails to get a reading from the UART Host Device it will perform one of two actions. A failed reading is most commonly caused by the absence of data being sent from the UART Host Device or a lack of an End of Packet Byte sent from the UART Host Device.
MC-M3E-UNIV-X is a four-conductor cable used to connect a UART Host Device to a Mini Mobile Module EVO. X represents length in inches. Ex. MC-M3E-UNIV-24 specifies a 24” long cable.
Wire Color | Signal | Direction | Description |
|---|---|---|---|
Green | Read Button | Output from M3E | Pull low (25–50 ms) to trigger a read event from the host device |
White | Read Request | Input to host device | M3E pulls low when ready to receive data; host sends data within 500 ms |
Black | UART Rx / Data | Input to M3E | Connect to TX on host device; UART 9600-N-8-1 |
Blue | Ground | Common | Shared ground between host device and M3E |
MC-M3E-UNIV-X can be used without the “Read Button” wire if desired. When configured without the “Read Button” wire connected, the reading must be initiated by pressing the Read Button on the Mini Mobile Module.
These examples demonstrate how to connect an Arduino to the Mini Mobile Module M3E using OpenGage Mode via the MC-M3E-UNIV-24 OpenGage UART Cable. Before running any example, ensure the M3E is configured in UART 9600-N-8-1 mode using the Xpress Setup Program or Extended Setup Program and paired with an EVO series MobileCollect Base Receiver.
In this configuration the Arduino waits passively for the operator to press the Read Button on the M3E. When pressed, the M3E pulls the Read Request line LOW, the Arduino sends its data packet, and the M3E transmits it wirelessly. No host-side triggering logic is required.
This is the simplest integration pattern and a good starting point for verifying your wiring and data packet format before adding automated triggering.
// ============================================================
// OpenGage Mode — Example 1: Manual Trigger
// MicroRidge MobileCollect Mini Mobile Module M3E
//
// The operator presses the Read Button on the M3E to
// initiate a read. The Arduino waits for the Read Request
// signal, then sends a data packet over UART.
//
// Wiring:
// Pin 2 (OUTPUT) → Green wire → Read Button on M3E
// Pin 3 (INPUT) → White wire → Read Request from M3E
// TX → Black wire → UART Data to M3E
// GND → Blue wire → Common Ground
// ============================================================
// ── Pin Definitions ──────────────────────────────────────────
#define READ_BUTTON_PIN 2 // OUTPUT: Pull LOW to trigger a read from Arduino side.
// In this example the operator uses the M3E button,
// so this pin idles HIGH and is not actively used.
#define READ_REQUEST_PIN 3 // INPUT: M3E pulls LOW when ready to receive data.
// ── Serial Port Configuration ────────────────────────────────
// Serial0 uses the hardware UART on pins TX=1, RX=0.
// Must match M3E OpenGage Mode setting: 9600-N-8-1.
#define UART_TX_PIN 1
#define UART_RX_PIN 0
// ── Timing ───────────────────────────────────────────────────
// Maximum time to wait for a Read Request signal after a read
// event is initiated. If no Read Request is received within
// this window, the loop resets and waits for the next event.
const unsigned long READ_REQUEST_TIMEOUT_MS = 500;
// ── Setup ────────────────────────────────────────────────────
void setup() {
// Initialize Serial0 at 9600 baud, 8 data bits, no parity,
// 1 stop bit — matches M3E UART 9600-N-8-1 mode exactly.
Serial0.begin(9600, SERIAL_8N1, UART_RX_PIN, UART_TX_PIN);
// Read Button pin: idle HIGH. The M3E Read Button line
// is active LOW — holding HIGH means "no trigger from Arduino."
pinMode(READ_BUTTON_PIN, OUTPUT);
digitalWrite(READ_BUTTON_PIN, HIGH);
// Read Request pin: INPUT_PULLUP keeps the line HIGH by default.
// The M3E pulls it LOW when it is ready to receive a packet.
pinMode(READ_REQUEST_PIN, INPUT_PULLUP);
}
// ── Main Loop ────────────────────────────────────────────────
void loop() {
// Wait indefinitely for the M3E to pull Read Request LOW.
// This happens when the operator presses the Read Button on
// the M3E housing.
if (digitalRead(READ_REQUEST_PIN) == LOW) {
// Read Request received — send data packet immediately.
// The M3E requires the packet within 500 ms of Read
// Request going LOW. Sending promptly is best practice.
// ── Build and Send Data Packet ───────────────────────────
// Replace the string below with your actual measurement
// value or sensor output. The packet must end with a
// Carriage Return \r (0x0D) as the End-of-Packet byte.
// Maximum packet length: 40 data bytes + 1 end-of-packet byte.
Serial0.write("Measurement: 5.2354\r");
// ── Minimum Gap Between Packets ──────────────────────────
// Wait at least 150 ms before the next read event to
// allow the M3E to complete its wireless transmission.
delay(150);
}
}
In this configuration the Arduino controls the read timing entirely. It pulls the Read Button line LOW to trigger a read event at a defined interval, waits for the M3E to pull Read Request LOW, then sends the data packet. No operator interaction is required — suitable for continuous monitoring, automated inspection fixtures, and any application requiring timed or event-driven data capture.
// ============================================================
// OpenGage Mode — Example 2: Automatic Trigger
// MicroRidge MobileCollect Mini Mobile Module M3E
//
// The Arduino initiates read events automatically at a defined
// interval by pulling the Read Button line LOW. The M3E
// responds with a Read Request signal, and the Arduino sends
// its data packet over UART.
//
// Wiring:
// Pin 2 (OUTPUT) → Green wire → Read Button on M3E
// Pin 3 (INPUT) → White wire → Read Request from M3E
// TX → Black wire → UART Data to M3E
// GND → Blue wire → Common Ground
// ============================================================
// ── Pin Definitions ──────────────────────────────────────────
#define READ_BUTTON_PIN 2 // OUTPUT: Pull LOW for 25–50 ms to trigger a read.
#define READ_REQUEST_PIN 3 // INPUT: M3E pulls LOW when ready to receive data.
// ── Serial Port Configuration ────────────────────────────────
#define UART_TX_PIN 1
#define UART_RX_PIN 0
// ── Timing ───────────────────────────────────────────────────
// How often the Arduino triggers a read (milliseconds).
// Set this to match your required sampling rate.
// Note: keep this above 150 ms minimum to satisfy the M3E
// minimum gap requirement between data packets.
const unsigned long READ_INTERVAL_MS = 1500;
// Read Button pulse duration. Must be 25–50 ms per M3E spec.
const unsigned long READ_BUTTON_PULSE_MS = 25;
// Maximum time to wait for Read Request LOW after triggering.
// If the M3E does not respond within this window, the
// trigger attempt is abandoned and the next interval begins.
const unsigned long READ_REQUEST_TIMEOUT_MS = 500;
// ── Timing State ─────────────────────────────────────────────
unsigned long lastReadTime = 0; // Timestamp of the last completed read event.
// ── Setup ────────────────────────────────────────────────────
void setup() {
Serial0.begin(9600, SERIAL_8N1, UART_RX_PIN, UART_TX_PIN);
// Read Button idles HIGH — M3E interprets LOW as a trigger.
pinMode(READ_BUTTON_PIN, OUTPUT);
digitalWrite(READ_BUTTON_PIN, HIGH);
// Read Request idles HIGH via internal pullup.
// M3E pulls it LOW when ready to receive.
pinMode(READ_REQUEST_PIN, INPUT_PULLUP);
}
// ── Main Loop ────────────────────────────────────────────────
void loop() {
unsigned long currentTime = millis();
// Check if the read interval has elapsed since the last event.
if (currentTime - lastReadTime >= READ_INTERVAL_MS) {
// ── Trigger Read Event ───────────────────────────────────
// Pull Read Button LOW for the required pulse duration,
// then release it HIGH to signal the M3E.
digitalWrite(READ_BUTTON_PIN, LOW);
delay(READ_BUTTON_PULSE_MS); // Hold LOW for 25 ms (within 25–50 ms spec)
digitalWrite(READ_BUTTON_PIN, HIGH); // Release — M3E will now pull Read Request LOW
// ── Wait for Read Request ────────────────────────────────
// Poll Read Request pin. The M3E pulls it LOW to signal
// it is ready to receive the data packet. If no signal is
// received within the timeout window, skip this cycle.
unsigned long waitStart = millis();
bool readRequestReceived = false;
while (millis() - waitStart < READ_REQUEST_TIMEOUT_MS) {
if (digitalRead(READ_REQUEST_PIN) == LOW) {
readRequestReceived = true;
break;
}
}
// ── Send Data Packet ─────────────────────────────────────
if (readRequestReceived) {
// Read Request confirmed — send data packet immediately.
// Replace this string with your actual measurement value.
// Packet must end with \r (Carriage Return, 0x0D).
Serial0.write("Measurement: 5.2354\r");
// Record the time of this successful read event.
lastReadTime = millis();
// Observe the 150 ms minimum gap before the next packet.
delay(150);
} else {
// No Read Request received within the timeout window.
// M3E may be out of range or not yet paired.
// Update lastReadTime to prevent rapid retry loops.
lastReadTime = millis();
}
}
}
OpenGage Mode supports an optional unit suffix in the data packet that the M3E passes through to the Base Receiver and host application. This example demonstrates how to send a floating-point measurement value with a unit designation using the two-byte unit prefix sequence required by the M3E packet format.
This example uses the automatic trigger pattern from Example 2 and adds structured measurement data with units.
// ============================================================
// OpenGage Mode — Example 3: Measurement Data with Units
// MicroRidge MobileCollect Mini Mobile Module M3E
//
// Demonstrates sending a formatted measurement value with a
// unit suffix. The M3E passes the unit through to the
// Base Receiver and host application.
//
// Unit packet format (append before End-of-Packet byte):
// 0xFF 0xE0 [unit character]
//
// Supported unit characters:
// I = inch M = mm N = meter F = foot
// D = degree G = gram L = pound H = kilogram
//
// Wiring:
// Pin 2 (OUTPUT) → Green wire → Read Button on M3E
// Pin 3 (INPUT) → White wire → Read Request from M3E
// TX → Black wire → UART Data to M3E
// GND → Blue wire → Common Ground
// ============================================================
// ── Pin Definitions ──────────────────────────────────────────
#define READ_BUTTON_PIN 2
#define READ_REQUEST_PIN 3
// ── Serial Port Configuration ────────────────────────────────
#define UART_TX_PIN 1
#define UART_RX_PIN 0
// ── Unit Byte Constants ───────────────────────────────────────
// These two bytes precede the unit character in the packet.
// Required by the M3E to identify the unit suffix.
#define UNIT_PREFIX_1 0xFF // Decimal 255
#define UNIT_PREFIX_2 0xE0 // Decimal 224
// Unit characters — use one of these after the prefix bytes.
#define UNIT_INCH 'I'
#define UNIT_MM 'M'
#define UNIT_METER 'N'
#define UNIT_FOOT 'F'
#define UNIT_DEGREE 'D'
#define UNIT_GRAM 'G'
#define UNIT_POUND 'L'
#define UNIT_KILOGRAM 'H'
// ── End-of-Packet Byte ───────────────────────────────────────
// Carriage Return (0x0D) is required to terminate every packet.
#define END_OF_PACKET 0x0D
// ── Timing ───────────────────────────────────────────────────
const unsigned long READ_INTERVAL_MS = 1500;
const unsigned long READ_BUTTON_PULSE_MS = 25;
const unsigned long READ_REQUEST_TIMEOUT_MS = 500;
// ── Timing State ─────────────────────────────────────────────
unsigned long lastReadTime = 0;
// ── Setup ────────────────────────────────────────────────────
void setup() {
Serial0.begin(9600, SERIAL_8N1, UART_RX_PIN, UART_TX_PIN);
pinMode(READ_BUTTON_PIN, OUTPUT);
digitalWrite(READ_BUTTON_PIN, HIGH);
pinMode(READ_REQUEST_PIN, INPUT_PULLUP);
}
// ── sendMeasurement() ────────────────────────────────────────
// Sends a floating-point measurement value with a unit suffix
// over UART in the M3E OpenGage Mode packet format.
//
// Parameters:
// value — the measurement value as a float
// unitChar — one of the unit character constants defined above
//
// Packet structure:
// [ASCII value string] [0xFF] [0xE0] [unit char] [0x0D]
//
// Example output bytes for 9.2015 inches:
// '9' '.' '2' '0' '1' '5' 0xFF 0xE0 'I' 0x0D
// ─────────────────────────────────────────────────────────────
void sendMeasurement(float value, char unitChar) {
// Convert float to ASCII string.
// dtostrf(value, width, decimal places, buffer)
// Width 8, 4 decimal places — adjust to match your precision.
char valueStr[16];
dtostrf(value, 8, 4, valueStr);
// Send the ASCII measurement string (trimmed of leading spaces).
Serial0.print(String(value, 4));
// Send the two-byte unit prefix followed by the unit character.
Serial0.write(UNIT_PREFIX_1); // 0xFF
Serial0.write(UNIT_PREFIX_2); // 0xE0
Serial0.write(unitChar); // e.g. 'I' for inch
// Send the End-of-Packet byte — required to terminate the packet.
Serial0.write(END_OF_PACKET); // 0x0D (Carriage Return)
}
// ── Main Loop ────────────────────────────────────────────────
void loop() {
unsigned long currentTime = millis();
if (currentTime - lastReadTime >= READ_INTERVAL_MS) {
// ── Trigger Read Event ───────────────────────────────────
digitalWrite(READ_BUTTON_PIN, LOW);
delay(READ_BUTTON_PULSE_MS);
digitalWrite(READ_BUTTON_PIN, HIGH);
// ── Wait for Read Request ────────────────────────────────
unsigned long waitStart = millis();
bool readRequestReceived = false;
while (millis() - waitStart < READ_REQUEST_TIMEOUT_MS) {
if (digitalRead(READ_REQUEST_PIN) == LOW) {
readRequestReceived = true;
break;
}
}
// ── Send Measurement with Units ──────────────────────────
if (readRequestReceived) {
// Replace this value with your actual sensor reading.
// Replace UNIT_INCH with the appropriate unit constant
// for your measurement type.
float measurement = 9.2015;
sendMeasurement(measurement, UNIT_INCH);
// Example — sending a temperature in degrees:
// sendMeasurement(72.4, UNIT_DEGREE);
// Example — sending a weight in grams:
// sendMeasurement(142.75, UNIT_GRAM);
lastReadTime = millis();
delay(150); // Observe 150 ms minimum gap between packets.
} else {
lastReadTime = millis();
}
}
}
In this configuration the Arduino triggers reads automatically at a defined interval, but the operator can also initiate a read at any time by pressing the Read Button on the M3E. Both trigger paths converge on the same Read Request detection and send logic — the packet format is identical regardless of how the read was initiated. Whichever fires first resets the interval timer, preventing a duplicate auto-trigger immediately after a manual read.
This is the recommended pattern for production deployments where automated data capture is the primary mode but operators need the ability to take an out-of-cycle reading without interrupting the system.
// ============================================================
// OpenGage Mode — Example 4: Dual Trigger
// MicroRidge MobileCollect Mini Mobile Module M3E
//
// Supports two read trigger sources simultaneously:
// 1. Automatic — Arduino pulls Read Button LOW on a defined
// interval, no operator input required.
// 2. Manual — Operator presses the Read Button on the M3E
// at any time, regardless of the auto-trigger interval.
//
// Both paths share the same Read Request detection and send
// logic. Whichever fires first resets the interval timer,
// preventing a duplicate auto-trigger after a manual read.
//
// Wiring:
// Pin 2 (OUTPUT) → Green wire → Read Button on M3E
// Pin 3 (INPUT) → White wire → Read Request from M3E
// TX → Black wire → UART Data to M3E
// GND → Blue wire → Common Ground
// ============================================================
// ── Pin Definitions ──────────────────────────────────────────
#define READ_BUTTON_PIN 2 // OUTPUT: Pull LOW for 25–50 ms to auto-trigger a read.
#define READ_REQUEST_PIN 3 // INPUT: M3E pulls LOW when ready to receive data.
// Goes LOW from EITHER trigger source —
// auto-trigger OR operator button press.
// ── Serial Port Configuration ────────────────────────────────
#define UART_TX_PIN 1
#define UART_RX_PIN 0
// ── Timing ───────────────────────────────────────────────────
// Auto-trigger interval (milliseconds). The Arduino will
// initiate a read automatically every READ_INTERVAL_MS.
// Keep above 150 ms minimum to satisfy the M3E packet gap.
const unsigned long READ_INTERVAL_MS = 1500;
// Read Button pulse duration. Must be 25–50 ms per M3E spec.
const unsigned long READ_BUTTON_PULSE_MS = 25;
// Maximum time to wait for Read Request LOW after an
// auto-trigger. If no response, abandon and try next cycle.
const unsigned long READ_REQUEST_TIMEOUT_MS = 500;
// ── Timing State ─────────────────────────────────────────────
unsigned long lastReadTime = 0; // Timestamp of last completed read (auto or manual).
// ── Setup ────────────────────────────────────────────────────
void setup() {
Serial0.begin(9600, SERIAL_8N1, UART_RX_PIN, UART_TX_PIN);
// Read Button idles HIGH — M3E interprets LOW as a trigger.
pinMode(READ_BUTTON_PIN, OUTPUT);
digitalWrite(READ_BUTTON_PIN, HIGH);
// Read Request idles HIGH via internal pullup.
// Goes LOW from either trigger source.
pinMode(READ_REQUEST_PIN, INPUT_PULLUP);
}
// ── sendPacket() ─────────────────────────────────────────────
// Shared send function called by both trigger paths.
// Replace the string with your actual measurement value.
// Packet must end with \r (Carriage Return, 0x0D).
// ─────────────────────────────────────────────────────────────
void sendPacket() {
Serial0.write("Measurement: 5.2354\r");
}
// ── Main Loop ────────────────────────────────────────────────
void loop() {
unsigned long currentTime = millis();
// ── Path 1: Auto-Trigger ─────────────────────────────────
// Check if the auto-trigger interval has elapsed.
// If so, pull Read Button LOW to initiate a read event,
// then wait for Read Request LOW before sending.
if (currentTime - lastReadTime >= READ_INTERVAL_MS) {
// Pull Read Button LOW for the required pulse duration.
digitalWrite(READ_BUTTON_PIN, LOW);
delay(READ_BUTTON_PULSE_MS); // Hold LOW 25 ms (within 25–50 ms spec)
digitalWrite(READ_BUTTON_PIN, HIGH); // Release — M3E will pull Read Request LOW
// Wait for Read Request LOW with timeout.
unsigned long waitStart = millis();
while (millis() - waitStart < READ_REQUEST_TIMEOUT_MS) {
if (digitalRead(READ_REQUEST_PIN) == LOW) {
sendPacket(); // Send data packet immediately on Read Request
lastReadTime = millis(); // Reset interval timer
delay(150); // Observe 150 ms minimum gap between packets
break;
}
}
// If no Read Request received within timeout, update
// lastReadTime to prevent an immediate retry next loop.
if (millis() - lastReadTime > READ_REQUEST_TIMEOUT_MS) {
lastReadTime = millis();
}
}
// ── Path 2: Manual Trigger ───────────────────────────────
// Poll Read Request continuously between auto-trigger events.
// If the operator presses the Read Button on the M3E housing,
// the M3E pulls Read Request LOW independently of the Arduino.
// Detect it here and send immediately — no Arduino-side
// trigger pulse required for operator-initiated reads.
else if (digitalRead(READ_REQUEST_PIN) == LOW) {
sendPacket(); // Send data packet immediately
lastReadTime = millis(); // Reset interval timer — prevents duplicate
// auto-trigger firing right after manual read
delay(150); // Observe 150 ms minimum gap between packets
}
}
OpenGage Mode is a fundamental expansion of what MobileCollect can connect to. For over four decades, MicroRidge has built the MobileCollect platform around one principle: measurement data should move from the point of collection to the host application automatically, accurately, and without operator intervention. OpenGage Mode extends that principle beyond the gage bench — to custom fixtures, sensors, microcontroller platforms, and any UART-capable measurement device operating on the production floor or in the lab.
For quality engineers, it means non-standard measurement devices can now participate in the same SPC workflow as your traditional gage fleet — with the same data integrity, the same closed-loop confirmation, and the same RM2.4 reliability that MobileCollect is built on. For embedded and controls engineers, it means industrial wireless is one cable and one configuration step away from any device that speaks 3V UART, with no RF design overhead and no secondary wireless infrastructure to manage.
The Mini Mobile Module EVO (M3E) with OpenGage Mode is available now with the MC-M3E-UNIV-24 as the dedicated connection cable for getting started.
If you have questions about whether OpenGage Mode is the right fit for your application, need help with wiring or data packet configuration, or want to discuss integrating the M3E into an existing MobileCollect system, reach out directly — we’re happy to help.
sales@microridge.com | 541-593-1656
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.