Menu
Microbots
0
  • Learn
    • Getting Started
    • Maker Builds
    • Education
  • Shop
    • Modules & Parts
    • Tools & Gears
    • Robots & Displays
  • About
    • Our Story
    • Reach Out
    • FAQs
  • Sign in
  • English
  • Your Cart is Empty
Microbots
  • Learn
    • Getting Started
    • Maker Builds
    • Education
  • Shop
    • Modules & Parts
    • Tools & Gears
    • Robots & Displays
  • About
    • Our Story
    • Reach Out
    • FAQs
  • Language

  • 0 0

CodeCell: Getting Started with Zigbee

CodeCell C6 is powered by the ESP32-C6, supporting Zigbee, Thread, Wi-Fi 6, and Bluetooth LE. In this guide we’ll focus on Zigbee and how you can use it with CodeCell C6 in the Arduino IDE.

CodeCell C6 Zigbee

What Is Zigbee?

Zigbee is a wireless communication protocol built for low power and reliability. Unlike Wi-Fi, Zigbee is not meant for large data transfers. Instead, it focuses on small messages between devices such as sensors, lights, switches, and smart plugs.

Key characteristics of Zigbee:

  • Low power: Great for battery-powered devices.
  • Mesh network: Each device can relay messages, extending range across a home or building.
  • Reliable: Works well even in environments with lots of Wi-Fi traffic.
  • Smart-home friendly: Used in systems like Philips Hue, Aqara, IKEA TRÅDFRI and many hubs that support Zigbee or Matter bridges.

Zigbee vs Wi-Fi vs Bluetooth LE

  • Wi-Fi: High speed, high power. Best for internet access, web servers, and cloud-connected devices.
  • Bluetooth LE: Short-range, low power. Best for phone peripherals and direct connections.
  • Zigbee: Best for sensors, automation, and smart-home devices. Because Zigbee forms a mesh, you can place small devices around a room or house, and they help extend each other’s range.

If You’re New to Zigbee + Home Assistant

If you’re just starting with Zigbee, one of the easiest ways to experiment is with Home Assistant:

  • Grab a Zigbee USB coordinator like the SONOFF Zigbee USB Dongle (or similar).
  • Plug it into a Raspberry Pi running Home Assistant.
  • In Home Assistant, add the Zigbee integration (e.g. ZHA) and pair your CodeCell C6 as a new device.

This setup makes the USB dongle your Zigbee coordinator, and your CodeCell boards become nodes on that network. 


Arduino IDE Setup for Zigbee on CodeCell C6

Before uploading the example, make sure the Arduino Tools menu is configured for Zigbee on the ESP32-C6. In the Arduino IDE, go to Tools and check:

  • Board: ESP32C6 Dev Module
  • Flash Size: 8MB (64Mb)
    This matches the C6 module’s flash size so the Zigbee stack and your sketch fit correctly.
  • Partition Scheme: Zigbee 8MB with spiffs
    This layout reserves space for the Zigbee stack and NVS while still leaving room for SPIFFS and your application.
  • Zigbee Mode: Zigbee ED (end device)
    This makes the CodeCell behave as a Zigbee end device (sensor, switch, etc.) that joins a coordinator like your Home Assistant dongle.

Once these are set, you can compile and flash the sketch below directly to your CodeCell C6 or C6 Drive.


Example 1 – Zigbee On/Off Light (CodeCell as a Simple Light)

In this example, the CodeCell controls a real lamp using Home Assistant automations:

Home Assistant Zigbee

  • Shake the CodeCell to toggle the lamp ON/OFF
  • Hold your finger near the proximity sensor to enable “brightness mode”
  • Tilt up/down to increase/decrease brightness (while proximity is active)

The CodeCell exposes two Zigbee endpoints:

  • Endpoint 1 (ZigbeeAnalog): a brightness value (0–254) derived from Pitch angle (only when proximity is active)
  • Endpoint 4 (ZigbeeBinary): a binary toggle that flips state on each shake

Important: Home Assistant will receive these as entities, but you still need to create automations that map them to your actual lamp. In our setup we created 3 automations:

  • If shake detected → toggle lamp ON/OFF
  • If tilt up → increase brightness
  • If tilt down → decrease brightness
/*
  Example: CodeCell Zigbee Lamp Control - Tilt-Brightness + Shake Switch
  Boards: CodeCell C6 / CodeCell C6 Drive

  Overview:
  - Endpoint 1 (ZigbeeAnalog): When proximity sensor is pressed, the CodeCell's Pitch angle is mapped to brightness
      Use this value in Home Assistant to set a lamp's brightness.
  - Endpoint 2 (ZigbeeBinary): toggled by a shake gesture, toggles the binary state ON/OFF
      Use this in Home Assistant to turn the lamp on/off.

  Behavior:
  - Press proximity sensor with fingure → proximity detected → "brightness control" is active.
  - Tilt the CodeCell to change Pitch → this updates the brightness value.
  - Remove your fingure → brightness control stops (lamp can stay at last value).
  - Shake the CodeCell → endpoint toggles (can be mapped to toggle lamp automations)

  Required Arduino Tools Settings:
  - Board: ESP32C6 Dev Module
  - Flash Size: 8MB (64Mb)
  - Partition Scheme: Zigbee 8MB with spiffs
  - Zigbee Mode: Zigbee ED (end device)
*/

#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif

#include <CodeCell.h>
#include "Zigbee.h"
#include <math.h> 

// Zigbee endpoints
#define ZIGBEE_BRIGHTNESS_ENDPOINT  1   // Numeric brightness value (0–254)
#define ZIGBEE_SHAKE_ENDPOINT       4   // Binary toggle (shake switch)

// Proximity threshold for "brightness control active"
#define PROX_ACTIVE_THRESHOLD       200U   // Adjust to taste

// Pitch → brightness mapping
#define PITCH_MIN_DEG              -45.0f  // Fully down
#define PITCH_MAX_DEG               45.0f  // Fully up

// Shake detection
const float SHAKE_THRESHOLD           = 15.0f;   // Adjust for sensitivity
const unsigned long SHAKE_DEBOUNCE_MS = 800UL;   // Minimum time between shakes

CodeCell myCodeCell;

// Zigbee endpoints
ZigbeeAnalog zbBrightness(ZIGBEE_BRIGHTNESS_ENDPOINT);
ZigbeeBinary zbShake(ZIGBEE_SHAKE_ENDPOINT);

// Motion variables
float Roll  = 0.0f;
float Pitch = 0.0f;
float Yaw   = 0.0f;

float ax = 0.0f, ay = 0.0f, az = 0.0f;

uint8_t lastBrightness           = 0;
unsigned long lastBrightReportMs = 0;
const uint8_t BRIGHT_DELTA_MIN   = 3;      // Minimum change to report
const unsigned long BRIGHT_REPORT_INTERVAL_MS = 300UL;

bool shakeState          = false;      // Toggles ON/OFF on each shake
unsigned long lastShakeMs = 0;

void handleBrightness(uint16_t proximity);
void handleShake();

void setup() {
  Serial.begin(115200);

  // Enable Light + Rotation (pitch) + Accelerometer
  myCodeCell.Init(LIGHT + MOTION_ROTATION + MOTION_ACCELEROMETER);

  myCodeCell.LED(0, 0, 0);//Turn off on-board LED

  // Brightness endpoint (analog-like input) 
  zbBrightness.setManufacturerAndModel("Microbots", "CodeCellC6-PitchBrightness");
  zbBrightness.addAnalogInput();

  // Use Espressif's "percentage" application type so ZHA treats it as a generic level
  zbBrightness.setAnalogInputApplication(ESP_ZB_ZCL_AI_PERCENTAGE_OTHER);
  zbBrightness.setAnalogInputDescription("Brightness level (0–254) from Pitch angle");
  zbBrightness.setAnalogInputResolution(1.0f);
  zbBrightness.setAnalogInputMinMax(0.0f, 254.0f);

  // Shake endpoint 
  zbShake.setManufacturerAndModel("Microbots", "CodeCellC6-ShakeSwitch");
  zbShake.addBinaryInput();
  zbShake.setBinaryInputApplication(BINARY_INPUT_APPLICATION_TYPE_SECURITY_MOTION_DETECTION);
  zbShake.setBinaryInputDescription("Shake to toggle");

  // Register endpoints with Zigbee core 
  Serial.println("Adding Zigbee endpoints (brightness + shake)");
  Zigbee.addEndpoint(&zbBrightness);
  Zigbee.addEndpoint(&zbShake);

  // Start Zigbee
  Serial.println("Starting Zigbee...");
  if (!Zigbee.begin()) {
    Serial.println("Zigbee failed to start, rebooting...");
    ESP.restart();//If not connected - reset esp32
  }

  Serial.println("Connecting to Zigbee network...");
  while (!Zigbee.connected()) {
    Serial.print(".");
    delay(100);
  }
  Serial.println("\nZigbee connected!");
}

void loop() {
  if (myCodeCell.Run(10)) { // Run sensors at 10 Hz
    
    uint16_t proximity = myCodeCell.Light_ProximityRead(); // Read proximity first (to know if brightness control is active)

    // Read rotation (roll, pitch, yaw)
    myCodeCell.Motion_RotationRead(Roll, Pitch, Yaw);

    // Handle brightness control using Pitch when proximity is active
    handleBrightness(proximity);

    // Handle shake-based toggle
    handleShake();
  }
}

/**
 * Handle brightness control:
 * - If proximity is above threshold, use Pitch to map to brightness 0–254.
 * - Sends brightness to Zigbee as analog input.
 * - LED shows brightness using green channel.
 */
void handleBrightness(uint16_t proximity) {
  unsigned long now = millis();

  if (proximity < PROX_ACTIVE_THRESHOLD) {
    // No hand close → brightness control not active
    myCodeCell.LED(0, 0, 0);  // LED off
    return;
  }

  // Clamp pitch and map to 0–254
  float pitchClamped = Pitch;
  if (pitchClamped < PITCH_MIN_DEG) {
    pitchClamped = PITCH_MIN_DEG;
  }
  else if (pitchClamped > PITCH_MAX_DEG) {
    pitchClamped = PITCH_MAX_DEG;
  }
  else{
    //skip
  }

  // Normalize Angle
  float normalized = (pitchClamped - PITCH_MIN_DEG) / (PITCH_MAX_DEG - PITCH_MIN_DEG);
  if (normalized < 0.0f) {
    normalized = 0.0f;
  } else if (normalized > 1.0f) {
    normalized = 1.0f;
  }
  else{
    //skip
  }

  uint8_t brightness = (uint8_t)(normalized * 254.0f);

  // Only report if changed enough or enough time passed
  if ( (abs((int32_t)brightness - (int32_t)lastBrightness) >= (int32_t)BRIGHT_DELTA_MIN) ||
       (now - lastBrightReportMs >= BRIGHT_REPORT_INTERVAL_MS) ) {

    lastBrightReportMs = now;
    lastBrightness = brightness;

    zbBrightness.setAnalogInput((float)brightness);
    zbBrightness.reportAnalogInput();

    Serial.print("Pitch: ");
    Serial.print(Pitch);
    Serial.print(" deg -> Brightness: ");
    Serial.println(brightness);
  }

  // Visual feedback: LED green = brightness level
  myCodeCell.LED(0, brightness, 0);
}

/**
 * Handle shake detection:
 * - Read accelerometer.
 * - If total acceleration crosses threshold (and debounce passes),
 *   toggle a Zigbee binary endpoint.
 */
void handleShake() {
  unsigned long now = millis();

  myCodeCell.Motion_AccelerometerRead(ax, ay, az);
  float totalAcceleration = sqrt(ax * ax + ay * ay + az * az);

  if (totalAcceleration > SHAKE_THRESHOLD && (now - lastShakeMs) > SHAKE_DEBOUNCE_MS) {
    lastShakeMs = now;

    // Toggle internal state
    shakeState = !shakeState;

    Serial.print("Shake detected! New switch state: ");
    Serial.println(shakeState ? "ON" : "OFF");

    // Update and report binary input (shake switch) to Zigbee
    zbShake.setBinaryInput(shakeState);
    zbShake.reportBinaryInput();
  }
}

How It Works

  • Brightness control: When your finger is close to the proximity sensor (value above PROX_ACTIVE_THRESHOLD), the CodeCell maps Pitch to a brightness value (0–254) and reports it via ZigbeeAnalog.
  • Shake toggle: A shake gesture toggles a boolean state and reports it via ZigbeeBinary. Home Assistant can use that change as a trigger.
  • Home Assistant automations: Use the CodeCell entities as triggers/inputs, then control any lamp entity you want (smart bulb, smart plug, etc.).

Other Basic Zigbee Examples You Can Try

  • Zigbee Light Switch
  • Zigbee Color Light (Control Color & Brightness)
  • Zigbee Proximity Presence Sensor
  • Zigbee Motion Sensor (BNO085 Motion State)

Try modifying thresholds, report intervals, or combining multiple endpoints in one sketch, and you’ll quickly have your own custom Zigbee devices running on CodeCell C6.

  • Share:

Follow

Github

  • About
  • Software
  • Education
  • Contact
  • FAQs
  • Terms
  • Refund Policy
  • Privacy Policy

Join our Community ~ Be the first to know about new products and get exciting deals!

© 2026 Microbots.

★ Reviews

Let customers speak for us

41 reviews
Write a review
80%
(33)
5%
(2)
2%
(1)
5%
(2)
7%
(3)
21
37
A
CodeCell C6
Anonymous

Love it

L
CoilCell
Laszlo Hasenau

Nice to have the drivers integrated, sufficient for very small units, where low force needed.

User picture
L
CodeCell C6 Drive
Leon

Love this thing! The coding for controlling the integrated drivers is extremely intuitive, the chip is fast as always and all the other sensors work like a charm. If there were 6 stars id give all of em but theres only 5 XD

A
CodeCell C6 Drive
Anonymous

Pequeno e esperto. TEM projetos com câmera 📷🎥?
DVR PARA MOTO 🛵?

A
CodeCell C3
Anonymous

Busy developing something that has been a very popular topic in the maker space. Once complete I will share it all with you including the coding.I am really impressed with the punch this little C3 packs. Really a great piece of engineering. Keep up the brilliant work and thank you for making this little giant!!!!!!

123