CompuLab IOT-DIN-IMX8PLUS
The CompuLab IOT-DIN-IMX8PLUS is a modular DIN rail-mounted industrial computer designed for edge computing and real-time control. Powered by an NXP i.MX8M Plus quad-core ARM Cortex-A53 processor, it offers high computing performance alongside industrial interfaces and modular expansion options.
In Adapnex, the device target compulab_iotdin_imx8p provides native drivers for the onboard digital I/O lines and frontplane analog expansion modules.
Built-in Digital I/O
The onboard digital I/O interface is managed by the DIODriver class. The driver interfaces directly with the Linux GPIO subsystem to provide fast, deterministic digital input sampling and output driving.
The driver exposes four fixed digital channels:
| Channel | Direction | Type | Driver Mapping |
|---|---|---|---|
|
Input |
Digital Input (GPIOD) |
|
|
Input |
Digital Input (GPIOD) |
|
|
Output |
Digital Output (GPIOD) |
|
|
Output |
Digital Output (GPIOD) |
|
Input signals evaluate to true when energized and propagate to mapped variables during the pre-update phase. Output signals are committed to physical pins during the post-update phase:
// Bind digital lines to task variables
dio_driver->DI0 >> controller->safety_interlock;
dio_driver->DO0 << controller->status_beacon;
Analog Expansion Module (IFM-ADC8)
The CompuLab IOT-DIN supports modular frontplane expansion cards. The IFM-ADC8 card provides 8 channels of 12-bit analog voltage inputs (0 to 10 V DC).
In Adapnex, the ADC8Driver class interfaces with the Linux Industrial I/O (IIO) subsystem to sample all 8 channels cyclically.
Slot Addressing
Expansion cards are stacked onto the side of the unit in order. The ADC8Driver constructor takes a letter identifying the card stacking position, where "A" represents the first card, "B" represents the second, and so on:
// Instantiate the ADC8 driver for the card at position "A"
const auto adc_driver = group->CreateTask<ADC8Driver>("A");
If no module is present at the specified position, the driver throws std::runtime_error during construction.
Channel Mapping and Voltage Scaling
The driver automatically scales raw 11-bit ADC counts (0 to 2047) to physical voltages between 0.0f and 10.0f volts. Channels I0 through I7 deliver floating-point values directly in volts:
| Channel | Type | Range | Driver Mapping |
|---|---|---|---|
|
Analog Input (IIO) |
0.0 to 10.0 V DC |
|
You can connect analog channels directly to task variables using the stream operator:
// Map analog channels 0 and 1 to sensor variables in the task
adc_driver->I0 >> controller->tank_level_voltage;
adc_driver->I1 >> controller->line_pressure_voltage;
Full Example: Industrial Monitoring Station
The following complete application initializes the built-in digital I/O lines alongside an IFM-ADC8 analog card in slot "A". The application reads a tank level sensor on I0, checks a safety gate on DI0, and activates an alarm beacon on DO0:
#include "adapnex.h"
class StationMonitor final : public Task {
public:
// Process inputs
float tank_voltage = 0.0f;
bool safety_ok = false;
// Process outputs
bool alarm_beacon = false;
bool pump_enable = false;
void Update() override {
// High liquid level threshold is 8.5V
const bool level_exceeded = tank_voltage > 8.5f;
if (!safety_ok || level_exceeded) {
pump_enable = false;
alarm_beacon = true;
} else {
pump_enable = true;
alarm_beacon = false;
}
}
};
void setup() {
const auto group = Application::CreateCyclicTaskGroup({.period = 25ms});
// 1. Register hardware drivers first
const auto dio_driver = group->CreateTask<DIODriver>();
const auto adc_driver = group->CreateTask<ADC8Driver>("A");
// 2. Register application task
const auto monitor = group->CreateTask<StationMonitor>();
// 3. Connect hardware channels to task variables
dio_driver->DI0 >> monitor->safety_ok;
adc_driver->I0 >> monitor->tank_voltage;
dio_driver->DO0 << monitor->alarm_beacon;
dio_driver->DO1 << monitor->pump_enable;
}