Camera Pipeline API
Header: main/cam_lora.h
A FreeRTOS task that manages camera capture, LoRa transfer, motion detection, and remote command handling. This is the main application pipeline.
Configuration
Section titled “Configuration”cam_lora_config_t
Section titled “cam_lora_config_t”| Field | Type | Default | Description |
|---|---|---|---|
lora_dest | uint16_t | 0 | Base station LoRa address |
periodic_ms | uint32_t | 0 | Periodic capture interval in ms (0 = disabled) |
motion_enabled | bool | false | Enable motion detection trigger |
jpeg_quality | uint8_t | 12 | OV2640 JPEG quality (0–63, lower = better) |
Functions
Section titled “Functions”cam_lora_start
Section titled “cam_lora_start”esp_err_t cam_lora_start(const cam_lora_config_t *config);Initialize and start the camera-to-LoRa pipeline. Creates a FreeRTOS task (cam_lora, 8KB stack, priority 5) that:
- Initializes the camera (fake or real)
- Polls for LoRa commands every 100ms
- Checks periodic and motion triggers
- Captures and transfers JPEG images
Returns: ESP_OK on success, ESP_ERR_NO_MEM if task creation fails.
cam_lora_stop
Section titled “cam_lora_stop”void cam_lora_stop(void);Signal the pipeline task to stop. The task self-deletes on its next iteration.
cam_lora_trigger_capture
Section titled “cam_lora_trigger_capture”void cam_lora_trigger_capture(void);Request an immediate capture from outside the pipeline task. Sets an internal flag that the task checks on its next poll cycle.
cam_lora_get_capture_count
Section titled “cam_lora_get_capture_count”uint32_t cam_lora_get_capture_count(void);Returns the total number of successful captures since pipeline start.
cam_lora_is_running
Section titled “cam_lora_is_running”bool cam_lora_is_running(void);Check if the pipeline task is currently running.
Trigger modes
Section titled “Trigger modes”The task supports three capture triggers, evaluated in priority order:
1. On-demand (highest priority)
Section titled “1. On-demand (highest priority)”A remote C:CAPTURE command or call to cam_lora_trigger_capture() sets the capture_pending flag. The task processes this immediately on its next poll cycle.
2. Periodic
Section titled “2. Periodic”When periodic_ms > 0, the task captures at fixed intervals. An on-demand capture resets the periodic timer.
3. Motion detection
Section titled “3. Motion detection”When motion_enabled is true, the task grabs a camera frame every 2 seconds and feeds the JPEG size to motion_check(). If motion is detected (>15% size change with debounce), it triggers a capture.
Remote commands
Section titled “Remote commands”The task listens for LoRa packets and handles these commands:
| Command | Action |
|---|---|
C:CAPTURE | Set capture pending flag |
C:STATUS | Reply with S:HEAP=N:UP=N:RSSI=N:CAP=N:VER=X |
C:PING | Reply with S:PONG |
C:CONFIG:period=N | Set periodic interval (ms) |
C:CONFIG:motion=0|1 | Enable/disable motion detection |
C:CONFIG:threshold=N | Set motion threshold percentage |
Capture flow
Section titled “Capture flow”flowchart TD
A["cam_lora_capture_and_send()"] --> B["fake_camera_fb_get()<br/>Get JPEG framebuffer"]
B --> C["Copy JPEG to PSRAM<br/>Free camera buffer early"]
C --> D["fake_camera_fb_return()"]
D --> E["motion_check(jpeg_len)<br/>Feed motion detector"]
E --> F["xfer_send_image()<br/>Fragment + send over LoRa"]
F --> G["free(jpeg_copy)"]
The camera framebuffer is released as soon as the JPEG is copied to a PSRAM-backed buffer. This allows the camera to continue capturing while the LoRa transfer proceeds (transfers can take 10+ seconds).