Skip to content

dunknowcoding/ArduinoNRF-Zigbee

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

113 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

⚑ NiusZigbee

A complete Zigbee 3.0 / Zigbee PRO stack on two cheap chips. An ArduinoNRF (nRF52840) drives an AliExpress CC2530 radio over UART β€” and runs the entire Zigbee stack itself: scan & join, self-healing mesh routing, AES-CCM* NWK/APS security, commissioning, Green Power, and a dozen ZCL clusters. No TI Z-Stack, no gateway, no cloud. Flash the radio once, then it's just an Arduino sketch.

Arduino Library MCU Radio Zigbee Backends License Release

The companion to the ArduinoNRF board package, kept as a separate library so the board package stays small.

Why it's different

  • 🧠 The whole stack runs on the host MCU β€” the $1 CC2530 is just a PHY/MAC radio; NWK, APS, ZCL, ZDO, security and routing all live on the nRF52840.
  • πŸ”“ No vendor stack required β€” a clean-room SDCC transceiver firmware, flashed once over the debug port by the board package's built-in CCDebugger.
  • πŸ” Two backends, one API β€” run the native host stack, or drive a CC2530 running TI Z-Stack ZNP as a certified coprocessor.
  • πŸ“‘ TI-grade MAC reliability β€” IEEE 802.15.4 unslotted CSMA-CA, MAC-level ACK + retransmit, and energy-detect scan in the radio firmware: the same channel-access, per-hop reliability, and channel-sensing the official Z-Stack MAC uses (verified recovering frames under congestion on the bench).
  • πŸ› οΈ Hardware-proven β€” bring-up across up to 5 boards: a 3-hop line, a self-healing 2Γ—2 mesh, Green Power, and source-routed delivery.
  • πŸ”‘ Own crypto, R23-ready β€” all cryptography is in-tree (no external library), including an RFC-7748-verified X25519 and a SPEKE Dynamic Link Key, the Zigbee PRO 2023 key-establishment that retires the well-known link key.

What it does

  • Raw 802.15.4 send / receive / sniff on the CC2530, with a bundled SDCC transceiver firmware (no TI Z-Stack needed; the module is flashed once over its debug port by the board package's built-in CCDebugger).
  • A complete Zigbee 3.0 / Zigbee PRO stack, host-side on the nRF52840: active scan + join, AODV routing + source routing, multi-hop forwarding, AES-CCM* NWK and APS security (on the nRF hardware AES), end-to-end acked delivery, multi-hop APS fragmentation, group multicast, binding, persistence, Trust-Center key transport + rotation + install codes, BDB / finding-and-binding / Touchlink commissioning, Green Power (battery-less devices), a dozen ZCL device clusters, and ZDO network management β€” the full Zigbee PRO surface.
  • Two module backends: the native host stack above (default), or drive a CC2530 running TI Z-Stack ZNP as a certified-stack coprocessor over the MT API (CC2530ZnpRadio).
  • Verified on air on up to 5 boards (ProMicro clones + nice!nano v2): a 3-hop line at 100% delivery, a self-healing 2Γ—2 mesh, mesh + Green Power, and source-routed delivery. β†’ details in docs/VERIFIED_BEHAVIOR.md.

How it works

   ArduinoNRF (nRF52840)                         CC2530 module
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    UART  115200    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ CC2530Radio (this β”‚  D0 ─► P0.2 (RX)   β”‚  SDCC 802.15.4     β”‚
   β”‚ library)          β”‚  D1 ◄─ P0.3 (TX)   β”‚  transceiver fw    │──))) 2.4 GHz
   β”‚                   β”‚                    β”‚                    β”‚
   β”‚ CCDebugger (board β”‚  D8 ─► P2.1 (DD)   β”‚  (flashed once via β”‚
   β”‚ package) flashes  β”‚  D9 ─► P2.2 (DC)   β”‚   the debug port)  β”‚
   β”‚ the module        β”‚  D10─► RST         β”‚                    β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Flashing the module needs no external programmer β€” the board package's built-in CCDebugger does it over the 2-wire debug port.
  • At runtime the nRF talks to the module over UART with a small framed protocol; the CC2530 does the radio PHY/MAC, the nRF does everything above it.

Mesh topology

Each node is one nRF52840 + CC2530 pair. The library forces a chosen shape on a bench of co-located radios with depth-filtered joins + IEEE association-ignore lists, so the same boards can play coordinator, router, end device, or Green Power sink. All four shapes below are verified on hardware (evidence).

NiusZigbee mesh topology: board1 coordinator, board2/board3 routers, board4 end device, board5 Green Power

Topology Build flag What it shows
3-hop line board1β†’board2β†’board3β†’board4 -DNIUS_ZIGBEE_LINE_TOPO=1 APS-acked data across 3 hops and back at 100% (aps[q=15 ok=15 drop=0])
2Γ—2 mesh + route repair -DNIUS_ZIGBEE_MESH_TOPO=1 board2/board3 redundant routers; board4 self-heals onto the other router when its parent is silenced
Mesh + Green Power -DNIUS_ZIGBEE_GP_SINK=1 board1 runs the mesh and sinks board5's battery-less Green Power frames
Source-route OTA (NWK-secured) -DNIUS_ZIGBEE_SOURCEROUTE=1 board4's Route Record walks up the line; board1 source-routes a frame back down, secured per hop with the relay index AAD-excluded

board4/board5 are nice!nano v2 (S140) boards β€” the SoftDevice sits dormant, the hardware AES is free, and the full stack runs identically to the no-SoftDevice ProMicro boards.

Install

  1. Install the ArduinoNRF board package (provides the board + the CCDebugger flasher).
  2. Install this library β€” Sketch β–Έ Include Library β–Έ Add .ZIP Library…, clone into your Arduino libraries/ folder, or via Library Manager (published as NiusZigbee; the repo keeps the ArduinoNRF-Zigbee name).

Quick start

  1. Wire it up β€” debug pins (D8/D9/D10) and UART pins (D0/D1), 3.3 V only. See docs/WIRING.md. P2.0 (CFG1) is unused by this firmware; leave it floating or tie to GND.
  2. Flash the module firmware once β€” Examples β–Έ ArduinoNRF-Zigbee β–Έ CC2530_FlashFirmware (uses the built-in CC-Debugger; docs/FLASHING.md).
  3. Use it β€” start with CC2530_Info (confirm the link), CC2530_Sniffer (packet sniffer), or CC2530_Link (two-node radio link). The full mesh demo is CC2530_BeaconJoin (scan/join, routing, multi-hop, NWK security, acked APS); build the roles with -DNIUS_ZIGBEE_THIS_NODE=0x0001/0x0002/0x0003 and the topology flags above. See examples/ for the complete set, including ZCL cluster demos and the single-board protocol self-tests.
#include <CC2530Radio.h>
CC2530Radio radio;                 // uses Serial1 (D0/D1)

void onFrame(const uint8_t* p, uint8_t n, int8_t rssi, uint8_t lqi) { /* ... */ }

void setup() {
  radio.begin(11);                 // 115200 UART, channel 11
  radio.onReceive(onFrame);
}
void loop() {
  radio.poll();
  radio.send((const uint8_t*)"hi", 2);
}

Board layout note: some nice!nano-compatible bootloaders report SoftDevice: not found in INFO_UF2.TXT. For those, select the no-SoftDevice bootloader option (bootloader=promicroserialnosd) so the sketch links at 0x1000. A SoftDevice layout can upload but never starts.

API (CC2530Radio)

Method Purpose
begin(channel=11, baud=115200) open the UART, ping, select channel
ping() / firmwareVersion() liveness check / firmware version
setChannel(11..26) / channel() select / read the 802.15.4 channel
setPromiscuous(bool) receive all frames (sniffer) vs filtered
setAddress(pan, short, ieee) program CC2530 PAN ID, short address, IEEE address
configureMac(flags, retries) / getMacInfo(info) hardware filtering, Auto ACK, CCA TX, retry count
setTxPowerRaw(value) write the CC2530 TXPOWER register
send(payload, len) transmit a raw 802.15.4 frame (radio adds FCS)
sendWithRetries(payload, len, retries) / lastTxAttempts() transmit with retries + attempt count
sendData(...) / onDataReceive(cb) short-address 802.15.4 MAC data frames
sendNwkData(...) / onNwkReceive(cb) simple Zigbee NWK data frames
sendNwkCommand(...) / onNwkCommandReceive(cb) NWK command frames (Route Request/Reply, Status, Leave, Rejoin)
sendApsData(...) / onApsReceive(cb) unicast Zigbee APS data frames
sendZdoCommand(...) / onZdoReceive(cb) ZDO (endpoint 0 / profile 0) frames
sendZclCommand(...) / onZclReceive(cb) basic ZCL command frames
onReceive(cb) + poll() deliver raw received frames to your callback

send() carries raw 802.15.4 β€” perfect for CC2530↔CC2530 links and sniffing. The sendData/sendNwk*/sendAps*/sendZdo*/sendZcl* families add each successive Zigbee frame layer on top of that MAC base. The higher-level stack (scan/join, routing, security, commissioning, clusters) is provided by the Zigbee* classes summarized below; the per-class layering story is in docs/STACK_ROADMAP.md.

Zigbee PRO networking & security

Layered on the MAC base; each piece ships with a hardware self-test example.

  • NWK security. ZigbeeSecurity protects every NWK frame with AES-CCM* ENC-MIC-32 (Zigbee aux header, on-air level zeroing, frame-counter replay table) on the nRF52840 hardware AES. The CCM* core (ZigbeeCcmStar.h) is shared with APS.
  • APS reliability. ZigbeeApsRetransmit + ZigbeeApsDuplicateTable give end-to-end acked delivery with retransmit + duplicate rejection; ZigbeeApsFragment splits/reassembles oversized payloads.
  • Trust-Center key transport. ZigbeeApsKey + ZigbeeApsSecurity: Transport-Key / Request-Key / Switch-Key, AES-MMO hash, HMAC-MMO, specialized key derivation, APS CCM* envelope. Wired into the join via -DNIUS_ZIGBEE_SECURE_JOIN=1 (HW-verified end to end; needs CC2530 fw v0.4).
  • Routing & forwarding. ZigbeeRouting runs AODV (RREQ/RREP, reverse routes); the example forwards multi-hop unicast with per-hop re-encryption.
  • Network management. ZDO Mgmt_Lqi / Mgmt_Rtg, ZigbeeBroadcastTable (dedup + passive-ack), ZigbeePanIdConflict.
  • Sleepy end devices. ZigbeeMac::buildDataRequest + ZigbeeIndirectQueue + ZigbeeEndDeviceTimeout (keep-alive negotiation).
  • Persistence & binding. ZigbeePersistence (network identity + frame counter, anti-replay across reboots); ZigbeeBindingTable (ZDO Bind/Unbind).
  • Source routing. ZigbeeSourceRouteTable + Route Record collection + concentrator-originated source-routed data frames.
  • Groups & app encryption. ZigbeeGroupTable + ZigbeeGroupsCluster; ZigbeeApsSecurity::secureDataFrame adds an APS link-key envelope over NWK.
  • Commissioning (BDB / Touchlink). ZigbeeBdb, ZigbeeFindingBinding, ZigbeeInstallCode, ZigbeeTouchlink (with a software AES-128 inverse cipher, since the nRF ECB is encrypt-only), ZigbeeInterPan.
  • Green Power. ZigbeeGreenPower (GPDF + AES-CCM* + commissioning) + ZigbeeGpSinkTable (frame-counter replay protection), plus ZigbeeGpProxy + the GP cluster (0x0021) ZigbeeGreenPowerCluster to tunnel a battery-less device across the mesh to a distant sink.
  • ZCL device clusters. Basic, Identify, Groups, Scenes, On/Off, Level Control, Color Control, Thermostat, Window Covering, Door Lock, IAS Zone, Occupancy Sensing, Temperature / Relative-Humidity / Electrical Measurement, OTA Upgrade, attribute reporting, and a ZigbeeLight device abstraction, each exercised by a hardware self-test example.

Current stack boundary

NiusZigbee implements the full Zigbee 3.0 / Zigbee PRO surface on top of the SDCC CC2530 MAC/PHY backend (MAC frames/association/filtering Β· NWK scan/join/route/ source-route/security Β· APS acked delivery/fragmentation/groups/app encryption Β· TC key transport + rotation + install codes + BDB/Touchlink commissioning Β· ZDO discovery + management + binding Β· the ZCL clusters above (On/Off, Level, Color, Thermostat, Window Covering, Door Lock, IAS Zone, Occupancy, Temperature / Humidity / Electrical Measurement, OTA) + Green Power).

It is not certified Zigbee PRO (that needs the official test harness), but the technical surface is complete. Source-routed frames are NWK-secured on air β€” the mutable relay-index byte is excluded from the CCM* AAD, so a relay can advance it and re-secure under its own aux header without breaking the MIC (radio.sendNwkDataSourceRouted()). Sleepy-child support is done end to end: the host queues indirect traffic and the CC2530 firmware sets the auto-ACK frame-pending bit (FRMCTRL1.PENDING_OR, via radio.setFramePending()) so a polling child learns when data is waiting.

The CC2530 transceiver firmware now carries the same channel-access and per-hop reliability the official Z-Stack MAC uses: IEEE 802.15.4 unslotted CSMA-CA (random exponential backoff before TX), MAC-level ACK + retransmit (wait for the ACK, retransmit up to macMaxFrameRetries), and live MAC reliability counters (mac[retx noack]) so per-hop delivery is observable on the bench. A second backend lives beside the raw driver β€” CC2530ZnpRadio drives a CC2530 running TI Z-Stack ZNP over the MT API. Milestone status and on-air evidence: docs/STACK_ROADMAP.md Β· docs/VERIFIED_BEHAVIOR.md.

Extending to new modules

Drop a driver in src/modules/<NAME>/, its firmware in extras/firmware/<name>/, a forwarder header in src/, and examples under examples/. See src/ZigbeeModule.h. The built-in CCDebugger flashes any TI CC253x image (SDCC or Z-Stack).

Firmware

The CC2530 transceiver firmware source (SDCC) and prebuilt binary live in extras/firmware/cc2530/. Build notes: extras/firmware/cc2530/BUILD.md.

License

Apache 2.0 β€” see LICENSE. Author: dunknowcoding (YouTube: NiusRobotLab). If you use it in a product, please credit the original author and note your changes.

About

Zigbee Arduino library designed specially for ArduinoNRF board library

Topics

Resources

License

Stars

3 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors