A Cheap Serial Logger for Istanbul Bus Delays, Revisited

这篇内容暂时只有 English 版本,以下是原文。

Last winter I ran a small board off a USB port for eleven weeks, logging arrival predictions from the LRT signs near my flat in Kadıköy. The data volume was unremarkable: roughly 40k rows, one line per vehicle-prediction pair, about 3 MB compressed. The failure mode was not volume. It was the serial link dying silently at 3am and the logger happily writing nothing for six hours while still claiming success.

The setup was a tiny ESP32 with a USB-serial bridge, a Python reader on a laptop, and a cron job that restarted the reader every hour. The naive version looked like this:

import serial, time
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=2)
while True:
    line = ser.readline().decode('ascii', 'replace').strip()
    if line:
        print(line, flush=True)

That code is fine until the board resets. When it did, readline returned empty strings forever and the loop spun without ever opening the port again. My first fix was to count consecutive empty reads and reopen the device after 100 of them. That worked, but it hid the real problem: I was not recording whether the link was alive, only whether lines were appearing.

The better version writes a heartbeat row every 60 seconds with the port state and the number of bytes read since the last heartbeat. If the byte count is zero across two heartbeats, reopen. If reopening fails three times, stop and leave a marker. The cost is one extra row per minute, which is noise at this scale, and the benefit is that a dead link is visible in the data instead of being an absence I have to infer later.

What broke it again was the laptop sleeping on battery after a power cut. The cron restart only helps if the machine is awake. I moved the reader to a small always-on box and added a systemd restart on failure, but I never solved the case where the USB bridge itself disappears from /dev and comes back under a different name. That still needs a human.

The boundary I keep hitting: this approach assumes the sign is the source of truth. When the sign itself stops updating, the logger records stale predictions with fresh timestamps, and nothing in the serial data tells me which is which. I have not found a cheap way around that without a second independent clock.

If you have logged a public display like this, how did you tell a quiet period from a dead feed without adding another sensor?

0
赞同度 100% · 0 条评论 · 1 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。