Add an end-to-end Pi quick start guide
Replaces the "Running at boot" section with a five-step guide that
starts from enabling the UART, the step that is easiest to miss and
the one that produces the "device not found" failure:
1. enable the serial port with raspi-config (and answer No to the
login shell, or the console holds the port)
2. confirm which device exists, with a table mapping what you see
to the --device value to pass
3. install the service, with both possible failure messages and
what each one means
4. verify via systemd, the journal and the status page
5. fall back to a foreground run and --list-ports when cards are
not detected
Also fixes a contradiction: the section claimed the installer
defaults --device to /dev/rdm-reader when it is /dev/serial0, while
the options table three lines below said /dev/serial0. That mismatch
is exactly what leads someone to install against the wrong device.
Notes that --no-service does not skip the device checks, verified
against the script's control flow, and drops the raspi-config menu
number rather than assert one that varies by release.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -21,7 +21,7 @@ Built for a Raspberry Pi, but it runs anywhere with a serial port.
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [Serving card data to a web app (`--serve`)](#serving-card-data-to-a-web-app---serve)
|
||||
- [Running at boot (Raspberry Pi)](#running-at-boot-raspberry-pi)
|
||||
- [Quick start on a Raspberry Pi](#quick-start-on-a-raspberry-pi)
|
||||
- [Status LED](#status-led)
|
||||
- [Wiring](#wiring)
|
||||
- [The protocol](#the-protocol)
|
||||
@@ -411,50 +411,145 @@ actually cost you something.
|
||||
|
||||
---
|
||||
|
||||
## Running at boot (Raspberry Pi)
|
||||
## Quick start on a Raspberry Pi
|
||||
|
||||
The defaults already match the common wiring — **`/dev/serial0`** for the
|
||||
reader on the Pi's UART and **GPIO 23** for the LED — so the LED pin and device
|
||||
usually need no arguments at all:
|
||||
End-to-end: enable the serial port, confirm the reader is visible, install the
|
||||
service, verify it runs. Steps 1–2 change nothing on disk and are safe to run
|
||||
first.
|
||||
|
||||
### 1. Enable the serial port
|
||||
|
||||
`/dev/serial0` is the Pi's on-board UART, and it does not exist until the UART
|
||||
is switched on:
|
||||
|
||||
```bash
|
||||
sudo raspi-config
|
||||
# Interface Options -> Serial Port
|
||||
# "Would you like a login shell to be accessible over serial?" -> No
|
||||
# "Would you like the serial port hardware to be enabled?" -> Yes
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
Menu numbering shifts between `raspi-config` releases, so navigate by name:
|
||||
**Interface Options**, then **Serial Port**.
|
||||
|
||||
**Both answers matter.** Answering *Yes* to the login shell leaves a console on
|
||||
the port, so the reader gets nothing: the app either reports `device not found`
|
||||
or opens the port and never sees a card.
|
||||
|
||||
### 2. Confirm the device appears
|
||||
|
||||
```bash
|
||||
ls -l /dev/serial0 /dev/rdm-reader 2>&1
|
||||
```
|
||||
|
||||
| What you see | Wiring | Device to pass |
|
||||
| --- | --- | --- |
|
||||
| `/dev/serial0 -> ttyAMA0` (or `ttyS0`) | UART, header pins **8 / 10** | `--device /dev/serial0` |
|
||||
| `/dev/rdm-reader` | USB-to-serial adapter | `--device /dev/rdm-reader` |
|
||||
| `No such file or directory` for both | nothing openable yet | see below |
|
||||
|
||||
`/dev/rdm-reader` is created by the udev rule and matches a **USB** bridge chip,
|
||||
so it can never exist on a UART setup. The two are mutually exclusive — a
|
||||
service pointing at the wrong one exits `1` on every start.
|
||||
|
||||
If neither exists, ask what the system does see:
|
||||
|
||||
```bash
|
||||
ls /dev/ttyUSB* /dev/ttyACM* /dev/ttyS* 2>/dev/null
|
||||
dmesg | grep -iE "ttyUSB|ttyAMA|ch34|ftdi|cp210|pl2303" | tail
|
||||
```
|
||||
|
||||
No `ttyUSB`/`ttyACM` line in `dmesg` means the adapter is not enumerating at
|
||||
all — a cable, power or hardware problem that no `--device` value can fix.
|
||||
|
||||
If a `/dev/ttyUSB0` appears but `/dev/rdm-reader` does not, the adapter's chip
|
||||
is not the CH340 the rule matches by default. See **Identifying the right
|
||||
ttyUSB** below.
|
||||
|
||||
### 3. Install the service
|
||||
|
||||
The defaults already match the common wiring — `/dev/serial0` for the reader on
|
||||
the UART, GPIO 23 for the LED:
|
||||
|
||||
```bash
|
||||
sudo ./deploy/install.sh --origin https://your.web.app
|
||||
```
|
||||
|
||||
To be explicit (and safe if the defaults ever change):
|
||||
`deploy/install.sh` is the only installer — there is no `deploy.sh`. It sets up
|
||||
a service account, a virtualenv, a udev rule and a systemd unit, then enables
|
||||
the service.
|
||||
|
||||
Tell it which device you have, since the two are not interchangeable:
|
||||
|
||||
```bash
|
||||
sudo ./deploy/install.sh --origin https://your.web.app \
|
||||
--device /dev/serial0 \
|
||||
--led-pin 23 \
|
||||
--led-mode presence
|
||||
sudo ./deploy/install.sh --device /dev/serial0 # UART, pins 8 / 10
|
||||
sudo ./deploy/install.sh --device /dev/rdm-reader # USB adapter
|
||||
```
|
||||
|
||||
| Argument | Why |
|
||||
It refuses to enable the service unless the device exists **and** opens at
|
||||
9600 baud, so a wrong port fails here instead of becoming a crash-looping unit
|
||||
that burns its restart limit within seconds and then stays dead. Success looks
|
||||
like:
|
||||
|
||||
```
|
||||
/dev/serial0 opened at 9600 baud
|
||||
```
|
||||
|
||||
If it stops instead, the message is one of exactly two:
|
||||
|
||||
| Message | Cause |
|
||||
| --- | --- |
|
||||
| `--device /dev/serial0` | The reader is wired to the UART pins (8 / 10). This is the default. For a USB-to-serial adapter pass `--device /dev/rdm-reader` instead — that alias is created by udev for USB adapters only, so it never exists on a UART setup |
|
||||
| `--led-pin 23` | BCM GPIO 23, which is **physical pin 16**. The default |
|
||||
| `--led-mode presence` | Lit while a card is on the reader, dark otherwise. The default |
|
||||
| `<device> does not exist, so the service could never start` | step 1 or 2 not done, or the wrong of the two devices |
|
||||
| `could not open <device> at 9600 baud` | device exists but is not usable — UART held by the serial console, or the user is not in `dialout` |
|
||||
|
||||
> **`--led-pin` is the BCM GPIO number, not the header pin.** If your LED wire
|
||||
> is on physical pin 16, pass `--led-pin 23` (the default). Passing
|
||||
> `--led-pin 16` would drive **GPIO 16**, which is physical pin 36 — a different
|
||||
> pin entirely. The LED is optional: with no LED, pass `--led-mode presence`
|
||||
> regardless and ignore the light, or add `--no-led` to the unit if you want
|
||||
> the app to stop trying.
|
||||
Nothing is enabled in either case, and re-running is safe: the account, udev
|
||||
rule and virtualenv are all idempotent.
|
||||
|
||||
### Standalone install
|
||||
### 4. Verify it runs
|
||||
|
||||
`deploy/install.sh` is the only installer — there is no `deploy.sh`.
|
||||
```bash
|
||||
systemctl status rdm-card-reader # state
|
||||
systemctl is-enabled rdm-card-reader # should be 'enabled' (starts at boot)
|
||||
journalctl -u rdm-card-reader -f # live log
|
||||
ss -ltnp | grep 8765 # confirms something is listening
|
||||
```
|
||||
|
||||
That installs a service account, a virtualenv, a systemd unit and a udev rule,
|
||||
then enables the service. The device defaults to `/dev/rdm-reader`; if the
|
||||
reader is on the Pi's UART instead, add `--device /dev/serial0` — see
|
||||
**UART or USB?** above. The installer refuses to enable the service unless the
|
||||
device exists and opens, so a misconfigured port fails during install rather
|
||||
than as a crash-looping unit.
|
||||
A healthy startup logs one line:
|
||||
|
||||
Useful installer options:
|
||||
```
|
||||
OK reader on /dev/serial0 ; bridge on http://127.0.0.1:8765 (mode: login)
|
||||
```
|
||||
|
||||
Then tap a card and check — or just open **<http://127.0.0.1:8765/>** for the
|
||||
status page, which shows the reader state and a live event log:
|
||||
|
||||
```bash
|
||||
curl -sS http://127.0.0.1:8765/api/card | python3 -m json.tool
|
||||
```
|
||||
|
||||
### 5. If cards are not detected
|
||||
|
||||
Run the reader in the foreground, using the venv the installer built, to see
|
||||
the failure directly instead of through the journal:
|
||||
|
||||
```bash
|
||||
sudo /opt/rdm-card-reader/.venv/bin/rdm-card-reader --port /dev/serial0
|
||||
```
|
||||
|
||||
`--list-ports --verbose-ports` answers "is the port even there?" — it prints
|
||||
candidates with `OK`/`---` (exists?) and then every identified port with its
|
||||
`by-id` path, USB id and serial number:
|
||||
|
||||
```bash
|
||||
sudo /opt/rdm-card-reader/.venv/bin/rdm-card-reader --list-ports --verbose-ports
|
||||
```
|
||||
|
||||
A service that cannot see cards while the foreground run works usually means
|
||||
the unit is pointed at the other device — compare its `ExecStart` (below) with
|
||||
what `--list-ports` reports.
|
||||
|
||||
### Installer options
|
||||
|
||||
| Option | Default | Meaning |
|
||||
| --- | --- | --- |
|
||||
@@ -468,7 +563,16 @@ Useful installer options:
|
||||
| `--user NAME` | `rdmcard` | Service account |
|
||||
| `--no-service` | off | Install and configure, but do not enable the service |
|
||||
|
||||
The unit runs the app as:
|
||||
> **`--no-service` does not skip the device checks.** They run before it, so an
|
||||
> install with no reader attached still exits `1`.
|
||||
|
||||
> **`--led-pin` is the BCM GPIO number, not the header pin.** If your LED wire
|
||||
> is on physical pin 16, pass `--led-pin 23` (the default). Passing
|
||||
> `--led-pin 16` would drive **GPIO 16**, which is physical pin 36 — a different
|
||||
> pin entirely. The LED is optional: with no LED, leave the default and ignore
|
||||
> the light, or add `--no-led` to the unit to stop the app trying.
|
||||
|
||||
### What the unit runs
|
||||
|
||||
```
|
||||
/opt/rdm-card-reader/.venv/bin/rdm-card-reader \
|
||||
@@ -481,22 +585,6 @@ The unit runs the app as:
|
||||
added. `--serve` is what makes the API available; without it the app only
|
||||
prints events, which a service sends to the journal.
|
||||
|
||||
Afterwards:
|
||||
|
||||
```bash
|
||||
systemctl status rdm-card-reader # state
|
||||
systemctl is-enabled rdm-card-reader # should be 'enabled' (starts at boot)
|
||||
journalctl -u rdm-card-reader -f # live log
|
||||
ss -ltnp | grep 8765 # confirms something is listening
|
||||
curl -sS http://127.0.0.1:8765/api/card # tap a card, then run this
|
||||
```
|
||||
|
||||
A healthy startup logs one line:
|
||||
|
||||
```
|
||||
OK reader on /dev/serial0 ; bridge on http://127.0.0.1:8765 (mode: login)
|
||||
```
|
||||
|
||||
### Checking the reader from the command line
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user