66CPU Freq (MHz)
256Flash (KB)
3PWM Channels
500CAN Speed (kbps)
MicrocontrollerAtmel AVR32 UC3C1512 · 32-bit ARM core @ 66 MHz
Memory256 KB Flash · 64 KB SRAM · 4 KB EEPROM
RTOSFreeRTOS 10.2 with 4 priority levels (Kernel, Control, Monitor, Idle)
ADC Channels12-bit SAR ADC · 3 active inputs (Pressure, Temperature, Flow)
PWM Modules3 TC (Timer/Counter) channels @ 16-bit precision · 1 kHz base frequency
CommunicationCAN 2.0B · CANopen DS301/DS305 with 4 TPDOs + 2 RPDOs
Safety FeaturesWatchdog Timer (WDT) · Brown-out Detection · Dual ADC measurements
System Architecture
The aerosol module controller implements a multi-threaded real-time control system on the Atmel AVR32 microcontroller. The firmware is structured into independent FreeRTOS tasks handling sensor acquisition, control algorithms, communication, and safety monitoring. Each task runs at its own priority level with deterministic timing guarantees.
Hardware Interface Layer
ADC Sensor Acquisition
Reads analog sensor inputs for chamber pressure, temperature, and flow rate measurements.
void adc_init(void)
- Configures 12-bit SAR ADC
- Sets channel 0–2 for pressure/temp/flow
- Selects internal 2.5V reference
- Enables differential mode for noise rejection
uint16_t adc_read_pressure(void)
Samples chamber pressure from ADC channel 0. Returns 12-bit raw value (0–4095 maps to 0–200 kPa).
// Reads ADC0, applies 1st-order IIR filter
// 16x oversampling for noise reduction
// Returns: Filtered pressure in 0.05 kPa resolution
uint16_t adc_read_temperature(void)
Acquires chamber temperature from thermistor input on ADC channel 1. Applies linearization correction for NTC thermistor.
// Reads ADC1 (NTC thermistor divider)
// Applies Steinhart-Hart equation linearization
// Returns: Temperature in 0.1°C resolution (0–134°C)
uint8_t adc_read_flow_sensor(void)
Monitors aerosol flow rate from turbine sensor. Counts pulses and converts to flow percentage.
// Reads ADC2 frequency from turbine sensor
// Pulse counting over 100 ms window
// Returns: Flow rate as 0–100% (proportional to Hz)
PWM Actuation & Control
void pwm_init(void)
Initializes three PWM outputs for fog pump, flow control valve, and heater element. Configures 16-bit timer/counters at 1 kHz base frequency.
// TC0 (Timer 0): Fog pump motor – Duty cycle 0–100%
// TC1 (Timer 1): Proportional valve – Duty cycle 0–100%
// TC2 (Timer 2): Heater resistor – Duty cycle 0–100%
// All channels use center-aligned PWM for smooth control
void pwm_set_fog_pump(uint8_t duty_percent)
Sets fog pump motor PWM duty cycle to regulate aerosol concentration. Accepts 0–100% input with 1% resolution.
// Maps duty (0–100) to TC0 compare register
// Applies rate limiting: max ΔDuty = 5% per cycle
// Prevents motor inrush current
// Input: duty_percent (0=off, 100=full)
void pwm_set_flow_valve(uint8_t duty_percent)
Modulates proportional flow control valve. Duty cycle controls aerosol delivery speed into chamber (0–100%).
// Maps duty (0–100) to TC1 compare register
// Dead-band compensation: min 15% to overcome static friction
// Hysteresis band: ±2% to prevent chatter
// Input: duty_percent (0=closed, 100=full open)
void pwm_set_heater(uint8_t duty_percent)
Controls heating element for chamber temperature regulation. Uses Pulse-Width Modulation to limit peak power draw.
// Maps duty (0–100) to TC2 compare register
// Frequency: 1 kHz (heater thermal time constant >> 1 ms)
// Soft-start ramp: 20 ms to reach commanded duty
// Safety limit: Max 100°C setpoint with 135°C hard limit
Control Algorithms
void fog_concentration_control(uint8_t target_percent)
Implements fog concentration feedback controller. Closes loop on pump speed to achieve target aerosol density in chamber.
// Algorithm: PI controller on pump duty cycle
// Setpoint: target_percent (0–100%)
// Feedback: Flow sensor (ADC2)
// Kp = 0.8, Ki = 0.15 (tuned for 200 ms response)
// Output: Fog pump PWM duty 0–100%
void temperature_control(uint8_t target_celsius)
Temperature regulation using proportional heater control. Maintains chamber temperature within ±2°C of target setpoint.
// Algorithm: PI control on heater duty
// Setpoint: target_celsius (0–134°C)
// Feedback: NTC thermistor (ADC1, linearized)
// Kp = 1.2, Ki = 0.08 (thermal time constant ~2 sec)
// Output: Heater PWM duty 0–100%
// Safety: Hard cutoff at 135°C via overshoot protection
void pressure_control(uint8_t target_kpa)
Chamber pressure regulation via proportional valve. Maintains differential pressure for efficient aerosol delivery.
// Algorithm: PI feedback control
// Setpoint: target_kpa (0–200 kPa)
// Feedback: Piezoresistive sensor (ADC0)
// Kp = 0.6, Ki = 0.12 (response time ~300 ms)
// Output: Flow valve PWM duty 0–100%
// Interlock: Disabled if pump not running (pump_duty < 10%)
Real-time Task Scheduler
/* FreeRTOS Task Definitions */
// Task 1: Sensor Acquisition (50 ms period, Priority=2)
void vTaskSensorMonitor(void *pvParameters) {
while (1) {
uint16_t raw_pressure = adc_read_pressure();
uint16_t raw_temp = adc_read_temperature();
uint8_t raw_flow = adc_read_flow_sensor();
// Update global control state
g_sensor_state.pressure_kpa = (raw_pressure / 4095.0f) * 200.0f;
g_sensor_state.temp_celsius = (raw_temp / 4095.0f) * 134.0f;
g_sensor_state.flow_percent = raw_flow;
// Safety checks
if (g_sensor_state.pressure_kpa > 220) {
gpio_set_high(GPIO_SAFETY_SHUTDOWN); // Emergency stop
}
vTaskDelay(pdMS_TO_TICKS(50));
}
}
// Task 2: Control Loop (100 ms period, Priority=3)
void vTaskControlLoop(void *pvParameters) {
while (1) {
fog_concentration_control(g_setpoint.fog_percent);
temperature_control(g_setpoint.temp_celsius);
pressure_control(g_setpoint.pressure_kpa);
vTaskDelay(pdMS_TO_TICKS(100));
}
}
// Task 3: CANopen Communication (50 ms period, Priority=2)
void vTaskCANopen(void *pvParameters) {
while (1) {
// Transmit TPDO (Telemetry)
can_send_tpdo1(g_sensor_state);
// Process RPDO (Commands)
canopen_rpdo_handler();
vTaskDelay(pdMS_TO_TICKS(50));
}
}
// Task 4: Safety Monitor (20 ms period, Priority=1 - Highest)
void vTaskSafetyMonitor(void *pvParameters) {
while (1) {
// Watchdog kick
wdt_reload();
// Fault detection
if (g_sensor_state.pressure_kpa < 50) {
fault_handler(FAULT_LOW_PRESSURE);
}
if (g_sensor_state.temp_celsius > 140) {
fault_handler(FAULT_OVERTEMP);
}
vTaskDelay(pdMS_TO_TICKS(20));
}
}
CANopen Communication Protocol
The firmware implements CANopen DS301 protocol for integration with the sterilizer control system. Telemetry (TPDO) transmits sensor measurements every 50 ms, while command reception (RPDO) updates setpoints from the main controller.
TPDO1 (TX 0x181)SoC: 87.3% | Pressure: 120 kPa | Temp: 95°C | Flow: 75%
RPDO1 (RX 0x201)Fog Target: 75% | Pressure Target: 120 kPa | Temp Target: 95°C
RPDO2 (RX 0x301)Cycle Duration: 60 min | Mode: Running | Safety Enable: 1
Cycle Time50 ms (20 Hz message rate, non-blocking async CAN ISR)
Safety & Fault Handling
- Watchdog Timer (WDT) — 1.5 second timeout with mandatory reload from highest-priority task. Guards against firmware lockup.
- Dual Sensor Redundancy — Pressure measured via two independent paths (direct + monitor line). Discrepancy triggers safe shutdown.
- Temperature Overshoot Protection — Heater cutoff at 135°C with 10-second cooldown before re-enable.
- Pressure Interlock — Flow valve disabled if pump duty < 10% to prevent cavitation.
- Brown-out Detection — BOD at 2.7V triggers controlled shutdown sequence to prevent Flash corruption.
- CAN Error Handling — Missing RPDO command for >500 ms triggers safe default state (all actuators to 0%).
Development Environment & Tools
- Compiler — Atmel Studio 7 with GCC ARM Embedded toolchain (arm-none-eabi-gcc 8.3.1)
- Hardware Debugger — JTAGICE3 (on-chip debugging, real-time trace)
- Simulation — QEMU AVR32 simulator for pre-hardware validation
- Code Analysis — Splint static analyzer + MISRA-C 2012 compliance checks
- Testing — Unity framework for unit tests; HIL with National Instruments PXI chassis
Memory Layout & Resource Allocation
// AVR32 UC3C Flash Allocation (256 KB)
0x00000000 — 0x00003FFF : Bootloader (16 KB)
0x00004000 — 0x0003FFFF : Application code + Data (228 KB)
0x00040000 — 0x00040FFF : EEPROM emulation (4 KB, wear-leveling)
// SRAM Allocation (64 KB)
0x20000000 — 0x2000FFFF : FreeRTOS heap + task stacks (20 KB)
0x20005000 — 0x200057FF : CAN message buffers (2 KB)
0x20006000 — 0x200067FF : ADC sample buffer (2 KB)
0x20007000 — 0x20007FFF : Persistent state storage (4 KB)
Performance Metrics & Timing Analysis
Sensor-to-Control Latency~15 ms (ADC acquisition + task switch)
Control Loop Update Rate100 Hz (10 ms period, jitter <1 ms)
CAN Message Latency~5 ms from sensor read to CAN transmission
Firmware Size~45 KB (compiled, with optimizations)
CPU Utilization~25% average (leaves 75% headroom for diagnostics)
Power Consumption~120 mW @ 66 MHz (typical operation)
← All Projects