Data Flow
This diagram shows how data moves through the Multiflexmeter system.
%%{init: {'theme':'base', 'themeVariables': { 'fontSize':'16px'}}}%%
flowchart TB
subgraph PHYS["🌍 Physical Environment"]
MILL["🏛️ Mallemolen Mill
Temperature, Humidity, etc."]
end
subgraph SENSE["📡 Sensing Layer"]
SENSOR["🔍 I2C Sensor (0x36)
CMD: 0x10 (trigger)
CMD: 0x11 (read)"]
end
subgraph DEVICE["📟 Multiflexmeter Device"]
direction TB
subgraph FW["💻 Firmware Layer"]
direction LR
SINTF["📊 Sensor Interface
sensors.cpp"]
MAIN["🎛️ Main Controller
main.cpp"]
CONF["⚙️ Config Manager
rom_conf.cpp"]
end
subgraph HW["🔧 Hardware Layer"]
direction LR
I2CDRV["🔌 I2C Driver @ 80kHz
smbus.cpp"]
NETSTACK["📶 LoRaWAN Stack
LMIC Library"]
EEPROM["💾 EEPROM
41 bytes config"]
end
end
subgraph NET["☁️ Network Infrastructure"]
GW["📡 LoRaWAN Gateway
EU868 Band"]
TTN["🌐 The Things Network
OTAA Join / Downlink"]
end
subgraph BACK["💾 Backend Systems"]
direction TB
SERVER["💻 Backend Server
MQTT/HTTP Integration"]
DB[("🗄️ Database
Time Series Data")]
UI["📱 Web Interface
Visualization"]
end
%% Uplink Data Flow (Solid Lines)
MILL ==>|"Environmental
Changes"| SENSOR
SENSOR ==>|"I2C Raw Data
[bytes]"| I2CDRV
I2CDRV ==>|"Parsed Bytes"| SINTF
SINTF ==>|"Sensor Values"| MAIN
MAIN ==>|"LoRaWAN Payload
Port 1: Data
Port 2: Version"| NETSTACK
CONF <-.->|"Read/Write
DevEUI, AppKey
Interval"| EEPROM
NETSTACK ==>|"868MHz RF
SF7-SF12"| GW
GW ==>|"Internet
Forwarding"| TTN
TTN ==>|"JSON Payload
+ Metadata"| SERVER
SERVER ==>|"Store"| DB
DB ==>|"Query"| UI
%% Downlink Command Flow (Dashed Lines)
UI -.->|"User Commands"| SERVER
SERVER -.->|"Downlink Payload"| TTN
TTN -.->|"Scheduled
Downlink"| GW
GW -.->|"RX1/RX2
Window"| NETSTACK
NETSTACK -.->|"Decode"| MAIN
MAIN -.->|"0xDEAD: Reset
0x10: Interval
0x11: Sensor Cmd"| CONF
MAIN -.->|"Forward
Commands"| SINTF
SINTF -.->|"I2C Write"| I2CDRV
I2CDRV -.->|"Execute"| SENSOR
%% Styling
style PHYS fill:#d4edda,stroke:#28a745,stroke-width:3px
style SENSE fill:#cfe2ff,stroke:#084298,stroke-width:3px
style DEVICE fill:#fff3cd,stroke:#856404,stroke-width:3px
style NET fill:#e7f1ff,stroke:#004085,stroke-width:3px
style BACK fill:#f8d7da,stroke:#721c24,stroke-width:3px
style MILL fill:#a3e4d7,stroke:#196f3d,stroke-width:2px
style SENSOR fill:#aed6f1,stroke:#1f618d,stroke-width:2px
style I2CDRV fill:#fad7a0,stroke:#b9770e,stroke-width:2px
style SINTF fill:#fad7a0,stroke:#b9770e,stroke-width:2px
style MAIN fill:#fad7a0,stroke:#b9770e,stroke-width:2px
style CONF fill:#fad7a0,stroke:#b9770e,stroke-width:2px
style NETSTACK fill:#fad7a0,stroke:#b9770e,stroke-width:2px
style EEPROM fill:#d7bde2,stroke:#6c3483,stroke-width:2px
style GW fill:#aed6f1,stroke:#1f618d,stroke-width:2px
style TTN fill:#aed6f1,stroke:#1f618d,stroke-width:2px
style SERVER fill:#f5b7b1,stroke:#943126,stroke-width:2px
style DB fill:#f5b7b1,stroke:#943126,stroke-width:2px
style UI fill:#f5b7b1,stroke:#943126,stroke-width:2px
Data Format at Each Stage
Section titled “Data Format at Each Stage”1. Sensor → Device (I2C)
Section titled “1. Sensor → Device (I2C)”Command: 0x10 (trigger) → No responseCommand: 0x11 (read) → [length][byte1][byte2]...[byteN]2. Device → Network (LoRaWAN)
Section titled “2. Device → Network (LoRaWAN)”Port: 1 (sensor data)Payload: [sensor_data_bytes]
Port: 2 (version ping)Payload: [fw_version_msb][fw_version_lsb][hw_version_msb][hw_version_lsb]3. Network → Backend (IP)
Section titled “3. Network → Backend (IP)”{ "device_id": "...", "timestamp": "...", "payload": "base64_encoded_data", "port": 1, "rssi": -120, "snr": 5.2}4. Backend Commands → Device
Section titled “4. Backend Commands → Device”Reset: 0xDE 0xADSet Interval: 0x10 [interval_msb] [interval_lsb]Sensor Command: 0x11 [command_bytes...]Configuration Flow
Section titled “Configuration Flow”flowchart TD
Start([Device Boot]) --> Load[Load Settings from EEPROM]
Load --> Check{Valid Config?}
Check -->|No| Default[Use Default Settings]
Check -->|Yes| Use[Use Loaded Settings]
Default --> Run[Device Running]
Use --> Run
Run --> Receive{Downlink
Received?}
Receive -->|No| Run
Receive -->|Yes| Update[Update Setting]
Update --> Save[Save to EEPROM]
Save --> Apply[Apply New Setting]
Apply --> Run
style Load fill:#e1f5ff
style Save fill:#ffe1e1
style Apply fill:#e1ffe1
Settings Stored in EEPROM (41 bytes)
Section titled “Settings Stored in EEPROM (41 bytes)”| Offset | Size | Field | Description |
|---|---|---|---|
| 0-3 | 4 | MAGIC | ”MFM\0” identifier |
| 4-5 | 2 | HW_VERSION | Hardware version |
| 6-13 | 8 | APP_EUI | LoRaWAN Application EUI |
| 14-21 | 8 | DEV_EUI | LoRaWAN Device EUI |
| 22-37 | 16 | APP_KEY | LoRaWAN Application Key |
| 38-39 | 2 | INTERVAL | Measurement interval (seconds) |
| 40 | 1 | TTN_POLICY | Use TTN fair use policy |
All settings persist across resets and power cycles.