generated from sirlilpanda/kicad-project-template-actionless
Added the zig_main project to software for zig based implementation of code for robot
This commit is contained in:
820
software/zig_main/docs/getting-started.md
Normal file
820
software/zig_main/docs/getting-started.md
Normal file
@@ -0,0 +1,820 @@
|
||||
# Getting Started with Zig ESP-IDF Sample
|
||||
|
||||
A complete guide to building ESP32 firmware using Zig and ESP-IDF.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Installation](#installation)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Building Your First Project](#building-your-first-project)
|
||||
- [Working with Components](#working-with-components)
|
||||
- [Examples](#examples)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Next Steps](#next-steps)
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required Software
|
||||
|
||||
- **Python 3.12+** (for ESP-IDF tools)
|
||||
- **Git** (for cloning repositories)
|
||||
- **CMake 3.16+** (bundled with ESP-IDF)
|
||||
- **Ninja** or **Make** (bundled with ESP-IDF)
|
||||
- **Zig compiler** (optional - will be auto-downloaded if not found)
|
||||
|
||||
### Supported Operating Systems
|
||||
|
||||
- **Linux** (Ubuntu 20.04+, Debian, Fedora, Arch)
|
||||
- **macOS** (10.15+)
|
||||
- **Windows** (10/11 with PowerShell or WSL2)
|
||||
- **Nix/NixOS** (via `flake.nix`)
|
||||
|
||||
### Supported ESP32 Targets
|
||||
|
||||
| Architecture | Targets |
|
||||
|--------------|---------|
|
||||
| **RISC-V** | ESP32-C2, C3, C5, C6, C61, H2, H21, H4, P4 |
|
||||
| **Xtensa** | ESP32, ESP32-S2, ESP32-S3 |
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Step 1: Install ESP-IDF
|
||||
|
||||
**Option A: Standard Installation**
|
||||
|
||||
```bash
|
||||
# Clone ESP-IDF
|
||||
git clone --recursive https://github.com/espressif/esp-idf.git
|
||||
cd esp-idf
|
||||
|
||||
# Linux/macOS:
|
||||
./install.sh
|
||||
|
||||
# Windows (PowerShell):
|
||||
.\install.ps1
|
||||
|
||||
# Windows (Command Prompt):
|
||||
install.bat
|
||||
```
|
||||
|
||||
**Option B: Using Nix Flakes** (Linux/macOS)
|
||||
|
||||
```bash
|
||||
# Enter development environment with all dependencies
|
||||
nix develop
|
||||
|
||||
# Or use direnv for automatic activation
|
||||
echo "use flake" > .envrc
|
||||
direnv allow
|
||||
```
|
||||
|
||||
**Option C: ESP-IDF installer** (Windows/macOS)
|
||||
|
||||
Download from: https://dl.espressif.com/dl/esp-idf/
|
||||
|
||||
### Step 2: Set up ESP-IDF Environment
|
||||
|
||||
Every time you open a new terminal, activate ESP-IDF:
|
||||
|
||||
```bash
|
||||
# Linux/macOS:
|
||||
. $HOME/esp/esp-idf/export.sh
|
||||
|
||||
# Windows (PowerShell):
|
||||
. $HOME/esp/esp-idf/export.ps1
|
||||
|
||||
# Windows (Command Prompt):
|
||||
%USERPROFILE%\esp\esp-idf\export.bat
|
||||
```
|
||||
|
||||
### Step 3: Clone This Project
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kassane/zig-esp-idf-sample.git
|
||||
cd zig-esp-idf-sample
|
||||
```
|
||||
|
||||
### Step 4: Verify Installation
|
||||
|
||||
```bash
|
||||
idf.py --version
|
||||
# Expected output: ESP-IDF v5.x.x or v6.x.x
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Set Your Target Device
|
||||
|
||||
```bash
|
||||
# For ESP32-C6 (RISC-V)
|
||||
idf.py set-target esp32c6
|
||||
|
||||
# For ESP32-S3 (Xtensa)
|
||||
idf.py set-target esp32s3
|
||||
|
||||
# For ESP32 (original, Xtensa)
|
||||
idf.py set-target esp32
|
||||
```
|
||||
|
||||
### 2. Build the Project
|
||||
|
||||
```bash
|
||||
idf.py build
|
||||
```
|
||||
|
||||
**What happens during build:**
|
||||
- ✅ CMake detects your target and configures the build
|
||||
- ✅ Zig toolchain is automatically downloaded (if needed)
|
||||
- ✅ C bindings are generated from ESP-IDF headers
|
||||
- ✅ Target-specific patches are applied
|
||||
- ✅ Zig code is compiled to object files
|
||||
- ✅ Everything is linked with ESP-IDF libraries
|
||||
- ✅ Firmware binaries are generated
|
||||
|
||||
### 3. Flash to Device
|
||||
|
||||
```bash
|
||||
# Connect your ESP32 via USB, then:
|
||||
idf.py -p PORT flash
|
||||
|
||||
# Find your port:
|
||||
# Linux: /dev/ttyUSB0 or /dev/ttyACM0
|
||||
# macOS: /dev/cu.usbserial-*
|
||||
# Windows: COM3, COM4, etc.
|
||||
|
||||
# Example:
|
||||
idf.py -p /dev/ttyUSB0 flash
|
||||
```
|
||||
|
||||
### 4. Monitor Output
|
||||
|
||||
```bash
|
||||
idf.py -p PORT monitor
|
||||
|
||||
# Or combine flash + monitor:
|
||||
idf.py -p PORT flash monitor
|
||||
|
||||
# Exit monitor: Ctrl+]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
zig-esp-idf-sample/
|
||||
├── build.zig # Zig build script (compiles Zig code)
|
||||
├── build.zig.zon # Zig package manifest
|
||||
├── CMakeLists.txt # Root CMake config
|
||||
├── sdkconfig # ESP-IDF configuration (generated)
|
||||
├── sdkconfig.defaults # Default SDK config
|
||||
├── sdkconfig.defaults.esp32 # ESP32-specific defaults
|
||||
├── partitions_matter.csv # Custom partition table for Matter (3 MB app, 4 MB flash)
|
||||
├── dependencies.lock # Component version lock
|
||||
├── wokwi.toml # Wokwi simulator config
|
||||
│
|
||||
├── main/
|
||||
│ ├── CMakeLists.txt # Main component config
|
||||
│ ├── placeholder.c # Minimal C entry point (required by CMake)
|
||||
│ ├── matter_wrappers.cpp # C++ shims for esp_matter C++ API (activated when component present)
|
||||
│ ├── app.zig # Main Zig application entry
|
||||
│ ├── idf_component.yml # Component dependencies
|
||||
│ ├── Kconfig.projbuild # Project configuration options
|
||||
│ └── examples/
|
||||
│ ├── gpio-blink.zig # Toggle LED on GPIO2
|
||||
│ ├── uart-echo.zig # UART echo
|
||||
│ ├── i2c-scan.zig # I2C bus scan
|
||||
│ ├── wifi-station.zig # WiFi station
|
||||
│ ├── http-server.zig # HTTP server
|
||||
│ ├── ble-gatt-server.zig # BLE GATT server
|
||||
│ ├── smartled-rgb.zig # WS2812B LED strip
|
||||
│ ├── dsp-math.zig # DSP/FFT operations
|
||||
│ └── matter-light.zig # Matter On/Off Light
|
||||
│
|
||||
├── imports/ # Zig API wrappers and bindings
|
||||
│ ├── idf.zig # Main ESP-IDF facade module
|
||||
│ ├── idf-sys.zig # Generated C bindings (auto-generated)
|
||||
│ ├── sys.zig # Re-exports idf-sys
|
||||
│ ├── error.zig # esp_err_t → Zig error mapping
|
||||
│ ├── logger.zig # std.log integration (espLogFn)
|
||||
│ ├── version.zig # ESP-IDF version info (ver)
|
||||
│ ├── heap.zig # HeapCapsAllocator, MultiHeapAllocator
|
||||
│ ├── bootloader.zig # Partition/bootloader control
|
||||
│ ├── gpio.zig # GPIO wrapper
|
||||
│ ├── wifi.zig # WiFi station/AP/scan
|
||||
│ ├── uart.zig # UART driver
|
||||
│ ├── i2c.zig # I2C master
|
||||
│ ├── spi.zig # SPI master (+ SDSPI)
|
||||
│ ├── i2s.zig # I2S audio (STD, PDM, TDM)
|
||||
│ ├── http.zig # HTTP server + client
|
||||
│ ├── mqtt.zig # MQTT client
|
||||
│ ├── lwip.zig # lwIP sockets, DNS, SNTP
|
||||
│ ├── crc.zig # ESP-ROM CRC-8/16/32
|
||||
│ ├── bluetooth.zig # Bluedroid BLE
|
||||
│ ├── nimble.zig # NimBLE BLE (compile-time guarded)
|
||||
│ ├── now.zig # ESP-NOW protocol
|
||||
│ ├── nvs.zig # NVS flash key-value storage
|
||||
│ ├── partition.zig # Partition table operations
|
||||
│ ├── sleep.zig # Deep/light sleep + wakeup
|
||||
│ ├── event.zig # ESP event loop
|
||||
│ ├── wdt.zig # Task watchdog timer
|
||||
│ ├── rtos.zig # FreeRTOS tasks/queues/semaphores/timers
|
||||
│ ├── pcnt.zig # Pulse counter (pulse)
|
||||
│ ├── phy.zig # Wireless PHY / RF calibration
|
||||
│ ├── segger.zig # Segger SystemView profiling
|
||||
│ ├── led-strip.zig # LED strip — requires espressif/led_strip
|
||||
│ ├── dsp.zig # DSP/FFT — requires espressif/esp-dsp
|
||||
│ ├── hosted.zig # ESP-Hosted coexistence — requires espressif/esp_hosted
|
||||
│ ├── wifi_remote.zig # WiFi remote — requires espressif/esp_wifi_remote
|
||||
│ ├── timer.zig # High-resolution esp_timer (one-shot + periodic)
|
||||
│ ├── ledc.zig # LED PWM controller (duty, fade)
|
||||
│ ├── twai.zig # TWAI/CAN bus driver
|
||||
│ ├── pm.zig # Power management locks
|
||||
│ ├── pthread.zig # POSIX threads (FreeRTOS-backed)
|
||||
│ └── panic.zig # Zig panic handler
|
||||
│
|
||||
├── include/ # C headers for binding generation
|
||||
│ ├── stubs.h # Core ESP-IDF headers (input to zig translate-c)
|
||||
│ ├── wifi_stubs.h # WiFi macro wrappers
|
||||
│ ├── bt_stubs.h # Bluetooth macro wrappers
|
||||
│ ├── matter_stubs.h # C wrapper interface for esp_matter (C++ component)
|
||||
│ ├── matter_closure_patch.h # GCC 14 C++23 fix for closure-control cluster
|
||||
│ └── bindings.h # Additional bindings
|
||||
│
|
||||
├── cmake/ # CMake build system scripts
|
||||
│ ├── zig-config.cmake # Main Zig configuration
|
||||
│ ├── zig-download.cmake # Auto-download Zig toolchain
|
||||
│ ├── zig-runner.cmake # Helper functions for Zig
|
||||
│ ├── bindings.cmake # Binding generation
|
||||
│ ├── extra-components.cmake # Managed component detection
|
||||
│ └── patch.cmake # Post-processing patches
|
||||
│
|
||||
├── patches/ # Binding fixes for translate-c issues
|
||||
│ ├── *.zig
|
||||
│
|
||||
├── docs/ # Documentation
|
||||
│ ├── build-internals.md # Build system details
|
||||
│ ├── build-scheme.png # Build flow diagram
|
||||
│ └── zig-xtensa.md # Xtensa toolchain info
|
||||
│
|
||||
└── flake.nix # Nix development environment
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Building Your First Project
|
||||
|
||||
### Example 1: Hello World
|
||||
|
||||
```zig
|
||||
const std = @import("std");
|
||||
const idf = @import("esp_idf");
|
||||
|
||||
comptime {
|
||||
@export(&main, .{ .name = "app_main" });
|
||||
}
|
||||
|
||||
fn main() callconv(.c) void {
|
||||
log.info("Hello from Zig on ESP32!", .{});
|
||||
log.info("Zig version: {s}", .{@import("builtin").zig_version_string});
|
||||
|
||||
// Show memory info
|
||||
var heap = idf.heap.HeapCapsAllocator.init(null); // default: MALLOC_CAP_DEFAULT
|
||||
log.info("Free heap: {} bytes", .{heap.freeSize()});
|
||||
|
||||
// Sleep forever
|
||||
while (true) {
|
||||
idf.rtos.Task.delayMs(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite zig std_options config
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = idf.log.espLogFn,
|
||||
};
|
||||
// rename log instance
|
||||
const log = std.log.scoped(.@"esp-idf");
|
||||
// overwrite std panic-handler
|
||||
pub const panic = idf.esp_panic.panic;
|
||||
```
|
||||
|
||||
**Build and run:**
|
||||
```bash
|
||||
idf.py build flash monitor
|
||||
```
|
||||
|
||||
### Example 2: Blinking LED
|
||||
|
||||
**Create `main/examples/blink.zig`:**
|
||||
|
||||
```zig
|
||||
const std = @import("std");
|
||||
const idf = @import("esp_idf");
|
||||
|
||||
const LED_PIN = .@"18"; // Change to your LED pin
|
||||
|
||||
comptime {
|
||||
@export(&main, .{ .name = "app_main" });
|
||||
}
|
||||
|
||||
fn main() callconv(.c) void {
|
||||
// Configure GPIO as output
|
||||
idf.gpio.Direction.set(LED_PIN, .output) catch {
|
||||
log.err("Failed to configure GPIO", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
log.info("Blinking LED on GPIO {d}", .{LED_PIN});
|
||||
|
||||
while (true) {
|
||||
// LED ON
|
||||
idf.gpio.Level.set(LED_PIN, 1) catch {};
|
||||
log.info("LED ON", .{});
|
||||
idf.rtos.Task.delayMs(1000);
|
||||
|
||||
// LED OFF
|
||||
idf.gpio.Level.set(LED_PIN, 0) catch {};
|
||||
log.info("LED OFF", .{});
|
||||
idf.rtos.Task.delayMs(1000);
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite zig std_options config
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = idf.log.espLogFn,
|
||||
};
|
||||
// rename log instance
|
||||
const log = std.log.scoped(.blink);
|
||||
// overwrite std panic-handler
|
||||
pub const panic = idf.esp_panic.panic;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Working with Components
|
||||
|
||||
### Adding Managed Components
|
||||
|
||||
Components are specified in `main/idf_component.yml`:
|
||||
|
||||
**Add a component:**
|
||||
|
||||
```bash
|
||||
# Use idf.py command:
|
||||
idf.py add-dependency espressif/led_strip
|
||||
# then
|
||||
idf.py reconfigure
|
||||
```
|
||||
|
||||
### Using LED Strip Component
|
||||
|
||||
**The build system automatically:**
|
||||
1. ✅ Detects components in `dependencies.lock`
|
||||
2. ✅ Adds include paths to binding generation
|
||||
3. ✅ Generates `HAS_*` defines (e.g., `HAS_LED_STRIP=1`)
|
||||
4. ✅ Includes headers in `include/stubs.h` conditionally
|
||||
5. ✅ Makes APIs available in Zig via `idf.*` modules
|
||||
|
||||
**1. Ensure LED strip is in `main/idf_component.yml`:**
|
||||
```yaml
|
||||
dependencies:
|
||||
espressif/led_strip: "*"
|
||||
```
|
||||
|
||||
**2. Reconfigure:**
|
||||
```bash
|
||||
idf.py reconfigure
|
||||
```
|
||||
|
||||
**3. Check provided example:**
|
||||
|
||||
The example in [examples/smartled-rgb.zig](../main/examples/smartled-rgb.zig) demonstrates:
|
||||
- Configuring WS2812B LED strip on GPIO 2
|
||||
- Setting individual pixel colors
|
||||
- Refreshing the display
|
||||
- Blinking pattern
|
||||
|
||||
### DSP basics (FFT + math)
|
||||
|
||||
[examples/dsp-math.zig](../main/examples/dsp-math.zig)
|
||||
|
||||
- Generates a sine tone (freq = 0.2 normalized)
|
||||
- Applies Hann window
|
||||
- Does FFT (1024 points, float32, radix-2)
|
||||
- Computes power spectrum in dB
|
||||
- Prints ASCII plot of the spectrum (64×10 chars, -120 to +40 dB)
|
||||
|
||||
### Using WiFi
|
||||
|
||||
**Use the WiFi station example:**
|
||||
[examples/wifi-station.zig](../main/examples/wifi-station.zig)
|
||||
|
||||
**Configure WiFi credentials:**
|
||||
|
||||
```bash
|
||||
idf.py menuconfig
|
||||
# Navigate to: Example Configuration
|
||||
# Set WiFi SSID and Password
|
||||
```
|
||||
|
||||
Or edit [main/Kconfig.projbuild](../main/Kconfig.projbuild) to change default values.
|
||||
|
||||
### Available Wrapper APIs
|
||||
|
||||
The project provides comprehensive Zig wrappers in `imports/`:
|
||||
|
||||
| Module | Description | Notes |
|
||||
|--------|-------------|-------|
|
||||
| `idf.gpio` | GPIO control | Any target |
|
||||
| `idf.wifi` | WiFi station/AP/scan | Not on H2/H4/P4 |
|
||||
| `idf.bt` | Bluedroid BLE | Requires `CONFIG_BT_ENABLED` |
|
||||
| `idf.nimble` | NimBLE BLE | Requires `CONFIG_BT_NIMBLE_ENABLED` |
|
||||
| `idf.heap` | HeapCapsAllocator, MultiHeapAllocator | Any target |
|
||||
| `idf.rtos` | FreeRTOS tasks/queues/semaphores/timers | Any target |
|
||||
| `idf.nvs` | NVS flash key-value storage | Any target |
|
||||
| `idf.partition` | Partition table operations | Any target |
|
||||
| `idf.sleep` | Deep/light sleep + wakeup sources | Any target |
|
||||
| `idf.event` | ESP event loop | Any target |
|
||||
| `idf.wdt` | Task watchdog timer | Any target |
|
||||
| `idf.bl` | Bootloader/partition control | Any target |
|
||||
| `idf.i2c` | I2C master | Any target |
|
||||
| `idf.spi` | SPI master + SDSPI | Any target |
|
||||
| `idf.uart` | UART driver | Any target |
|
||||
| `idf.i2s` | I2S audio (STD, PDM, TDM) | Any target |
|
||||
| `idf.http` | HTTP server (httpd) + client | Any target |
|
||||
| `idf.mqtt` | MQTT client | Any target |
|
||||
| `idf.lwip` | lwIP sockets, DNS, SNTP | Any target |
|
||||
| `idf.crc` | ESP-ROM CRC-8/16/32 | Any target |
|
||||
| `idf.esp_now` | ESP-NOW protocol | Any target |
|
||||
| `idf.pulse` | Pulse counter (PCNT) | Any target |
|
||||
| `idf.phy` | Wireless PHY / RF calibration | Any target |
|
||||
| `idf.segger` | Segger SystemView profiling | Any target |
|
||||
| `idf.ver` | ESP-IDF version info | Any target |
|
||||
| `idf.led` | LED strip WS2812B | Requires `espressif/led_strip` |
|
||||
| `idf.dsp` | DSP/FFT operations | Requires `espressif/esp-dsp` |
|
||||
| `idf.esp_hosted` | ESP-Hosted coexistence | Requires `espressif/esp_hosted` |
|
||||
| `idf.wifi_remote` | WiFi via slave MCU | Requires `espressif/esp_wifi_remote` |
|
||||
| `idf.timer` | High-resolution esp_timer | Any target |
|
||||
| `idf.ledc` | LED PWM controller | Any target |
|
||||
| `idf.twai` | TWAI/CAN bus driver | Any target |
|
||||
| `idf.pm` | Power management locks | Any target |
|
||||
| `idf.pthread` | POSIX threads (FreeRTOS-backed) | Any target |
|
||||
| `idf.matter` | Matter/CHIP protocol | Requires `espressif/esp_matter` |
|
||||
| `idf.log` | std.log integration (`espLogFn`) | Any target |
|
||||
| `idf.err` | esp_err_t → Zig error mapping | Any target |
|
||||
| `idf.sys` | Raw C bindings | Direct ESP-IDF API access |
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### FreeRTOS Tasks
|
||||
|
||||
```zig
|
||||
const idf = @import("esp_idf");
|
||||
const std = @import("std");
|
||||
|
||||
// overwrite std panic-handler
|
||||
pub const panic = idf.esp_panic.panic;
|
||||
// overwrite std.log
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = idf.log.espLogFn,
|
||||
};
|
||||
|
||||
export fn myTask(_: ?*anyopaque) callconv(.c) void {
|
||||
const log = std.log.scoped(.task);
|
||||
while (true) {
|
||||
log.info("Task running!", .{});
|
||||
idf.rtos.Task.delayMs(1000);
|
||||
}
|
||||
}
|
||||
|
||||
export fn app_main() callconv(.c) void {
|
||||
_ = idf.rtos.Task.create(myTask, "my_task", 2048, null, 5) catch @panic("Failed to create task");
|
||||
|
||||
// Main task continues...
|
||||
while (true) {
|
||||
idf.rtos.Task.delayMs(1000);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using Custom Allocators
|
||||
|
||||
```zig
|
||||
const idf = @import("esp_idf");
|
||||
const std = @import("std");
|
||||
|
||||
export fn app_main() callconv(.c) void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.c_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const allocator = arena.allocator();
|
||||
|
||||
var list: std.ArrayList(u32) = .empty;
|
||||
defer list.deinit(allocator);
|
||||
|
||||
list.append(allocator, 10) catch {};
|
||||
list.append(allocator, 20) catch {};
|
||||
list.append(allocator, 30) catch {};
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Accessing Raw C APIs
|
||||
|
||||
When wrappers aren't available, use raw bindings:
|
||||
|
||||
```zig
|
||||
const idf = @import("esp_idf");
|
||||
const std = @import("std");
|
||||
const sys = idf.sys;
|
||||
const log = std.log.scoped(.@"esp-idf");
|
||||
|
||||
export fn app_main() callconv(.c) void {
|
||||
var mac_addr: [6]u8 = undefined;
|
||||
|
||||
// Direct ESP-IDF C API call
|
||||
const result = sys.esp_efuse_mac_get_default(&mac_addr);
|
||||
if (result != sys.ESP_OK) {
|
||||
std.log.err("Failed to get MAC address", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("MAC: {X:0>2}:{X:0>2}:{X:0>2}:{X:0>2}:{X:0>2}:{X:0>2}", .{
|
||||
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||
mac_addr[3], mac_addr[4], mac_addr[5],
|
||||
});
|
||||
}
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = idf.log.espLogFn,
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Errors
|
||||
|
||||
**"zig: command not found"**
|
||||
- The Zig toolchain should auto-download. Check `build/zig-relsafe-*` directory
|
||||
- Or install manually: https://ziglang.org/download/
|
||||
- For Nix users: `nix develop`
|
||||
|
||||
**"Component not found: espressif__led_strip"**
|
||||
```bash
|
||||
# Check idf_component.yml
|
||||
cat main/idf_component.yml
|
||||
|
||||
# Reconfigure to download components
|
||||
idf.py reconfigure
|
||||
```
|
||||
|
||||
**"translate-c failed"**
|
||||
- Check `include/stubs.h` and `include/wifi_stubs.h` for syntax errors
|
||||
- Ensure managed components exist in `managed_components/`
|
||||
- Check that `HAS_*` defines match components in `cmake/extra-components.cmake`
|
||||
|
||||
**Binding generation errors**
|
||||
- The `patches/` directory contains fixes for common `translate-c` issues
|
||||
- If you see struct layout errors, a patch likely needs updating
|
||||
- Check `cmake/patch.cmake` for how patches are applied
|
||||
|
||||
### Flash Errors
|
||||
|
||||
**"Serial port not found"**
|
||||
```bash
|
||||
# Linux: Add user to dialout group
|
||||
sudo usermod -a -G dialout $USER
|
||||
# Log out and back in
|
||||
|
||||
# Check available ports
|
||||
ls /dev/tty*
|
||||
|
||||
# Windows: Check Device Manager for COM port
|
||||
```
|
||||
|
||||
**"Failed to connect to ESP32"**
|
||||
- Hold BOOT button while connecting
|
||||
- Try different USB cable/port (must be data cable, not power-only)
|
||||
- Verify target matches your device: `idf.py set-target esp32c6`
|
||||
- Check USB drivers are installed (CP210x or CH340)
|
||||
|
||||
### Runtime Errors
|
||||
|
||||
**"Guru Meditation Error: Core panic"**
|
||||
- Check stack size (increase in `xTaskCreate`, default 2048 often too small)
|
||||
- Verify GPIO pins match your hardware
|
||||
- Enable debug build: `idf.py menuconfig` → Compiler options → Debug (-Og)
|
||||
- Check `sdkconfig` for panic handler settings
|
||||
|
||||
**"Out of memory" / Heap errors**
|
||||
- Use arena allocators: `std.heap.ArenaAllocator`
|
||||
- Check available heap: `heap.freeSize()`
|
||||
- Reduce allocations in hot paths
|
||||
- Consider enabling PSRAM if available
|
||||
- Check `idf.py size-components` for memory usage
|
||||
|
||||
**WiFi not connecting**
|
||||
- Verify SSID and password in menuconfig
|
||||
- Check WiFi country code matches your region
|
||||
- Ensure 2.4GHz WiFi (5GHz not supported)
|
||||
- Check WiFi credentials don't contain special characters
|
||||
|
||||
**Matter example: "app partition is too small"**
|
||||
|
||||
The Matter binary is ~2.2 MB and requires a 4 MB flash chip and custom partition table:
|
||||
```bash
|
||||
# Ensure sdkconfig has 4 MB flash and custom partition:
|
||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
# CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
# CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_matter.csv"
|
||||
|
||||
# If sdkconfig doesn't reflect sdkconfig.defaults changes, update it:
|
||||
idf.py reconfigure
|
||||
idf.py build -DCONFIG_ZIG_EXAMPLE_MATTER_LIGHT=y
|
||||
```
|
||||
|
||||
**Matter example: IDF version incompatibility**
|
||||
- `espressif/esp_matter` 1.4.x requires IDF **v5.x** (tested with v5.5)
|
||||
- Not compatible with IDF v6.x (depends on `json`/`mqtt` components removed in v6)
|
||||
- Check your IDF version: `idf.py --version`
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Learn More
|
||||
|
||||
- **Zig Language:** https://ziglang.org/documentation/master/
|
||||
- **ESP-IDF Docs:** https://docs.espressif.com/projects/esp-idf/
|
||||
- **Project Wiki:**
|
||||
- [Build Internals](./build-internals.md)
|
||||
- [Xtensa Toolchain](./zig-xtensa.md)
|
||||
|
||||
### Explore Examples
|
||||
|
||||
All examples are in `main/examples/`:
|
||||
- `gpio-blink.zig` - Toggle an LED on GPIO2 (any target)
|
||||
- `uart-echo.zig` - Read UART1 and echo back
|
||||
- `i2c-scan.zig` - Scan I2C bus for devices
|
||||
- `wifi-station.zig` - Connect to a WiFi AP
|
||||
- `http-server.zig` - Serve a web page over WiFi
|
||||
- `ble-gatt-server.zig` - BLE peripheral with GATT notifications (requires `CONFIG_BT_ENABLED`)
|
||||
- `smartled-rgb.zig` - WS2812B LED strip control (requires `espressif/led_strip`)
|
||||
- `dsp-math.zig` - FFT + power spectrum via DSP (requires `espressif/esp-dsp`)
|
||||
- `matter-light.zig` - Matter On/Off Light device (requires `espressif/esp_matter`, IDF v5.x, 4 MB flash)
|
||||
|
||||
### Configuration
|
||||
|
||||
```bash
|
||||
# Interactive configuration menu
|
||||
idf.py menuconfig
|
||||
|
||||
# Key settings to explore:
|
||||
# - Component config → FreeRTOS → Tick rate (Hz)
|
||||
# - Component config → ESP System Settings → Panic handler behavior
|
||||
# - Partition Table → Choose partition scheme
|
||||
# - Example Configuration → WiFi credentials
|
||||
# - Compiler options → Optimization level
|
||||
```
|
||||
|
||||
### Testing with Wokwi Simulator
|
||||
|
||||
The project includes `wokwi.toml` for simulation:
|
||||
|
||||
1. Install Wokwi CLI: https://docs.wokwi.com/wokwi-ci/idf-wokwi-usage
|
||||
2. Edit `wokwi.toml` to match your project
|
||||
3. Run: `idf.py wokwi --timeout 30000`
|
||||
|
||||
or use VSCode Extension
|
||||
|
||||
* More info: https://docs.wokwi.com/vscode/getting-started
|
||||
|
||||
### Advanced Topics
|
||||
|
||||
- **Custom Components:** Create reusable Zig modules in `imports/`
|
||||
- **WiFi & Networking:** HTTP servers, WebSockets, mDNS
|
||||
- **OTA Updates:** Over-the-air firmware updates
|
||||
- **Bluetooth:** BLE advertising, GATT services
|
||||
- **Deep Sleep:** Ultra-low power modes
|
||||
- **File Systems:** SPIFFS, FAT, LittleFS
|
||||
- **Cryptography:** Hardware-accelerated crypto
|
||||
|
||||
### Development Tips
|
||||
|
||||
**Use `sdkconfig.defaults` for version control:**
|
||||
- Base config: `sdkconfig.defaults`
|
||||
- Target-specific: `sdkconfig.defaults.esp32`
|
||||
- Don't commit `sdkconfig` (it's generated)
|
||||
|
||||
**Debugging:**
|
||||
```bash
|
||||
# Monitor with timestamps
|
||||
idf.py monitor --timestamps
|
||||
|
||||
# Filter logs by tag
|
||||
idf.py monitor --print-filter "tag:app"
|
||||
|
||||
# Save logs to file
|
||||
idf.py monitor | tee output.log
|
||||
```
|
||||
|
||||
**Clean builds when needed:**
|
||||
```bash
|
||||
# Clean Zig cache
|
||||
rm -rf .zig-cache
|
||||
|
||||
# Full CMake clean
|
||||
idf.py fullclean
|
||||
|
||||
# Regenerate bindings
|
||||
idf.py reconfigure
|
||||
```
|
||||
|
||||
### Contributing
|
||||
|
||||
Found a bug or want to contribute?
|
||||
- **GitHub:** https://github.com/kassane/zig-esp-idf-sample
|
||||
- **Issues:** https://github.com/kassane/zig-esp-idf-sample/issues
|
||||
- **Pull Requests:** See [CONTRIBUTING.md](../CONTRIBUTING.md)
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Common Commands
|
||||
|
||||
```bash
|
||||
# Setup
|
||||
idf.py set-target esp32c6 # Set target device
|
||||
idf.py reconfigure # Regenerate build config / update deps
|
||||
|
||||
# Build
|
||||
idf.py build # Build project
|
||||
idf.py clean # Clean build files
|
||||
idf.py fullclean # Full clean (including config)
|
||||
|
||||
# Flash
|
||||
idf.py -p PORT flash # Flash firmware
|
||||
idf.py -p PORT monitor # Monitor serial output
|
||||
idf.py -p PORT flash monitor # Flash and monitor
|
||||
idf.py -p PORT app-flash # Flash app only (faster)
|
||||
|
||||
# Config
|
||||
idf.py menuconfig # Interactive configuration
|
||||
idf.py size # Show binary sizes
|
||||
idf.py size-components # Component size breakdown
|
||||
|
||||
# Dependencies
|
||||
idf.py add-dependency PKG # Add managed component
|
||||
|
||||
# Help
|
||||
idf.py --help # Show all commands
|
||||
idf.py --list-targets # List supported targets
|
||||
```
|
||||
|
||||
### File Locations
|
||||
|
||||
- **Main app:** `main/app.zig`
|
||||
- **Examples:** `main/examples/*.zig`
|
||||
- **Dependencies:** `main/idf_component.yml`
|
||||
- **Configuration:** `sdkconfig`, `sdkconfig.defaults*`
|
||||
- **Bindings:** `imports/idf-sys.zig` (auto-generated)
|
||||
- **Wrappers:** `imports/*.zig`
|
||||
- **Build scripts:** `cmake/*.cmake`
|
||||
|
||||
### Pin Configuration
|
||||
|
||||
Check your board's pinout:
|
||||
- **GPIO Pins:** Varies by model (ESP32: 0-39, ESP32-C6: 0-30)
|
||||
- **Built-in LED:** Often GPIO 2, 8, or 18
|
||||
- **UART:** Usually GPIO 1 (TX), GPIO 3 (RX)
|
||||
- **I2C:** SDA/SCL pins vary by board
|
||||
- **SPI:** MOSI/MISO/CLK pins vary by board
|
||||
|
||||
### Hardware Requirements
|
||||
|
||||
- **ESP32 Development Board** (any supported variant)
|
||||
- **USB Cable** (must be data cable, not power-only)
|
||||
- **LEDs/Components** (optional, for examples)
|
||||
- **LED Strip WS2812B** (optional, for smartled-rgb example)
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
- **Documentation:** [docs/](.)
|
||||
- **Issues:** https://github.com/kassane/zig-esp-idf-sample/issues
|
||||
- **Discussions:** https://github.com/kassane/zig-esp-idf-sample/discussions
|
||||
Reference in New Issue
Block a user