Files
dcp4ever 42efd83bc0 Initial commit: ESP32-C3 WiFi→BLE bridge for Phomemo M110
- BLE client (NimBLE) with auto-scan/reconnect
- ESC/POS protocol encoder (GS v 0 raster)
- Web API: /api/status, /api/connect, /api/print
- Web UI: image upload with dithering, QR codes, positioning
- Client-side QR generation (qrcode-generator)
- Supports bitmap, QR, and raw ESC/POS print types
2026-06-13 16:38:54 +02:00

4.2 KiB
Raw Permalink Blame History

ESP32 M110 Label Printer Bridge

WiFi → BLE Bridge für den Phomemo M110 Bluetooth-Etikettendrucker.
Läuft auf ESP32-C3 (PlatformIO / Arduino).

Hardware

  • ESP32-C3 DevKit (oder kompatibel mit WiFi + BLE)
  • Phomemo M110 Etikettendrucker (203 dpi, 48mm Druckbreite)

Quickstart

1. Konfiguration

WiFi-Zugangsdaten und BLE-Name des Druckers in platformio.ini eintragen:

build_flags = -std=gnu++17 -DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=1
    -DWIFI_SSID='"MeinWLAN"'
    -DWIFI_PASS='"MeinPasswort"'
    -DPRINTER_BLE_NAME='"Q199G4180950002"'

Den BLE-Namen findest du auf dem Etikett auf der Drucker-Rückseite.

2. Build & Flash

pio run -t upload      # Firmware
pio run -t uploadfs    # Web-Interface (LittleFS)

3. Verwenden

Web-Interface unter http://<esp32-ip>/ öffnen.

Oder per curl:

# Status
curl http://192.168.1.100/api/status

# QR-Code drucken (106×106px, zentriert)
curl -X POST http://192.168.1.100/api/print \
  -H "Content-Type: application/json" \
  -d '{"type":"qr","data":"https://techahead.de","scale":4}'

# Bild drucken (1-Bit Bitmap als Base64)
curl -X POST http://192.168.1.100/api/print \
  -H "Content-Type: application/json" \
  -d '{"type":"bitmap","data":"...","width":384,"height":200,"density":15,"offsetX":0}'

# BLE-Scan starten
curl -X POST http://192.168.1.100/api/connect

API

Endpoint Methode Beschreibung
/ GET Web-Interface
/api/status GET JSON: WiFi, BLE, Drucker-Status
/api/connect POST BLE-Scan starten
/api/print POST Druckauftrag

POST /api/print

{
  "type": "qr",
  "data": "https://example.com",
  "scale": 4,
  "offsetX": 0
}
{
  "type": "bitmap",
  "data": "<base64>",
  "width": 384,
  "height": 200,
  "density": 15,
  "offsetX": 0
}
{
  "type": "raw",
  "data": "<base64-ESC/POS-bytes>"
}

Web-Interface

  • 🖼️ Bild drucken: Upload per Drag & Drop, Vorschau mit B/W-Dithering (Atkinson, Floyd-Steinberg, Schwellwert), Positionierung auf 48mm-Band, einstellbare Druckdichte
  • 📱 QR-Code: Text/URL eingeben, Skalierung, Positionierung. QR wird client-seitig generiert — Vorschau = Druckergebnis
  • Status: WiFi/BLE-Verbindung, RSSI, Uptime

M110 BLE Protokoll

  • Service UUID: 0000FF00-0000-1000-8000-00805F9B34FB
  • Write Characteristic: 0000FF02-0000-1000-8000-00805F9B34FB
  • Verbindung: Per advertised name, kein Pairing
  • Protokoll: ESC/POS GS v 0 Raster-Bitmap
  • Auflösung: 384px (48mm) @ 203dpi → 48 Bytes/Zeile
  • Esc/POS-Kommandos:
    • ESC @ — Drucker initialisieren
    • ESC N 0x0D <speed> — Druckgeschwindigkeit (15)
    • ESC N 0x04 <density> — Druckdichte (115)
    • GS DC1 <type> — Medientyp (0x0A=LabelWithGaps, 0x0B=Continuous)
    • GS v 0 <xL><xH><yL><yH> <data> — Raster-Bitmap (max 240 Zeilen empfohlen)
    • GS F0 05 00 / GS F0 03 00 — Footer

Das Protokoll basiert auf Reverse-Engineering von phomemo-tools und phomemo-macos.

Projektstruktur

esp32-m110-label/
├── platformio.ini              # PlatformIO Config
├── private_config.ini.example  # Vorlage für Credentials
├── README.md
├── src/
│   ├── main.cpp                # WiFi, HTTP-API, Setup
│   ├── config.h                # UUIDs, Konstanten
│   ├── printer.h               # M110 ESC/POS Encoder
│   ├── ble_client.h            # NimBLE Scanner + Connection Manager
│   └── qr_renderer.h           # QR-Code → Bitmap Renderer
└── data/
    ├── index.html              # Web-Interface
    └── qrcode.min.js           # QR-Code Generator (client-side)

Libraries

Lizenz

MIT