# Hello Web Camera Example This example demonstrates a web camera server that streams camera images via HTTP MJPEG stream and provides camera control through a web interface. ## Features - Camera initialization using CUBE32 camera driver - WiFi connection using the credentials set from the mobile app over BLE OTA (stored in NVS), with the Kconfig settings as fallback - HTTP server for camera control (port 80) - MJPEG streaming server (port 81) - Camera settings control via web interface (resolution, quality, brightness, contrast, etc.) - LVGL status screen showing connection status, IP address, client count and camera info; the layout adapts to the screen size (18 pt title and 14 pt text on 240 px displays, 24 pt and 18 pt on the 320×320 display). Without LVGL the example runs console-only ## Required Kconfig Settings ### Camera Configuration Navigate to `CUBE32 Camera Configuration` in menuconfig: | Setting | Required Value | Notes | |---------|----------------|-------| | **Enable Camera Driver** | `y` (enabled) | Must be enabled | | **Camera Frame Size** | **≥ 800x600 (SVGA)** | Minimum recommended for web streaming. Higher resolutions (XGA, SXGA) require this initial allocation to avoid frame buffer overflow when changing resolution via web UI. | | **Camera Pixel Format** | **JPEG** | Required for MJPEG streaming. RGB565 will not work. | | H Mirror | Optional | Enable if image appears horizontally flipped | | V Flip | Optional | Enable if image appears vertically flipped | > ⚠️ **Important**: The initial frame size in Kconfig determines the frame buffer allocation. If you want to use higher resolutions (e.g., 1024x768 or 1280x1024) via the web interface, you **must** set the initial frame size to at least that resolution or higher. Otherwise, you will encounter "FB-OVF" (Frame Buffer Overflow) errors. ### Display Configuration The status screen needs LVGL and the fonts below (the release `sdkconfig.defaults` already has them; in the dev project they are listed in `sdkconfig.required`): | Setting | Why | |---------|-----| | `CONFIG_CUBE32_LVGL_ENABLED=y`, `CONFIG_CUBE32_TOUCH_ENABLED=y` | LVGL display driver (ST7789 240×320 or ST7796S 320×320, auto-detected) | | `CONFIG_LV_FONT_MONTSERRAT_18=y` / `_24=y` | Title on 240 px / 320 px displays | | `CONFIG_LV_FONT_MONTSERRAT_14=y` / `_18=y` | Body text on 240 px / 320 px displays | | `CONFIG_LV_FONT_MONTSERRAT_10/20=y` | Required by the BLE OTA UI whenever LVGL is on | ### WiFi Configuration WiFi credentials set from the CUBE32 mobile app over BLE OTA are stored in NVS and used first. The menuconfig values are the fallback when no credentials are stored in NVS (the log shows `WiFi credentials: NVS` or `sdkconfig fallback`). Navigate to `CUBE32 WiFi Configuration` in menuconfig: | Setting | Description | |---------|-------------| | WiFi SSID (fallback) | Your WiFi network name | | WiFi Password (fallback) | Your WiFi password | | Maximum retry | Number of connection retries (default: 5) | ## How to Configure 1. Run menuconfig: ```bash idf.py menuconfig ``` 2. Configure Camera: - Go to `Component config` → `CUBE32 Camera Configuration` - Enable `Enable Camera Driver` - Set `Camera Frame Size` to `SVGA (800x600)` or higher (recommended: `XGA (1024x768)`) - Set `Camera Pixel Format` to `JPEG` 3. Configure WiFi (optional, set the credentials from the mobile app over BLE OTA instead, or as the fallback here): - Go to `CUBE32 WiFi Configuration` - Enter your WiFi SSID and Password (fallback) 4. Select this example: - Go to `CUBE32 Application Selection` - Select `Hello Web Camera Example` 5. Build and flash: ```bash idf.py build flash monitor ``` ## Usage 1. After flashing, the device will connect to your WiFi network 2. Check the console output or LVGL display for the IP address 3. Open a web browser and navigate to `http://<IP_ADDRESS>/` 4. The web interface allows you to: - View live camera stream - Change resolution (up to the initially configured frame size) - Adjust quality (10-63, lower is better quality) - Control brightness, contrast, saturation - Enable/disable horizontal mirror and vertical flip - Toggle various camera effects ## Web Interface Endpoints | Endpoint | Port | Method | Description | |----------|------|--------|-------------| | `/` | 80 | GET | Camera control web interface | | `/status` | 80 | GET | Get current camera settings (JSON) | | `/control` | 80 | POST | Set camera parameter | | `/ping` | 80 | GET | Connection test | | `/stream` | 81 | GET | MJPEG video stream | ## Troubleshooting ### Stream stops at high resolution - **Cause**: Frame buffer was allocated for a smaller size than requested - **Solution**: Set `Camera Frame Size` in Kconfig to the maximum resolution you want to use ### "FB-OVF" (Frame Buffer Overflow) error - **Cause**: Camera produces frames faster than they can be processed - **Solution**: 1. Increase initial frame size in Kconfig 2. Reduce JPEG quality (higher number = faster encoding) ### "NO-EOI" (No End Of Image) error - **Cause**: JPEG encoder failed to complete frame - **Solution**: Reduce resolution or increase JPEG quality number ### Camera capture failed - **Cause**: Camera not properly initialized or I2C communication issue - **Solution**: 1. Check camera hardware connections 2. Ensure I2C bus is properly initialized 3. Check power supply to camera module ### Web interface shows wrong resolution - **Cause**: Outdated camera_index.h with incorrect framesize enum values - **Solution**: Ensure using the latest camera_index.h with correct FRAMESIZE enum mappings ## Display Information The display (any supported size, 240×240 up to 320×320) shows: - Title: "CUBE32 Web Camera" - Status: WiFi connection status - IP: Device IP address - Clients: Number of active stream clients - Camera: Resolution and format (e.g., "1024x768 JPEG") ## Memory Requirements - PSRAM: Required for camera frame buffers - Heap: ~50KB for HTTP servers and tasks - Stack: 8KB for HTTP server task ## Example Console Output ``` I (1234) hello_web_cam: ======================================== I (1234) hello_web_cam: CUBE32 Hello Web Camera Example I (1234) hello_web_cam: ======================================== I (1345) cube32_camera: Camera initialized successfully I (1456) hello_web_cam: Camera initialized with JPEG format for streaming I (1567) hello_web_cam: Camera capture test OK: 1024x768, 45678 bytes I (1678) hello_web_cam: Connecting to WiFi: MyNetwork I (2345) hello_web_cam: Got IP: 192.168.1.100 I (2456) hello_web_cam: Starting HTTP servers... I (2567) hello_web_cam: Control Server started I (2678) hello_web_cam: Stream Server started I (2789) hello_web_cam: ======================================== I (2789) hello_web_cam: Web Camera Server Ready! I (2789) hello_web_cam: Open http://192.168.1.100/ in browser I (2789) hello_web_cam: Stream: http://192.168.1.100:81/stream I (2789) hello_web_cam: ======================================== ```
To create a project from this example, run:
idf.py create-project-from-example "cube32esp/cube32_bsp=0.0.17:hello_web_cam"