← Kembali Konsep Mahir Konektivitas
Jembatan Jangkauan LoRa Jangkauan berkilo-kilometer untuk mesh sensormu — base station CameraPlus yang spek-nya rampung.
Board LILYGO LoRa32 v2.1 (ESP32 + SX1276)
Perkiraan biaya ~$42
Waktu pasang 90 mnt
Sensor LoRa 915 MHz radio, SSD1306 OLED status display
Saat WiFi di-jam, mati, atau sekadar tak terjangkau, LoRa menjaga event sensor tetap mengalir. Ini desain base station CameraPlus: LILYGO LoRa32 menjembatani paket LoRa 915 MHz ke HTTP, dengan protokol biner 60-byte terautentikasi (HMAC + proteksi replay), layar status OLED, loop polling outbox, dan reboot self-heal 12 jam. Protokol, endpoint, dan format paket sudah terkunci dan terdokumentasi; firmware-nya kerangka lengkap menunggu hardware Fase 1 — ikuti dan bangun bersama kami.
Dirawat dan diuji lapangan oleh tim Latent.
Mulai pemasangan terpandu Yang kamu butuhkan LILYGO LoRa32 v2.1 (915 MHz) ~$35 Antena 915 MHz ~$5 Kabel USB + adaptor 5V ~$5 Perkiraan biaya ~$42
Langkah pemasangan 2 Cek frekuensi regionalmu
3 Provisi, jangan hardcode
Config perangkat Config lengkap — salin, unduh, atau ikuti panduan pemasangan.
Salin Unduh
# =============================================================================
# CameraPlus — LoRa base station
# Hardware: LILYGO LoRa32 915 MHz (ESP32 + SX1276)
#
# STRUCTURE-ONLY SKELETON. No functional firmware yet — only section
# headings + comments describing what each block will contain when
# the device arrives. To be completed in firmware Phase 1
# (see ../../ROADMAP.md).
# =============================================================================
# ── 1. Identity ──────────────────────────────────────────────────────────────
# esphome:
# name: cameraplus-lora-base
# friendly_name: CameraPlus LoRa Base Station
# platformio_options:
# board_build.flash_mode: dio
# on_boot:
# priority: 800
# then:
# - lambda: |-
# id(boot_reason_int) = (int) esp_reset_reason();
# id(sender_id) = SENDER_ID_BASE_STATION; // from compile-time define
# id(last_seq) = 0;
# ── 2. Chip + framework ──────────────────────────────────────────────────────
# esp32:
# board: esp32dev
# framework:
# type: esp-idf
# version: recommended
# sdkconfig_options:
# CONFIG_ESP_TASK_WDT_TIMEOUT_S: "15"
# ── 3. WiFi (rugged default; LoRa is the additive path) ──────────────────────
# wifi:
# ssid: !secret uplink_ssid
# password: !secret uplink_password
# power_save_mode: none
# reboot_timeout: 1800s
# ── 4. Logger ────────────────────────────────────────────────────────────────
# logger:
# level: INFO
# ── 5. HTTP — outbound to CRM ────────────────────────────────────────────────
# http_request:
# verify_ssl: false
# timeout: 5s
# ── 6. OLED display (SSD1306 over I2C) ──────────────────────────────────────
# i2c:
# sda: GPIO21
# scl: GPIO22
# display:
# - platform: ssd1306_i2c
# model: "SSD1306 128x64"
# update_interval: 1s
# lambda: |-
# // 4-line status display:
# // line 1: "LFnet base · v1"
# // line 2: wifi state + IP
# // line 3: last rx (sender_id, RSSI, time)
# // line 4: outbox queue length
# // when usb_relay_on is true, line 1 ends with " · USB"
# ── 7. LoRa SX1276 over SPI ─────────────────────────────────────────────────
# spi:
# clk_pin: GPIO5
# miso_pin: GPIO19
# mosi_pin: GPIO27
# # NOTE: LoRa support in ESPHome native is partial. Options:
# # a) Use a third-party `lora_sx127x` external_component
# # b) Talk SPI directly from a lambda — possible but verbose
# # c) Fall back to IDF + ESPHome custom component (most flexible)
# # Decision pending — write up the choice once we have the device in hand
# # and can test bandwidth/latency.
# ── 8. Globals — protocol state ──────────────────────────────────────────────
# globals:
# - { id: boot_reason_int, type: int, initial_value: '0' }
# - { id: sender_id, type: 'uint8_t', initial_value: '0xF0' } # base station sender_id
# - { id: last_seq, type: 'uint32_t', initial_value: '0' }
# - { id: usb_relay_on, type: 'bool', initial_value: 'false', restore_value: true }
# - { id: outbox_len, type: 'uint16_t', initial_value: '0' }
# - { id: last_rx_sender, type: 'uint8_t', initial_value: '0' }
# - { id: last_rx_at, type: 'uint32_t', initial_value: '0' }
# - { id: last_rx_rssi, type: int, initial_value: '0' }
# ── 9. Scripts ──────────────────────────────────────────────────────────────
# script:
# - id: post_lora_event
# parameters: { body: string }
# then:
# - http_request.post:
# url: "https://crm.darksoc.org/api/dcmonitor/lora_event"
# body: !lambda 'return body;'
# request_headers:
# Content-Type: application/octet-stream
# X-LoRa-Sender: !lambda 'return std::to_string(id(last_rx_sender));'
# X-LoRa-RSSI: !lambda 'return std::to_string(id(last_rx_rssi));'
#
# - id: poll_outbox
# then:
# - http_request.get:
# url: "https://crm.darksoc.org/api/dcmonitor/lora_outbox"
# capture_response: true
# on_response:
# - lambda: |-
# // body is binary bytes of next-to-send LoRa packet
# // (or zero-length if outbox is empty)
# // tx via SX1276 driver
# // POST ack back to CRM
# ── 10. Intervals ────────────────────────────────────────────────────────────
# interval:
# - interval: 100ms
# then:
# - lambda: |-
# // Poll SX1276 for received packet (DIO0 interrupt-driven in real impl)
# // On rx:
# // 1. Validate HMAC against PSK from NVS
# // 2. Check replay (seq monotonic per sender_id)
# // 3. Stamp last_rx_* globals (for OLED)
# // 4. id(post_lora_event).execute(binary_payload)
# // 5. If usb_relay_on, also ESP_LOGI("lfnet", "LFNET:<base64>")
#
# - interval: 2000ms
# then:
# - script.execute: poll_outbox
#
# - interval: 12h
# startup_delay: 12h
# then:
# - button.press: reboot_button # routine self-heal
# ── 11. Encoder / button — USB relay toggle ──────────────────────────────────
# binary_sensor:
# - platform: gpio
# pin: { number: GPIO0, inverted: true, mode: { input: true, pullup: true } }
# id: usb_btn
# on_click:
# min_length: 30ms
# max_length: 700ms
# then:
# - lambda: |-
# id(usb_relay_on) = !id(usb_relay_on);
# ── 12. Reboot button ────────────────────────────────────────────────────────
# button:
# - platform: restart
# id: reboot_button
# name: "Reboot"
# =============================================================================
# CONFIGURATION TO PROVISION AT FLASH TIME (via compile-time defines or NVS):
#
# SENDER_ID_BASE_STATION — this device's sender_id (0xF0–0xFE reserved for
# non-sensor infrastructure like base stations)
# LORA_PSK_HEX — 32-byte hex string, deployment-wide PSK
# LORA_FREQUENCY_HZ — e.g. 915000000 for 915 MHz
# LORA_SF — spreading factor 7..12
# LORA_BW — bandwidth 125 / 250 / 500 kHz
#
# These are NOT in this file. They are loaded from NVS provisioned at first
# flash via a separate setup tool, or compiled in via build flags.
# =============================================================================
Ulasan (0) Belum ada ulasan — jadilah yang pertama.
Masuk dulu untuk fitur ini — hanya 20 detik dan gratis. Masuk