Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ client source code.

| Path | Contents |
| --- | --- |
| [`firmware/`](firmware/) | PlatformIO firmware: hardware drivers, print queue, protocol parser, BLE, TCP, Wi-Fi AP+STA, and embedded Web UI |
| [`firmware/`](firmware/) | PlatformIO firmware: hardware drivers, print queue, protocol parser, BLE, TCP, STA Wi-Fi with temporary setup AP, and embedded Web UI |
| [`python/`](python/) | BLE test-page client and protocol tests |
| [`docs/`](docs/) | Hardware notes, architecture, and [print protocol](docs/protocol.md) |
| [`android/`](android/) · [`ios/`](ios/) · [`wxapp/`](wxapp/) | Client source code for other platforms |
Expand Down Expand Up @@ -49,9 +49,12 @@ python3 -m unittest discover -s python -p 'test_*.py'
Print data uses the project's compact `MP` frame protocol. The firmware accepts
the same protocol over BLE, raw TCP port `9100`, and HTTP `POST /api/print`.

Wi-Fi runs as AP+STA. Connect to `Mini-Printer-XXXX` and open
`http://192.168.4.1/` for the offline setup and print page. The page can join another Wi-Fi network while keeping
the setup AP available, and can rasterize an image in the browser for printing.
Wi-Fi normally runs as STA only. On first boot, after a saved-network startup
failure, or after a triple click on the printer button, the temporary
`Mini-Printer-XXXX` setup AP becomes available. Open `http://192.168.4.1/`
(or use the captive portal) to select a network. The AP closes after successful
provisioning. The embedded page can rasterize images in the browser and print
through either the temporary setup AP or normal STA operation.

The TCP endpoint is not IPP or AirPrint. See [`docs/protocol.md`](docs/protocol.md)
for frame fields and status codes, and [`firmware/README.md`](firmware/README.md)
Expand Down
3 changes: 1 addition & 2 deletions docs/hal.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ The pin map in `src/em_config.h` targets the original V4 board. Each file in
| Driver | Pins and responsibility |
| --- | --- |
| `em_adc` | GPIO 4 enables ADC, GPIO 34 reads the battery divider, GPIO 36 reads the NTC divider |
| `em_button` | GPIO 5 input pull-up, debounce, single/double/long press events |
| `em_indicator` | GPIO 18 LED; the V4 buzzer pin is shared, so buzzer mode requires a different board pin |
| `em_motor` | GPIO 23/22/21/19 stepper coil phases |
| `em_paper` | GPIO 35 paper detector and change interrupt; low means paper present |
| `em_spi` | Print-head HSPI on GPIO 15 clock, GPIO 16 MISO, and GPIO 13 data; transfers one 48-byte raster line through the full-duplex SPI path. GPIO 12 is the latch and must not be selected as SPI MISO. |
| `em_printer` | GPIO 12 latch, six strobe pins, GPIO 17 head boost gate |

`em_task` samples sensors and publishes status. `print_service` serializes all
`em_task` samples sensors and publishes status. GPIO 5 is configured as an input pull-up by the external `kbutton.c` Arduino adapter; button debounce and gesture recognition live in that reusable library rather than the hardware layer. `print_service` serializes all
printing and feeding through one FreeRTOS task. Manual feed steps are issued by
that task; stopping a feed needs no cross-task timer callback. The motor driver
never changes the head boost gate.
Expand Down
60 changes: 44 additions & 16 deletions firmware/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ TCP :9100 ─────┼── MP protocol ── print service ── print
HTTP /api/print┘ │
FreeRTOS queue

Wi-Fi AP+STA ── wifi_manager
├── mDNS
├── TCP :9100
└── HTTP :80
Wi-Fi STA ────── wifi_manager ── HTTP :80 / TCP :9100 / mDNS
│
└── temporary AP+STA setup mode
```

- `hal/` owns GPIO, SPI, motor, sensors, and print-head timing.
Expand All @@ -40,7 +39,7 @@ pio test -e native

## BLE

The default `esp32dev` build enables BLE, Wi-Fi AP+STA, HTTP, and TCP together.
The default `esp32dev` build enables BLE, Wi-Fi, HTTP, and TCP together. Normal operation uses STA only; AP+STA is enabled temporarily for provisioning and recovery.
It starts a BLE-only controller and releases unused Bluetooth Classic controller
memory before initializing the BLE stack.

Expand All @@ -60,10 +59,22 @@ characteristic returns/notifications status frames.

## Wi-Fi

Wi-Fi runs in `WIFI_AP_STA` mode. The setup/recovery SoftAP remains available
even after the printer joins another network.
Normal operation uses `WIFI_STA` only. The setup SoftAP exists only while the
printer is being provisioned or recovered.

The AP SSID is:
Startup behavior is:

```text
no saved network
-> setup AP

saved network
-> STA connect for up to 30 seconds
-> success: online, STA only
-> failure: setup AP
```

The setup AP SSID is:

```text
Mini-Printer-XXXX
Expand All @@ -72,19 +83,35 @@ Mini-Printer-XXXX
where `XXXX` is derived from the ESP32 ID. Development builds use an open AP
unless `WIFI_AP_PASSWORD` is configured.

A triple click on GPIO 5 requests setup mode at any time. If saved credentials
exist, setup mode is a temporary five-minute recovery window. A first-boot
device with no credentials remains in setup until configured. After a successful
connection the HTTP response is sent first, then the AP closes after a short
delay and the printer returns to STA-only operation.

While setup mode is active:

- captive DNS points hostnames at the setup AP
- `/api/wifi/scan`, `/api/wifi/connect`, and `/api/wifi/forget` are enabled
- the embedded Web UI can still print through `POST /api/print`
- raw MP printing on TCP port `9100` remains available

The AP is still temporary; successful provisioning or the setup timeout returns
the printer to STA-only operation.

The printer stores STA credentials as one NVS record only after a successful
connection. A failed save is reported to the browser. Saved credentials are
restored on restart; credentials from earlier firmware releases are still read.
Failed setup attempts are not persisted.
connection. A failed setup attempt is not persisted. During normal operation,
a transient STA disconnect relies on automatic reconnect and does **not** open
the setup AP.

The printer exposes:
Normal network services are:

- HTTP on port `80`
- MP protocol over raw TCP on port `9100`
- mDNS as `mini-printer-xxxx.local`

Connect to `Mini-Printer-XXXX` and open `http://192.168.4.1/` in a browser.
The setup AP does not redirect other hostnames.
During setup, connect to `Mini-Printer-XXXX`. Captive DNS redirects generic
HTTP probes to the embedded page; `http://192.168.4.1/` is also available.

The TCP service is not IPP, AirPrint, JetDirect, or ESC/POS. It carries the
project's MP framing protocol.
Expand Down Expand Up @@ -127,5 +154,6 @@ The current pin map targets the original V4 board configuration. Print-head
timing and thermistor calibration are intentionally kept in the hardware layer
so they can be validated and tuned independently of protocol/network changes.

The GPIO 5 button prints a built-in diagnostic page on a double click. Holding
it for about one second feeds paper, and releasing it stops the feed.
GPIO 5 uses the shared `kbutton.c` gesture state machine. A double click prints
a built-in diagnostic page, a triple click enters Wi-Fi setup mode, and holding
the button for about one second feeds paper until release.
3 changes: 2 additions & 1 deletion firmware/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ framework = arduino
monitor_speed = 115200
build_flags = -D BLE_ENABLED=1
build_src_filter = +<*>
lib_deps =
https://github.com/lsongdev/kbutton.c.git#f0665ecca96674aa7ee033407734f0f76b386a40

; BLE + Wi-Fi no longer fits the 1.25 MiB default app slot.
; min_spiffs keeps OTA support while giving each app partition more room.
Expand All @@ -20,4 +22,3 @@ test_build_src = yes
build_flags = -Itest/mocks
build_src_filter =
+<protocol/>
+<hal/em_button.cpp>
127 changes: 65 additions & 62 deletions firmware/src/em_config.h
Original file line number Diff line number Diff line change
@@ -1,74 +1,77 @@
#ifndef _EM_CONFIG_H_
#define _EM_CONFIG_H_
#include <Arduino.h>
#ifndef _EM_CONFIG_H_
#define _EM_CONFIG_H_

#include <Arduino.h>

#ifndef BLE_ENABLED
#define BLE_ENABLED 1
#endif

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define BLE_NAME "Mini-Printer"

// Wi-Fi runs in AP+STA mode. The AP is always available as a setup and
// recovery path while STA credentials are stored in NVS after a successful
// connection.
#define WIFI_ENABLED 1
#define WIFI_AP_SSID "Mini-Printer"
#define WIFI_AP_PASSWORD ""
#define WIFI_HTTP_PORT 80
#define WIFI_PRINT_PORT 9100
#define WIFI_CLIENT_IDLE_TIMEOUT_MS 30000
#define WIFI_CONNECT_TIMEOUT_MS 15000
#define WIFI_PREFS_NAMESPACE "wifi"

#define DEFAULT_PRINT_DENSITY 64
#define PRINT_QUEUE_DEPTH 16
#define PRINT_TRAILING_FEED_STEPS 230

// 按键引脚
// 34 35 36 39 仅可以作为输入 INPUT, 不支持 INPUT_PULLUP
#define PIN_KEY 5
#define PIN_PAPER 35
#define PIN_BATTERY_ADC 34
#define PIN_ADC_EN 4
#define BATTERY_ADC_BIT 12
#define PIN_TEMPERATRUE 36
#define PIN_BEEP 18
#define PIN_LED 18

#define PIN_MOTOR_AP 23
#define PIN_MOTOR_AM 22
#define PIN_MOTOR_BP 21
#define PIN_MOTOR_BM 19


#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define BLE_NAME "Mini-Printer"

// Wi-Fi normally runs as STA only. The setup AP is enabled only when there
// are no credentials, the saved network is unavailable at boot, or the user
// explicitly enters setup mode.
#define WIFI_ENABLED 1
#define WIFI_AP_SSID "Mini-Printer"
#define WIFI_AP_PASSWORD ""
#define WIFI_HTTP_PORT 80
#define WIFI_PRINT_PORT 9100
#define WIFI_CLIENT_IDLE_TIMEOUT_MS 30000
#define WIFI_CONNECT_TIMEOUT_MS 15000
#define WIFI_STARTUP_CONNECT_TIMEOUT_MS 30000
#define WIFI_SETUP_TIMEOUT_MS 300000
#define WIFI_SETUP_CLOSE_DELAY_MS 1500
#define WIFI_PREFS_NAMESPACE "wifi"

#define DEFAULT_PRINT_DENSITY 64
#define PRINT_QUEUE_DEPTH 16
#define PRINT_TRAILING_FEED_STEPS 230

// 按键引脚
// 34 35 36 39 仅可以作为输入 INPUT, 不支持 INPUT_PULLUP
#define PIN_KEY 5
#define PIN_PAPER 35
#define PIN_BATTERY_ADC 34
#define PIN_ADC_EN 4
#define BATTERY_ADC_BIT 12
#define PIN_TEMPERATRUE 36
#define PIN_BEEP 18
#define PIN_LED 18

#define PIN_MOTOR_AP 23
#define PIN_MOTOR_AM 22
#define PIN_MOTOR_BP 21
#define PIN_MOTOR_BM 19

#define PIN_LAT 12
#define PIN_SCK 15
#define PIN_SPI_MISO 16
#define PIN_SDA 13
// 原厂 V4
#define PIN_STB1 26
#define PIN_STB2 27
#define PIN_STB3 14
#define PIN_STB4 32
#define PIN_STB5 33
#define PIN_STB6 25
// 打印头电源升压控制引脚
#define PIN_VHEN 17

// 原厂 V4
#define PIN_STB1 26
#define PIN_STB2 27
#define PIN_STB3 14
#define PIN_STB4 32
#define PIN_STB5 33
#define PIN_STB6 25

// 打印头电源升压控制引脚
#define PIN_VHEN 17

#define PRINT_TIME 2600
#define PRINT_END_TIME 200
#define PRINTER_BOOST_SETTLE_MS 50
#define MOTOR_WATI_TIME 4000
#define LAT_TIME 1
#define PRINTER_MAX_TEMPERATURE_C 65
#define PRINTER_TEMPERATURE_CHECK_LINES 16
#define PRINTER_STALL_TIMEOUT_MS 20000
#define us_delay(us) delayMicroseconds(us)
#endif
#define LAT_TIME 1

#define PRINTER_MAX_TEMPERATURE_C 65
#define PRINTER_TEMPERATURE_CHECK_LINES 16
#define PRINTER_STALL_TIMEOUT_MS 20000

#define us_delay(us) delayMicroseconds(us)

#endif
Loading
Loading