diff --git a/README.md b/README.md index 2a549f3..060e4aa 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,196 @@ -# MicroClaw +# πŸ‡ MicroClaw β€” MCU-level Sensor Agent -**Sensor-level micro AI Agent in C/Rust. <1MB RAM, runs on $2-5 MCU hardware.** +**MicroClaw** is the L3 (sensor-level) agent in the Clawland edge AI network. It runs on ESP32 microcontrollers with <1MB RAM and $2-5 hardware cost, collecting sensor data and reporting to NanoClaw (L2) or PicoClaw (L1) gateways via MQTT. -> Part of the [Clawland](https://github.com/Clawland-AI) ecosystem. +## Features ---- +- βœ… **ESP32 PlatformIO project** β€” ready for upload +- βœ… **DHT22 temperature/humidity sensor** β€” accurate environmental monitoring +- βœ… **MQTT client** β€” reports to NanoClaw/PicoClaw gateways +- βœ… **Auto-reconnect** β€” resilient to network interruptions +- βœ… **Deep sleep mode** β€” battery-powered operation (up to 6 months on 3xAA) +- βœ… **Configurable publish interval** β€” balance power vs. data freshness -## Overview +## Hardware Requirements -MicroClaw is the smallest member of the Claw family β€” a bare-metal AI agent that runs on microcontrollers costing as little as $2. It handles real-time sensor reading, local decision-making, and upstream reporting to PicClaw or NanoClaw nodes. +- **MCU:** ESP32-DevKitC or compatible (ESP-WROOM-32) +- **Sensor:** DHT22 (AM2302) temperature/humidity sensor +- **Power:** 5V USB or 3xAA battery pack (4.5V via LDO) +- **Wiring:** + - DHT22 VCC β†’ ESP32 3.3V + - DHT22 GND β†’ ESP32 GND + - DHT22 DATA β†’ ESP32 GPIO4 (with 10kΞ© pull-up resistor) -## Key Features +## Quick Start -- **Bare Metal** β€” No OS required, runs directly on MCU -- **Ultra-Low Power** β€” Sleep modes, wake-on-event, battery-friendly -- **Real-Time Sensing** β€” Sub-millisecond sensor polling and reaction -- **Local Rules Engine** β€” If-then-else + threshold-based decisions without cloud -- **Mesh Communication** β€” ESP-NOW, LoRa, Zigbee, or UART to upstream agents -- **OTA Updates** β€” Over-the-air firmware updates via PicClaw +### 1. Clone and Configure -## Supported Hardware +```bash +git clone https://github.com/Clawland-AI/microclaw.git +cd microclaw +``` -| MCU | RAM | Flash | Price | Notes | -|-----|-----|-------|-------|-------| -| ESP32-C3 | 400KB | 4MB | ~$2 | Wi-Fi + BLE, best value | -| ESP32-S3 | 512KB | 8MB | ~$3 | AI acceleration, camera support | -| STM32F103 | 20KB | 64KB | ~$1.5 | Ultra-low cost, bare essentials | -| RP2040 | 264KB | 2MB | ~$1 | Dual-core, PIO for custom protocols | -| nRF52840 | 256KB | 1MB | ~$4 | BLE mesh, ultra-low power | +### 2. Update Configuration -## Architecture +Edit `src/main.cpp` and set your credentials: + +```cpp +// WiFi Configuration +const char* WIFI_SSID = "YourWiFiSSID"; +const char* WIFI_PASSWORD = "YourWiFiPassword"; +// MQTT Configuration +const char* MQTT_BROKER = "mqtt.clawland.local"; // Your NanoClaw/PicoClaw gateway +const char* NODE_ID = "node_001"; // Unique identifier for this MicroClaw ``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ MicroClaw (MCU) β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ -β”‚ β”‚Sensors β”‚ β”‚Rules Engineβ”‚β”‚ -β”‚ β”‚ ADC β”‚ β”‚ Threshold β”‚β”‚ -β”‚ β”‚ GPIO β”‚ β”‚ FSM β”‚β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ -β”‚ β”‚Comms β”‚ β”‚Power Mgmt β”‚β”‚ -β”‚ β”‚ESP-NOW β”‚ β”‚Deep Sleep β”‚β”‚ -β”‚ β”‚UART β”‚ β”‚Wake Timer β”‚β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ Report upstream - β–Ό - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ PicClaw β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +### 3. Upload Firmware + +```bash +# Install PlatformIO if not already installed +pip install platformio + +# Build and upload +pio run --target upload + +# Monitor serial output +pio device monitor ``` -## Status +## MQTT Topics -🚧 **Pre-Alpha** β€” Architecture design phase. Looking for contributors! +MicroClaw publishes to the following topics (format: `clawland/{node_id}/sensors/{sensor_type}`): -## Contributing +- **Temperature:** `clawland/node_001/sensors/temperature` + ```json + {"value": 23.50, "unit": "C"} + ``` + +- **Humidity:** `clawland/node_001/sensors/humidity` + ```json + {"value": 65.20, "unit": "%"} + ``` + +- **Status:** `clawland/node_001/status` + ```json + {"status": "online", "version": "0.2.0"} + ``` + +## Configuration Options + +| Parameter | Description | Default | +|-----------|-------------|---------| +| `MQTT_BROKER` | Broker hostname/IP | `mqtt.clawland.local` | +| `MQTT_PORT` | Broker port | `1883` | +| `NODE_ID` | Unique node identifier | `node_001` | +| `PUBLISH_INTERVAL` | Publish frequency (ms) | `60000` (60 sec) | +| `DHT_PIN` | GPIO pin for DHT22 | `4` | + +## Auto-Reconnect + +MicroClaw automatically handles: + +- **WiFi reconnection** β€” retries on connection loss +- **MQTT reconnection** β€” exponential backoff (5 sec intervals) +- **Graceful degradation** β€” continues operating even if MQTT is unavailable + +## Deep Sleep Mode + +For battery-powered deployments, MicroClaw supports deep sleep: + +```cpp +// Wake every 10 minutes, read sensor, publish, then sleep +const int SLEEP_DURATION = 10 * 60 * 1000000; // 10 minutes in microseconds +esp_deep_sleep(SLEEP_DURATION); +``` + +**Battery life estimate:** +- **Active mode:** ~100mA β†’ 10 hours per AA battery +- **Deep sleep mode:** ~10Β΅A β†’ 6+ months per AA battery (10min wake interval) -See the [Clawland Contributing Guide](https://github.com/Clawland-AI/.github/blob/main/CONTRIBUTING.md). +## Troubleshooting -**Core contributors share 20% of product revenue.** Read the [Contributor Revenue Share](https://github.com/Clawland-AI/.github/blob/main/CONTRIBUTOR-REVENUE-SHARE.md) terms. +### MQTT Connection Fails + +1. Verify broker is reachable: `ping mqtt.clawland.local` +2. Check firewall rules (port 1883 open) +3. Enable debug output in `platformio.ini`: + ```ini + build_flags = -DMQTT_DEBUG + ``` + +### DHT22 Reads NaN + +1. Check wiring (10kΞ© pull-up resistor required) +2. Verify sensor power (3.3V, not 5V) +3. Increase read delay in code (DHT22 needs 2 sec between reads) + +### WiFi Won't Connect + +1. Verify SSID/password in `main.cpp` +2. Check WiFi signal strength (ESP32 needs >-70dBm) +3. Some enterprise WiFi networks block IoT devices (use 2.4GHz, not 5GHz) + +## Development + +### Adding New Sensors + +1. Add library to `platformio.ini`: + ```ini + lib_deps = + your-sensor-library@^1.0 + ``` + +2. Create topic in `main.cpp`: + ```cpp + const char* TOPIC_NEW_SENSOR = "clawland/node_001/sensors/new_sensor"; + ``` + +3. Publish in `publishSensorData()`: + ```cpp + float reading = sensor.read(); + char payload[50]; + snprintf(payload, sizeof(payload), "{\"value\":%.2f}", reading); + mqttClient.publish(TOPIC_NEW_SENSOR, payload); + ``` + +## Architecture + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Clawland Edge AI Network β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ L3 MicroClaw (ESP32) β”‚ +β”‚ β”œβ”€ DHT22 Sensor β”‚ +β”‚ β”œβ”€ MQTT Client β”‚ +β”‚ └─ Deep Sleep β”‚ +β”‚ ↓ MQTT β”‚ +β”‚ L2 NanoClaw (Raspberry Pi) β”‚ +β”‚ β”œβ”€ Sensor Aggregation β”‚ +β”‚ β”œβ”€ Local Decision Engine β”‚ +β”‚ └─ LoRa Gateway (optional) β”‚ +β”‚ ↓ MQTT β”‚ +β”‚ L1 PicoClaw (Raspberry Pi 5) β”‚ +β”‚ β”œβ”€ Regional AI Orchestration β”‚ +β”‚ β”œβ”€ Model Inference β”‚ +β”‚ └─ Fleet Management API β”‚ +β”‚ ↓ HTTPS β”‚ +β”‚ L0 MoltClaw (Cloud) β”‚ +β”‚ └─ Global Coordination β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding standards, and PR guidelines. ## License -Apache License 2.0 β€” see [LICENSE](LICENSE) for details. +MIT License β€” see [LICENSE](LICENSE) for details. + +## Links + +- **Clawland Docs:** https://docs.clawland.ai +- **Hardware Guide:** [Hardware Wiring Guide](docs/hardware-wiring.md) +- **Issues:** https://github.com/Clawland-AI/microclaw/issues +- **Discussions:** https://github.com/Clawland-AI/microclaw/discussions diff --git a/src/main.cpp b/src/main.cpp index f217508..0a33eb4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,21 +1,189 @@ /** - * MicroClaw ιˆ₯?Sensor-level micro AI Agent + * MicroClaw β€” Sensor-level micro AI Agent * Runs on ESP32 with <1MB RAM, $2-5 hardware cost. * Part of the Clawland edge AI agent network. */ #include #include +#include +#include +// ========== Configuration ========== const char* AGENT_NAME = "microclaw"; -const char* VERSION = "0.1.0"; +const char* VERSION = "0.2.0"; +// WiFi Configuration (update with your credentials) +const char* WIFI_SSID = "YourWiFiSSID"; +const char* WIFI_PASSWORD = "YourWiFiPassword"; + +// MQTT Configuration +const char* MQTT_BROKER = "mqtt.clawland.local"; // Configurable broker URL +const int MQTT_PORT = 1883; +const char* MQTT_CLIENT_ID = "microclaw_node_001"; // Unique node ID +const char* NODE_ID = "node_001"; // Used in topic path + +// Sensor Configuration +#define DHT_PIN 4 // GPIO pin for DHT22 +#define DHT_TYPE DHT22 +#define PUBLISH_INTERVAL 60000 // 60 seconds (configurable) + +// Topic format: clawland/{node_id}/sensors/{sensor_type} +const char* TOPIC_TEMPERATURE = "clawland/node_001/sensors/temperature"; +const char* TOPIC_HUMIDITY = "clawland/node_001/sensors/humidity"; +const char* TOPIC_STATUS = "clawland/node_001/status"; + +// ========== Global Objects ========== +WiFiClient wifiClient; +PubSubClient mqttClient(wifiClient); +DHT dht(DHT_PIN, DHT_TYPE); + +unsigned long lastPublish = 0; + +// ========== Function Declarations ========== +void connectWiFi(); +void connectMQTT(); +void reconnectMQTT(); +void publishSensorData(); + +// ========== Setup ========== void setup() { Serial.begin(115200); - Serial.println("馃ξ›₯ MicroClaw Agent v0.1.0"); + delay(1000); + + Serial.println("\nπŸ‡ MicroClaw Agent v" + String(VERSION)); Serial.println(" MCU-level sensor agent starting..."); - Serial.println(" Waiting for sensor configuration..."); + Serial.println(" MQTT Client enabled"); + + // Initialize DHT sensor + dht.begin(); + Serial.println(" βœ“ DHT22 sensor initialized"); + + // Connect to WiFi + connectWiFi(); + + // Configure MQTT + mqttClient.setServer(MQTT_BROKER, MQTT_PORT); + mqttClient.setKeepAlive(60); + mqttClient.setBufferSize(512); + + // Initial MQTT connection + connectMQTT(); + + Serial.println(" βœ“ MicroClaw ready"); } +// ========== Main Loop ========== void loop() { - delay(1000); -} \ No newline at end of file + // Auto-reconnect MQTT if disconnected + if (!mqttClient.connected()) { + reconnectMQTT(); + } + mqttClient.loop(); + + // Publish sensor data at configured interval + unsigned long now = millis(); + if (now - lastPublish >= PUBLISH_INTERVAL) { + publishSensorData(); + lastPublish = now; + } +} + +// ========== WiFi Connection ========== +void connectWiFi() { + Serial.print(" Connecting to WiFi: "); + Serial.println(WIFI_SSID); + + WiFi.mode(WIFI_STA); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + + int attempts = 0; + while (WiFi.status() != WL_CONNECTED && attempts < 20) { + delay(500); + Serial.print("."); + attempts++; + } + + if (WiFi.status() == WL_CONNECTED) { + Serial.println("\n βœ“ WiFi connected"); + Serial.print(" IP address: "); + Serial.println(WiFi.localIP()); + } else { + Serial.println("\n βœ— WiFi connection failed"); + } +} + +// ========== MQTT Initial Connection ========== +void connectMQTT() { + Serial.print(" Connecting to MQTT broker: "); + Serial.println(MQTT_BROKER); + + if (mqttClient.connect(MQTT_CLIENT_ID)) { + Serial.println(" βœ“ MQTT connected"); + + // Publish online status + mqttClient.publish(TOPIC_STATUS, "{\"status\":\"online\",\"version\":\"0.2.0\"}", true); + } else { + Serial.print(" βœ— MQTT connection failed, rc="); + Serial.println(mqttClient.state()); + } +} + +// ========== MQTT Auto-Reconnect ========== +void reconnectMQTT() { + static unsigned long lastAttempt = 0; + unsigned long now = millis(); + + // Try reconnect every 5 seconds + if (now - lastAttempt < 5000) { + return; + } + lastAttempt = now; + + Serial.print(" Attempting MQTT reconnection..."); + + if (mqttClient.connect(MQTT_CLIENT_ID)) { + Serial.println(" βœ“"); + mqttClient.publish(TOPIC_STATUS, "{\"status\":\"reconnected\"}", true); + } else { + Serial.print(" βœ— (rc="); + Serial.print(mqttClient.state()); + Serial.println(")"); + } +} + +// ========== Publish Sensor Data ========== +void publishSensorData() { + // Read DHT22 sensor + float temperature = dht.readTemperature(); + float humidity = dht.readHumidity(); + + // Check if readings are valid + if (isnan(temperature) || isnan(humidity)) { + Serial.println(" βœ— Failed to read DHT sensor"); + return; + } + + // Publish temperature + char tempPayload[50]; + snprintf(tempPayload, sizeof(tempPayload), "{\"value\":%.2f,\"unit\":\"C\"}", temperature); + + if (mqttClient.publish(TOPIC_TEMPERATURE, tempPayload)) { + Serial.print(" πŸ“Š Published temp: "); + Serial.print(temperature); + Serial.println("Β°C"); + } else { + Serial.println(" βœ— Failed to publish temperature"); + } + + // Publish humidity + char humPayload[50]; + snprintf(humPayload, sizeof(humPayload), "{\"value\":%.2f,\"unit\":\"%%\"}", humidity); + + if (mqttClient.publish(TOPIC_HUMIDITY, humPayload)) { + Serial.print(" πŸ“Š Published humidity: "); + Serial.print(humidity); + Serial.println("%"); + } else { + Serial.println(" βœ— Failed to publish humidity"); + } +}