commit 32e8277e4b81b08a600bcfbf13756497f8e459ac Author: Dominic Date: Thu Jul 23 18:20:55 2026 +0000 ESPHome-Konfigs für CC1101-Funksender/-empfänger inkl. Flash-Anleitung - Sender (ESP32-C3 Super Mini) und Empfänger (ESP32-S3), beide mit CC1101 433 MHz - README dokumentiert USB-TTL-Anschluss, da der interne USB-Serial/JTAG nach Zadig unter Windows 11 nicht mehr nutzbar ist - Verdrahtungsschema CC1101 als SVG diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26f4d9c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +secrets.yaml +.esphome/ +*.bin diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e15b38 --- /dev/null +++ b/README.md @@ -0,0 +1,215 @@ +# Funksender Tor + +Automatische Toröffnung per 433 MHz. Jedes Fahrzeug bekommt einen kleinen Sender +am Zündungsplus, der Empfänger am Tor öffnet, sobald ein bekanntes Fahrzeug nah +genug ist. Kein Knopfdruck, keine App, kein Account. + +**Hardware:** ESP32-C3 Super Mini + CC1101 (433 MHz) je Sender, +ESP32-S3 + CC1101 als Empfänger am Tor. + +--- + +## Inhalt + +- [Verdrahtung CC1101](#verdrahtung-cc1101) +- [Flashen](#flashen) — **hier steht der USB-TTL-Kram** +- [ESPHome einrichten](#esphome-einrichten) +- [Reichweite einstellen](#reichweite-einstellen) +- [Weiteres Fahrzeug hinzufügen](#weiteres-fahrzeug-hinzufügen) +- [Paketformat](#paketformat) + +--- + +## Verdrahtung CC1101 + +Die Pins des CC1101 sitzen als **4 Zeilen à 2 Pins**, Antenne rechts: + +``` +① GND │ VDD ② +③ GDO0 │ CSN ④ +⑤ SCK │ MOSI ⑥ +⑦ MISO │ GDO2 ⑧ +``` + +> **Achtung:** Pin 1 ist **GND**, Pin 2 ist **VDD**. Nicht die verbreitete +> Belegung mancher anderer CC1101-Boards annehmen, wo es umgekehrt ist — +> Vertauschen macht das Modul und ggf. den ESP heiß. + +| CC1101 | Signal | ESP32-C3 Super Mini | +|--------|--------|---------------------| +| 1 | GND | `G` (links) | +| 2 | VDD | `3.3` (links) — **niemals 5V** | +| 3 | GDO0 | `GPIO3` (links) | +| 4 | CSN | `GPIO4` (links) | +| 5 | SCK | `GPIO6` (rechts) | +| 6 | MOSI | `GPIO7` (rechts) | +| 7 | MISO | `GPIO5` (rechts) | +| 8 | GDO2 | *frei lassen* | + +Schema: [`doku/verdrahtung-cc1101.svg`](doku/verdrahtung-cc1101.svg) + +Beim Empfänger (ESP32-S3) sind die SPI-Pins in `tor_empfaenger.yaml` noch +Platzhalter und müssen an die tatsächliche Verdrahtung angepasst werden. + +--- + +## Flashen + +### Warum nicht über den USB-C-Anschluss? + +Der ESP32-C3 hat einen eingebauten USB-Serial/JTAG-Controller. Unter Windows 11 +sollte er automatisch als COM-Port erscheinen — **tut er aber nicht mehr, sobald +Zadig einmal auf ihm gelaufen ist.** + +Was passiert war: Zadig ersetzt den nativen `usbser.sys` durch WinUSB bzw. +selbstgenerierte libwdi/libusbK-Treiber. Danach zeigt der Geräte-Manager zwar +einen COM-Port, aber esptool bekommt nur + +``` +A fatal error occurred: Failed to connect to ESP32-C3: No serial data received. +``` + +Das lässt sich reparieren (siehe unten), ist aber fummelig. **Der USB-TTL-Adapter +umgeht das Thema komplett.** + +### USB-TTL-Adapter anschließen ← *das ist der Weg, der funktioniert hat* + +> **Adapter zwingend auf 3.3 V jumpern.** Der ESP32-C3 ist nicht 5V-tolerant. + +| USB-TTL-Adapter | ESP32-C3 Super Mini | +|-----------------|---------------------| +| TX | `GPIO20` (rechts, vorletzter Pin) | +| RX | `GPIO21` (rechts, letzter Pin) | +| GND | `G` (links, 2. Pin) | +| 3.3V | `3.3` (links, 3. Pin) | + +TX und RX sind **gekreuzt** — das ist so richtig. +Das CC1101 kann angeschlossen bleiben, GPIO20/21 kollidieren mit nichts. + +Liefert der Adapter auf 3.3 V zu wenig Strom, den ESP stattdessen über ein +USB-Netzteil an der USB-C-Buchse versorgen und vom Adapter nur TX, RX und GND +anschließen. **Nicht beide Quellen gleichzeitig.** + +### Boot-Modus + +**`GPIO9` ↔ `G` brücken, danach erst Strom drauf.** Reihenfolge ist wichtig. +Nach dem Flashen die Brücke wieder entfernen. + +### Ablauf + +```bash +# 1. Verbindung prüfen — COM-Port des TTL-Adapters aus dem Geräte-Manager +python -m esptool --chip esp32c3 --port COM16 chip-id +``` + +Erwartete Ausgabe: + +``` +Chip type: ESP32-C3 AZ (QFN32) (revision v1.1) +Features: Wi-Fi, BT 5 (LE), Single Core, 160MHz, Embedded Flash 4MB (XMC) +MAC: 44:b1:76:18:cb:ec +``` + +```bash +# 2. Factory-Image flashen (nicht die normale .bin!) +python -m esptool --chip esp32c3 --port COM16 --baud 460800 \ + write-flash 0x0 auto-sender-01.factory.bin +``` + +Bricht es bei 460800 ab, mit `--baud 115200` wiederholen. + +Danach GPIO9-Brücke raus, Strom aus/an. Ab hier läuft alles über OTA — +der Adapter wird nicht mehr gebraucht. + +`esptool` installieren falls nötig: `pip install esptool` + +### Falls der interne USB doch mal repariert werden soll + +Als Administrator: + +```cmd +pnputil /enum-drivers | findstr /i "libwdi libusb" +pnputil /delete-driver oemXX.inf /uninstall /force +``` + +Alle gefundenen libwdi/libusbK-Pakete löschen, besonders das mit +`MS_COMP_USBSER` — das kapert systemweit jedes CDC-Gerät. Danach neu starten. +Windows zieht dann wieder `usbser.sys`. + +**Zadig nicht mehr auf den ESP32-C3 loslassen.** Für den eingebauten +USB-Serial/JTAG ist es das falsche Werkzeug (außer man will JTAG-Debugging +über OpenOCD). + +--- + +## ESPHome einrichten + +Beide YAMLs erwarten in `secrets.yaml`: + +```yaml +wifi_ssid: "..." +wifi_password: "..." +api_key: "..." # base64, 32 Byte +ota_password: "..." +``` + +1. In ESPHome (HA-Add-on) neues Gerät anlegen +2. Inhalt der passenden Datei aus `esphome/` einfügen +3. Drei Punkte → **Install** → **Manual download** → **Factory format** +4. Mit esptool flashen (siehe oben) + +`reboot_timeout: 0s` beim Sender ist kein Versehen: im Auto ist kein WLAN in +Reichweite, ohne diese Zeile startet der ESP alle 15 Minuten neu. + +--- + +## Reichweite einstellen + +Die Reichweite wird **nicht** am Sender begrenzt — alle Sender laufen mit voller +Leistung. Der Empfänger entscheidet anhand der Signalstärke (RSSI), ob das +Fahrzeug nah genug ist. + +Der Schwellwert liegt als Schieberegler **„RSSI Schwelle"** in Home Assistant, +Änderungen brauchen kein Neuflashen. + +Einmessen: + +1. Empfänger-Log in ESPHome öffnen +2. Mit dem Fahrzeug in verschiedenen Abständen anhalten +3. RSSI-Werte notieren — z. B. `Fahrzeug 1, RSSI -73.5 dBm, LQI 12` +4. Den Wert bei der gewünschten Distanz (~5 m) als Schwelle setzen + +Je näher der Wert an 0, desto kürzer die Reichweite. Startwert ist `-60`. + +Nach jeder Öffnung greift eine **Sperrzeit von 60 Sekunden**. + +--- + +## Weiteres Fahrzeug hinzufügen + +In `auto_sender_01.yaml` nur die beiden Substitutions oben ändern: + +```yaml +substitutions: + geraet: auto-sender-02 + fahrzeug_id: "0x02" +``` + +Der Empfänger akzeptiert IDs `0x01` bis `0x0A` (1–10) und muss dafür **nicht** +angefasst werden. Sollen weniger Fahrzeuge erlaubt sein, im `on_packet`-Lambda +die Zeile `if (fz < 1 || fz > 10)` anpassen. + +--- + +## Paketformat + +4 Bytes, GFSK, 4800 Baud, CRC-16 aktiv, Sync `0xD391`: + +| Byte | Inhalt | +|------|--------| +| 0 | `0xA7` Magic | +| 1 | `0x3C` Magic | +| 2 | Fahrzeug-ID (`0x01`–`0x0A`) | +| 3 | reserviert (`0x00`) | + +Der Sender schickt das Paket alle 2 Sekunden, solange die Zündung an ist. diff --git a/doku/verdrahtung-cc1101.svg b/doku/verdrahtung-cc1101.svg new file mode 100644 index 0000000..62ab6a7 --- /dev/null +++ b/doku/verdrahtung-cc1101.svg @@ -0,0 +1,162 @@ + + + + + + + + + ⚠️ Nie 5V! · Pin1=GND · Pin2=VDD(3.3V) · GPIO9↔GND nur beim Flashen! + + + + + + USB-C + ESP32-C3 + Super Mini + + + + + 5V + ✗ nicht verbinden + + + + G + → CC1101 Pin 1 + + + + 3.3 + → CC1101 Pin 2 + + + + 4 + → CC1101 Pin 4 + + + + 3 + → CC1101 Pin 3 + + + + 2 + nicht benutzt + + + + 1 + + + + 0 + + + + + 5 + Pin 7 ← + + + + 6 + Pin 5 ← + + + + 7 + Pin 6 ← + + + + 8 + + 9 + + 10 + + 20 + + 21 + + + + CC1101 V2.0 + 433MHz + + + CC1101 + + + 40MHz + + + + SMA + ANT + + + + + 1 + + 2 + GND + VDD + + + + 3 + + 4 + GDO0 + CSN + + + + 5 + + 6 + SCK + MOSI + + + + 7 + + 8 + MISO + GDO2* + + + + 7 Verbindungen (Dupont-Kabel): + + + + G→1(GND) + + + 3.3→2(VDD) + + + GPIO3→3(GDO0) + + + GPIO4→4(CSN) + + + GPIO6→5(SCK) + + + GPIO7→6(MOSI) + + GPIO5→7(MISO) + + diff --git a/esphome/auto_sender_01.yaml b/esphome/auto_sender_01.yaml new file mode 100644 index 0000000..52ab509 --- /dev/null +++ b/esphome/auto_sender_01.yaml @@ -0,0 +1,65 @@ +substitutions: + geraet: auto-sender-01 # <- pro Fahrzeug ändern: 01, 02, 03 ... + fahrzeug_id: "0x01" # <- pro Fahrzeug ändern: 0x01, 0x02, 0x03 ... + +esphome: + name: ${geraet} + friendly_name: Auto Sender 01 + +esp32: + board: esp32-c3-devkitm-1 + framework: + type: esp-idf + +logger: + +api: + encryption: + key: !secret api_key + +ota: + - platform: esphome + password: !secret ota_password + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + # Wichtig: im Auto ist kein WLAN in Reichweite. + # Ohne diese Zeile würde der ESP alle 15 Min neu starten. + reboot_timeout: 0s + +# --- SPI zum CC1101 --- +spi: + clk_pin: GPIO6 + mosi_pin: GPIO7 + miso_pin: GPIO5 + +# --- CC1101 im Paketmodus --- +cc1101: + cs_pin: GPIO4 + gdo0_pin: GPIO3 + frequency: 433.92MHz + modulation_type: GFSK + symbol_rate: 4800 + output_power: 10 # volle Leistung, Reichweite regelt der Empfänger per RSSI + packet_mode: true + packet_length: 4 + crc_enable: true + sync0: 0x91 + sync1: 0xD3 + +# --- alle 2 Sekunden die Fahrzeug-Kennung senden --- +# Paketaufbau: [Magic, Magic, Fahrzeug-ID, Reserve] +interval: + - interval: 2s + then: + - cc1101.send_packet: + data: [0xA7, 0x3C, ${fahrzeug_id}, 0x00] + +# Onboard-LED des Super Mini (invertiert) +light: + - platform: status_led + name: Status + pin: + number: GPIO8 + inverted: true diff --git a/esphome/tor_empfaenger.yaml b/esphome/tor_empfaenger.yaml new file mode 100644 index 0000000..253eb5d --- /dev/null +++ b/esphome/tor_empfaenger.yaml @@ -0,0 +1,110 @@ +esphome: + name: tor-empfaenger + friendly_name: Tor Empfänger + +esp32: + board: esp32-s3-devkitc-1 # <- ggf. an dein Board anpassen + framework: + type: esp-idf + +logger: + +api: + encryption: + key: !secret api_key + +ota: + - platform: esphome + password: !secret ota_password + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + +# --- SPI zum CC1101 --- +# Diese Pins am S3 prüfen und ggf. anpassen! +spi: + clk_pin: GPIO12 + mosi_pin: GPIO11 + miso_pin: GPIO13 + +cc1101: + cs_pin: GPIO10 + gdo0_pin: GPIO9 + frequency: 433.92MHz + modulation_type: GFSK + symbol_rate: 4800 + packet_mode: true + packet_length: 4 + crc_enable: true + sync0: 0x91 + sync1: 0xD3 + on_packet: + then: + - lambda: |- + // Magic-Bytes prüfen + if (x.size() < 3 || x[0] != 0xA7 || x[1] != 0x3C) return; + + uint8_t fz = x[2]; + ESP_LOGI("tor", "Fahrzeug %u, RSSI %.1f dBm, LQI %u", fz, rssi, lqi); + + // Reichweite: nur öffnen wenn Signal stark genug (= Auto nah) + if (rssi < id(rssi_schwelle).state) return; + + // erlaubte Fahrzeuge + if (fz < 1 || fz > 10) { + ESP_LOGW("tor", "Unbekannte Fahrzeug-ID: %u", fz); + return; + } + + // Sperrzeit, damit das Tor nicht dauernd getriggert wird + uint32_t jetzt = millis(); + if (id(letzte_oeffnung) != 0 && (jetzt - id(letzte_oeffnung)) < 60000) return; + id(letzte_oeffnung) = jetzt; + + ESP_LOGI("tor", "Tor öffnen für Fahrzeug %u (RSSI %.1f)", fz, rssi); + id(letztes_fahrzeug).publish_state(std::to_string(fz)); + id(tor_impuls).press(); + +globals: + - id: letzte_oeffnung + type: uint32_t + restore_value: false + initial_value: '0' + +# --- RSSI-Schwelle, in HA per Schieberegler einstellbar --- +# Je näher an 0, desto kürzer die Reichweite. +# Startwert -60 entspricht grob 5 m — beim Einrichten im Log ablesen und anpassen. +number: + - platform: template + name: RSSI Schwelle + id: rssi_schwelle + min_value: -100 + max_value: -20 + step: 1 + initial_value: -60 + optimistic: true + restore_value: true + unit_of_measurement: dBm + entity_category: config + +text_sensor: + - platform: template + name: Letztes Fahrzeug + id: letztes_fahrzeug + +# --- Torimpuls: Relais 500 ms schließen --- +switch: + - platform: gpio + id: tor_relais + pin: GPIO7 # <- an deine Relais-Verdrahtung anpassen + restore_mode: ALWAYS_OFF + +button: + - platform: template + name: Tor Impuls + id: tor_impuls + on_press: + - switch.turn_on: tor_relais + - delay: 500ms + - switch.turn_off: tor_relais