Skip to content

Commit d432df0

Browse files
sbasu107cursoragent
andcommitted
Fix Mermaid diagram syntax for GitHub rendering.
Use quoted labels with br tags instead of backslash-n, remove curly braces from node text, and simplify multi-target edges. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent f1e6ea9 commit d432df0

1 file changed

Lines changed: 33 additions & 88 deletions

File tree

README.md

Lines changed: 33 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ If you are new to embedded telemetry, start here:
2424

2525
```mermaid
2626
flowchart LR
27-
CAN[CAN bus\n(sensor messages)] --> Daemon[can_telem\n(decode & route)]
28-
Daemon --> USB[USB drive\n(spreadsheet logs)]
29-
Daemon --> Cloud[InfluxDB Cloud]
30-
Daemon --> Radio[Serial radio\n(wireless stream)]
27+
CAN["CAN bus<br/>(sensor messages)"] --> Daemon["can_telem<br/>(decode and route)"]
28+
Daemon --> USB["USB drive<br/>(spreadsheet logs)"]
29+
Daemon --> Cloud["InfluxDB Cloud"]
30+
Daemon --> Radio["Serial radio<br/>(wireless stream)"]
3131
```
3232

3333
| Piece | Role |
@@ -48,35 +48,46 @@ flowchart TD
4848
CLIFlags[/"CLI flags"/]
4949
Token[/"INFLUX_TOKEN"/]
5050
51-
ConfFile & CLIFlags & Token --> ParseConfig[Parse config & credentials]
51+
ConfFile --> ParseConfig
52+
CLIFlags --> ParseConfig
53+
Token --> ParseConfig
54+
ParseConfig["Parse config and credentials"]
5255
5356
subgraph Startup
54-
ParseConfig --> LoadFormat[Load format.json\n→ signal hash table]
55-
ParseConfig --> OpenCAN[Open SocketCAN\ne.g. can0]
56-
ParseConfig --> InitCSV[Init CSV writer\n→ /mnt/usb/{DD-Mon-YYYY}/]
57-
ParseConfig --> InitInflux[Init InfluxDB\n→ libcurl]
58-
ParseConfig --> InitRadio[Init serial radio\n→ /dev/ttyAMA0 or ttyUSB0]
57+
ParseConfig --> LoadFormat["Load format.json<br/>signal hash table"]
58+
ParseConfig --> OpenCAN["Open SocketCAN<br/>e.g. can0"]
59+
ParseConfig --> InitCSV["Init CSV writer<br/>/mnt/usb/DD-Mon-YYYY/"]
60+
ParseConfig --> InitInflux["Init InfluxDB<br/>libcurl"]
61+
ParseConfig --> InitRadio["Init serial radio<br/>ttyAMA0 or ttyUSB0"]
5962
end
6063
61-
LoadFormat & OpenCAN & InitCSV & InitInflux & InitRadio --> PollLoop
64+
LoadFormat --> PollLoop
65+
OpenCAN --> PollLoop
66+
InitCSV --> PollLoop
67+
InitInflux --> PollLoop
68+
InitRadio --> PollLoop
6269
6370
subgraph Runtime [Runtime Loop]
64-
PollLoop[poll 200ms timeout]
71+
PollLoop["poll 200ms timeout"]
6572
6673
PollLoop -->|CAN frame arrives| Decode[decoder_extract]
67-
Decode --> Lookup[Lookup CAN ID in hash table\n→ signal_def_t list\none frame can carry N signals]
74+
Decode --> Lookup["Lookup CAN ID<br/>decode signals"]
6875
69-
Lookup --> Writer[writer_append\nupdate in-memory snapshot]
70-
Lookup --> InfluxAcc[influx_accumulate\nbatched mean]
71-
Lookup --> RadioAcc[serial_radio_accumulate\nlast value]
76+
Lookup --> Writer["writer_append<br/>update snapshot"]
77+
Lookup --> InfluxAcc["influx_accumulate<br/>batched mean"]
78+
Lookup --> RadioAcc["serial_radio_accumulate<br/>last value"]
7279
73-
Writer & InfluxAcc & RadioAcc --> PollLoop
80+
Writer --> PollLoop
81+
InfluxAcc --> PollLoop
82+
RadioAcc --> PollLoop
7483
75-
PollLoop -->|timer expires| WriterTick[writer_tick\nFlush wide CSV row\nevery 500 ms]
76-
PollLoop -->|timer expires| InfluxTick[influx_tick\nFlush batch → InfluxDB Cloud]
77-
PollLoop -->|timer expires| RadioTick[serial_radio_tick\nFlush latest values → UART\nFormat: ts_ns,signal,value]
84+
PollLoop -->|timer expires| WriterTick["writer_tick<br/>flush wide CSV"]
85+
PollLoop -->|timer expires| InfluxTick["influx_tick<br/>upload to InfluxDB"]
86+
PollLoop -->|timer expires| RadioTick["serial_radio_tick<br/>flush to UART"]
7887
79-
WriterTick & InfluxTick & RadioTick --> PollLoop
88+
WriterTick --> PollLoop
89+
InfluxTick --> PollLoop
90+
RadioTick --> PollLoop
8091
end
8192
```
8293

@@ -146,65 +157,6 @@ ip route show default
146157
curl -s -o /dev/null -w "%{http_code}\n" https://us-east-1-1.aws.cloud2.influxdata.com/health
147158
```
148159

149-
### Real-time clock (DS3231)
150-
151-
Telemetry timestamps come from `CLOCK_REALTIME`. On the driverio Pi, a DS3231 RTC keeps time when the vehicle is offline and seeds the system clock on boot.
152-
153-
Timekeeping flow:
154-
155-
1. **Boot:** kernel reads `/dev/rtc0` and sets system time.
156-
2. **Online:** `systemd-timesyncd` syncs system time over NTP (LTE).
157-
3. **Write-back:** system time is copied to the RTC hourly and on shutdown so the module stays accurate between power cycles.
158-
159-
Install the RTC sync units shipped in this repo:
160-
161-
```bash
162-
sudo cp deploy/rtc-sync.service deploy/rtc-sync.timer deploy/rtc-sync-shutdown.service /etc/systemd/system/
163-
sudo systemctl daemon-reload
164-
sudo systemctl enable --now systemd-timesyncd rtc-sync.timer rtc-sync-shutdown.service
165-
sudo hwclock --systohc --utc
166-
```
167-
168-
Verify:
169-
170-
```bash
171-
timedatectl status # expect: System clock synchronized: yes
172-
sudo hwclock --show --utc # should match date -u within ~1 second
173-
```
174-
175-
If the RTC has never been set (or lost its battery), set system time first, then write it to the hardware clock:
176-
177-
```bash
178-
sudo timedatectl set-time "2026-06-12 14:00:00"
179-
sudo hwclock --systohc --utc
180-
```
181-
182-
### Internet connectivity (WiFi first, LTE fallback)
183-
184-
InfluxDB uploads require internet at boot. The Pi prefers any saved WiFi profile and falls back to the Quectel EG25-G LTE modem when no known network is in range.
185-
186-
Install the connectivity service:
187-
188-
```bash
189-
sudo cp deploy/network-connect.default /etc/default/network-connect
190-
sudo cp deploy/network-connect.service /etc/systemd/system/
191-
chmod +x deploy/network-connect.sh
192-
sudo nmcli connection modify lte connection.autoconnect no
193-
sudo systemctl disable --now sc2-lte.service 2>/dev/null || true
194-
sudo systemctl daemon-reload
195-
sudo systemctl enable --now network-connect.service
196-
```
197-
198-
Saved WiFi profiles (`nmcli connection show`) are tried automatically. LTE uses APN `fast.t-mobile.com` (Tello/T-Mobile) and can be overridden in `/etc/default/network-connect`.
199-
200-
Verify:
201-
202-
```bash
203-
systemctl status network-connect.service
204-
ip route show default
205-
curl -s -o /dev/null -w "%{http_code}\n" https://us-east-1-1.aws.cloud2.influxdata.com/health
206-
```
207-
208160
### Bring up CAN interface
209161

210162
```bash
@@ -280,13 +232,6 @@ The default InfluxDB measurement is `telemetry_snapshot`, which matches the mobi
280232
telemetry_snapshot,signal=<signal_name> value=<number>
281233
```
282234

283-
The default InfluxDB measurement is `telemetry_snapshot`, which matches the
284-
mobile app. Each uploaded reading is written as:
285-
286-
```text
287-
telemetry_snapshot,signal=<signal_name> value=<number>
288-
```
289-
290235
### CLI flags
291236

292237
```
@@ -423,7 +368,7 @@ can-telem-cloud/
423368
│ └── db_watcher.[ch] — SQLite DB watcher for TX signals
424369
├── third_party/
425370
│ └── cJSON.[ch] — JSON parser
426-
├── sc-data-format/ — git submodule containing format.json and format_exp.md
371+
├── sc-data-format/ — git submodule containing format.json
427372
├── deploy/ — systemd unit files (RTC sync, network connect, can-telem)
428373
├── can_telem.conf.example
429374
└── Makefile

0 commit comments

Comments
 (0)