├── images ├── dir_tree.jpg └── ESP32C6_pinout.png ├── libraries ├── ESPAsyncWebServer │ ├── keywords.txt │ ├── library.properties │ ├── library.json │ └── src │ │ ├── SPIFFSEditor.h │ │ ├── WebAuthentication.h │ │ ├── AsyncWebSynchronization.h │ │ ├── AsyncEventSource.h │ │ ├── StringArray.h │ │ ├── WebResponseImpl.h │ │ ├── WebHandlerImpl.h │ │ └── WebServer.cpp ├── location.jpg ├── AsyncTCP │ ├── library.properties │ ├── library.json │ └── README.md └── README.md ├── 09-zigbee-bulb ├── tools_config.jpg ├── .gitignore ├── Zigbee_Light_Bulb │ ├── ci.json │ └── Zigbee_Light_Bulb.ino ├── platformio.ini ├── include │ └── README └── Readme.md ├── 08-zigbee-switch ├── tools_config.jpg ├── .gitignore ├── Zigbee_Light_Switch │ ├── ci.json │ ├── Zigbee_Light_Switch.ino │ └── README.md ├── Readme.md ├── platformio.ini └── include │ └── README ├── 03_scan_wifi ├── .gitignore ├── platformio.ini ├── scan_wifi │ ├── scan_wifi.ino │ ├── main.cpp │ └── main.cpp.orig └── include │ └── README ├── 07_ble_led ├── .gitignore ├── platformio.ini ├── ble_led │ ├── ble_led.ino │ └── main.cpp └── include │ └── README ├── 02_blink_pulse_led ├── .gitignore ├── platformio.ini ├── blink_pulse_led │ ├── blink_pulse_led.ino │ └── main.cpp └── include │ └── README ├── 04_wifi_blackhole ├── .gitignore ├── wifi_blackhole │ ├── secrets.h.template │ ├── wifi_blackhole.ino │ └── main.cpp ├── platformio.ini └── include │ └── README ├── 05_wifi_tx_power ├── .gitignore ├── wifi_tx_power │ ├── secrets.h.template │ └── wifi_tx_power.ino ├── platformio.ini └── include │ └── README ├── 06_async_web_led ├── .gitignore ├── async_web_led │ ├── secrets.h.template │ ├── README.md │ ├── async_web_led.ino │ ├── html.h │ └── main.cpp ├── platformio.ini └── include │ └── README ├── 10_deep_sleep_tmr ├── .gitignore ├── platformio.ini ├── deep_sleep_tmr │ ├── deep_sleep_tmr.ino │ └── main.cpp └── include │ └── README ├── 11_deep_sleep_io ├── .gitignore ├── platformio.ini ├── deep_sleep_io │ ├── deep_sleep_io.ino │ └── main.cpp └── include │ └── README ├── 13_wifi_uptime ├── .gitignore ├── wifi_uptime │ ├── secrets.h.template │ ├── wifi_uptime.ino │ ├── html.h │ ├── README.md │ └── main.cpp ├── platformio.ini └── include │ └── README ├── 15_zigbee-on-off-light ├── tools_config.jpg ├── zigbee2mqtt_state.jpg ├── zigbee2mqtt_devices.jpg ├── Zigbee_On_Off_Light │ ├── ci.json │ ├── Zigbee_On_Off_Light.ino │ ├── README-org.md │ ├── main.cpp │ └── README.md ├── Readme.md ├── platformio.ini └── include │ └── README ├── 12_xiao32c6_antenna ├── .gitignore ├── img │ ├── xiao_esp32c6_rssi.png │ ├── xiao_esp32c6_ant_circuit.jpg │ └── xiao_esp32c6_ant_circuit_clean.jpg ├── platformio.ini ├── xiao32c6_antenna │ ├── xiao32c6_antenna.ino │ └── main.cpp ├── include │ └── README └── README.md ├── 14_zigbee-on-off-switch ├── tools_config.jpg ├── Zigbee_On_Off_Switch │ ├── ci.json │ ├── Zigbee_On_Off_Switch.ino │ ├── README-org.md │ ├── README.md │ └── main.cpp ├── Readme.md ├── platformio.ini └── include │ └── README ├── .hgtags ├── COPYING ├── 01_pin_names ├── pin_names │ ├── pin_names.ino │ └── main.cpp ├── platformio.ini └── include │ └── README └── boards ├── seeed_xiao_esp32c6.json └── README.md /images/dir_tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/images/dir_tree.jpg -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/keywords.txt: -------------------------------------------------------------------------------- 1 | JsonArray KEYWORD1 2 | add KEYWORD2 3 | createArray KEYWORD3 4 | -------------------------------------------------------------------------------- /libraries/location.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/libraries/location.jpg -------------------------------------------------------------------------------- /images/ESP32C6_pinout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/images/ESP32C6_pinout.png -------------------------------------------------------------------------------- /09-zigbee-bulb/tools_config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/09-zigbee-bulb/tools_config.jpg -------------------------------------------------------------------------------- /08-zigbee-switch/tools_config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/08-zigbee-switch/tools_config.jpg -------------------------------------------------------------------------------- /03_scan_wifi/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /07_ble_led/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /02_blink_pulse_led/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /04_wifi_blackhole/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /05_wifi_tx_power/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /06_async_web_led/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /08-zigbee-switch/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /09-zigbee-bulb/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /10_deep_sleep_tmr/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /11_deep_sleep_io/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /13_wifi_uptime/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/tools_config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/15_zigbee-on-off-light/tools_config.jpg -------------------------------------------------------------------------------- /12_xiao32c6_antenna/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/tools_config.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/14_zigbee-on-off-switch/tools_config.jpg -------------------------------------------------------------------------------- /15_zigbee-on-off-light/zigbee2mqtt_state.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/15_zigbee-on-off-light/zigbee2mqtt_state.jpg -------------------------------------------------------------------------------- /12_xiao32c6_antenna/img/xiao_esp32c6_rssi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/12_xiao32c6_antenna/img/xiao_esp32c6_rssi.png -------------------------------------------------------------------------------- /15_zigbee-on-off-light/zigbee2mqtt_devices.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/15_zigbee-on-off-light/zigbee2mqtt_devices.jpg -------------------------------------------------------------------------------- /12_xiao32c6_antenna/img/xiao_esp32c6_ant_circuit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/12_xiao32c6_antenna/img/xiao_esp32c6_ant_circuit.jpg -------------------------------------------------------------------------------- /12_xiao32c6_antenna/img/xiao_esp32c6_ant_circuit_clean.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sigmdel/xiao_esp32c6_sketches/HEAD/12_xiao32c6_antenna/img/xiao_esp32c6_ant_circuit_clean.jpg -------------------------------------------------------------------------------- /15_zigbee-on-off-light/Zigbee_On_Off_Light/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "fqbn_append": "PartitionScheme=zigbee,ZigbeeMode=ed", 3 | "requires": [ 4 | "CONFIG_SOC_IEEE802154_SUPPORTED=y" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/Zigbee_On_Off_Switch/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "fqbn_append": "PartitionScheme=zigbee_zczr,ZigbeeMode=zczr", 3 | "requires": [ 4 | "CONFIG_SOC_IEEE802154_SUPPORTED=y" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /13_wifi_uptime/wifi_uptime/secrets.h.template: -------------------------------------------------------------------------------- 1 | // Replace with the correct network credentials 2 | const char* ssid = "***Wi-Fi***Network***Name***"; 3 | const char* password = "***Wi-Fi***Network***Password***"; 4 | -------------------------------------------------------------------------------- /04_wifi_blackhole/wifi_blackhole/secrets.h.template: -------------------------------------------------------------------------------- 1 | // Replace with the correct network credentials 2 | const char* ssid = "***Wi-Fi***Network***Name***"; 3 | const char* password = "***Wi-Fi***Network***Password***"; 4 | -------------------------------------------------------------------------------- /05_wifi_tx_power/wifi_tx_power/secrets.h.template: -------------------------------------------------------------------------------- 1 | // Replace with the correct network credentials 2 | const char* ssid = "***Wi-Fi***Network***Name***"; 3 | const char* password = "***Wi-Fi***Network***Password***"; 4 | -------------------------------------------------------------------------------- /06_async_web_led/async_web_led/secrets.h.template: -------------------------------------------------------------------------------- 1 | // Replace with the correct network credentials 2 | const char* ssid = "***Wi-Fi***Network***Name***"; 3 | const char* password = "***Wi-Fi***Network***Password***"; 4 | -------------------------------------------------------------------------------- /09-zigbee-bulb/Zigbee_Light_Bulb/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": { 3 | "esp32": false, 4 | "esp32c3": false, 5 | "esp32c6": false, 6 | "esp32h2": false, 7 | "esp32s2": false, 8 | "esp32s3": false 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /08-zigbee-switch/Zigbee_Light_Switch/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": { 3 | "esp32": false, 4 | "esp32c3": false, 5 | "esp32c6": false, 6 | "esp32h2": false, 7 | "esp32s2": false, 8 | "esp32s3": false 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /libraries/AsyncTCP/library.properties: -------------------------------------------------------------------------------- 1 | name=AsyncTCP 2 | version=1.1.1 3 | author=Me-No-Dev 4 | maintainer=Me-No-Dev 5 | sentence=Async TCP Library for ESP32 6 | paragraph=Async TCP Library for ESP32 7 | category=Other 8 | url=https://github.com/me-no-dev/AsyncTCP 9 | architectures=* 10 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/library.properties: -------------------------------------------------------------------------------- 1 | name=ESP Async WebServer 2 | version=1.2.4 3 | author=Me-No-Dev 4 | maintainer=Me-No-Dev 5 | sentence=Async Web Server for ESP8266 and ESP31B 6 | paragraph=Async Web Server for ESP8266 and ESP31B 7 | category=Other 8 | url=https://github.com/me-no-dev/ESPAsyncWebServer 9 | architectures=* 10 | -------------------------------------------------------------------------------- /.hgtags: -------------------------------------------------------------------------------- 1 | 4aebe92e64ff9196e6e9a3a958b5e435578f6100 main 2 | 4aebe92e64ff9196e6e9a3a958b5e435578f6100 main 3 | 0000000000000000000000000000000000000000 main 4 | 0000000000000000000000000000000000000000 main 5 | 822c7aacb9ae51da5c9f9d16926364b8914a241c main 6 | 822c7aacb9ae51da5c9f9d16926364b8914a241c main 7 | 0000000000000000000000000000000000000000 main 8 | -------------------------------------------------------------------------------- /libraries/AsyncTCP/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"AsyncTCP", 3 | "description":"Asynchronous TCP Library for ESP32", 4 | "keywords":"async,tcp", 5 | "authors": 6 | { 7 | "name": "Hristo Gochkov", 8 | "maintainer": true 9 | }, 10 | "repository": 11 | { 12 | "type": "git", 13 | "url": "https://github.com/me-no-dev/AsyncTCP.git" 14 | }, 15 | "version": "1.1.1", 16 | "license": "LGPL-3.0", 17 | "frameworks": "arduino", 18 | "platforms": "espressif32", 19 | "build": { 20 | "libCompatMode": 2 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/Readme.md: -------------------------------------------------------------------------------- 1 | # 14_zigbee-on-off-switch 2 | 3 | The `Zigbee_On_Off_Switch` directory contains basically a clone of the example sketch from the `esp32` Arduino core version 3.1.1 with slight adjustments to support the XIAO ESP32C6 board. 4 | 5 | A new Zigbee_On_Off_Switch/[Readme](Zigbee_On_Off_Switch/README.md) file contains details about the changes. It also shows that the Zigbee_On_Off_Light end device can connect to the Zigbee_On_Off_Switch coordinator so that the latter's boot button controls the LED on the Zingbee_On_Off_Light device. 6 | -------------------------------------------------------------------------------- /06_async_web_led/async_web_led/README.md: -------------------------------------------------------------------------------- 1 | # Additional Libraries 2 | 3 | The `async_web_led` sketch is dependent on two libraries 4 | 5 | 1. [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) 6 | 2. [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) 7 | 8 | Minimalist copies of the libraries are included in the [../../libraries](../../libraries/README.md) directory. **Please do not redistribute these files and always return to the original source when using the libraries in other projects.** 9 | 10 | Each of the libraries is released under the LGPL-3.0 licence. Its terms can be found in `libraries/AsyncTCP/LICENSE`. 11 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/Readme.md: -------------------------------------------------------------------------------- 1 | # 15_zigbee-on-off-light 2 | 3 | The `Zigbee_On_Off_Light` directory contains basically a clone of the example sketch from the `esp32` Arduino core version 3.1.1 with slight adjustments to support the XIAO ESP32C6 board. 4 | 5 | A new Zigbee_On_Off_Light/[Readme](Zigbee_On_Off_Light/README.md) file contains details about the changes and also shows that the Zigbee_On_Off_Light end device can connect to a Zigbee2MQTT coordinator. In the near future, [First Look at the Seeed Studio XIAO ESP32C6](https://www.sigmdel.ca/michel/ha/xiao/xiao_esp32c6_intro_en.html) or perhaps a new posting, will expand on that later development. 6 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (C) 2024, Michel Deslierres 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /08-zigbee-switch/Readme.md: -------------------------------------------------------------------------------- 1 | # 08-zigbee-switch 2 | 3 | The `Zigbee_Light_Switch` directory contains a clone of the example sketch from the `esp32` version 3.0.2 package which is found here in a Linux system: 4 | `~/.arduino15/packages/esp32/hardware/esp32/3.0.2/libraries/ESP32/examples/Zigbee/Zigbee_Light_Switch` 5 | 6 | No modifications were made to the source code. 7 | 8 | Do not forget to set the Arduino configuration as instructed in the sketch [README.md](Zigbee_Light_Switch/README.md) file before compiling. Here are the settings used with a XIAO ESP32C6. 9 | 10 | ![](tools_config.jpg) 11 | 12 | With these settings, a XIAO ESP32-C6 running the unmodified Light Switch sketch, was paired with another XIAO ESP32-C6 running a modified Light Bulb sketch and the LED of the second XIAO could be controlled with the Boot button of the first XIAO. 13 | -------------------------------------------------------------------------------- /07_ble_led/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = ble_led 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"ESP Async WebServer", 3 | "description":"Asynchronous HTTP and WebSocket Server Library for ESP8266 and ESP32", 4 | "keywords":"http,async,websocket,webserver", 5 | "authors": 6 | { 7 | "name": "Hristo Gochkov", 8 | "maintainer": true 9 | }, 10 | "repository": 11 | { 12 | "type": "git", 13 | "url": "https://github.com/me-no-dev/ESPAsyncWebServer.git" 14 | }, 15 | "version": "1.2.4", 16 | "license": "LGPL-3.0", 17 | "frameworks": "arduino", 18 | "platforms": ["espressif8266", "espressif32"], 19 | "dependencies": [ 20 | { 21 | "owner": "me-no-dev", 22 | "name": "AsyncTCP", 23 | "version": "^1.1.1", 24 | "platforms": "espressif32" 25 | }, 26 | { 27 | "name": "Hash", 28 | "platforms": "espressif8266" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /03_scan_wifi/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = scan_wifi 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /05_wifi_tx_power/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = wifi_tx_power 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /11_deep_sleep_io/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = deep_sleep_io 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /02_blink_pulse_led/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = blink_pulse_led 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /04_wifi_blackhole/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = wifi_blackhole 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /10_deep_sleep_tmr/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = deep_sleep_tmr 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /12_xiao32c6_antenna/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = xiao32c6_antenna 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | -------------------------------------------------------------------------------- /06_async_web_led/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | src_dir = async_web_led 13 | boards_dir = ../boards 14 | 15 | [env:seeed_xiao_esp32c6] 16 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 17 | board = seeed_xiao_esp32c6 18 | framework = arduino 19 | monitor_speed = 460800 20 | ;upload_port = /dev/ttyACM0 21 | ;monitor_port = /dev/ttyACM0 22 | lib_deps = 23 | https://github.com/me-no-dev/AsyncTCP 24 | https://github.com/me-no-dev/ESPAsyncWebServer 25 | -------------------------------------------------------------------------------- /07_ble_led/ble_led/ble_led.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * ble_led.ino 3 | * Turn on or off the builtin LED with a Bluetooth LE app 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 15 | * Michel Deslierres 16 | * June 28, 2024 17 | * 18 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 19 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 20 | * */ 21 | // SPDX-License-Identifier: 0BSD 22 | -------------------------------------------------------------------------------- /01_pin_names/pin_names/pin_names.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * pin_names.ino 3 | * Lists XIAO ESP32C6 I/O pin numbers and their Arduino names 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 15 | * Michel Deslierres 16 | * June 25, 2024 17 | * 18 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 19 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 20 | * */ 21 | // SPDX-License-Identifier: 0BSD 22 | -------------------------------------------------------------------------------- /03_scan_wifi/scan_wifi/scan_wifi.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * scan_wifi.ino 3 | * Prints a list of available wifi networks every five seconds 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 15 | * Michel Deslierres 16 | * June 25, 2024 17 | * 18 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 19 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 20 | * */ 21 | // SPDX-License-Identifier: 0BSD 22 | -------------------------------------------------------------------------------- /04_wifi_blackhole/wifi_blackhole/wifi_blackhole.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi_blackhole.ino 3 | * Wi-Fi station connect timing example 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 15 | * Michel Deslierres 16 | * June 25, 2024 17 | * 18 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 19 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 20 | * */ 21 | // SPDX-License-Identifier: 0BSD 22 | -------------------------------------------------------------------------------- /09-zigbee-bulb/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = Zigbee_Light_Bulb 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | build_flags = 24 | -D ZIGBEE_MODE_ED 25 | board_build.partitions = zigbee.csv 26 | -------------------------------------------------------------------------------- /13_wifi_uptime/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = wifi_uptime 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | lib_deps = 24 | https://github.com/me-no-dev/AsyncTCP 25 | https://github.com/me-no-dev/ESPAsyncWebServer 26 | -------------------------------------------------------------------------------- /02_blink_pulse_led/blink_pulse_led/blink_pulse_led.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * blink_pulse_led.ino 3 | * Alternately blinks (heartbeat) and pulses the on-board LED 4 | * of the XIAO ESP32C6 dev board 5 | * 6 | * This is a stub to satisfy the Arduino IDE, the source code is in 7 | * the file main.cpp in the same directory. 8 | * 9 | * This sketch will compile in the Arduino IDE 10 | * 11 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 12 | * in the Additional Boards Manager URLS in the Preferences window. 13 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 14 | * 3- Select the XIAO_ESP32C6 board 15 | * 16 | * Michel Deslierres 17 | * June 25, 2024 18 | * 19 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 20 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 21 | * */ 22 | // SPDX-License-Identifier: 0BSD 23 | -------------------------------------------------------------------------------- /05_wifi_tx_power/wifi_tx_power/wifi_tx_power.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi_tx_power.ino 3 | * Tests each possible value for the Wi-Fi tx power and records 4 | * the time required to connect to the Wi-Fi network. 5 | * 6 | * This is a stub to satisfy the Arduino IDE, the source code is in 7 | * the file main.cpp in the same directory. 8 | * 9 | * This sketch will compile in the Arduino IDE 10 | * 11 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 12 | * in the Additional Boards Manager URLS in the Preferences window. 13 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 14 | * 3- Select the XIAO_ESP32C6 board 15 | * 16 | * Michel Deslierres 17 | * June 25, 2024 18 | * 19 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 20 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 21 | * */ 22 | // SPDX-License-Identifier: 0BSD 23 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/SPIFFSEditor.h: -------------------------------------------------------------------------------- 1 | #ifndef SPIFFSEditor_H_ 2 | #define SPIFFSEditor_H_ 3 | #include 4 | 5 | class SPIFFSEditor: public AsyncWebHandler { 6 | private: 7 | fs::FS _fs; 8 | String _username; 9 | String _password; 10 | bool _authenticated; 11 | uint32_t _startTime; 12 | public: 13 | #ifdef ESP32 14 | SPIFFSEditor(const fs::FS& fs, const String& username=String(), const String& password=String()); 15 | #else 16 | SPIFFSEditor(const String& username=String(), const String& password=String(), const fs::FS& fs=SPIFFS); 17 | #endif 18 | virtual bool canHandle(AsyncWebServerRequest *request) override final; 19 | virtual void handleRequest(AsyncWebServerRequest *request) override final; 20 | virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final; 21 | virtual bool isRequestHandlerTrivial() override final {return false;} 22 | }; 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /12_xiao32c6_antenna/xiao32c6_antenna/xiao32c6_antenna.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * xiao32c6_antenna.ino 3 | * Test various settings of GPIO3 and GPIO14 used to control the RF 4 | * switch for selecting the onboard ceramic antenna or an external 5 | * antenna of the XIAO ESP32C6 6 | * 7 | * This is a stub to satisfy the Arduino IDE, the source code is in 8 | * the file main.cpp in the same directory. 9 | * 10 | * This sketch will compile in the Arduino IDE 11 | * 12 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 13 | * in the Additional Boards Manager URLS in the Preferences window. 14 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 15 | * 3- Select the XIAO_ESP32C6 board 16 | * 17 | * Michel Deslierres 18 | * August 5, 2024 19 | * 20 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 21 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 22 | * */ 23 | // SPDX-License-Identifier: 0BSD 24 | -------------------------------------------------------------------------------- /06_async_web_led/async_web_led/async_web_led.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * async_web_led.ino 3 | * Toggles the built-in LED on and off with a Web interface 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 4- Make sure that the AsyncTCP and ESPAsyncWebServer libraries are in the 15 | ../../libraries directory. Details in librairies/README.md. 16 | 17 | * Michel Deslierres 18 | * August 9, 2024 19 | * 20 | * 21 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 22 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 23 | * */ 24 | // SPDX-License-Identifier: 0BSD 25 | -------------------------------------------------------------------------------- /01_pin_names/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = pin_names 14 | 15 | [env:seeed_xiao_esp32c6] 16 | platform = https://github.com/pioarduino/platform-espressif32.git#develop 17 | ; Instead of stable: https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | ; to test that the board definition was added to the develop branch. 19 | ; See Add Seeed XIAO ESP32C6 board definition #46 @ https://github.com/pioarduino/platform-espressif32/pull/46 20 | board = seeed_xiao_esp32c6 21 | framework = arduino 22 | monitor_speed = 460800 23 | ;upload_port = /dev/ttyACM0 24 | ;monitor_port = /dev/ttyACM0 25 | -------------------------------------------------------------------------------- /13_wifi_uptime/wifi_uptime/wifi_uptime.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * wifi_uptime.ino 3 | * Report Wi-Fi connection time and RSSI value in a Web interface 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board, the XIAO_ESP32C3 or 14 | * 4- Make sure that the AsyncTCP and ESPAsyncWebServer libraries are in the 15 | ../../libraries directory. Details in librairies/README.md. 16 | 17 | * Michel Deslierres 18 | * August 12, 2024 19 | * 20 | * 21 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 22 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 23 | * */ 24 | // SPDX-License-Identifier: 0BSD 25 | -------------------------------------------------------------------------------- /boards/seeed_xiao_esp32c6.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "core": "esp32", 4 | "extra_flags": [ 5 | "-DARDUINO_XIAO_ESP32C6", 6 | "-DARDUINO_USB_MODE=1", 7 | "-DARDUINO_USB_CDC_ON_BOOT=1" 8 | ], 9 | "f_cpu": "160000000L", 10 | "f_flash": "80000000L", 11 | "flash_mode": "qio", 12 | "hwids": [ 13 | [ 14 | "0x2886", 15 | "0x0046" 16 | ], 17 | [ 18 | "0x303a", 19 | "0x1001" 20 | ] 21 | ], 22 | "mcu": "esp32c6", 23 | "variant": "XIAO_ESP32C6" 24 | }, 25 | "connectivity": [ 26 | "wifi", 27 | "bluetooth", 28 | "zigbee", 29 | "thread" 30 | ], 31 | "debug": { 32 | "openocd_target": "esp32c6.cfg" 33 | }, 34 | "frameworks": [ 35 | "arduino", 36 | "espidf" 37 | ], 38 | "name": "Seeed Studio XIAO ESP32C6", 39 | "upload": { 40 | "flash_size": "4MB", 41 | "maximum_ram_size": 327680, 42 | "maximum_size": 4194304, 43 | "require_upload_port": true, 44 | "speed": 460800 45 | }, 46 | "url": "https://wiki.seeedstudio.com/XIAO_ESP32C6_Getting_Started/", 47 | "vendor": "Seeed Studio" 48 | } 49 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = Zigbee_On_Off_Light 14 | 15 | [env:seeed_xiao_esp32c6] 16 | ;platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 17 | platform = https://github.com/pioarduino/platform-espressif32.git#develop 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | build_flags = 24 | -D ZIGBEE_MODE_ED 25 | -D CORE_DEBUG_LEVEL=5 26 | ; optional, 5 = ESP_LOG_VERBOSE, see enum esp_log_level_t in esp_log.h 27 | board_build.partitions = zigbee.csv 28 | board_build.flash_mode = qio 29 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = Zigbee_On_Off_Switch 14 | 15 | [env:seeed_xiao_esp32c6] 16 | platform = https://github.com/pioarduino/platform-espressif32.git#develop 17 | board = seeed_xiao_esp32c6 18 | framework = arduino 19 | monitor_speed = 460800 20 | ;upload_port = /dev/ttyACM0 21 | ;monitor_port = /dev/ttyACM0 22 | build_flags = 23 | -D ZIGBEE_MODE_ZCZR 24 | -D CORE_DEBUG_LEVEL=5 25 | ; optional, 5 = ESP_LOG_VERBOSE, see enum esp_log_level_t in esp_log.h 26 | board_build.partitions = zigbee_zczr.csv 27 | 28 | ; Ref ESP32C6 Arduino 3.00 and Zigbee Support 29 | ; https://community.platformio.org/t/esp32c6-arduino-3-00-and-zigbee-support/40094 30 | ; Euan de Kock 31 | -------------------------------------------------------------------------------- /08-zigbee-switch/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 13 | src_dir = Zigbee_Light_Switch 14 | boards_dir = ../boards 15 | 16 | [env:seeed_xiao_esp32c6] 17 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip 18 | board = seeed_xiao_esp32c6 19 | framework = arduino 20 | monitor_speed = 460800 21 | ;upload_port = /dev/ttyACM0 22 | ;monitor_port = /dev/ttyACM0 23 | build_flags = 24 | -D ZIGBEE_MODE_ED 25 | -D ZIGBEE_MODE_ZCZR 26 | ;board_build.partitions = zigbee.csv 27 | board_build.partitions = zigbee_zczr.csv 28 | 29 | ; Ref ESP32C6 Arduino 3.00 and Zigbee Support 30 | ; https://community.platformio.org/t/esp32c6-arduino-3-00-and-zigbee-support/40094 31 | ; Euan de Kock 32 | -------------------------------------------------------------------------------- /libraries/AsyncTCP/README.md: -------------------------------------------------------------------------------- 1 | # AsyncTCP 2 | [![Build Status](https://travis-ci.org/me-no-dev/AsyncTCP.svg?branch=master)](https://travis-ci.org/me-no-dev/AsyncTCP) ![](https://github.com/me-no-dev/AsyncTCP/workflows/Async%20TCP%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/2f7e4d1df8b446d192cbfec6dc174d2d)](https://www.codacy.com/manual/me-no-dev/AsyncTCP?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/AsyncTCP&utm_campaign=Badge_Grade) 3 | 4 | ### Async TCP Library for ESP32 Arduino 5 | 6 | [![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 7 | 8 | This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs. 9 | 10 | This library is the base for [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) 11 | 12 | ## AsyncClient and AsyncServer 13 | The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use. 14 | -------------------------------------------------------------------------------- /10_deep_sleep_tmr/deep_sleep_tmr/deep_sleep_tmr.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * deep_sleep_tmr.ino 3 | * Puts XIAO ESP32C6 in deep sleep mode, with timed wakeups. 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 15 | * References: 16 | * TimerWakeUp.ino 17 | * @ https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/DeepSleep/TimerWakeUp/TimerWakeUp.ino 18 | * by Pranav Cherukupalli 19 | * 20 | * 15uA. with Xiao ESP32C6 with PPK2 while sleeping BASIC example 21 | * @ https://forum.seeedstudio.com/t/15ua-with-xiao-esp32c6-with-ppk2-while-sleeping-basic-example/276412 22 | * by PJ Glasso. 23 | * 24 | * Michel Deslierres 25 | * July 9, 2024 26 | * 27 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 28 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 29 | * */ 30 | // SPDX-License-Identifier: 0BSD 31 | 32 | -------------------------------------------------------------------------------- /11_deep_sleep_io/deep_sleep_io/deep_sleep_io.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * deep_sleep_io.ino 3 | * Puts XIAO ESP32C6 in deep sleep mode, with I/O activated wakeups. 4 | * 5 | * This is a stub to satisfy the Arduino IDE, the source code is in 6 | * the file main.cpp in the same directory. 7 | * 8 | * This sketch will compile in the Arduino IDE 9 | * 10 | * 1- Add https://espressif.github.io/arduino-esp32/package_esp32_index.json 11 | * in the Additional Boards Manager URLS in the Preferences window. 12 | * 2- Install platform esp32 by Espressif version 3.0.2 or newer with the Boards Manager 13 | * 3- Select the XIAO_ESP32C6 board 14 | * 15 | * References: 16 | * ExternalWakeUp.ino 17 | * @ https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/DeepSleep/ExternalWakeUp/ExternalWakeUp.ino 18 | * by Pranav Cherukupalli 19 | * 20 | * 15uA. with Xiao ESP32C6 with PPK2 while sleeping BASIC example 21 | * @ https://forum.seeedstudio.com/t/15ua-with-xiao-esp32c6-with-ppk2-while-sleeping-basic-example/276412 22 | * by PJ Glasso. 23 | * 24 | * Michel Deslierres 25 | * July 9, 2024 26 | * 27 | * Copyright 2024, Michel Deslierres. No rights reserved, this code is in the public domain. 28 | * In those jurisdictions where this may be a problem, the BSD Zero Clause License applies. 29 | * */ 30 | // SPDX-License-Identifier: 0BSD 31 | 32 | -------------------------------------------------------------------------------- /07_ble_led/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /01_pin_names/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /03_scan_wifi/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /05_wifi_tx_power/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /06_async_web_led/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /08-zigbee-switch/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /09-zigbee-bulb/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /11_deep_sleep_io/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /13_wifi_uptime/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /02_blink_pulse_led/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /04_wifi_blackhole/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /10_deep_sleep_tmr/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /12_xiao32c6_antenna/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /08-zigbee-switch/Zigbee_Light_Switch/Zigbee_Light_Switch.ino: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @brief This example demonstrates simple Zigbee light switch. 17 | * 18 | * The example demonstrates how to use ESP Zigbee stack to control a light bulb. 19 | * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator. 20 | * Button switch and Zigbee runs in separate tasks. 21 | * 22 | * Proper Zigbee mode must be selected in Tools->Zigbee mode 23 | * and also the correct partition scheme must be selected in Tools->Partition Scheme. 24 | * 25 | * Please check the README.md for instructions and more detailed description. 26 | * 27 | *--------------------------------------------------------------------------------------- 28 | * 29 | * Modified to work with the XIAO ESP32C6 30 | * - added USE_EXTERNAL_ANTENNA macro if using external antenna 31 | * 32 | * Michel Deslierres 33 | * July 7, 2024 34 | * 35 | * Corrected antenna switching compatible with ESP32 3.0.2 and up 36 | * August 6, 2024 37 | */ 38 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/WebAuthentication.h: -------------------------------------------------------------------------------- 1 | /* 2 | Asynchronous WebServer library for Espressif MCUs 3 | 4 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 5 | This file is part of the esp8266 core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef WEB_AUTHENTICATION_H_ 23 | #define WEB_AUTHENTICATION_H_ 24 | 25 | #include "Arduino.h" 26 | 27 | bool checkBasicAuthentication(const char * header, const char * username, const char * password); 28 | String requestDigestAuthentication(const char * realm); 29 | bool checkDigestAuthentication(const char * header, const char * method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); 30 | 31 | //for storing hashed versions on the device that can be authenticated against 32 | String generateDigestHash(const char * username, const char * password, const char * realm); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /09-zigbee-bulb/Zigbee_Light_Bulb/Zigbee_Light_Bulb.ino: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @brief This example demonstrates simple Zigbee light bulb. 17 | * 18 | * The example demonstrates how to use ESP Zigbee stack to create a end device light bulb. 19 | * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator. 20 | * 21 | * Proper Zigbee mode must be selected in Tools->Zigbee mode 22 | * and also the correct partition scheme must be selected in Tools->Partition Scheme. 23 | * 24 | * Please check the README.md for instructions and more detailed description. 25 | * 26 | *--------------------------------------------------------------------------------------- 27 | * 28 | * Modified to work with the XIAO ESP32C6 29 | * - added USE_EXTERNAL_ANTENNA macro if using external antenna 30 | * - added LQI_THRESHOLD macro if required 31 | * - uses single yellow builtin LED instead of RGB LED 32 | * 33 | * Michel Deslierres 34 | * July 7, 2024 35 | * 36 | * Corrected antenna switching compatible with ESP32 3.0.2 and up 37 | * August 6, 2024 38 | */ 39 | 40 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/Zigbee_On_Off_Light/Zigbee_On_Off_Light.ino: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @brief This example demonstrates simple Zigbee light bulb. 17 | * 18 | * The example demonstrates how to use Zigbee library to create a end device light bulb. 19 | * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator. 20 | * 21 | * Proper Zigbee mode must be selected in Tools->Zigbee mode 22 | * and also the correct partition scheme must be selected in Tools->Partition Scheme. 23 | * 24 | * Please check the README.md for instructions and more detailed description. 25 | * 26 | * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) 27 | * 28 | *--------------------------------------------------------------------------------------- 29 | * 30 | * Slightlty modified to support the XIAO ESP32C6 and perhaps other 31 | * ESP32-C6 or ESP32-H2 based boards 32 | * - support for simple LED added 33 | * - support for active LOW LED added 34 | * - support for the XIAO ESP32C6 external antenna added 35 | * 36 | * Michel Deslierres (https://github.com/sigmdel) 37 | * Jan 23, 2025 38 | */ 39 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /** 16 | * @brief This example demonstrates simple Zigbee light switch. 17 | * 18 | * The example demonstrates how to use Zigbee library to control a light bulb. 19 | * The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator (Switch). 20 | * Button switch and Zigbee runs in separate tasks. 21 | * 22 | * Proper Zigbee mode must be selected in Tools->Zigbee mode 23 | * and also the correct partition scheme must be selected in Tools->Partition Scheme. 24 | * 25 | * Please check the README.md for instructions and more detailed description. 26 | * 27 | * Created by Jan Procházka (https://github.com/P-R-O-C-H-Y/) 28 | * 29 | *--------------------------------------------------------------------------------------- 30 | * 31 | * Slightlty modified to support the XIAO ESP32C6 and perhaps other 32 | * ESP32-C6 or ESP32-H2 based boards without discrete USB-to-serial 33 | * adapter. Support the XIAO ESP32C6 external antenna if used. 34 | * 35 | * Michel Deslierres (https://github.com/sigmdel) 36 | * Jan 23, 2025 37 | */ 38 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/AsyncWebSynchronization.h: -------------------------------------------------------------------------------- 1 | #ifndef ASYNCWEBSYNCHRONIZATION_H_ 2 | #define ASYNCWEBSYNCHRONIZATION_H_ 3 | 4 | // Synchronisation is only available on ESP32, as the ESP8266 isn't using FreeRTOS by default 5 | 6 | #include 7 | 8 | #ifdef ESP32 9 | 10 | // This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore 11 | class AsyncWebLock 12 | { 13 | private: 14 | SemaphoreHandle_t _lock; 15 | mutable void *_lockedBy; 16 | 17 | public: 18 | AsyncWebLock() { 19 | _lock = xSemaphoreCreateBinary(); 20 | _lockedBy = NULL; 21 | xSemaphoreGive(_lock); 22 | } 23 | 24 | ~AsyncWebLock() { 25 | vSemaphoreDelete(_lock); 26 | } 27 | 28 | bool lock() const { 29 | extern void *pxCurrentTCB; 30 | if (_lockedBy != pxCurrentTCB) { 31 | xSemaphoreTake(_lock, portMAX_DELAY); 32 | _lockedBy = pxCurrentTCB; 33 | return true; 34 | } 35 | return false; 36 | } 37 | 38 | void unlock() const { 39 | _lockedBy = NULL; 40 | xSemaphoreGive(_lock); 41 | } 42 | }; 43 | 44 | #else 45 | 46 | // This is the 8266 version of the Sync Lock which is currently unimplemented 47 | class AsyncWebLock 48 | { 49 | 50 | public: 51 | AsyncWebLock() { 52 | } 53 | 54 | ~AsyncWebLock() { 55 | } 56 | 57 | bool lock() const { 58 | return false; 59 | } 60 | 61 | void unlock() const { 62 | } 63 | }; 64 | #endif 65 | 66 | class AsyncWebLockGuard 67 | { 68 | private: 69 | const AsyncWebLock *_lock; 70 | 71 | public: 72 | AsyncWebLockGuard(const AsyncWebLock &l) { 73 | if (l.lock()) { 74 | _lock = &l; 75 | } else { 76 | _lock = NULL; 77 | } 78 | } 79 | 80 | ~AsyncWebLockGuard() { 81 | if (_lock) { 82 | _lock->unlock(); 83 | } 84 | } 85 | }; 86 | 87 | #endif // ASYNCWEBSYNCHRONIZATION_H_ -------------------------------------------------------------------------------- /13_wifi_uptime/wifi_uptime/html.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const char html_index[] PROGMEM = R"rawliteral( 4 | 5 | 6 | 7 | %SERVERNAME% 8 | 9 | 10 | 11 | 17 | 18 | 19 |

%SERVERNAME%

20 | 21 |
Wi-Fi connection time: %UPTIME% m
22 | 23 |
RSSI: %RSSI%
24 | 25 |
Update count: %BCOUNT%
26 | 27 |

28 | 29 | 30 | )rawliteral"; 31 | 32 | const char html_404[] PROGMEM = R"rawliteral( 33 | 34 | 35 | 36 | %SERVERNAME% 37 | 38 | 39 | 40 | 46 | 47 | 48 |

%SERVERNAME%

49 |

404 Error

50 |

51 | 52 | )rawliteral"; 53 | -------------------------------------------------------------------------------- /06_async_web_led/async_web_led/html.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const char html_index[] PROGMEM = R"rawliteral( 4 | 5 | 6 | 7 | %SERVERNAME% 8 | 9 | 10 | 11 | 18 | 19 | 20 |

%SERVERNAME%

21 |
%LEDSTATUS%
22 |

23 |
Using AsyncWebServer
24 | 25 | )rawliteral"; 26 | 27 | // Could use 28 | //

29 | // instead of 30 | //

31 | 32 | 33 | const char html_404[] PROGMEM = R"rawliteral( 34 | 35 | 36 | 37 | %SERVERNAME% 38 | 39 | 40 | 41 | 47 | 48 | 49 |

%SERVERNAME%

50 |

404 Error

51 |

52 | 53 | )rawliteral"; 54 | -------------------------------------------------------------------------------- /libraries/README.md: -------------------------------------------------------------------------------- 1 | # Additional Libraries 2 | 3 | The `async_web_led` sketch is dependant on two libraries 4 | 5 | 1. [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) 6 | 2. [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) 7 | 8 | For about five years, the ESPAsyncWebServer library authored by Hristo Gochkov, was not being updated. Over that period it became incompatible with newer versions of the ESP32 Arduino core which prompted many developers to fork the project and update it in a rather haphazard way. It became difficult to locate a correct version to use in that period. The developers of the Arduino IDE and PlatformIO appear to have tried to solve the situation by offering to install many forks of the libraries, without much guidance to the user on which version would be best. 9 | 10 | A couple of months ago, version 1.2.4 of ESPAsyncWebServer compatible with ESP32 Arduino 3.0.0 was released. Since it is also compatible with the ESP32-C6, I have decided to use the "root" version of the library. Unfortunately, the Arduino Library Manager does not provide access to that version. Consequently, a manual installation of the libraries is required. While it is not particularly difficult to do, it seemed better to provide a **minimalist copy** of each the libraries in this repository in order to make it self-contained. **Please do not redistribute these files and always return to the original source when using the libraries in other projects.** 11 | 12 | It is still necessary to configure the Arduino IDE so that it can find the libraries. 13 | 14 | 1. Open the `async_web_led` sketch in the IDE. 15 | 16 | 2. Go to the Preferences window of the IDE: **File » Preferences** 17 | 18 | 3. Enter the directory containing `06_async_web_led` directory in `Sketchbok location:` ![](location.jpg) 19 | It would be a good to jot down the previous sketchbook location beforehand in order to restore it when done with the example sketch. 20 | 21 | 4. Click on the `OK` button. 22 | 23 | The Arduino IDE will automatically include any libraries found in the `libraries`. Be warned that it will want to install "updates" of these two libraries. Many of the offerings proposed by the IDE did not work, but the situation may have evolved since they were tried. It may be wise to forego updating when first testing the `async_web_led` sketch. 24 | 25 | Each of the libraries is released under the LGPL-3.0 licence. Its terms can be found in `libraries/AsyncTCP/LICENSE`. 26 | -------------------------------------------------------------------------------- /13_wifi_uptime/wifi_uptime/README.md: -------------------------------------------------------------------------------- 1 | # Purpose 2 | 3 | This sketch is the first draft of tests designed to compare the Wi-Fi connectivity of three development boards: 4 | 1. [XIAO ESP32C3](https://github.com/sigmdel/xiao_esp32c3_sketches), 5 | 1. [Super Mini C3](https://github.com/sigmdel/supermini_esp32c3_sketches), 6 | 1. [XIAO ESP32C6](https://github.com/sigmdel/xiao_esp32c6_sketches). 7 | 8 | The first two are based on the ESP32-C3 microcontroller while the third contains an ESP32-C6. The last two are equipped with an onboard ceramic antenna, while the first has an FPC external antenna connected to the U.FL connector. The wireless communication problems with the Super Mini C3 has already been documented. The Wi-Fi transmit power was reduced to 17 dBm which seemed optimal based on previous tests. 9 | 10 | # Preliminary Results 11 | 12 | The three boards were placed side by side as far as practical from a Wi-Fi access point while still within the house. The distance between the AP and the boards was about 16 metres with two walls between the devices. The received signal strength indicator values were transcribed into the following table at four different times over almost 3 days. 13 | 14 | | Board | 305 min | 1172 min | 4050 min | 4237 min | 15 | | --- |:---: | :---: | :---: | :---: | 16 | | XIAO ESP32C3 | -63 | -75 | -71 | -67 | 17 | | Super Mini C3 | -83 | -78 | n.c. | -83 | 18 | | XIAO ESP32C6 | -88 | -74 | -81 | -89 | 19 | 20 | Here n.c. indicates that the Super Mini was not connected. Not only could the web page not be reached, but the device was not even listed among the Wi-Fi clients by the router. Nevertheless, the board reestablished the connection. 21 | 22 | After almost a day of operation, the devices were remarkably cool. 23 | 24 | | Board | Temp (°C) | 25 | | --- | --- | 26 | | XIAO ESP32C3 | 20.7 | 27 | | Super Mini C3 | 19.9 | 28 | | XIAO ESP32C6 | 20.6 | 29 | 30 | This is basically ambient temperature. 31 | 32 | Clearly, the test has to be rewritten to better stress the Wi-Fi radios and with data logging for unattended operation. 33 | 34 | # Additional Libraries 35 | 36 | The `wifi_uptime` sketch is dependent on two libraries 37 | 38 | 1. [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) 39 | 2. [ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) 40 | 41 | Minimalist copies of the libraries are included in the [../../libraries](../../libraries/README.md) directory. **Please do not redistribute these files and always return to the original source when using the libraries in other projects.** 42 | 43 | Each of the libraries is released under the LGPL-3.0 licence. Its terms can be found in `libraries/AsyncTCP/LICENSE`. 44 | -------------------------------------------------------------------------------- /boards/README.md: -------------------------------------------------------------------------------- 1 | # Adding a Seeed XIAO ESP32C6 Board Definition in PlatformIO 2 | 3 | The stable (51.03.07) branch of the [pioarduino](https://github.com/pioarduino/platform-espressif32) platform does not contain a board definition for the XIAO ESP32C6. However, this directory contains a proposed definition `seeed_xiao_esp32c6.json` which has been successfully tested with all the projects in the repository. 4 | 5 | To use the [boards/seeed_xiao_esp32c6.json](seeed_xiao_esp32c6.json) definition in a PlatformIO project, add the following line in the project configuration file (`platformio.ini`): `boards_dir = ../boards`. Here is a typical example. 6 | 7 | ```ini 8 | platformio] 9 | src_dir = async_web_led 10 | boards_dir = ../boards 11 | 12 | [env:seeed_xiao_esp32c6] 13 | platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.07/platform-espressif32.zip 14 | board = seeed_xiao_esp32c6 15 | framework = arduino 16 | ... 17 | ``` 18 | 19 | > References: [Custom Embedded Boards](https://docs.platformio.org/en/latest/platforms/creating_board.html#installation), [boards_dir](https://docs.platformio.org/en/latest/projectconf/sections/platformio/options/directory/boards_dir.html#projectconf-pio-boards-dir). 20 | 21 | 22 | The development branch of the [pioarduino](https://github.com/pioarduino/platform-espressif32) platform contains the board definition since November 6, 2024 ([Commit bdae53d 23 | ](https://github.com/pioarduino/platform-espressif32/commit/bdae53d076dce7737f801cad9cba4595be3866a2). The first example project in this repository uses that branch. Here are the first few lines of its configuration file. 24 | 25 | ```ini 26 | [platformio] 27 | ; Make the Arduino IDE happy (.INO file must be in a directory of the same name) 28 | src_dir = pin_names 29 | 30 | [env:seeed_xiao_esp32c6] 31 | platform = https://github.com/pioarduino/platform-espressif32.git#develop 32 | ... 33 | ``` 34 | In this project, the content of the `../board` directory will be ignored. 35 | 36 | ## Credit 37 | 38 | Just came across [lucaskatayama:feat/seeed_xiao_esp32c6.json](https://github.com/platformio/platform-espressif32/pull/1472/commits/91ed04a0b6e197001d747e651d944a6f25928557) dated 0ct 4th. That board definition looks to be exactly the same as [seed_xiao_esp32c6.json](seeed_xiao_esp32c6.json) in this directory but for the order in which elements are listed. 39 | 40 | It's all a bit confusing. Lucas wanted to merge the board definition into [platform-espressif32](https://github.com/platformio/platform-espressif32platform-espressif32). According to [valeros](https://github.com/platformio/platform-espressif32/pull/1380#issuecomment-2205808510), [the ESP32-C6] *requires Arduino core v3.0 which is not officially supported **yet**.* (July 3). Two weeks later jason2866, announced the [pioarduino](https://github.com/pioarduino/platform-espressif32) fork writing *[since] it is **now** clear that there will be no official support for Arduino core 3.0.x from Platformio team, [...] i decided to fork the needed repo(s) and build a community version to support core 3.0.x (starting with core 3.0.3)*. (The emphasis on "yet" and "now" is mine.) So Lucas' work will not be used and I preempted his ability to contribute his definition to the pioarduino team? **My apologies to Lucas Katayama whose work I should have credited.** 41 | 42 | Also, many thanks to jason2866 for pioarduino, it works very well. 43 | -------------------------------------------------------------------------------- /04_wifi_blackhole/wifi_blackhole/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of wifi_blackhole 2 | // Copyright: see notice in wifi_blackhole.ino 3 | 4 | #include 5 | #include 6 | #include "secrets.h" 7 | 8 | unsigned long connect_time = 0; 9 | unsigned long etime = 0; 10 | unsigned long itime = 0; 11 | 12 | #if defined(ARDUINO_MAKERGO_C3_SUPERMINI) 13 | #define TITLE "MAKERGO_C3_SUPERMINI" 14 | #define NEED_TX_POWER // no name super mini C3 with antenna issues 15 | #elif defined(ARDUINO_NOLOGO_ESP32C3_SUPER_MINI) 16 | #define TITLE "NOLOGO_ESP32C3_SUPER_MINI" 17 | #elif defined(ARDUINO_DFROBOT_BEETLE_ESP32_C3) 18 | #define TITLE "DFROBOT_BEETLE_ESP32_C3" 19 | #elif defined(ARDUINO_XIAO_ESP32C3) 20 | #define TITLE "XIAO_ESP32C3" 21 | #elif defined(ARDUINO_XIAO_ESP32C6) 22 | // The onboard ceramic antenna is used by default. 23 | // Uncomment the following macro to use a connected external antenna. 24 | //#define USE_EXTERNAL_ANTENNA 25 | #define TITLE "XIAO_ESP32C6" 26 | #elif defined(ARDUINO_LOLIN_S2_MINI) 27 | #define TITLE "LOLIN_S2_MINI" 28 | #elif defined(ARDUINO_LOLIN32_LITE) 29 | #define TITLE "LOLIN32_LITE" 30 | #define BAUD 115200 31 | #elif defined(ARDUINO_LILYGO_T_DISPLAY) 32 | #define TITLE "LILYGO_T_DISPLAY" 33 | #define BAUD 115200 34 | #else 35 | #error "Unknown board" 36 | #endif 37 | 38 | 39 | #ifdef NEED_TX_POWER 40 | #define TX_POWER WIFI_POWER_11dBm 41 | // Set the above macro to the power level. See 42 | // https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.h 43 | #endif 44 | 45 | 46 | void setup() { 47 | #ifdef BAUD 48 | Serial.begin(BAUD); 49 | #else 50 | Serial.begin(); 51 | #endif 52 | delay(2000); 53 | 54 | Serial.print("\nAttempting to connect to the Wi-Fi network with "); 55 | Serial.println(TITLE); 56 | 57 | #if defined(ARDUINO_XIAO_ESP32C6) 58 | #if (ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 4)) 59 | // reproduce initVariant() from ESP32 v3.0.4 60 | uint8_t WIFI_ENABLE = 3; 61 | uint8_t WIFI_ANT_CONFIG = 14; 62 | // enable the RF switch 63 | pinMode(WIFI_ENABLE, OUTPUT); 64 | digitalWrite(WIFI_ENABLE, LOW); 65 | // select the internal antenna 66 | pinMode(WIFI_ANT_CONFIG, OUTPUT); 67 | digitalWrite(WIFI_ANT_CONFIG, LOW); 68 | #endif 69 | 70 | // same code for ESP32 v3.0.2 and up 71 | #if defined(USE_EXTERNAL_ANTENNA) 72 | digitalWrite(WIFI_ANT_CONFIG, HIGH); 73 | #endif 74 | 75 | Serial.print("Using "); 76 | #ifdef USE_EXTERNAL_ANTENNA 77 | Serial.print("an external"); 78 | #else 79 | Serial.print("the internal"); 80 | #endif 81 | Serial.println(" antenna."); 82 | #endif 83 | 84 | WiFi.mode(WIFI_STA); 85 | #ifdef NEED_TX_POWER 86 | delay(25); 87 | if (WiFi.getTxPower() != TX_POWER) { 88 | WiFi.setTxPower(TX_POWER); 89 | delay(25); 90 | } 91 | Serial.printf("Wi-Fi TX power set to: %d\n", WiFi.getTxPower()); 92 | delay(25); 93 | #endif 94 | connect_time = millis(); 95 | WiFi.begin(ssid, password); 96 | while (!WiFi.isConnected()) { 97 | // do nothing; 98 | } 99 | etime = millis() - connect_time; 100 | while ((uint32_t) WiFi.localIP() == (uint32_t) 0) { 101 | // do nothing 102 | }; 103 | itime = millis() - connect_time; 104 | 105 | } 106 | 107 | unsigned long report = 0; 108 | 109 | void loop() { 110 | if (millis() - report > 25000) { 111 | Serial.print("\nWiFi is connected with IP address: "); 112 | Serial.println(WiFi.localIP()); 113 | Serial.printf("Time to connect: %lu ms\n", etime); 114 | Serial.printf("Time to valid IP local address: %lu ms\n", itime); 115 | Serial.printf("Difference: %lu ms\n", itime - etime); 116 | report = millis(); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /01_pin_names/pin_names/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of pin_names.ino 2 | // Copyright: see notice in pin_names.ino 3 | 4 | // The XIAO ESP32C6 pin definitions are found in 5 | // https://github.com/espressif/arduino-esp32/blob/master/variants/XIAO_ESP32C6/pins_arduino.h 6 | // The BOOT_PIN definition for all ESP32s found in 7 | // https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal.h 8 | 9 | #include 10 | 11 | void iopins(void) { 12 | Serial.println("\n\nXIAO ESP32C6 I/O Pin Names and Numbers (defined in pins_arduino.h)"); 13 | 14 | Serial.println("\nThe symbolic name and corresponding I/O number of the 11 digital pins"); 15 | Serial.printf(" D0 = %2d\n", D0); 16 | Serial.printf(" D1 = %2d\n", D1); 17 | Serial.printf(" D2 = %2d\n", D2); 18 | Serial.printf(" D3 = %2d\n", D3); 19 | Serial.printf(" D4 = %2d\n", D4); 20 | Serial.printf(" D5 = %2d\n", D5); 21 | Serial.printf(" D6 = %2d\n", D6); 22 | Serial.printf(" D7 = %2d\n", D7); 23 | Serial.printf(" D8 = %2d\n", D8); 24 | Serial.printf(" D9 = %2d\n", D9); 25 | Serial.printf("D10 = %2d\n", D10); 26 | 27 | Serial.println("\nThe symbolic name and corresponding I/O number of the 3 analogue pins"); 28 | Serial.printf(" A0 = %d\n", A0); 29 | Serial.printf(" A1 = %d\n", A1); 30 | Serial.printf(" A2 = %d\n", A2); 31 | Serial.println("Note: Ax = Dx for x = 0, 1 and 2"); 32 | 33 | Serial.println("\nThe symbolic name and corresponding I/O number of the 7 serial pins"); 34 | Serial.printf(" TX = %2d [UART] (=D6)\n", TX); 35 | Serial.printf(" RX = %2d [UART] (=D7)\n", RX); 36 | 37 | Serial.printf(" SDA = %2d [I2C] (=D4)\n", SDA); 38 | Serial.printf(" SCL = %2d [I2C] (=D5)\n", SCL); 39 | 40 | Serial.printf(" SS = %2d [SPI] (=D3)\n", SS); 41 | Serial.printf("MOSI = %2d [SPI] (=D10)\n", MOSI); 42 | Serial.printf("MISO = %2d [SPI] (=D9)\n", MISO); 43 | Serial.printf(" SCK = %2d [SPI] (=D8)\n", SCK); 44 | 45 | Serial.println("\nOnboard yellow LED"); 46 | Serial.printf("LED_BUILTIN = %d\n", LED_BUILTIN); 47 | Serial.printf("BUILTIN_LED = %d // backward compatibility\n", BUILTIN_LED); 48 | 49 | Serial.println("\nAntenna"); 50 | if (ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4)) { 51 | Serial.printf(" WIFI_ENABLE = %d (RF switch power enable I/O)\n", WIFI_ENABLE); 52 | Serial.printf("WIFI_ANT_CONFIG = %d (RF switch select control I/O)\n", WIFI_ANT_CONFIG); 53 | } else { 54 | Serial.printf("RF switch I/O not defined in ESP32 %s\n", ESP_ARDUINO_VERSION_STR); 55 | Serial.println(" RF switch power enable I/O = 3 (= WIFI_ENABLE in ESP32 core 3.0.4 or later)"); 56 | Serial.println("RF switch select control I/O = 14 (= WIFI_ANT_CONFIG in ESP32 core 3.0.4 or later"); 57 | } 58 | 59 | #ifdef BOOT_PIN 60 | Serial.println("\nBoot Button (defined in esp32-hal.h)"); 61 | Serial.printf("BOOT_PIN = %2d\n", BOOT_PIN); 62 | #else 63 | Serial.println("BOOT_PIN not defined") 64 | #endif 65 | 66 | Serial.println("\nOther macros"); 67 | Serial.printf("USB_VID = 0x%04x\n", USB_VID); 68 | Serial.printf("USB_PID = 0x%04x\n", USB_PID); 69 | Serial.printf("USB_MANUFACTURER = \"%s\"\n", USB_MANUFACTURER); 70 | Serial.printf("USB_PROUCT = \"%s\"\n", USB_PRODUCT); 71 | Serial.printf("USB_SERIAL = \"%s\"\n", USB_SERIAL); 72 | 73 | Serial.println("\nBoard macro"); 74 | #ifdef ARDUINO_XIAO_ESP32C6 75 | Serial.println("ARDUINO_XIAO_ESP32C6 defined"); 76 | #else 77 | Serial.println("ARDUINO_XIAO_ESP32C6 not defined"); 78 | #ifdef ARDUINO_XIAO_ESP32C3 79 | Serial.println("ARDUINO_XIAO_ESP32C3 incorrectly defined"); // prior to version 3.0.2 esp32 80 | #endif 81 | #endif 82 | } 83 | 84 | void setup() { 85 | Serial.begin(); 86 | delay(1000); // 1 second delay should be sufficient for USB-CDC 87 | Serial.println("Setup completed"); 88 | } 89 | 90 | void loop() { 91 | iopins(); 92 | delay(10000); // wait 10 seconds 93 | } 94 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/Zigbee_On_Off_Switch/README-org.md: -------------------------------------------------------------------------------- 1 | # Arduino-ESP32 Zigbee On/Off Light Switch Example 2 | 3 | This example shows how to configure Zigbee Coordinator and use it as a Home Automation (HA) on/off light switch. 4 | 5 | # Supported Targets 6 | 7 | Currently, this example supports the following targets. 8 | 9 | | Supported Targets | ESP32-C6 | ESP32-H2 | 10 | | ----------------- | -------- | -------- | 11 | 12 | ## Hardware Required 13 | 14 | * One development board (ESP32-H2 or ESP32-C6) acting as Zigbee end device (loaded with Zigbee_On_Off_Light example). 15 | * A USB cable for power supply and programming. 16 | * Choose another board (ESP32-H2 or ESP32-C6) as Zigbee coordinator and upload the Zigbee_On_Off_Switch example. 17 | 18 | ### Configure the Project 19 | 20 | Set the Button Switch GPIO by changing the `GPIO_INPUT_IO_TOGGLE_SWITCH` definition. By default, it's the pin `9` (BOOT button on ESP32-C6 and ESP32-H2). 21 | 22 | #### Using Arduino IDE 23 | 24 | To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). 25 | 26 | * Before Compile/Verify, select the correct board: `Tools -> Board`. 27 | * Select the Coordinator Zigbee mode: `Tools -> Zigbee mode: Zigbee ZCZR (coordinator/router)`. 28 | * Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs`. 29 | * Select the COM port: `Tools -> Port: xxx where the `xxx` is the detected COM port. 30 | * Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. 31 | 32 | ## Troubleshooting 33 | 34 | If the End device flashed with the example `Zigbee_On_Off_Light` is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. 35 | You can do the following: 36 | 37 | * In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. 38 | * In the `Zigbee_On_Off_Light` example sketch call `Zigbee.factoryReset();`. 39 | 40 | By default, the coordinator network is closed after rebooting or flashing new firmware. 41 | To open the network you have 2 options: 42 | 43 | * Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. 44 | * In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. 45 | 46 | ***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** 47 | 48 | * **LED not blinking:** Check the wiring connection and the IO selection. 49 | * **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. 50 | * **COM port not detected:** Check the USB cable and the USB to Serial driver installation. 51 | 52 | If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). 53 | 54 | ## Contribute 55 | 56 | To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) 57 | 58 | If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! 59 | 60 | Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. 61 | 62 | ## Resources 63 | 64 | * Official ESP32 Forum: [Link](https://esp32.com) 65 | * Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) 66 | * ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) 67 | * ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) 68 | * Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) 69 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/Zigbee_On_Off_Light/README-org.md: -------------------------------------------------------------------------------- 1 | # Arduino-ESP32 Zigbee On/Off Light Example 2 | 3 | This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) on/off light. 4 | 5 | # Supported Targets 6 | 7 | Currently, this example supports the following targets. 8 | 9 | | Supported Targets | ESP32-C6 | ESP32-H2 | 10 | | ----------------- | -------- | -------- | 11 | 12 | ## Hardware Required 13 | 14 | * One development board (ESP32-H2 or ESP32-C6) acting as Zigbee coordinator (loaded with Zigbee_On_Off_switch example) 15 | * A USB cable for power supply and programming 16 | * Choose another board (ESP32-H2 or ESP32-C6) as Zigbee end device and upload the Zigbee_On_Off_Light example 17 | 18 | ### Configure the Project 19 | 20 | Set the LED GPIO by changing the `LED_PIN` definition. By default, the LED_PIN is `RGB_BUILTIN`. 21 | By default, the `rgbLedWrite` function is used to control the LED. You can change it to digitalWrite to control a simple LED. 22 | 23 | #### Using Arduino IDE 24 | 25 | To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). 26 | 27 | * Before Compile/Verify, select the correct board: `Tools -> Board`. 28 | * Select the End device Zigbee mode: `Tools -> Zigbee mode: Zigbee ED (end device)` 29 | * Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs` 30 | * Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. 31 | * Optional: Set debug level to verbose to see all logs from Zigbee stack: `Tools -> Core Debug Level: Verbose`. 32 | 33 | ## Troubleshooting 34 | 35 | If the End device flashed with this example is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. 36 | You can do the following: 37 | 38 | * In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. 39 | * Add to the sketch `Zigbee.factoryReset();` to reset the device and Zigbee stack. 40 | 41 | By default, the coordinator network is closed after rebooting or flashing new firmware. 42 | To open the network you have 2 options: 43 | 44 | * Open network after reboot by setting `Zigbee.setRebootOpenNetwork(time);` before calling `Zigbee.begin();`. 45 | * In application you can anytime call `Zigbee.openNetwork(time);` to open the network for devices to join. 46 | 47 | 48 | ***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** 49 | 50 | * **LED not blinking:** Check the wiring connection and the IO selection. 51 | * **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. 52 | * **COM port not detected:** Check the USB cable and the USB to Serial driver installation. 53 | 54 | If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). 55 | 56 | ## Contribute 57 | 58 | To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) 59 | 60 | If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! 61 | 62 | Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. 63 | 64 | ## Resources 65 | 66 | * Official ESP32 Forum: [Link](https://esp32.com) 67 | * Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) 68 | * ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) 69 | * ESP32-H2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf) 70 | * Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) 71 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/Zigbee_On_Off_Switch/README.md: -------------------------------------------------------------------------------- 1 | # Arduino-ESP32 Zigbee On/Off Switch Example 2 | 3 | This example shows how to configure Zigbee Coordinator and use it as a Home Automation (HA) on/off light switch. 4 | 5 | **The original README was renamed [README-org.md](README-org.md)** 6 | 7 | ## Supported Targets 8 | 9 | Currently, this example supports the following targets. 10 | 11 | | Supported Targets | ESP32-C6 | ESP32-H2 | 12 | | ----------------- | -------- | -------- | 13 | 14 | ## Hardware Required 15 | 16 | * A development board (ESP32-H2 or ESP32-C6 based) acting as a Zigbee end device (running the Zigbee_On_Off_Light example). 17 | 18 | * Another development board (ESP32-H2 or ESP32-C6 based) acting as a Zigbee coordinator (running the Zigbee_On_Off_Switch example). 19 | 20 | * 5 volt power supplies for the two boards and USB cables for power supply and programming. 21 | 22 | ## Configure the Project 23 | 24 | Three macros are defined at the top of the source (main.cpp) to handle different development boards. These are 25 | 1. GPIO_INPUT_IO_TOGGLE_SWITCH - number of the I/O pin to which a push button switch is connected. By default this is BOOT_PIN = 9 which is connected to the Boot button on the ESP32-H2 and the ESP32-C6. 26 | 1. SERIAL_BAUD - usually 115200 if the development board has a discrete USB-to-serial adapter and not used otherwise. 27 | 1. USE_EXTERNAL_ANTENNA - define only if the board is an XIAO ESP32C6 and only if an external antenna is used. 28 | 29 | The macros are automatically defined correctly for the [Seeed Studio XIAO ESP32C6](https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C6-p-5884.html) and should also be correct for the [Espressif Development Kits](https://www.espressif.com/en/products/devkits) although these have not been tested. It may be necessary to tweak some macros for other ESP32-C6 or ESP32-H2 based boards. 30 | 31 | 32 | ## Compiling and Uploading the Sketch 33 | 34 | ### Using Arduino IDE 35 | 36 | Before Compile/Verify, go to the `Tools` menu to modify the following options. 37 | 38 | * Select the correct **Board** (example: *"XIAO_ESP32C6"*). 39 | * Select the correct **Port** (examples: *"/dev/ttyACM0"* in Linux, *"Com4"* in Windows). 40 | * Set the **Partition Scheme** to *"Zigbee ZCZR 4MB with spiffs"*. 41 | * Set the **Zigbee mode** *"Zigbee ZCZR (coordinator/router)"*. 42 | * Optional: Set **Core Debug Level** to the desired level such as *"Verbose"* (default is *"None"*). 43 | * Optional: Set **Erase All Flash Before Sketch Upload** to *"Enabled"* (default is *"Disabled"*). 44 | 45 | ![IDE-Tools-screenshot](../tools_config.jpg) 46 | 47 | ### Using PlatformIO 48 | 49 | *forthcoming* 50 | 51 | ## Connecting to a Zigbee Coordinator 52 | 53 | Assuming that the Zigbee_On_Off_Light firmware was uploaded to the development board with **Erase All Flash Before Sketch Upload** set to *"Enabled"*, here are the steps to connect to a coordinator for the first time. 54 | 55 | It is best to ensure that the development board running the Zigbee_On_Off_Switch coordinator firmware is very near to the ESP32 dev board running the Zigbee_On_Off_Light end device firmware. Tests have shown that another Zigbee coordinator or a Zigbee router a few metres away will not interfere. 56 | 57 | - Power up the development board running the `Zigbee_On_Off_Light` sketch. 58 | 59 | - Power up the development board running the `Zigbee_On_Off_Switch` sketch. The `setup()` routine 60 | 61 | - opens the network allowing end device to join for 180 seconds with the `Zigbee.setRebootOpenNetwork()` method, 62 | 63 | - starts Zigbee in coordinator mode, 64 | 65 | - enters a loop waiting for a light end device to connect. 66 | 67 | After a short while, the end device (...Light) should have joined the Zigbee network created by the coordinator (...Switch). The serial output of the two devices should make that clear, especially if the **core debug level** was set to `"Verbose"`. In any case, test by pressing the boot button of the coordinator. It should toggle the state of the LED on the end device. 68 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/Zigbee_On_Off_Light/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // See Zigbee_On_Off_Light.ino for license 4 | // 5 | // Source: 6 | // https://github.com/espressif/arduino-esp32/blob/3.1.1/libraries/Zigbee/examples/Zigbee_On_Off_Light/Zigbee_On_Off_Light.ino 7 | 8 | #ifndef ZIGBEE_MODE_ED 9 | #error "Zigbee end device mode is not selected in Tools->Zigbee mode" 10 | #endif 11 | 12 | #include "Zigbee.h" 13 | 14 | /// --------------------- 15 | 16 | // Use correct builtin LED 17 | #if defined(RGB_BUILTIN) // not defined in XIAO_ESP32C6 variant pins_arduino.h 18 | #define LED_PIN RGB_BUILTIN 19 | #define LED_ON HIGH // default for other boards in original code 20 | #define SERIAL_BAUD 115200 21 | #elif defined(LED_BUILTIN) 22 | #define LED_PIN LED_BUILTIN 23 | #define LED_ON LOW // because I/O pin must be grounded to turn on LED 24 | #define SERIAL_BAUD 25 | #else 26 | #error "LED pin not defined" 27 | #endif 28 | 29 | #if defined(ARDUINO_XIAO_ESP32C6) 30 | // The onboard ceramic antenna is used by default. 31 | // Uncomment the following macro to use a connected external antenna. 32 | //#define USE_EXTERNAL_ANTENNA 33 | #else 34 | #undef USE_EXTERNAL_ANTENNA 35 | #endif 36 | 37 | // Define this print to the console a test number at startup 38 | #define TEST_NO 2 39 | 40 | /// --------------------- 41 | 42 | uint8_t led = LED_PIN; 43 | uint8_t button = BOOT_PIN; 44 | 45 | /* Zigbee light bulb configuration */ 46 | #define ZIGBEE_LIGHT_ENDPOINT 10 47 | 48 | ZigbeeLight zbLight = ZigbeeLight(ZIGBEE_LIGHT_ENDPOINT); 49 | 50 | /********************* RGB LED functions **************************/ 51 | void setLED(bool value) { 52 | //(if LED_PIN == RGB_BUILTIN, then rgbLedWrite() will be used under the hood) 53 | digitalWrite(LED_PIN, (value) ? LED_ON : 1 - LED_ON); 54 | } 55 | 56 | /********************* Arduino functions **************************/ 57 | void setup() { 58 | Serial.begin(SERIAL_BAUD); 59 | delay(5000); 60 | #ifdef TEST_NO 61 | Serial.printf("Zigbee_On_Off_Light, test #%d\n\n", TEST_NO); // 62 | #endif 63 | 64 | // Init LED and turn it OFF (if LED_PIN == RGB_BUILTIN, the rgbLedWrite() will be used under the hood) 65 | pinMode(led, OUTPUT); 66 | //digitalWrite(led, LOW); 67 | setLED(LOW); 68 | 69 | // Init button for factory reset 70 | pinMode(button, INPUT_PULLUP); 71 | 72 | #if defined(ARDUINO_XIAO_ESP32C6) && defined(USE_EXTERNAL_ANTENNA) 73 | // Assuming ESP_ARDUINO_VERSION >= 3.0.4 74 | digitalWrite(WIFI_ANT_CONFIG, HIGH); 75 | #endif 76 | 77 | //Optional: set Zigbee device name and model 78 | zbLight.setManufacturerAndModel("Espressif", "ZBLightBulb"); 79 | 80 | // Set callback function for light change 81 | zbLight.onLightChange(setLED); 82 | 83 | //Add endpoint to Zigbee Core 84 | Serial.println("Adding ZigbeeLight endpoint to Zigbee Core"); 85 | Zigbee.addEndpoint(&zbLight); 86 | 87 | // When all EPs are registered, start Zigbee. By default acts as ZIGBEE_END_DEVICE 88 | if (!Zigbee.begin()) { 89 | Serial.println("Zigbee failed to start!"); 90 | Serial.println("Rebooting..."); 91 | ESP.restart(); 92 | } 93 | Serial.println("Connecting to network"); 94 | while (!Zigbee.connected()) { 95 | Serial.print("."); 96 | delay(100); 97 | } 98 | Serial.println(); 99 | } 100 | 101 | void loop() { 102 | // Checking button for factory reset 103 | if (digitalRead(button) == LOW) { // Boot push button pressed 104 | // Key debounce handling 105 | delay(100); 106 | int startTime = millis(); 107 | while (digitalRead(button) == LOW) { 108 | delay(50); 109 | if ((millis() - startTime) > 3000) { 110 | // If button pressed for more than 3secs, factory reset Zigbee and reboot 111 | Serial.println("Resetting Zigbee to factory and rebooting in 1s."); 112 | delay(1000); 113 | Zigbee.factoryReset(); 114 | } 115 | } 116 | // Toggle the on board LED when if button is released in less than 3 seconds 117 | zbLight.setLight(!zbLight.getLightState()); 118 | } 119 | delay(100); 120 | } 121 | -------------------------------------------------------------------------------- /02_blink_pulse_led/blink_pulse_led/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of blink_pulse_led 2 | // Copyright: see notice in blink_pulse.ino 3 | 4 | #include 5 | 6 | static uint8_t ledPin = LED_BUILTIN; // yellow LED cathode connected to digital pin 7 | static uint8_t ledOn = LOW; // the LED anode is connected to 3.3V via 1.5K resistor 8 | 9 | static uint8_t buttonPin = 9; // Boot button 10 | uint8_t buttonState = 0; // It should be high when read by setup() 11 | uint8_t buttonActive = 0; // 12 | 13 | void setup() { 14 | Serial.begin(); 15 | delay(1000); // 1 second delay should be sufficient for USB-CDC 16 | Serial.println("Starting setup"); 17 | 18 | Serial.println("Setting up LED output I/O pin"); 19 | // declaring LED pin as output 20 | pinMode(ledPin, OUTPUT); 21 | // turn it off 22 | digitalWrite(ledPin, 1-ledOn); 23 | 24 | Serial.println("Setting up Boot button input I/O pin"); 25 | // declaring boot button pin as input 26 | pinMode(buttonPin, INPUT); // externally pulled high with 10K resistor 27 | buttonState = digitalRead(buttonPin); 28 | Serial.printf("Boot button default value: %d\n", buttonState); 29 | buttonActive = !buttonState; 30 | 31 | Serial.println("Completed setup"); 32 | Serial.println("Executing loop"); 33 | } 34 | 35 | #define DELTA 10 36 | #define DELAY 50 37 | 38 | unsigned long delaytime = 0; 39 | int delta = DELTA; 40 | int fade = 0; 41 | 42 | void pulse(void) { 43 | if (millis() - delaytime > DELAY) { 44 | fade += delta; 45 | if (fade <= 0) { 46 | fade = 0; 47 | delta = DELTA; 48 | } else if (fade >= 255) { 49 | fade = 255; 50 | delta = - DELTA; 51 | } 52 | analogWrite(ledPin, fade); 53 | delaytime = millis(); 54 | } 55 | } 56 | 57 | 58 | #define ON_TIME 80 59 | #define OFF_TIME 840 60 | 61 | unsigned long beattime = 0; 62 | int beatcount = 0; 63 | int beatdelay = 0; 64 | 65 | /* beatcount 66 | 0 = turn on for short delay 67 | 1 = turn off for short delay 68 | 2 = turn on for short delay 69 | 3 = turn off for long delay 70 | */ 71 | 72 | void heartbeat(void) { 73 | if (millis() - beattime > beatdelay) { 74 | 75 | if ((beatcount & 1) == 1) // if beatcount odd turn LED off 76 | digitalWrite(ledPin, 1-ledOn); 77 | else // if beatcount event turn LED on 78 | digitalWrite(ledPin, ledOn); 79 | 80 | if (beatcount >= 3) { 81 | beatdelay = OFF_TIME; 82 | beatcount = 0; 83 | } else { 84 | beatdelay = ON_TIME; 85 | beatcount++; 86 | } 87 | beattime = millis(); 88 | } 89 | } 90 | 91 | unsigned long timer = 0; 92 | bool doHeartBeat = true; 93 | 94 | void switchAction(bool automatic) { 95 | // turn LED off 96 | pinMode(ledPin, OUTPUT); // needed to get out of PWM mode 97 | digitalWrite(ledPin, 1-ledOn); 98 | doHeartBeat = !doHeartBeat; 99 | Serial.printf("Switching to %s mode %s\n", 100 | (doHeartBeat) ? "hearbeat" : "pulse", 101 | (automatic) ? "automatically" : "after button press" 102 | ); 103 | if (doHeartBeat) { 104 | beattime = millis(); 105 | beatcount = 0; 106 | beatdelay = OFF_TIME; 107 | } else { 108 | delaytime = 0; 109 | delta = 5; 110 | fade = 0; 111 | } 112 | timer = millis(); 113 | } 114 | 115 | #define AUTOSWITCH_DELAY 20000 // ms = 20 seconds 116 | #define DEBOUNCE_DELAY 100 // ms 117 | bool debouncing = false; 118 | unsigned long buttontime = 0; 119 | 120 | void loop() { 121 | if (doHeartBeat) 122 | heartbeat(); 123 | else 124 | pulse(); 125 | 126 | if (millis() - timer > AUTOSWITCH_DELAY) { 127 | switchAction(true); 128 | } else if (digitalRead(buttonPin) != buttonState) { 129 | if (!debouncing) { 130 | debouncing = true; 131 | buttontime = millis(); // debounce start time 132 | } else if (millis() - buttontime > DEBOUNCE_DELAY) { 133 | debouncing = false; 134 | if (buttonState == buttonActive) { 135 | // was active (ie down) so now button is inactive (ie released) 136 | switchAction(false); 137 | } 138 | buttonState = digitalRead(buttonPin); 139 | } 140 | } 141 | // do other stuff here 142 | } 143 | -------------------------------------------------------------------------------- /13_wifi_uptime/wifi_uptime/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of wifi_uptime Arduino sketch 2 | // Copyright: see notice in wifi_uptime.ino 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "html.h" 9 | #include "secrets.h" 10 | 11 | #if defined(ARDUINO_XIAO_ESP32C3) 12 | #define TITLE "Seeed XIAO ESP32C3" 13 | #elif defined(ARDUINO_XIAO_ESP32C6) 14 | // The onboard ceramic antenna is used by default. 15 | // Uncomment the following macro to use a connected external antenna. 16 | //#define USE_EXTERNAL_ANTENNA 17 | #define TITLE "Seeed XIAO ESP32C6" 18 | #elif defined(ARDUINO_MAKERGO_C3_SUPERMINI) 19 | #define TITLE "MakerGO C3 SuperMini" 20 | #define TX_POWER WIFI_POWER_17dBm 21 | #endif 22 | 23 | #ifndef TITLE 24 | #error "Unspecified TITLE" 25 | #endif 26 | 27 | unsigned long connectTimer = 0; 28 | String connectStatus = "0"; 29 | 30 | unsigned long bcount = 0; 31 | String buttonStatus = "0"; 32 | 33 | int rssi = -100; 34 | String rssiStatus = "-100"; 35 | 36 | // Webserver instance using default HTTP port 80 37 | AsyncWebServer server(80); 38 | 39 | // Template substitution function 40 | String processor(const String& var){ 41 | if (var == "UPTIME") return connectStatus; 42 | if (var == "BCOUNT") return buttonStatus; 43 | if (var == "RSSI") return rssiStatus; 44 | if (var == "SERVERNAME") return String(TITLE); 45 | return String(); // empty string 46 | } 47 | 48 | // 404 error handler 49 | void notFound(AsyncWebServerRequest *request) { 50 | request->send_P(404, "text/html", html_404, processor); 51 | } 52 | 53 | void setup() { 54 | Serial.begin(); 55 | delay(2000); // 2 second delay should be sufficient 56 | 57 | Serial.println(); 58 | Serial.printf("Testing Wi-Fi uptime with %s ", TITLE); 59 | 60 | #if defined(ARDUINO_XIAO_ESP32C6) 61 | #if (ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 4)) 62 | // reproduce initVariant() from ESP32 v3.0.4 63 | uint8_t WIFI_ENABLE = 3; 64 | uint8_t WIFI_ANT_CONFIG = 14; 65 | // enable the RF switch 66 | pinMode(WIFI_ENABLE, OUTPUT); 67 | digitalWrite(WIFI_ENABLE, LOW); 68 | // select the internal antenna 69 | pinMode(WIFI_ANT_CONFIG, OUTPUT); 70 | digitalWrite(WIFI_ANT_CONFIG, LOW); 71 | #endif 72 | 73 | // same code for ESP32 v3.0.2 and up 74 | #if defined(USE_EXTERNAL_ANTENNA) 75 | digitalWrite(WIFI_ANT_CONFIG, HIGH); 76 | #endif 77 | 78 | Serial.print("using "); 79 | #ifdef USE_EXTERNAL_ANTENNA 80 | Serial.print("an external"); 81 | #else 82 | Serial.print("the internal"); 83 | #endif 84 | Serial.println(" antenna."); 85 | #endif 86 | 87 | Serial.println(); 88 | 89 | WiFi.mode(WIFI_STA); 90 | 91 | #ifdef TX_POWER 92 | WiFi.setTxPower(TX_POWER); 93 | Serial.printf("Setting Wi-Fi Tx power to %d\n", TX_POWER); 94 | #endif 95 | 96 | // Connect to Wi-Fi network with SSID and password 97 | Serial.print("Connecting to "); 98 | Serial.println(ssid); 99 | 100 | WiFi.begin(ssid, password); 101 | while (WiFi.status() != WL_CONNECTED) { 102 | delay(100); 103 | Serial.print("."); 104 | } 105 | 106 | connectTimer = millis(); 107 | // Print local IP address and start web server 108 | Serial.println(""); 109 | Serial.println("WiFi connected."); 110 | Serial.println("IP address: "); 111 | Serial.println(WiFi.localIP()); 112 | 113 | // Setup and start Web server 114 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ 115 | Serial.println("Index page requested"); 116 | request->send_P(200, "text/html", html_index, processor); 117 | }); 118 | server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ 119 | Serial.println("Web button pressed"); 120 | bcount++; 121 | buttonStatus = bcount; 122 | 123 | connectStatus = (float) ((float)(millis() - connectTimer)/60000); 124 | rssi = WiFi.RSSI(); 125 | rssiStatus = rssi; 126 | request->send_P(200, "text/html", html_index, processor); // updates the client making the request only 127 | }); 128 | server.onNotFound(notFound); 129 | server.begin(); 130 | 131 | Serial.println("setup completed."); 132 | } 133 | 134 | void loop() { 135 | } 136 | -------------------------------------------------------------------------------- /08-zigbee-switch/Zigbee_Light_Switch/README.md: -------------------------------------------------------------------------------- 1 | # Arduino-ESP32 Zigbee Light Switch Example 2 | 3 | This example shows how to configure Zigbee Coordinator and use it as a Home Automation (HA) on/off light switch. 4 | 5 | **This example is based on ESP-Zigbee-SDK example esp_zigbee_HA_sample/HA_on_off_switch.** 6 | 7 | # Supported Targets 8 | 9 | Currently, this example supports the following targets. 10 | 11 | | Supported Targets | ESP32-C6 | ESP32-H2 | 12 | | ----------------- | -------- | -------- | 13 | 14 | ## Hardware Required 15 | 16 | * One development board (ESP32-H2 or ESP32-C6) acting as Zigbee end device (loaded with Zigbee_Light_bulb example). 17 | * A USB cable for power supply and programming. 18 | * Choose another board (ESP32-H2 or ESP32-C6) as Zigbee coordinator (loaded with Zigbee_Light_switch example). 19 | 20 | ### Configure the Project 21 | 22 | Set the Button Switch GPIO by changing the `GPIO_INPUT_IO_TOGGLE_SWITCH` definition. By default, the TOGGLE_SWITCH pin is `GPIO_NUM_9` which is the Boot button on many ESP32-C6 boards. 23 | 24 | #### Using Arduino IDE 25 | 26 | To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits). 27 | 28 | ![](tools_config.jpg) 29 | 30 | * Before Compile/Verify, select the correct board: `Tools -> Board`. 31 | * Select the Coordinator Zigbee mode: `Tools -> Zigbee mode: Zigbee ZCZR (coordinator)`. 32 | * Select Partition Scheme for Zigbee: `Tools -> Partition Scheme: Zigbee 4MB with spiffs`. 33 | * Select the COM port: `Tools -> Port: xxx where the `xxx` is the detected COM port. 34 | * Optional: Set debug level to info to see logs from Zigbee stack: `Tools -> Core Debug Level: Info`. 35 | 36 | ## Troubleshooting 37 | 38 | If the End device flashed with the example `Zigbee_Light_Bulb` is not connecting to the coordinator, erase the flash of the End device before flashing the example to the board. It is recommended to do this if you re-flash the coordinator. 39 | You can do the following: 40 | 41 | * In the Arduino IDE go to the Tools menu and set `Erase All Flash Before Sketch Upload` to `Enabled`. 42 | * In the `Zigbee_Light_Bulb` example sketch uncomment function `esp_zb_nvram_erase_at_start(true);` located in `esp_zb_task` function. 43 | 44 | By default, the coordinator network is open for 180s after rebooting or flashing new firmware. After that, the network is closed for adding new devices. 45 | You can change it by editing `esp_zb_bdb_open_network(180);` in `esp_zb_app_signal_handler` function. 46 | 47 | ***Important: Make sure you are using a good quality USB cable and that you have a reliable power source*** 48 | 49 | * **LED not blinking:** Check the wiring connection and the IO selection. 50 | * **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed. 51 | * **COM port not detected:** Check the USB cable and the USB to Serial driver installation. 52 | 53 | If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). 54 | 55 | ## Contribute 56 | 57 | To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) 58 | 59 | If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! 60 | 61 | Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. 62 | 63 | ## Resources 64 | 65 | The ESP Zigbee SDK provides more examples: 66 | * ESP Zigbee SDK Docs: [Link](https://docs.espressif.com/projects/esp-zigbee-sdk) 67 | * ESP Zigbee SDK Repo: [Link](https://github.com/espressif/esp-zigbee-sdk) 68 | 69 | * Official ESP32 Forum: [Link](https://esp32.com) 70 | * Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) 71 | * ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) 72 | * ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) 73 | * ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) 74 | * ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf) 75 | * Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) 76 | -------------------------------------------------------------------------------- /03_scan_wifi/scan_wifi/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch demonstrates how to scan WiFi networks. 3 | * The API is based on the Arduino WiFi Shield library, but has significant changes as newer WiFi functions are supported. 4 | * E.g. the return value of `encryptionType()` different because more modern encryption is supported. 5 | * Source: https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples/WiFiScan 6 | * This appears to be released under the GNU LESSER GENERAL PUBLIC LICENSE 7 | * see: https://github.com/espressif/arduino-esp32/blob/master/LICENSE.md 8 | */ 9 | #include 10 | #include "WiFi.h" 11 | 12 | #if defined(ARDUINO_XIAO_ESP32C6) 13 | // The onboard ceramic antenna is used by default. 14 | // Uncomment the following macro to use a connected external antenna. 15 | // #define USE_EXTERNAL_ANTENNA 16 | // To test with the RF switch disabled 17 | //#define DISABLE_RF_SWITCH 18 | #else 19 | #undef USE_EXTERNAL_ANTENNA // just making sure 20 | #undef DISABLE_RF_SWITCH // just making sure 21 | #endif 22 | 23 | void setup() { 24 | Serial.begin(); 25 | // Set WiFi to station mode and disconnect from an AP if it was previously connected. 26 | WiFi.mode(WIFI_STA); 27 | WiFi.disconnect(); 28 | delay(2000); 29 | 30 | #if defined(ARDUINO_XIAO_ESP32C6) 31 | #if (ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 4)) 32 | // reproduce initVariant() from ESP32 v3.0.4 33 | uint8_t WIFI_ENABLE = 3; 34 | uint8_t WIFI_ANT_CONFIG = 14; 35 | // enable the RF switch 36 | pinMode(WIFI_ENABLE, OUTPUT); 37 | digitalWrite(WIFI_ENABLE, LOW); 38 | // select the internal antenna 39 | pinMode(WIFI_ANT_CONFIG, OUTPUT); 40 | digitalWrite(WIFI_ANT_CONFIG, LOW); 41 | #endif 42 | 43 | // same code for ESP32 v3.0.2 and up 44 | #if defined(DISABLE_RF_SWITCH) 45 | digitalWrite(WIFI_ENABLE, HIGH); 46 | pinMode(WIFI_ENABLE, INPUT); 47 | #endif 48 | #if defined(USE_EXTERNAL_ANTENNA) 49 | digitalWrite(WIFI_ANT_CONFIG, HIGH); 50 | #endif 51 | 52 | Serial.print("The RF switch is "); 53 | #ifdef DISABLE_RF_SWITCH 54 | Serial.print("not "); 55 | #endif 56 | Serial.println("enabled."); 57 | 58 | Serial.print("Using "); 59 | #ifdef USE_EXTERNAL_ANTENNA 60 | Serial.print("an external"); 61 | #else 62 | Serial.print("the internal"); 63 | #endif 64 | Serial.println(" antenna."); 65 | #endif 66 | 67 | Serial.println("Setup done"); 68 | } 69 | 70 | void loop() { 71 | Serial.println("\nScan start"); 72 | 73 | // WiFi.scanNetworks will return the number of networks found. 74 | int n = WiFi.scanNetworks(); 75 | Serial.println("Scan done"); 76 | if (n == 0) { 77 | Serial.println("no networks found"); 78 | } else { 79 | Serial.print(n); 80 | Serial.println(" networks found"); 81 | Serial.println("Nr | SSID | RSSI | CH | Encryption"); 82 | for (int i = 0; i < n; ++i) { 83 | // Print SSID and RSSI for each network found 84 | Serial.printf("%2d", i + 1); 85 | Serial.print(" | "); 86 | Serial.printf("%-32.32s", WiFi.SSID(i).c_str()); 87 | Serial.print(" | "); 88 | Serial.printf("%4ld", WiFi.RSSI(i)); 89 | Serial.print(" | "); 90 | Serial.printf("%2ld", WiFi.channel(i)); 91 | Serial.print(" | "); 92 | switch (WiFi.encryptionType(i)) { 93 | case WIFI_AUTH_OPEN: Serial.print("open"); break; 94 | case WIFI_AUTH_WEP: Serial.print("WEP"); break; 95 | case WIFI_AUTH_WPA_PSK: Serial.print("WPA"); break; 96 | case WIFI_AUTH_WPA2_PSK: Serial.print("WPA2"); break; 97 | case WIFI_AUTH_WPA_WPA2_PSK: Serial.print("WPA+WPA2"); break; 98 | case WIFI_AUTH_WPA2_ENTERPRISE: Serial.print("WPA2-EAP"); break; 99 | case WIFI_AUTH_WPA3_PSK: Serial.print("WPA3"); break; 100 | case WIFI_AUTH_WPA2_WPA3_PSK: Serial.print("WPA2+WPA3"); break; 101 | case WIFI_AUTH_WAPI_PSK: Serial.print("WAPI"); break; 102 | default: Serial.print("unknown"); 103 | } 104 | Serial.println(); 105 | delay(10); 106 | } 107 | } 108 | Serial.println(""); 109 | 110 | // Delete the scan result to free memory for code below. 111 | WiFi.scanDelete(); 112 | 113 | // Wait a bit before scanning again. 114 | delay(5000); 115 | } 116 | -------------------------------------------------------------------------------- /09-zigbee-bulb/Readme.md: -------------------------------------------------------------------------------- 1 | # 09-zigbee-bulb 2 | 3 | The `Zigbee_Light_Bulb` directory contains basically a clone of the example sketch from the `esp32` version 3.0.2 package which is found here in a Linux system: 4 | `~/.arduino15/packages/esp32/hardware/esp32/3.0.2/libraries/ESP32/examples/Zigbee/Zigbee_Light_Bulb` 5 | 6 | However it was necessary to make slight adjustments to the code when using that sketch in conjunction with the `Zigbee_Light_Switch` with two ESP32-C6 boards. 7 | 8 | ## Modifications to the Source 9 | 10 | ### LED vs RGB_LED 11 | 12 | Some modification of the source code was necessary to support the XIAO ESP32-C6 and other boards that have an onboard LED but not an RGB LED. Changes are easily identified because of the use of ```#if defined(RGB_BUILTIN)```. 13 | 14 | ```cpp 15 | #if defined(RGB_BUILTIN) 16 | #define LED_PIN RGB_BUILTIN 17 | #elif defined(LED_BUILTIN) 18 | #define LED_PIN LED_BUILTIN 19 | #define LED_ON LOW // LOW = I/O pin must be grounded to turn on LED 20 | #else 21 | #error "NO LED defined" 22 | #endif 23 | ``` 24 | 25 | ### 26 | Note that on the XIAO the LED is turned on by writing LOW to its I/O pin. Set `#define LED_ON HIGH` for boards where setting the I/O pin high turns the LED on. 27 | 28 | 29 | ### Minimum Link Quality Indicator 30 | 31 | If Zigbee bulb does not connect to the Zigbee switch, with the following debug output 32 | 33 | ``` 34 | esp_zb_app_signal_handler(): Network steering was not successful (status: ESP_FAIL) 35 | ``` 36 | 37 | then it may be necessary to adjust the Link Quality Indicator threshold as suggested by [xiequnan](https://github.com/espressif/esp-zigbee-sdk/issues/363#issuecomment-2160086939). He proposed a value of 32, but matthiasbuettner159 in the next message used a value of 0. 38 | 39 | By default, the LQI threshold is not modified, uncomment the `LQI_THRESHOLD` macro and modify its value as desired. 40 | 41 | ``` 42 | //#define LQI_THRESHOLD 32 43 | ``` 44 | 45 | If `LQI_THRESHOLD` is defined, the LQI threshold will be set in the `esp_zb_task` function. 46 | 47 | ```cpp 48 | static void esp_zb_task(void *pvParameters) { 49 | esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG(); 50 | esp_zb_init(&zb_nwk_cfg); 51 | esp_zb_on_off_light_cfg_t light_cfg = ESP_ZB_DEFAULT_ON_OFF_LIGHT_CONFIG(); 52 | esp_zb_ep_list_t *esp_zb_on_off_light_ep = esp_zb_on_off_light_ep_create(HA_ESP_LIGHT_ENDPOINT, &light_cfg); 53 | esp_zb_device_register(esp_zb_on_off_light_ep); 54 | esp_zb_core_action_handler_register(zb_action_handler); 55 | esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK); 56 | #if defined(LQI_THRESHOLD) 57 | esp_zb_secur_network_min_join_lqi_set(LQI_THRESHOLD); 58 | #endif 59 | 60 | //Erase NVRAM before creating connection to new Coordinator 61 | esp_zb_nvram_erase_at_start(true); //Comment out this line to erase NVRAM data if you are conneting to new Coordinator 62 | 63 | ESP_ERROR_CHECK(esp_zb_start(false)); 64 | esp_zb_main_loop_iteration(); 65 | } 66 | ``` 67 | 68 | 74 | 75 | ## Compiling 76 | 77 | The Troubleshooting guide in the sketch [README.md](Zigbee_Light_Bulb/README.md) file suggests erasing the flash before uploading the firmware: 78 | 79 | > You can do the following: 80 | > - In the Arduino IDE go to the Tools menu and set Erase All Flash Before Sketch Upload to Enabled 81 | > - In the sketch uncomment function esp_zb_nvram_erase_at_start(true); located in esp_zb_task function. 82 | 83 | Presumably, if `esp_zb_nvram_erase_at_start(true);` is not a comment (it is NOT in the example sketch), the non-volatile storage will be erased when the task starts and there would not be any need to erase all flash before uploading the sketch. On the other hand, commenting out `esp_zb_nvram_erase_at_start(true);` could make pairing faster. 84 | 85 | Do not forget to set the Arduino configuration as instructed before compiling. Here are the settings used with a XIAO ESP32C6 86 | 87 | ![](tools_config.jpg) 88 | 89 | With these settings, and with a LQI_THRESHOLD of 32, the XIAO ESP32-C6 did pair with another XIAO ESP32-C6 running th Zigbee_Light_Switch sketch. 90 | -------------------------------------------------------------------------------- /06_async_web_led/async_web_led/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of async_web_led PlatformIO/Arduino sketch 2 | // Copyright: see notice in async_web_led.ino 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "html.h" 9 | #include "secrets.h" 10 | 11 | #if defined(BUILTIN_LED) 12 | static uint8_t ledPin = BUILTIN_LED; 13 | static uint8_t ledOn = LOW; 14 | #if defined(ARDUINO_XIAO_ESP32C6) 15 | // The onboard ceramic antenna is used by default. 16 | // Uncomment the following macro to use a connected external antenna. 17 | #define USE_EXTERNAL_ANTENNA 18 | #define TITLE "Seeed XIAO ESP32C6" 19 | #else 20 | #undef USE_EXTERNAL_ANTENNA 21 | #endif 22 | #elif defined(ARDUINO_XIAO_ESP32C3) 23 | // Connect an external LED: 24 | // The diode's cathode (-, usually the short lead on the flat side of the LED) is connected to GND. 25 | // The diode's anode (+, usually the long lead on the round side of the LED) is connected to a 26 | // current limiting 240 ohm resistor. The other lead of the resistor is connected to an I/O pin. 27 | // 28 | static uint8_t ledPin = D10; 29 | static uint8_t ledOn = HIGH; 30 | #define TITLE "Seeed XIAO ESP32C3" 31 | #else 32 | #error "ledPin not defined" 33 | #endif 34 | 35 | #ifndef TITLE 36 | #error "Unspecified TITLE" 37 | #endif 38 | 39 | int ledState = 0; 40 | String ledStatus = "OFF"; 41 | 42 | void setLed(int value) { 43 | digitalWrite(ledPin, (value)? ledOn : 1-ledOn); 44 | ledState = value; 45 | ledStatus = ((digitalRead(ledPin) == ledOn) ? "ON" : "OFF"); 46 | Serial.printf("LED now %s.\n", ledStatus.c_str()); 47 | } 48 | 49 | void toggleLed(void) { 50 | setLed(1-ledState); 51 | } 52 | 53 | // Webserver instance using default HTTP port 80 54 | AsyncWebServer server(80); 55 | 56 | // Template substitution function 57 | String processor(const String& var){ 58 | if (var == "LEDSTATUS") return String(ledStatus); 59 | if (var == "SERVERNAME") return String(TITLE); 60 | return String(); // empty string 61 | } 62 | 63 | // 404 error handler 64 | void notFound(AsyncWebServerRequest *request) { 65 | request->send_P(404, "text/html", html_404, processor); 66 | } 67 | 68 | void setup() { 69 | // Set the digital pin connected to the LED as an output 70 | pinMode(ledPin, OUTPUT); 71 | 72 | Serial.begin(); 73 | delay(3000); // 3 second delay should be sufficient 74 | 75 | #if defined(ARDUINO_XIAO_ESP32C6) 76 | #if (ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 4)) 77 | // reproduce initVariant() from ESP32 v3.0.4 78 | uint8_t WIFI_ENABLE = 3; 79 | uint8_t WIFI_ANT_CONFIG = 14; 80 | // enable the RF switch 81 | pinMode(WIFI_ENABLE, OUTPUT); 82 | digitalWrite(WIFI_ENABLE, LOW); 83 | // select the internal antenna 84 | pinMode(WIFI_ANT_CONFIG, OUTPUT); 85 | digitalWrite(WIFI_ANT_CONFIG, LOW); 86 | #endif 87 | 88 | // same code for ESP32 v3.0.2 and up 89 | #if defined(USE_EXTERNAL_ANTENNA) 90 | digitalWrite(WIFI_ANT_CONFIG, HIGH); 91 | #endif 92 | 93 | Serial.print("Using "); 94 | #ifdef USE_EXTERNAL_ANTENNA 95 | Serial.print("an external"); 96 | #else 97 | Serial.print("the internal"); 98 | #endif 99 | Serial.println(" antenna."); 100 | #endif 101 | 102 | setLed(0); 103 | 104 | WiFi.mode(WIFI_STA); 105 | 106 | #ifdef TX_POWER 107 | WiFi.setTxPower(TX_POWER); 108 | Serial.printf("Setting Wi-Fi Tx power to %d\n", TX_POWER); 109 | #endif 110 | 111 | // Connect to Wi-Fi network with SSID and password 112 | Serial.print("Connecting to "); 113 | Serial.println(ssid); 114 | 115 | WiFi.begin(ssid, password); 116 | while (WiFi.status() != WL_CONNECTED) { 117 | delay(100); 118 | Serial.print("."); 119 | } 120 | // Print local IP address and start web server 121 | Serial.println(""); 122 | Serial.println("WiFi connected."); 123 | Serial.println("IP address: "); 124 | Serial.println(WiFi.localIP()); 125 | 126 | // Setup and start Web server 127 | server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ 128 | Serial.println("Index page requested"); 129 | request->send_P(200, "text/html", html_index, processor); 130 | }); 131 | server.on("/led", HTTP_GET, [](AsyncWebServerRequest *request){ 132 | Serial.println("Web button pressed"); 133 | toggleLed(); 134 | request->send_P(200, "text/html", html_index, processor); // updates the client making the request only 135 | }); 136 | server.onNotFound(notFound); 137 | server.begin(); 138 | 139 | setLed(0); 140 | Serial.println("setup completed."); 141 | } 142 | 143 | void loop() { 144 | } 145 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/AsyncEventSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | Asynchronous WebServer library for Espressif MCUs 3 | 4 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | #ifndef ASYNCEVENTSOURCE_H_ 21 | #define ASYNCEVENTSOURCE_H_ 22 | 23 | #include 24 | #ifdef ESP32 25 | #include 26 | #define SSE_MAX_QUEUED_MESSAGES 32 27 | #else 28 | #include 29 | #define SSE_MAX_QUEUED_MESSAGES 8 30 | #endif 31 | #include 32 | 33 | #include "AsyncWebSynchronization.h" 34 | 35 | #ifdef ESP8266 36 | #include 37 | #ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library 38 | #include <../src/Hash.h> 39 | #endif 40 | #endif 41 | 42 | #ifdef ESP32 43 | #define DEFAULT_MAX_SSE_CLIENTS 8 44 | #else 45 | #define DEFAULT_MAX_SSE_CLIENTS 4 46 | #endif 47 | 48 | class AsyncEventSource; 49 | class AsyncEventSourceResponse; 50 | class AsyncEventSourceClient; 51 | typedef std::function ArEventHandlerFunction; 52 | 53 | class AsyncEventSourceMessage { 54 | private: 55 | uint8_t * _data; 56 | size_t _len; 57 | size_t _sent; 58 | //size_t _ack; 59 | size_t _acked; 60 | public: 61 | AsyncEventSourceMessage(const char * data, size_t len); 62 | ~AsyncEventSourceMessage(); 63 | size_t ack(size_t len, uint32_t time __attribute__((unused))); 64 | size_t send(AsyncClient *client); 65 | bool finished(){ return _acked == _len; } 66 | bool sent() { return _sent == _len; } 67 | }; 68 | 69 | class AsyncEventSourceClient { 70 | private: 71 | AsyncClient *_client; 72 | AsyncEventSource *_server; 73 | uint32_t _lastId; 74 | LinkedList _messageQueue; 75 | void _queueMessage(AsyncEventSourceMessage *dataMessage); 76 | void _runQueue(); 77 | 78 | public: 79 | 80 | AsyncEventSourceClient(AsyncWebServerRequest *request, AsyncEventSource *server); 81 | ~AsyncEventSourceClient(); 82 | 83 | AsyncClient* client(){ return _client; } 84 | void close(); 85 | void write(const char * message, size_t len); 86 | void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); 87 | bool connected() const { return (_client != NULL) && _client->connected(); } 88 | uint32_t lastId() const { return _lastId; } 89 | size_t packetsWaiting() const { return _messageQueue.length(); } 90 | 91 | //system callbacks (do not call) 92 | void _onAck(size_t len, uint32_t time); 93 | void _onPoll(); 94 | void _onTimeout(uint32_t time); 95 | void _onDisconnect(); 96 | }; 97 | 98 | class AsyncEventSource: public AsyncWebHandler { 99 | private: 100 | String _url; 101 | LinkedList _clients; 102 | ArEventHandlerFunction _connectcb; 103 | public: 104 | AsyncEventSource(const String& url); 105 | ~AsyncEventSource(); 106 | 107 | const char * url() const { return _url.c_str(); } 108 | void close(); 109 | void onConnect(ArEventHandlerFunction cb); 110 | void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); 111 | size_t count() const; //number clinets connected 112 | size_t avgPacketsWaiting() const; 113 | 114 | //system callbacks (do not call) 115 | void _addClient(AsyncEventSourceClient * client); 116 | void _handleDisconnect(AsyncEventSourceClient * client); 117 | virtual bool canHandle(AsyncWebServerRequest *request) override final; 118 | virtual void handleRequest(AsyncWebServerRequest *request) override final; 119 | }; 120 | 121 | class AsyncEventSourceResponse: public AsyncWebServerResponse { 122 | private: 123 | String _content; 124 | AsyncEventSource *_server; 125 | public: 126 | AsyncEventSourceResponse(AsyncEventSource *server); 127 | void _respond(AsyncWebServerRequest *request); 128 | size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); 129 | bool _sourceValid() const { return true; } 130 | }; 131 | 132 | 133 | #endif /* ASYNCEVENTSOURCE_H_ */ 134 | -------------------------------------------------------------------------------- /10_deep_sleep_tmr/deep_sleep_tmr/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of deep_sleep_tmr.ino 2 | // Copyright: see notice in deep_sleep_tmr.ino 3 | 4 | /************************************************************** 5 | OPERATION 6 | Each time the board wakes up from deep sleep, it restarts by 7 | executing the setup() function. First it displays the number 8 | of restarts since the last reset by slowly blinking out the 9 | count with the onboard yellow LED. Then, after a five second 10 | delay, the LED is flashed quickly a few times indicating 11 | that the board will be put into deep sleep for another 12 | SLEEP_PERIOD. 13 | 14 | NOTE 15 | Define the USE_SERIAL macro to print statements to the 16 | console with the Serial peripheral. This is best done in the 17 | Arduino IDE because its serial monitor will automatically 18 | reconnect with the ESP32-C6 when it wakes from deep sleep 19 | and reopens its serial port. With the PlaformIO terminal 20 | it is necessary to reconnect manually whenever the board 21 | comes out of deep sleep. 22 | *************************************************************/ 23 | 24 | #include 25 | 26 | //#define USE_SERIAL 27 | 28 | // 15 seccond sleep period in microseconds 29 | #define SLEEP_PERIOD 15000000 30 | 31 | // On board yellow LED 32 | const int ledPin = BUILTIN_LED; 33 | const int ledOn = LOW; 34 | 35 | // Counter for restarts stored in non-volatile memory 36 | RTC_DATA_ATTR int bootCount = 0; 37 | 38 | // Flash LED for count times with ms on and off times 39 | void blink(int count=1, int ms=50) { 40 | for (int i=0; i 25 | 26 | //#define USE_SERIAL 27 | 28 | // Only RTC IO pins 0 to 7 can be used as a source for external 29 | // wake on the ESP32-C6 which means only pins D0, D1 or D2 30 | // for that purpose on the XIAO ESP32C6 31 | const int wakeUpPin = 0; 32 | 33 | // On board yellow LED 34 | const int ledPin = BUILTIN_LED; 35 | const int ledOn = LOW; 36 | 37 | // Counter for restarts stored in non-volatile memory 38 | RTC_DATA_ATTR int bootCount = 0; 39 | 40 | // Flash LED for count times with ms on and off times 41 | void blink(int count=1, int ms=50) { 42 | for (int i=0; i 28 | class LinkedListNode { 29 | T _value; 30 | public: 31 | LinkedListNode* next; 32 | LinkedListNode(const T val): _value(val), next(nullptr) {} 33 | ~LinkedListNode(){} 34 | const T& value() const { return _value; }; 35 | T& value(){ return _value; } 36 | }; 37 | 38 | template class Item = LinkedListNode> 39 | class LinkedList { 40 | public: 41 | typedef Item ItemType; 42 | typedef std::function OnRemove; 43 | typedef std::function Predicate; 44 | private: 45 | ItemType* _root; 46 | OnRemove _onRemove; 47 | 48 | class Iterator { 49 | ItemType* _node; 50 | public: 51 | Iterator(ItemType* current = nullptr) : _node(current) {} 52 | Iterator(const Iterator& i) : _node(i._node) {} 53 | Iterator& operator ++() { _node = _node->next; return *this; } 54 | bool operator != (const Iterator& i) const { return _node != i._node; } 55 | const T& operator * () const { return _node->value(); } 56 | const T* operator -> () const { return &_node->value(); } 57 | }; 58 | 59 | public: 60 | typedef const Iterator ConstIterator; 61 | ConstIterator begin() const { return ConstIterator(_root); } 62 | ConstIterator end() const { return ConstIterator(nullptr); } 63 | 64 | LinkedList(OnRemove onRemove) : _root(nullptr), _onRemove(onRemove) {} 65 | ~LinkedList(){} 66 | void add(const T& t){ 67 | auto it = new ItemType(t); 68 | if(!_root){ 69 | _root = it; 70 | } else { 71 | auto i = _root; 72 | while(i->next) i = i->next; 73 | i->next = it; 74 | } 75 | } 76 | T& front() const { 77 | return _root->value(); 78 | } 79 | 80 | bool isEmpty() const { 81 | return _root == nullptr; 82 | } 83 | size_t length() const { 84 | size_t i = 0; 85 | auto it = _root; 86 | while(it){ 87 | i++; 88 | it = it->next; 89 | } 90 | return i; 91 | } 92 | size_t count_if(Predicate predicate) const { 93 | size_t i = 0; 94 | auto it = _root; 95 | while(it){ 96 | if (!predicate){ 97 | i++; 98 | } 99 | else if (predicate(it->value())) { 100 | i++; 101 | } 102 | it = it->next; 103 | } 104 | return i; 105 | } 106 | const T* nth(size_t N) const { 107 | size_t i = 0; 108 | auto it = _root; 109 | while(it){ 110 | if(i++ == N) 111 | return &(it->value()); 112 | it = it->next; 113 | } 114 | return nullptr; 115 | } 116 | bool remove(const T& t){ 117 | auto it = _root; 118 | auto pit = _root; 119 | while(it){ 120 | if(it->value() == t){ 121 | if(it == _root){ 122 | _root = _root->next; 123 | } else { 124 | pit->next = it->next; 125 | } 126 | 127 | if (_onRemove) { 128 | _onRemove(it->value()); 129 | } 130 | 131 | delete it; 132 | return true; 133 | } 134 | pit = it; 135 | it = it->next; 136 | } 137 | return false; 138 | } 139 | bool remove_first(Predicate predicate){ 140 | auto it = _root; 141 | auto pit = _root; 142 | while(it){ 143 | if(predicate(it->value())){ 144 | if(it == _root){ 145 | _root = _root->next; 146 | } else { 147 | pit->next = it->next; 148 | } 149 | if (_onRemove) { 150 | _onRemove(it->value()); 151 | } 152 | delete it; 153 | return true; 154 | } 155 | pit = it; 156 | it = it->next; 157 | } 158 | return false; 159 | } 160 | 161 | void free(){ 162 | while(_root != nullptr){ 163 | auto it = _root; 164 | _root = _root->next; 165 | if (_onRemove) { 166 | _onRemove(it->value()); 167 | } 168 | delete it; 169 | } 170 | _root = nullptr; 171 | } 172 | }; 173 | 174 | 175 | class StringArray : public LinkedList { 176 | public: 177 | 178 | StringArray() : LinkedList(nullptr) {} 179 | 180 | bool containsIgnoreCase(const String& str){ 181 | for (const auto& s : *this) { 182 | if (str.equalsIgnoreCase(s)) { 183 | return true; 184 | } 185 | } 186 | return false; 187 | } 188 | }; 189 | 190 | 191 | 192 | 193 | #endif /* STRINGARRAY_H_ */ 194 | -------------------------------------------------------------------------------- /15_zigbee-on-off-light/Zigbee_On_Off_Light/README.md: -------------------------------------------------------------------------------- 1 | # Arduino-ESP32 Zigbee On/Off Light Example 2 | 3 | This example shows how to configure the Zigbee end device and use it as a Home Automation (HA) on/off light. 4 | 5 | **The original README was renamed [README-org.md](README-org.md)** 6 | 7 | ## Supported Targets 8 | 9 | Currently, this example supports the following targets. 10 | 11 | | Supported Targets | ESP32-C6 | ESP32-H2 | 12 | | ----------------- | -------- | -------- | 13 | 14 | ## Hardware Required 15 | 16 | * A development board (ESP32-H2 or ESP32-C6 based) acting as a Zigbee end device (running the Zigbee_On_Off_Light example). 17 | 18 | * A USB cable for power supply and programming 19 | 20 | * A compatible Zigbee coordinator such as Zigbee2MQTT **or** another development board (ESP32-H2 or ESP32-C6 based) acting as a Zigbee coordinator (running the Zigbee_On_Off_Switch example). 21 | 22 | ## Configure the Project 23 | 24 | Four macros are defined at the top of the source (main.cpp) to handle different development boards. These are 25 | 1. LED_PIN - number of the I/O pin to which a simple LED or an RGB LED is connected. 26 | 1. LED_ON - can be HIGH or LOW depending on which signal turns the LED on. 27 | 1. SERIAL_BAUD - usually 115200 if the development board has a discrete USB-to-serial adapter and not used otherwise. 28 | 1. USE_EXTERNAL_ANTENNA - define only if the board is an XIAO ESP32C6 and only if an external antenna is used. 29 | 30 | The macros are automatically defined correctly for the [Seeed Studio XIAO ESP32C6](https://www.seeedstudio.com/Seeed-Studio-XIAO-ESP32C6-p-5884.html) and should also be correct for the [Espressif Development Kits](https://www.espressif.com/en/products/devkits) although these have not been tested. It may be necessary to tweak some macros for other ESP32-C6 or ESP32-H2 based boards. 31 | 32 | 33 | ## Compiling and Uploading the Sketch 34 | 35 | ### Using Arduino IDE 36 | 37 | Before Compile/Verify, go to the `Tools` menu to modify the following options. 38 | 39 | * Select the correct **Board** (example: *"XIAO_ESP32C6"*). 40 | * Select the correct **Port** (examples: *"/dev/ttyACM0"* in Linux, *"Com4"* in Windows). 41 | * Set the **Partition Scheme** to *"Zigbee 4MB with spiffs"*. 42 | * Set the **Zigbee mode** *"Zigbee ED (end device)"*. 43 | * Optional: Set **Core Debug Level** to the desired level such as *"Verbose"* (default is *"None"*). 44 | * Optional: Set **Erase All Flash Before Sketch Upload** to *"Enabled"* (default is *"Disabled"*). 45 | 46 | ![IDE-Tools-screenshot](../tools_config.jpg) 47 | 48 | ### Using PlatformIO 49 | 50 | *forthcoming* 51 | 52 | ## Connecting to a Zigbee Coordinator 53 | 54 | Assuming that the Zigbee_On_OFF_Light firmware was uploaded to the development board with **Erase All Flash Before Sketch Upload** set to *"Enabled"*, here are the steps to connect to a coordinator for the first time. 55 | 56 | ### Connecting to a Zigbee2MQTT Coordinator 57 | 58 | It is best to ensure that the Zigbee2MQTT coordinator is the nearest Zigbee coordinator to the ESP32 dev board. 59 | 60 | - Open the Zigbee2MQTT web interface (usually at https:[coordinator_ip]:8080/) 61 | - Enable end device connections to the zibgee network by clicking on the **[Permit join (All)]** button in the top menu. 62 | - Power up the development board running the `Zigbee_On_Off_Light` sketch. 63 | 64 | After a short while, the board should show up in the Devices table as *Model* `ZBlightBulb`, while the *Manufacturer* is listed as `Unsupported`. 65 | 66 | ![](../zigbee2mqtt_devices.jpg) 67 | 68 | Click on the **Friendly name** so see details about the Zigbee end device and then click on its **Exposes** tab. 69 | 70 | ![](../zigbee2mqtt_state.jpg) 71 | 72 | Clicking on the **OFF** and **ON** buttons in that view controls the LED of the ESP32 development board running the Zigbee_On_Off_Light sketch. 73 | 74 | Clicking on the boot button of the development board toggles the state of the onboard LED and the State of the end device is updated accordingly in its **Exposes** tab in the Zigbee2MQTT web interface. 75 | 76 | 77 | ### Connecting to a Zigbee_On_Off_Switch coordinator 78 | 79 | It is best to ensure that the development board running the Zigbee_On_Off_Switch coordinator firmware is very near to the ESP32 dev board running the Zigbee_On_Off_Light end device firmware. Tests have shown that a Zigbee2MQTT coordinator or a Zigbee router a few metres away will not interfere. 80 | 81 | - Power up the development board running the `Zigbee_On_Off_Light` sketch. 82 | - Power up the development board running the `Zigbee_On_Off_Switch` sketch (network joining is enabled by default). 83 | 84 | After a short while, the end device (...Light) should have joined the Zigbee network created by the coordinator (...Switch). The serial output of the two devices should make that clear, especially if the **core debug level** was set to `"Verbose"`. In any case, test by pressing the boot button of the coordinator. It should toggle the state of the LED on the end device. 85 | 86 | ### Switching between coordinators 87 | 88 | It should not be necessary to erase the flash memory of the end device and then to upload its firmware again in order to connect it to a new coordinator, although that should work. 89 | 90 | The easiest way to switch between coordinators is to perform a `Zigbee.factoryReset()` of the end device (...Light) and then to reset the device. 91 | 92 | - A `Zigbee.factoryReset()` of the end device (...Light) is performed when its boot button is depressed for more than 3 seconds. 93 | 94 | - A reset of the end device (...Light) is performed by pressing on its Reset button. 95 | 96 | Of course, it is important to ensure that the end device is closer to the desired coordinator than to the other coordinator. 97 | 98 | The [original README](README-org.md) has more troubleshooting advice. 99 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/WebResponseImpl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Asynchronous WebServer library for Espressif MCUs 3 | 4 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 5 | This file is part of the esp8266 core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef ASYNCWEBSERVERRESPONSEIMPL_H_ 22 | #define ASYNCWEBSERVERRESPONSEIMPL_H_ 23 | 24 | #ifdef Arduino_h 25 | // arduino is not compatible with std::vector 26 | #undef min 27 | #undef max 28 | #endif 29 | #include 30 | // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. 31 | 32 | class AsyncBasicResponse: public AsyncWebServerResponse { 33 | private: 34 | String _content; 35 | public: 36 | AsyncBasicResponse(int code, const String& contentType=String(), const String& content=String()); 37 | void _respond(AsyncWebServerRequest *request); 38 | size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); 39 | bool _sourceValid() const { return true; } 40 | }; 41 | 42 | class AsyncAbstractResponse: public AsyncWebServerResponse { 43 | private: 44 | String _head; 45 | // Data is inserted into cache at begin(). 46 | // This is inefficient with vector, but if we use some other container, 47 | // we won't be able to access it as contiguous array of bytes when reading from it, 48 | // so by gaining performance in one place, we'll lose it in another. 49 | std::vector _cache; 50 | size_t _readDataFromCacheOrContent(uint8_t* data, const size_t len); 51 | size_t _fillBufferAndProcessTemplates(uint8_t* buf, size_t maxLen); 52 | protected: 53 | AwsTemplateProcessor _callback; 54 | public: 55 | AsyncAbstractResponse(AwsTemplateProcessor callback=nullptr); 56 | void _respond(AsyncWebServerRequest *request); 57 | size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); 58 | bool _sourceValid() const { return false; } 59 | virtual size_t _fillBuffer(uint8_t *buf __attribute__((unused)), size_t maxLen __attribute__((unused))) { return 0; } 60 | }; 61 | 62 | #ifndef TEMPLATE_PLACEHOLDER 63 | #define TEMPLATE_PLACEHOLDER '%' 64 | #endif 65 | 66 | #define TEMPLATE_PARAM_NAME_LENGTH 32 67 | class AsyncFileResponse: public AsyncAbstractResponse { 68 | using File = fs::File; 69 | using FS = fs::FS; 70 | private: 71 | File _content; 72 | String _path; 73 | void _setContentType(const String& path); 74 | public: 75 | AsyncFileResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); 76 | AsyncFileResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); 77 | ~AsyncFileResponse(); 78 | bool _sourceValid() const { return !!(_content); } 79 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 80 | }; 81 | 82 | class AsyncStreamResponse: public AsyncAbstractResponse { 83 | private: 84 | Stream *_content; 85 | public: 86 | AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); 87 | bool _sourceValid() const { return !!(_content); } 88 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 89 | }; 90 | 91 | class AsyncCallbackResponse: public AsyncAbstractResponse { 92 | private: 93 | AwsResponseFiller _content; 94 | size_t _filledLength; 95 | public: 96 | AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); 97 | bool _sourceValid() const { return !!(_content); } 98 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 99 | }; 100 | 101 | class AsyncChunkedResponse: public AsyncAbstractResponse { 102 | private: 103 | AwsResponseFiller _content; 104 | size_t _filledLength; 105 | public: 106 | AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); 107 | bool _sourceValid() const { return !!(_content); } 108 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 109 | }; 110 | 111 | class AsyncProgmemResponse: public AsyncAbstractResponse { 112 | private: 113 | const uint8_t * _content; 114 | size_t _readLength; 115 | public: 116 | AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); 117 | bool _sourceValid() const { return true; } 118 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 119 | }; 120 | 121 | class cbuf; 122 | 123 | class AsyncResponseStream: public AsyncAbstractResponse, public Print { 124 | private: 125 | cbuf *_content; 126 | public: 127 | AsyncResponseStream(const String& contentType, size_t bufferSize); 128 | ~AsyncResponseStream(); 129 | bool _sourceValid() const { return (_state < RESPONSE_END); } 130 | virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; 131 | size_t write(const uint8_t *data, size_t len); 132 | size_t write(uint8_t data); 133 | using Print::write; 134 | }; 135 | 136 | #endif /* ASYNCWEBSERVERRESPONSEIMPL_H_ */ 137 | -------------------------------------------------------------------------------- /07_ble_led/ble_led/main.cpp: -------------------------------------------------------------------------------- 1 | // Main module of ble_led.ino 2 | // Copyright: see notice in ble_led.ino 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // This is a simplified example which can use custom UUIDs in which case 10 | // the client will probably show the UUID for the service and characteristic 11 | // or it can use some more or less valid reserved UUID from the Bluetooth(R) 12 | // Assigned Numbers document https://www.bluetooth.com/specifications/assigned-numbers/ 13 | // 14 | #define USE_CUSTOM_UUIDS 15 | 16 | #define BLUETOOTH_NAME "BLE_LED" 17 | 18 | #ifdef USE_CUSTOM_UUIDS 19 | // Custom UUID for service and characteristic must not conflict with a reserved UUID 20 | // that is no number in the XXXXXXXX-0000-1000-8000-00805F9B34FB range 21 | // Generated at https://www.guidgenerator.com/ 22 | // https://novelbits.io/uuid-for-custom-services-and-characteristics/ 23 | #define SERVICE_UUID "57a81fc3-3c5f-4d29-80e7-8b074e34888c" 24 | #define CHARACTERISTIC_UUID "2eeae074-8955-47f7-9470-73f85112974f" 25 | #else 26 | #define SERVICE_UUID "1815" //"00001815-0000-1000-8000-00805F9B34FB" // Automation IO Service 27 | //"1812" //"00001812-0000-1000-8000-00805F9B34FB" // Human Interface Device Service 28 | //"181c" //"0000181c-0000-1000-8000-00805F9B34FB" // User Data Service 29 | #define CHARACTERISTIC_UUID "2BE2" //"00002BE2-0000-1000-8000-00805F9B34FB" // Light Output 30 | //"2BO5" //"00002B05-0000-1000-8000-00805F9B34FB" // Power 31 | #endif 32 | 33 | #if defined(BUILTIN_LED) 34 | const uint8_t ledPin = BUILTIN_LED; 35 | const uint8_t ledOn = LOW; 36 | #else 37 | #error "ledPin not defined" 38 | #endif 39 | 40 | #if defined(ARDUINO_XIAO_ESP32C6) 41 | // The onboard ceramic antenna is used by default. 42 | // Uncomment the following macro to use a connected external antenna. 43 | //#define USE_EXTERNAL_ANTENNA 44 | #else 45 | #undef USE_EXTERNAL_ANTENNA 46 | #endif 47 | 48 | BLEServer *pServer = nullptr; 49 | BLECharacteristic *pCharacteristic = nullptr; 50 | 51 | bool deviceConnected = false; 52 | 53 | class MyServerCallbacks: public BLEServerCallbacks { 54 | void onConnect(BLEServer* pServer) { 55 | deviceConnected = true; 56 | Serial.println("Device connected"); 57 | }; 58 | 59 | void onDisconnect(BLEServer* pServer) { 60 | deviceConnected = false; 61 | Serial.println("Device disconnected"); 62 | Serial.println("Restart advertising"); 63 | BLEDevice::startAdvertising(); 64 | } 65 | }; 66 | 67 | class WriteCallbacks : public BLECharacteristicCallbacks { 68 | void onWrite(BLECharacteristic *pCharacteristic) { 69 | String value = pCharacteristic->getValue().c_str(); 70 | if (value == "on") { 71 | digitalWrite(ledPin, ledOn); 72 | Serial.println("Received \"on\" value"); 73 | } else if(value == "off"){ 74 | digitalWrite(ledPin, 1-ledOn); 75 | Serial.println("Received \"off\" value"); 76 | } else { 77 | Serial.printf("Received non valid \"%s\" value \n", value.c_str()); 78 | } 79 | } 80 | }; 81 | 82 | 83 | void setup() { 84 | #if defined(ARDUINO_ESP32C6) 85 | Serial.begin(); 86 | delay(2000); // should be enough for the USB CDC to initialize 87 | #else 88 | Serial.begin(115200); 89 | while (!Serial) delay(10); 90 | #endif 91 | 92 | Serial.println("\nSetup:"); 93 | 94 | #if defined(ARDUINO_XIAO_ESP32C6) 95 | #if (ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3, 0, 4)) 96 | // reproduce initVariant() from ESP32 v3.0.4 97 | uint8_t WIFI_ENABLE = 3; 98 | uint8_t WIFI_ANT_CONFIG = 14; 99 | // enable the RF switch 100 | pinMode(WIFI_ENABLE, OUTPUT); 101 | digitalWrite(WIFI_ENABLE, LOW); 102 | // select the internal antenna 103 | pinMode(WIFI_ANT_CONFIG, OUTPUT); 104 | digitalWrite(WIFI_ANT_CONFIG, LOW); 105 | #endif 106 | 107 | // same code for ESP32 v3.0.2 and up 108 | #if defined(USE_EXTERNAL_ANTENNA) 109 | digitalWrite(WIFI_ANT_CONFIG, HIGH); 110 | #endif 111 | 112 | Serial.print("Using "); 113 | #ifdef USE_EXTERNAL_ANTENNA 114 | Serial.print("an external"); 115 | #else 116 | Serial.print("the internal"); 117 | #endif 118 | Serial.println(" antenna."); 119 | #endif 120 | 121 | Serial.println("Initializing LED"); 122 | pinMode(ledPin, OUTPUT); 123 | digitalWrite(ledPin, 1-ledOn); 124 | 125 | Serial.println("Initializing BLEDevice"); 126 | BLEDevice::init(BLUETOOTH_NAME); 127 | 128 | Serial.println("Creating a BLE server"); 129 | pServer = BLEDevice::createServer(); 130 | pServer->setCallbacks(new MyServerCallbacks()); 131 | 132 | Serial.println("Adding a BLE service"); 133 | BLEService *pService = pServer->createService(SERVICE_UUID); 134 | 135 | Serial.println("Adding a BLE characteristic"); 136 | pCharacteristic = pService->createCharacteristic( 137 | CHARACTERISTIC_UUID, 138 | BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE); 139 | pCharacteristic->setCallbacks(new WriteCallbacks); 140 | 141 | Serial.println("Starting BLE service"); 142 | pService->start(); 143 | 144 | Serial.println("Add advertiser"); 145 | BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); 146 | pAdvertising->addServiceUUID(pService->getUUID()); 147 | pAdvertising->setScanResponse(true); 148 | 149 | Serial.println("Start BLE advertising"); 150 | BLEDevice::startAdvertising(); 151 | 152 | Serial.println("\nSetup completed"); 153 | } 154 | 155 | unsigned long timer = 0; 156 | 157 | void loop() { 158 | if (millis() - timer > 10000) { 159 | if (deviceConnected) { 160 | Serial.println("Send 'on' or 'off' string to control the LED"); 161 | } else { 162 | Serial.print("Connect to "); 163 | Serial.print(BLUETOOTH_NAME); 164 | Serial.print(" (address: "); 165 | Serial.print(BLEDevice::getAddress().toString().c_str()); 166 | Serial.println(")"); 167 | } 168 | timer = millis(); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /03_scan_wifi/scan_wifi/main.cpp.orig: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch is based on WiFiScan from the ESP32 Arduino core 3 | * Source: https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples/WiFiScan 4 | * This appears to be released under the GNU LESSER GENERAL PUBLIC LICENSE 5 | * see: https://github.com/espressif/arduino-esp32/blob/master/LICENSE.md 6 | */ 7 | #include 8 | #include "WiFi.h" 9 | 10 | #define INTERNAL_ANTENNA LOW 11 | #define EXTERNAL_ANTENNA HIGH 12 | 13 | #define ENABLE_RF_SWITCH LOW 14 | #define DISABLE_RF_SWITCH HIGH 15 | 16 | /* 17 | These are defined as 18 | static const uint8_t WIFI_ENABLE = 3; 19 | static const uint8_t WIFI_ANT_CONFIG = 14; 20 | in ESP32 3.0.4 21 | */ 22 | static const uint8_t RF_SWITCH_VDD = 3; 23 | static const uint8_t RF_SWITCH_VCTL = 14; 24 | 25 | /* 26 | Each IO pad can be in one of 3 states: 27 | a) mode INPUT 28 | b) mode OUTPUT value 0 29 | c) mode OUTPUT value 1 30 | so that there are 9 possible combinations or 31 | tests to run. 32 | */ 33 | void setTest(int test) { 34 | Serial.printf("Test #%d\n", test); 35 | switch (test) { 36 | 37 | case 1: 38 | pinMode(RF_SWITCH_VDD, INPUT); 39 | pinMode(RF_SWITCH_VCTL, INPUT); 40 | Serial.println("RF_SWITCH_VDD and RF_SWITCH_VCTL I/O pins are in INPUT mode; the RF switch is in its default state"); 41 | break; 42 | case 2: 43 | pinMode(RF_SWITCH_VDD, INPUT); 44 | pinMode(RF_SWITCH_VCTL, OUTPUT); 45 | delay(100); 46 | digitalWrite(RF_SWITCH_VCTL, INTERNAL_ANTENNA); 47 | Serial.println("RF_SWITCH_VDD I/O pin in INPUT MODE, RF_SWITCH_VCTL is OUTPUT = INTERNAL_ANTENNA (LOW)"); 48 | break; 49 | case 3: 50 | pinMode(RF_SWITCH_VDD, INPUT); 51 | pinMode(RF_SWITCH_VCTL, OUTPUT); 52 | delay(100); 53 | digitalWrite(RF_SWITCH_VCTL, EXTERNAL_ANTENNA); 54 | Serial.println("RF_SWITCH_VDD I/O pin in INPUT MODE, RF_SWITCH_VCTL is OUTPUT = EXTERNAL_ANTENNA (HIGH)"); 55 | break; 56 | 57 | 58 | case 4: 59 | pinMode(RF_SWITCH_VDD, OUTPUT); 60 | delay(100); 61 | digitalWrite(RF_SWITCH_VDD, DISABLE_RF_SWITCH); 62 | pinMode(RF_SWITCH_VCTL, INPUT); 63 | Serial.println("RF_SWITCH_VDD is OUTPUT = DISABLE_RF_SWITCH (HIGH), RF_SWITCH_VCTL I/O pin in INPUT mode;"); 64 | break; 65 | case 5: 66 | pinMode(RF_SWITCH_VDD, OUTPUT); 67 | delay(100); 68 | digitalWrite(RF_SWITCH_VDD, DISABLE_RF_SWITCH); 69 | delay(100); 70 | pinMode(RF_SWITCH_VCTL, OUTPUT); 71 | delay(100); 72 | digitalWrite(RF_SWITCH_VCTL, INTERNAL_ANTENNA); 73 | Serial.println("RF_SWITCH_VDD is OUTPUT = DISABLE_RF_SWITCH (HIGH), RF_SWITCH_VCTL is OUTPUT = INTERNAL_ANTENNA (LOW)"); 74 | break; 75 | case 6: 76 | pinMode(RF_SWITCH_VDD, OUTPUT); 77 | delay(100); 78 | digitalWrite(RF_SWITCH_VDD, DISABLE_RF_SWITCH); 79 | delay(100); 80 | pinMode(RF_SWITCH_VCTL, OUTPUT); 81 | delay(100); 82 | digitalWrite(RF_SWITCH_VCTL, EXTERNAL_ANTENNA); 83 | Serial.println("RF_SWITCH_VDD is OUTPUT = DISABLE_RF_SWITCH (HIGH), RF_SWITCH_VCTL is OUTPUT = EXTERNAL_ANTENNA (HIGH)"); 84 | break; 85 | 86 | 87 | case 7: 88 | pinMode(RF_SWITCH_VDD, OUTPUT); 89 | delay(100); 90 | digitalWrite(RF_SWITCH_VDD, ENABLE_RF_SWITCH); 91 | pinMode(RF_SWITCH_VCTL, INPUT); 92 | Serial.println("RF_SWITCH_VDD is OUTPUT = ENABLE_RF_SWITCH (LOW), RF_SWITCH_VCTL I/O pin in INPUT mode;"); 93 | break; 94 | case 8: 95 | pinMode(RF_SWITCH_VDD, OUTPUT); 96 | delay(100); 97 | digitalWrite(RF_SWITCH_VDD, ENABLE_RF_SWITCH); 98 | delay(100); 99 | pinMode(RF_SWITCH_VCTL, OUTPUT); 100 | delay(100); 101 | digitalWrite(RF_SWITCH_VCTL, INTERNAL_ANTENNA); 102 | Serial.println("RF_SWITCH_VDD is OUTPUT = ENABLE_RF_SWITCH (LOW), RF_SWITCH_VCTL is OUTPUT = INTERNAL_ANTENNA (LOW)"); 103 | break; 104 | case 9: 105 | pinMode(RF_SWITCH_VDD, OUTPUT); 106 | delay(100); 107 | digitalWrite(RF_SWITCH_VDD, ENABLE_RF_SWITCH); 108 | delay(100); 109 | pinMode(RF_SWITCH_VCTL, OUTPUT); 110 | delay(100); 111 | digitalWrite(RF_SWITCH_VCTL, EXTERNAL_ANTENNA); 112 | Serial.println("RF_SWITCH_VDD is OUTPUT = ENABLE_RF_SWITCH (LOW), RF_SWITCH_VCTL is OUTPUT = EXTERNAL_ANTENNA (HIGH)"); 113 | break; 114 | default: 115 | Serial.println("Invalid test number"); 116 | } 117 | } 118 | 119 | #define SCANS_PER_TEST 3 120 | 121 | void setup() { 122 | Serial.begin(); 123 | // Set WiFi to station mode and disconnect from an AP if it was previously connected. 124 | WiFi.mode(WIFI_STA); 125 | WiFi.disconnect(); 126 | delay(2000); 127 | } 128 | 129 | void loop() { 130 | 131 | Serial.println("\nStarting test suite"); 132 | Serial.println("-------------------"); 133 | 134 | for (int test=1; test<10; test++) { 135 | 136 | setTest(test); 137 | 138 | for (int i=0; iFM8625H means powering it by grounding the gate of the MOSFET. 10 | 11 | 2. GPIO14 selects which antenna is connected to the ESP32-C6 ANT port. 12 | 13 | As Alfonso Accosta (fons) said, the schematic is pretty confusing due to the crossed-out components. I tried to make sense of the circuit starting with the assumption that the internal antenna should be selected by default. 14 | 15 | 1. R23 is part of a voltage divider in combination with R24, which would apply 1.1 V to the VCTL line of the RF switch. That is neither HIGH or LOW and makes no sense, so I think that we can safely assume that R23 has indeed been removed. Consequently VCTL is grounded through R24 meaning that internal antenna is selected (RF1 is routed to ANT). I/O pad 14 must be put into OUTPUT mode and set to HIGH to select the external antenna. 16 | 17 | 2. At first blush, I would have argued that R22 was necessary because otherwise the RF switch is not enabled by default. After playing with the two I/O pins, observing the counter-intuitive behaviour described by Alfonso and reading a comment by msfujino, I became convinced that R22 has been removed as indicated. 18 | 19 | 3. There is no need to worry about the L4 inductance and C25 capacitor. They seem to be part of an impedance matching circuit, but I do think they are superfluous as there are two pi impedance matching networks between the RF1 and RF2 pins of the RF switch and the internal and external antennas. 20 | 21 | So this is what I believe is the cleaned-up circuit. 22 | 23 | ![cleaned circuit](img/xiao_esp32c6_ant_circuit_clean.jpg) 24 | 25 | What's important is that the hardware does not enable the RF switch by default. If correct, then one would assume that wireless communication would not work at all, but it was possible to connect the XIAO with Wi-Fi, BLE and Zigbee. The explanation was the comment by msfujino: I came to the conclusion that the ANT is never connected to either RF port and that the signal is leaking because it is not sufficiently isolated.. 26 | 27 | Both msfujino and fons talked of testing this hypothesis so I decided to do the same. The source code of my exploratory sketch is in the [xiao32c6_antenna](xiao32c6_antenna/) directory. 28 | 29 | The sketch is fundamentally very simple. A Wi-Fi scan was performed and the [received signal strength indicator](https://en.wikipedia.org/wiki/Received_signal_strength_indicator) value or RSSI for each found Wi-Fi network was recorded. The idea was to do this systematically to compare the RSSIs according to the state of the two I/O pads used to control the RF switch. Each of the I/O pad can be in one of three states: 30 | 1. in INPUT mode (sometimes called Hi-Z or high impedance) 31 | 2. in OUTPUT mode with a LOW value (0 volts) 32 | 3. in OUTPUT mode with a HIGH value (3.3 volts) 33 | 34 | Consequently there are 9 possible combinations to investigate. In addition, the sketch does an initial scan without modifying in any way the I/O pads in order to be able to identify their initial state. (I did that because I could not find a way to read the mode/direction registers and latched values in the ESP32 Arduino core for the RISC-V architecture). When running the test using the on-board antenna, there was no attached external antenna. A rod antenna (rubber-ducky like) was connected when testing the external antenna but in this case, the on-board antenna remained present. 35 | 36 | The results obtained from four runs of the program are found in the [data](data/) subdirectory. The reader is free to run the tests or to look at the results I obtained to see if he or she interprets them as I have. But here is a figure that is quite eloquent. It shows the RSSI values for the SIGMDELNET access point (about 1 metre from the XIAO) in the first run of each of the nine tests. There should be 9 bars, but only 8 are shown because the 0;Z and 0;0 values were exactly the same. Since the 0;Z and 0;0 labels mean meaning GPIO3 is in OUTPUT mode with a LOW value in both cases and GPIO14 is in INPUT mode in the first case and in OUTPUT mode with a LOW value in the second case, this is a confirmation that R23 is absent and R24 acts a pull down resistor in my estimation. 37 | 38 | ![](img/xiao_esp32c6_rssi.png) 39 | 40 | When reading the graph, remember that when *an RSSI value is represented in a negative form (e.g. -100), the closer the value is to 0, the stronger the received signal has been* ([Source](https://en.wikipedia.org/wiki/Received_signal_strength_indicator#In_802.11_implementations)). Consequently the **shorter columns indicate a higher signal strength**. Comparing the two graphs, the external antenna is always better than the on-board ceramic antenna *except* when the RF switch is enabled (the last two columns). When the RF switch is enabled, best result is obtained by selecting the actual antenna. 41 | 42 | The recent release of version 3.0.4 of the ESP32 Arduino core added a `.../variants/XIAO_ESP32C6/variant.cpp` file with the following function. 43 | 44 | ```C 45 | void initVariant(void) { 46 | pinMode(WIFI_ENABLE, OUTPUT); 47 | digitalWrite(WIFI_ENABLE, LOW); //turn on this function 48 | 49 | pinMode(WIFI_ANT_CONFIG, OUTPUT); 50 | digitalWrite(WIFI_ANT_CONFIG, LOW); //use built-in antenna, set HIGH to use external antenna 51 | } 52 | ``` 53 | 54 | The RF switch is enabled in software which I think confirms that there is not R22 to pull the gate of the MOSFET to ground. By my estimation, the last two statements were not needed, but it may be a good idea to set `WIFI_ANT_CONFIG` (= GPIO14) in OUTPUT mode so that a single `digitalWrite(WIFI_ANT_CONFIG, HIGH)` would suffice to select the external antenna in a user sketch. And if one sets a pin in OUTPUT mode, it is probably best to set a value at the same time. 55 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/WebHandlerImpl.h: -------------------------------------------------------------------------------- 1 | /* 2 | Asynchronous WebServer library for Espressif MCUs 3 | 4 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 5 | This file is part of the esp8266 core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #ifndef ASYNCWEBSERVERHANDLERIMPL_H_ 22 | #define ASYNCWEBSERVERHANDLERIMPL_H_ 23 | 24 | #include 25 | #ifdef ASYNCWEBSERVER_REGEX 26 | #include 27 | #endif 28 | 29 | #include "stddef.h" 30 | #include 31 | 32 | class AsyncStaticWebHandler: public AsyncWebHandler { 33 | using File = fs::File; 34 | using FS = fs::FS; 35 | private: 36 | bool _getFile(AsyncWebServerRequest *request); 37 | bool _fileExists(AsyncWebServerRequest *request, const String& path); 38 | uint8_t _countBits(const uint8_t value) const; 39 | protected: 40 | FS _fs; 41 | String _uri; 42 | String _path; 43 | String _default_file; 44 | String _cache_control; 45 | String _last_modified; 46 | AwsTemplateProcessor _callback; 47 | bool _isDir; 48 | bool _gzipFirst; 49 | uint8_t _gzipStats; 50 | public: 51 | AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control); 52 | virtual bool canHandle(AsyncWebServerRequest *request) override final; 53 | virtual void handleRequest(AsyncWebServerRequest *request) override final; 54 | AsyncStaticWebHandler& setIsDir(bool isDir); 55 | AsyncStaticWebHandler& setDefaultFile(const char* filename); 56 | AsyncStaticWebHandler& setCacheControl(const char* cache_control); 57 | AsyncStaticWebHandler& setLastModified(const char* last_modified); 58 | AsyncStaticWebHandler& setLastModified(struct tm* last_modified); 59 | #ifdef ESP8266 60 | AsyncStaticWebHandler& setLastModified(time_t last_modified); 61 | AsyncStaticWebHandler& setLastModified(); //sets to current time. Make sure sntp is runing and time is updated 62 | #endif 63 | AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) {_callback = newCallback; return *this;} 64 | }; 65 | 66 | class AsyncCallbackWebHandler: public AsyncWebHandler { 67 | private: 68 | protected: 69 | String _uri; 70 | WebRequestMethodComposite _method; 71 | ArRequestHandlerFunction _onRequest; 72 | ArUploadHandlerFunction _onUpload; 73 | ArBodyHandlerFunction _onBody; 74 | bool _isRegex; 75 | public: 76 | AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} 77 | void setUri(const String& uri){ 78 | _uri = uri; 79 | _isRegex = uri.startsWith("^") && uri.endsWith("$"); 80 | } 81 | void setMethod(WebRequestMethodComposite method){ _method = method; } 82 | void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; } 83 | void onUpload(ArUploadHandlerFunction fn){ _onUpload = fn; } 84 | void onBody(ArBodyHandlerFunction fn){ _onBody = fn; } 85 | 86 | virtual bool canHandle(AsyncWebServerRequest *request) override final{ 87 | 88 | if(!_onRequest) 89 | return false; 90 | 91 | if(!(_method & request->method())) 92 | return false; 93 | 94 | #ifdef ASYNCWEBSERVER_REGEX 95 | if (_isRegex) { 96 | std::regex pattern(_uri.c_str()); 97 | std::smatch matches; 98 | std::string s(request->url().c_str()); 99 | if(std::regex_search(s, matches, pattern)) { 100 | for (size_t i = 1; i < matches.size(); ++i) { // start from 1 101 | request->_addPathParam(matches[i].str().c_str()); 102 | } 103 | } else { 104 | return false; 105 | } 106 | } else 107 | #endif 108 | if (_uri.length() && _uri.startsWith("/*.")) { 109 | String uriTemplate = String (_uri); 110 | uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); 111 | if (!request->url().endsWith(uriTemplate)) 112 | return false; 113 | } 114 | else 115 | if (_uri.length() && _uri.endsWith("*")) { 116 | String uriTemplate = String(_uri); 117 | uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); 118 | if (!request->url().startsWith(uriTemplate)) 119 | return false; 120 | } 121 | else if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) 122 | return false; 123 | 124 | request->addInterestingHeader("ANY"); 125 | return true; 126 | } 127 | 128 | virtual void handleRequest(AsyncWebServerRequest *request) override final { 129 | if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) 130 | return request->requestAuthentication(); 131 | if(_onRequest) 132 | _onRequest(request); 133 | else 134 | request->send(500); 135 | } 136 | virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { 137 | if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) 138 | return request->requestAuthentication(); 139 | if(_onUpload) 140 | _onUpload(request, filename, index, data, len, final); 141 | } 142 | virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { 143 | if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) 144 | return request->requestAuthentication(); 145 | if(_onBody) 146 | _onBody(request, data, len, index, total); 147 | } 148 | virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;} 149 | }; 150 | 151 | #endif /* ASYNCWEBSERVERHANDLERIMPL_H_ */ 152 | -------------------------------------------------------------------------------- /libraries/ESPAsyncWebServer/src/WebServer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Asynchronous WebServer library for Espressif MCUs 3 | 4 | Copyright (c) 2016 Hristo Gochkov. All rights reserved. 5 | This file is part of the esp8266 core for Arduino environment. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | #include "ESPAsyncWebServer.h" 22 | #include "WebHandlerImpl.h" 23 | 24 | bool ON_STA_FILTER(AsyncWebServerRequest *request) { 25 | return WiFi.localIP() == request->client()->localIP(); 26 | } 27 | 28 | bool ON_AP_FILTER(AsyncWebServerRequest *request) { 29 | return WiFi.localIP() != request->client()->localIP(); 30 | } 31 | 32 | 33 | AsyncWebServer::AsyncWebServer(uint16_t port) 34 | : _server(port) 35 | , _rewrites(LinkedList([](AsyncWebRewrite* r){ delete r; })) 36 | , _handlers(LinkedList([](AsyncWebHandler* h){ delete h; })) 37 | { 38 | _catchAllHandler = new AsyncCallbackWebHandler(); 39 | if(_catchAllHandler == NULL) 40 | return; 41 | _server.onClient([](void *s, AsyncClient* c){ 42 | if(c == NULL) 43 | return; 44 | c->setRxTimeout(3); 45 | AsyncWebServerRequest *r = new AsyncWebServerRequest((AsyncWebServer*)s, c); 46 | if(r == NULL){ 47 | c->close(true); 48 | c->free(); 49 | delete c; 50 | } 51 | }, this); 52 | } 53 | 54 | AsyncWebServer::~AsyncWebServer(){ 55 | reset(); 56 | end(); 57 | if(_catchAllHandler) delete _catchAllHandler; 58 | } 59 | 60 | AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){ 61 | _rewrites.add(rewrite); 62 | return *rewrite; 63 | } 64 | 65 | bool AsyncWebServer::removeRewrite(AsyncWebRewrite *rewrite){ 66 | return _rewrites.remove(rewrite); 67 | } 68 | 69 | AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){ 70 | return addRewrite(new AsyncWebRewrite(from, to)); 71 | } 72 | 73 | AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler){ 74 | _handlers.add(handler); 75 | return *handler; 76 | } 77 | 78 | bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){ 79 | return _handlers.remove(handler); 80 | } 81 | 82 | void AsyncWebServer::begin(){ 83 | _server.setNoDelay(true); 84 | _server.begin(); 85 | } 86 | 87 | void AsyncWebServer::end(){ 88 | _server.end(); 89 | } 90 | 91 | #if ASYNC_TCP_SSL_ENABLED 92 | void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void* arg){ 93 | _server.onSslFileRequest(cb, arg); 94 | } 95 | 96 | void AsyncWebServer::beginSecure(const char *cert, const char *key, const char *password){ 97 | _server.beginSecure(cert, key, password); 98 | } 99 | #endif 100 | 101 | void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request){ 102 | delete request; 103 | } 104 | 105 | void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request){ 106 | for(const auto& r: _rewrites){ 107 | if (r->match(request)){ 108 | request->_url = r->toUrl(); 109 | request->_addGetParams(r->params()); 110 | } 111 | } 112 | } 113 | 114 | void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){ 115 | for(const auto& h: _handlers){ 116 | if (h->filter(request) && h->canHandle(request)){ 117 | request->setHandler(h); 118 | return; 119 | } 120 | } 121 | 122 | request->addInterestingHeader("ANY"); 123 | request->setHandler(_catchAllHandler); 124 | } 125 | 126 | 127 | AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody){ 128 | AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); 129 | handler->setUri(uri); 130 | handler->setMethod(method); 131 | handler->onRequest(onRequest); 132 | handler->onUpload(onUpload); 133 | handler->onBody(onBody); 134 | addHandler(handler); 135 | return *handler; 136 | } 137 | 138 | AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload){ 139 | AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); 140 | handler->setUri(uri); 141 | handler->setMethod(method); 142 | handler->onRequest(onRequest); 143 | handler->onUpload(onUpload); 144 | addHandler(handler); 145 | return *handler; 146 | } 147 | 148 | AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest){ 149 | AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); 150 | handler->setUri(uri); 151 | handler->setMethod(method); 152 | handler->onRequest(onRequest); 153 | addHandler(handler); 154 | return *handler; 155 | } 156 | 157 | AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest){ 158 | AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); 159 | handler->setUri(uri); 160 | handler->onRequest(onRequest); 161 | addHandler(handler); 162 | return *handler; 163 | } 164 | 165 | AsyncStaticWebHandler& AsyncWebServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control){ 166 | AsyncStaticWebHandler* handler = new AsyncStaticWebHandler(uri, fs, path, cache_control); 167 | addHandler(handler); 168 | return *handler; 169 | } 170 | 171 | void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn){ 172 | _catchAllHandler->onRequest(fn); 173 | } 174 | 175 | void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn){ 176 | _catchAllHandler->onUpload(fn); 177 | } 178 | 179 | void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn){ 180 | _catchAllHandler->onBody(fn); 181 | } 182 | 183 | void AsyncWebServer::reset(){ 184 | _rewrites.free(); 185 | _handlers.free(); 186 | 187 | if (_catchAllHandler != NULL){ 188 | _catchAllHandler->onRequest(NULL); 189 | _catchAllHandler->onUpload(NULL); 190 | _catchAllHandler->onBody(NULL); 191 | } 192 | } 193 | 194 | -------------------------------------------------------------------------------- /12_xiao32c6_antenna/xiao32c6_antenna/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch is based on WiFiScan from the ESP32 Arduino core 3 | * Source: https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi/examples/WiFiScan 4 | * This appears to be released under the GNU LESSER GENERAL PUBLIC LICENSE 5 | * see: https://github.com/espressif/arduino-esp32/blob/master/LICENSE.md 6 | */ 7 | #include 8 | #include "WiFi.h" 9 | 10 | #define INTERNAL_ANTENNA LOW 11 | #define EXTERNAL_ANTENNA HIGH 12 | 13 | #define ENABLE_RF_SWITCH LOW 14 | #define DISABLE_RF_SWITCH HIGH 15 | 16 | /* 17 | These are defined as 18 | static const uint8_t WIFI_ENABLE = 3; 19 | static const uint8_t WIFI_ANT_CONFIG = 14; 20 | in ESP32 3.0.4 21 | */ 22 | static const uint8_t RF_SWITCH_VDD = 3; 23 | static const uint8_t RF_SWITCH_VCTL = 14; 24 | 25 | /* 26 | Each IO pad can be in one of 3 states: 27 | a) mode INPUT 28 | b) mode OUTPUT value 0 29 | c) mode OUTPUT value 1 30 | so that there are 9 possible combinations or 31 | tests to run. 32 | */ 33 | void setTest(int test) { 34 | Serial.printf("Test #%d\n", test); 35 | switch (test) { 36 | 37 | case 1: 38 | pinMode(RF_SWITCH_VDD, INPUT); 39 | pinMode(RF_SWITCH_VCTL, INPUT); 40 | Serial.println("RF_SWITCH_VDD and RF_SWITCH_VCTL I/O pins are in INPUT mode; the RF switch is in its default state"); 41 | break; 42 | case 2: 43 | pinMode(RF_SWITCH_VDD, INPUT); 44 | pinMode(RF_SWITCH_VCTL, OUTPUT); 45 | delay(100); 46 | digitalWrite(RF_SWITCH_VCTL, INTERNAL_ANTENNA); 47 | Serial.println("RF_SWITCH_VDD I/O pin in INPUT mode; RF_SWITCH_VCTL is OUTPUT = INTERNAL_ANTENNA (LOW)"); 48 | break; 49 | case 3: 50 | pinMode(RF_SWITCH_VDD, INPUT); 51 | pinMode(RF_SWITCH_VCTL, OUTPUT); 52 | delay(100); 53 | digitalWrite(RF_SWITCH_VCTL, EXTERNAL_ANTENNA); 54 | Serial.println("RF_SWITCH_VDD I/O pin in INPUT mode; RF_SWITCH_VCTL is OUTPUT = EXTERNAL_ANTENNA (HIGH)"); 55 | break; 56 | 57 | case 4: 58 | pinMode(RF_SWITCH_VDD, OUTPUT); 59 | delay(100); 60 | digitalWrite(RF_SWITCH_VDD, DISABLE_RF_SWITCH); 61 | pinMode(RF_SWITCH_VCTL, INPUT); 62 | Serial.println("RF_SWITCH_VDD is OUTPUT = DISABLE_RF_SWITCH (HIGH); RF_SWITCH_VCTL I/O pin in INPUT mode"); 63 | break; 64 | case 5: 65 | pinMode(RF_SWITCH_VDD, OUTPUT); 66 | delay(100); 67 | digitalWrite(RF_SWITCH_VDD, DISABLE_RF_SWITCH); 68 | delay(100); 69 | pinMode(RF_SWITCH_VCTL, OUTPUT); 70 | delay(100); 71 | digitalWrite(RF_SWITCH_VCTL, INTERNAL_ANTENNA); 72 | Serial.println("RF_SWITCH_VDD is OUTPUT = DISABLE_RF_SWITCH (HIGH); RF_SWITCH_VCTL is OUTPUT = INTERNAL_ANTENNA (LOW)"); 73 | break; 74 | case 6: 75 | pinMode(RF_SWITCH_VDD, OUTPUT); 76 | delay(100); 77 | digitalWrite(RF_SWITCH_VDD, DISABLE_RF_SWITCH); 78 | delay(100); 79 | pinMode(RF_SWITCH_VCTL, OUTPUT); 80 | delay(100); 81 | digitalWrite(RF_SWITCH_VCTL, EXTERNAL_ANTENNA); 82 | Serial.println("RF_SWITCH_VDD is OUTPUT = DISABLE_RF_SWITCH (HIGH); RF_SWITCH_VCTL is OUTPUT = EXTERNAL_ANTENNA (HIGH)"); 83 | break; 84 | 85 | case 7: 86 | pinMode(RF_SWITCH_VDD, OUTPUT); 87 | delay(100); 88 | digitalWrite(RF_SWITCH_VDD, ENABLE_RF_SWITCH); 89 | pinMode(RF_SWITCH_VCTL, INPUT); 90 | Serial.println("RF_SWITCH_VDD is OUTPUT = ENABLE_RF_SWITCH (LOW); RF_SWITCH_VCTL I/O pin in INPUT mode"); 91 | break; 92 | case 8: 93 | pinMode(RF_SWITCH_VDD, OUTPUT); 94 | delay(100); 95 | digitalWrite(RF_SWITCH_VDD, ENABLE_RF_SWITCH); 96 | delay(100); 97 | pinMode(RF_SWITCH_VCTL, OUTPUT); 98 | delay(100); 99 | digitalWrite(RF_SWITCH_VCTL, INTERNAL_ANTENNA); 100 | Serial.println("RF_SWITCH_VDD is OUTPUT = ENABLE_RF_SWITCH (LOW); RF_SWITCH_VCTL is OUTPUT = INTERNAL_ANTENNA (LOW)"); 101 | break; 102 | case 9: 103 | pinMode(RF_SWITCH_VDD, OUTPUT); 104 | delay(100); 105 | digitalWrite(RF_SWITCH_VDD, ENABLE_RF_SWITCH); 106 | delay(100); 107 | pinMode(RF_SWITCH_VCTL, OUTPUT); 108 | delay(100); 109 | digitalWrite(RF_SWITCH_VCTL, EXTERNAL_ANTENNA); 110 | Serial.println("RF_SWITCH_VDD is OUTPUT = ENABLE_RF_SWITCH (LOW); RF_SWITCH_VCTL is OUTPUT = EXTERNAL_ANTENNA (HIGH)"); 111 | break; 112 | default: 113 | Serial.println("Invalid test number"); 114 | } 115 | } 116 | 117 | #define SCANS_PER_TEST 3 118 | 119 | void doScan(int test) { 120 | if (test) 121 | setTest(test); // skip test 0 done in setup() 122 | for (int i=0; i 0; i--) { 170 | Serial.printf("Test will begin in %d seconds\n", i); 171 | delay(1000); 172 | } 173 | 174 | // Start with a scan without modifying the IO pin 3 and 14 to confirm 175 | // that initVarian() in ESP32 core 3.0.4+ modifies the use of the RF switch 176 | Serial.println("\nInitial scan with default antenna settings"); 177 | Serial.printf("\in ESP32 Arduino version %s\n", ESP_ARDUINO_VERSION_STR); 178 | Serial.println("--------------------------------------------"); 179 | 180 | doScan(0); 181 | } 182 | 183 | void loop() { 184 | Serial.println("\nStarting test suite"); 185 | Serial.println("-------------------"); 186 | 187 | for (int test=1; test<10; test++) { 188 | doScan(test); 189 | } 190 | Serial.println("\nTest suite completed."); 191 | Serial.println("Will restart in 5 minutes"); 192 | delay(5*60*1000); 193 | } 194 | -------------------------------------------------------------------------------- /14_zigbee-on-off-switch/Zigbee_On_Off_Switch/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // See Zigbee_On_Off_Switch.ino for license 4 | // 5 | // Source: 6 | // https://github.com/espressif/arduino-esp32/blob/3.1.1/libraries/Zigbee/examples/Zigbee_On_Off_Switch/Zigbee_On_Off_Switch.ino 7 | 8 | #ifndef ZIGBEE_MODE_ZCZR 9 | #error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" 10 | #endif 11 | 12 | #include "Zigbee.h" 13 | 14 | // --------------------- 15 | 16 | #define GPIO_INPUT_IO_TOGGLE_SWITCH BOOT_PIN // I/O pin 9 on ESP32-C6 and ESP32-H2 17 | 18 | #if defined(ARDUINO_USB_CDC_ON_BOOT) // no discrete USB-to-serial adapter 19 | #define SERIAL_BAUD 20 | #else 21 | #define SERIAL_BAUD 115200 22 | #endif 23 | 24 | #if defined(ARDUINO_XIAO_ESP32C6) 25 | // The onboard ceramic antenna is used by default. 26 | // Uncomment the following macro to use a connected external antenna. 27 | //#define USE_EXTERNAL_ANTENNA 28 | #else 29 | #undef USE_EXTERNAL_ANTENNA 30 | #endif 31 | 32 | // Define this print to the console a test number at startup 33 | #define TEST_NO 1 34 | 35 | /// --------------------- 36 | 37 | /* Zigbee switch configuration */ 38 | #define SWITCH_ENDPOINT_NUMBER 5 39 | 40 | #define PAIR_SIZE(TYPE_STR_PAIR) (sizeof(TYPE_STR_PAIR) / sizeof(TYPE_STR_PAIR[0])) 41 | 42 | typedef enum { 43 | SWITCH_ON_CONTROL, 44 | SWITCH_OFF_CONTROL, 45 | SWITCH_ONOFF_TOGGLE_CONTROL, 46 | SWITCH_LEVEL_UP_CONTROL, 47 | SWITCH_LEVEL_DOWN_CONTROL, 48 | SWITCH_LEVEL_CYCLE_CONTROL, 49 | SWITCH_COLOR_CONTROL, 50 | } SwitchFunction; 51 | 52 | typedef struct { 53 | uint8_t pin; 54 | SwitchFunction func; 55 | } SwitchData; 56 | 57 | typedef enum { 58 | SWITCH_IDLE, 59 | SWITCH_PRESS_ARMED, 60 | SWITCH_PRESS_DETECTED, 61 | SWITCH_PRESSED, 62 | SWITCH_RELEASE_DETECTED, 63 | } SwitchState; 64 | 65 | static SwitchData buttonFunctionPair[] = {{GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL}}; 66 | 67 | ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); 68 | 69 | /********************* Zigbee functions **************************/ 70 | static void onZbButton(SwitchData *button_func_pair) { 71 | if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) { 72 | // Send toggle command to the light 73 | Serial.println("Toggling light"); 74 | zbSwitch.lightToggle(); 75 | } 76 | } 77 | 78 | /********************* GPIO functions **************************/ 79 | static QueueHandle_t gpio_evt_queue = NULL; 80 | 81 | static void IRAM_ATTR onGpioInterrupt(void *arg) { 82 | xQueueSendFromISR(gpio_evt_queue, (SwitchData *)arg, NULL); 83 | } 84 | 85 | static void enableGpioInterrupt(bool enabled) { 86 | for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); ++i) { 87 | if (enabled) { 88 | enableInterrupt((buttonFunctionPair[i]).pin); 89 | } else { 90 | disableInterrupt((buttonFunctionPair[i]).pin); 91 | } 92 | } 93 | } 94 | 95 | /********************* Arduino functions **************************/ 96 | void setup() { 97 | Serial.begin(SERIAL_BAUD); 98 | delay(5000); 99 | #ifdef TEST_NO 100 | Serial.printf("Zigbee_On_Off_Switch, test #%d\n\n", TEST_NO); // 101 | #endif 102 | 103 | //Optional: set Zigbee device name and model 104 | zbSwitch.setManufacturerAndModel("Espressif", "ZigbeeSwitch"); 105 | 106 | //Optional to allow multiple light to bind to the switch 107 | zbSwitch.allowMultipleBinding(true); 108 | 109 | //Add endpoint to Zigbee Core 110 | Serial.println("Adding ZigbeeSwitch endpoint to Zigbee Core"); 111 | Zigbee.addEndpoint(&zbSwitch); 112 | 113 | //Open network for 180 seconds after boot 114 | Zigbee.setRebootOpenNetwork(180); 115 | 116 | // Init button switch 117 | for (int i = 0; i < PAIR_SIZE(buttonFunctionPair); i++) { 118 | pinMode(buttonFunctionPair[i].pin, INPUT_PULLUP); 119 | /* create a queue to handle gpio event from isr */ 120 | gpio_evt_queue = xQueueCreate(10, sizeof(SwitchData)); 121 | if (gpio_evt_queue == 0) { 122 | Serial.println("Queue creating failed, rebooting..."); 123 | ESP.restart(); 124 | } 125 | attachInterruptArg(buttonFunctionPair[i].pin, onGpioInterrupt, (void *)(buttonFunctionPair + i), FALLING); 126 | } 127 | 128 | // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode 129 | if (!Zigbee.begin(ZIGBEE_COORDINATOR)) { 130 | Serial.println("Zigbee failed to start!"); 131 | Serial.println("Rebooting..."); 132 | ESP.restart(); 133 | } 134 | 135 | Serial.println("Waiting for Light to bind to the switch"); 136 | //Wait for switch to bind to a light: 137 | while (!zbSwitch.bound()) { 138 | Serial.printf("."); 139 | delay(500); 140 | } 141 | 142 | // Optional: List all bound devices and read manufacturer and model name 143 | std::list boundLights = zbSwitch.getBoundDevices(); 144 | for (const auto &device : boundLights) { 145 | Serial.printf("Device on endpoint %d, short address: 0x%x\r\n", device->endpoint, device->short_addr); 146 | Serial.printf( 147 | "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], 148 | device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0] 149 | ); 150 | char *manufacturer = zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr); 151 | char *model = zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr); 152 | if (manufacturer != nullptr) { 153 | Serial.printf("Light manufacturer: %s\r\n", manufacturer); 154 | } 155 | if (model != nullptr) { 156 | Serial.printf("Light model: %s\r\n", model); 157 | } 158 | } 159 | 160 | Serial.println(); 161 | } 162 | 163 | void loop() { 164 | // Handle button switch in loop() 165 | uint8_t pin = 0; 166 | SwitchData buttonSwitch; 167 | static SwitchState buttonState = SWITCH_IDLE; 168 | bool eventFlag = false; 169 | 170 | /* check if there is any queue received, if yes read out the buttonSwitch */ 171 | if (xQueueReceive(gpio_evt_queue, &buttonSwitch, portMAX_DELAY)) { 172 | pin = buttonSwitch.pin; 173 | enableGpioInterrupt(false); 174 | eventFlag = true; 175 | } 176 | while (eventFlag) { 177 | bool value = digitalRead(pin); 178 | switch (buttonState) { 179 | case SWITCH_IDLE: buttonState = (value == LOW) ? SWITCH_PRESS_DETECTED : SWITCH_IDLE; break; 180 | case SWITCH_PRESS_DETECTED: buttonState = (value == LOW) ? SWITCH_PRESS_DETECTED : SWITCH_RELEASE_DETECTED; break; 181 | case SWITCH_RELEASE_DETECTED: 182 | buttonState = SWITCH_IDLE; 183 | /* callback to button_handler */ 184 | (*onZbButton)(&buttonSwitch); 185 | break; 186 | default: break; 187 | } 188 | if (buttonState == SWITCH_IDLE) { 189 | enableGpioInterrupt(true); 190 | eventFlag = false; 191 | break; 192 | } 193 | vTaskDelay(10 / portTICK_PERIOD_MS); 194 | } 195 | 196 | // print the bound lights every 10 seconds 197 | static uint32_t lastPrint = 0; 198 | if (millis() - lastPrint > 10000) { 199 | lastPrint = millis(); 200 | zbSwitch.printBoundDevices(Serial); 201 | } 202 | } 203 | --------------------------------------------------------------------------------