Přeskočit na obsah

Berry TX/RX komunikace

Jak ve firmware 0.12.11 používat spectoda.tx/rx pro zprávy mezi kontrolery a espnow.tx/rx pro raw ESP-NOW packety v Berry Scriptu.

Berry má ve firmware 0.12.11 dvě vrstvy pro vlastní komunikaci:

  • spectoda.tx/rx je aplikační Spectoda message API. Data se balí do Spectoda komunikace a zpráva se vybírá podle krátkého message labelu. Používejte ho pro komunikaci mezi kontrolery v jedné instalaci.
  • espnow.tx/rx je raw ESP-NOW API. Pracuje s MAC adresou, raw bytes payloadem a aktuálním ESP-NOW kanálem kontroleru. Používejte ho pro nízkoúrovňové packety, device-specific ovladače nebo debug transportu.

espnow.tx/rx je ve FW 0.12.11 aktuálně ESP32-specific API navázané na ESP-NOW vrstvu kontroleru. Na platformách bez ESP-NOW implementace nebo ve WASM/runtime buildu mimo ESP32 nemusí být dostupné funkční odesílání ani příjem raw ESP-NOW packetů.

Praktické pravidlo:

PotřebaPoužijte
Poslat vlastní zprávu ostatním kontrolerům přes Spectoda vrstvuspectoda.tx(label, data)
Přijímat vlastní Spectoda message podle labeluspectoda.rx(label, callback)
Přijímat raw ESP-NOW packety z ovladače nebo cizího zařízeníespnow.rx(filter, callback)
Poslat raw ESP-NOW payload na konkrétní MAC adresuespnow.tx(mac, data)

Pokud řešíte běžnou aplikační komunikaci mezi kontrolery, nezačínejte MAC adresami. MAC adresa je transportní detail. Pro raw transportní práci použijte espnow.tx/rx; pro obecné projektové protokoly použijte spectoda.tx/rx.

spectoda.rx() zaregistruje callback pro zprávy se zadaným message labelem. Vrací funkci off(), kterou lze konkrétní registraci zase odhlásit.

import spectoda
var off = spectoda.rx("PING", def(data, label)
print("message", label, data.tohex())
end)
# Později, pokud už callback nemá běžet:
off()

Signatura:

spectoda.rx(label: string, callback: function(data: bytes, label: string)) -> function

Callback dostane:

  • data jako Berry bytes
  • label jako string s message labelem, který callback vyvolal

Jedno stejné label může mít více callbacků. To je důležité pro pluginy: dva nezávislé Berry pluginy mohou poslouchat stejný message label a každý dostane vlastní off() handle.

Message label je interně label_t, tedy krátký Spectoda label o délce až 5 znaků. Používejte například PING, ARTN, SYNC nebo jiné krátké značky.

spectoda.tx() odešle Berry bytes payload jako Spectoda message se zadaným labelem.

import spectoda
var data = bytes()
data.append(1)
data.append(42)
data.append(255)
if !spectoda.tx("PING", data)
print("PING tx failed")
end

Signatura:

spectoda.tx(label: string, data: bytes) -> bool

Aktuální tvar ve FW 0.12.11 je broadcast request do Spectoda komunikační vrstvy. Nezadává se MAC adresa a callback nečeká na odpověď. true znamená, že zprávu runtime přijal k odeslání; neznamená to potvrzení doručení od každého kontroleru.

Payload držte malý. Pro Spectoda ESP-NOW mesh packet je praktický limit 208 bajtů. Pokud potřebujete pravidelně streamovat data, posílejte binární payload, omezte debug print() a dejte pozor na frekvenci odesílání.

Obě vrstvy pracují s binárními daty. To je záměr: payload je kompaktní a Berry nemusí převádět stringy nebo mapy na interní serializaci.

var p = bytes()
# Jednobajtový typ zprávy.
p.append(1)
# Hodnota 0..100.
p.append(75)
spectoda.tx("BRIG", p)

Na druhé straně:

spectoda.rx("BRIG", def(data, label)
if data.size() < 2
return
end
var msg_type = data.get(0)
var brigh = data.get(1)
print("type", msg_type, "brigh", brigh)
end)

espnow.rx() zaregistruje raw ESP-NOW callback. Na rozdíl od spectoda.rx() má první argument mapu filtru. Filtr se vyhodnocuje nativně v C++ vrstvě před tím, než se packet předá do Berry.

import espnow
var off = espnow.rx({
"mac": "AA:BB:CC:DD:EE:FF",
"size": 13,
"magic": [0x81, 0x91]
}, def(mac, data, rssi, channel)
print(mac, data.tohex(), rssi, channel)
end)
# Později:
off()

Signatura:

espnow.rx(filter: map|nil, callback: function(mac: string, data: bytes, rssi: int, channel: int)) -> function

Callback dostane:

  • mac jako MAC adresu odesílatele ve tvaru AA:BB:CC:DD:EE:FF
  • data jako zkopírovaný Berry bytes payload
  • rssi jako sílu signálu přijatého packetu
  • channel jako Wi-Fi kanál, na kterém packet dorazil

Podporované klíče filtru:

KlíčTypVýznam
macstringPovolí jen packety z jedné MAC adresy.
sizeintPovolí jen payload s přesnou délkou 1..250 bajtů.
magicint nebo list<int>Povolí jen payload, jehož první bajt odpovídá jedné z hodnot. Seznam může mít maximálně 4 hodnoty.

Filtr může být i nil, ale pro reálné projekty je lepší filtrovat už v C++. Například GLEDOPTO GL-RC-001WL posílá 13bajtový payload, který začíná hodnotou 0x81 nebo 0x91, takže dobrý základní filtr je:

var f = {
"size": 13,
"magic": [0x81, 0x91]
}

Pokud znáte MAC adresu svého ovladače, přidejte i mac. Tím snížíte počet packetů, které musí Berry zpracovat.

Ve FW 0.12.11 je raw RX cesta primárně side-channel pro packety, které nejsou rozpoznané jako Spectoda Mesh komunikace. Firmware do espnow.rx() předává packety odmítnuté před mesh dekódováním, typicky payloady kratší než 32 bajtů nebo payloady, jejichž délka není násobkem 16 bajtů. Pokud navrhujete vlastní raw ESP-NOW protokol pro příjem v Berry, zvolte tvar payloadu, který nebude vypadat jako Spectoda Mesh packet, nebo si chování ověřte na cílové verzi firmware.

espnow.tx() odešle raw ESP-NOW payload na zadanou MAC adresu.

import espnow
var p = bytes()
p.append(0x01)
p.append(0x02)
var ok = espnow.tx("FF:FF:FF:FF:FF:FF", p)
print("raw tx", ok)

Signatura:

espnow.tx(mac: string, data: bytes) -> bool

Praktické vlastnosti ve FW 0.12.11:

  • payload musí mít velikost 1..250 bajtů
  • odesílá se na aktuálním ESP-NOW kanálu kontroleru
  • funkce nepřepíná kanál
  • návratová hodnota říká, jestli se packet podařilo zařadit k odeslání
  • raw ESP-NOW payload není zabalený do Spectoda Mesh zprávy

Broadcast MAC FF:FF:FF:FF:FF:FF je vhodná pro raw experimenty a device-specific protokoly, ale pro běžnou komunikaci kontrolerů v projektu používejte spectoda.tx/rx.

Nový callback pattern je:

var off = espnow.rx({"size": 13}, def(mac, data, rssi, channel)
print(data.tohex())
end)
# off je funkce. Zavoláním odhlásí právě tuto registraci.
off()

Stejný pattern platí i pro spectoda.rx():

var off = spectoda.rx("SYNC", def(data, label)
print(data.tohex())
end)
off()

Každý návratový handle odhlašuje jen jednu konkrétní registraci. Pokud stejný plugin zaregistruje více callbacků, uložte si více handle funkcí.

Starší kompatibilní tvar:

espnow.rx = def(mac, data, rssi, channel)
print(data.tohex())
end
espnow.rx = nil

Ve FW 0.12.11 ještě existuje, ale pro nový kód ho nepoužívejte. Při přiřazení callbacku se vyčistí všechny aktivní raw ESP-NOW registrace a nainstaluje se jeden nefiltrovaný callback. To se špatně kombinuje s více pluginy.

Nový kód pište vždy jako:

var off = espnow.rx(filter, callback)

espnow.rx() je navržené jako raw side-channel nad ESP-NOW. Díky tomu může kontroler přijímat například packety z GLEDOPTO ovladače a zároveň ponechat zapnutou normální ESP-NOW komunikaci mezi kontrolery.

Nepoužívejte staré ESPNOWRADIO IO pro nové projekty, které mají současně fungovat jako běžná Spectoda instalace. ESPNOWRADIO je legacy cesta pro samostatnou raw radio práci a v nových skriptech má být nahrazené espnow.rx/tx.

Není potřeba nastavovat espnow.enable = true. ESP-NOW je v běžném runtime zapnuté podle konfigurace kontroleru. Pokud ESP-NOW explicitně vypnete, raw TX/RX ani Controller-to-Controller komunikace nebudou fungovat.

GLEDOPTO GL-RC-001WL posílá při stisku tlačítka ESP-NOW packety na více Wi-Fi kanálech. Script proto typicky deduplikuje sekvenci uvnitř payloadu a reaguje jen na první packet daného stisku.

Základní příjem:

import espnow
var last_seq = -1
var off = espnow.rx({
"mac": "AA:BB:CC:DD:EE:FF",
"size": 13,
"magic": [0x81, 0x91]
}, def(mac, data, rssi, channel)
var seq = data.get(1, 4)
if seq == last_seq
return
end
last_seq = seq
var button = data.get(6)
print("GLEDOPTO", button, "rssi", rssi, "ch", channel)
end)

Pro hotové mapování tlačítek na toggl, brigh a tempe EventState použijte veřejné příklady pro GLEDOPTO GL-RC-001WL v repozitáři Spectoda Examples.

Pro vlastní komunikaci mezi kontrolery:

  • zvolte krátký message label, například SYNC, BRIG, ARTN
  • udržujte payload binární a malý
  • na začátek payloadu dejte typ zprávy nebo verzi protokolu
  • callback odhlašujte přes off(), pokud plugin dočasně mění režim
  • nepoužívejte MAC adresy, pokud cílem není raw transportní práce

Pro raw ESP-NOW:

  • vždy nastavte alespoň size a magic, pokud znáte formát packetu
  • mac přidejte tam, kde je potřeba svázat projekt s konkrétním ovladačem
  • ve callbacku zpracovávejte minimum práce a složitější stav držte v pluginu
  • logování přes print() zapínejte jen při testování