Skip to content

Commit

Permalink
Merge pull request #23 from hpsaturn/generic_camera
Browse files Browse the repository at this point in the history
added generic camera sample for custom cameras
  • Loading branch information
hpsaturn authored Apr 28, 2024
2 parents 765ae4a + b84accb commit c5bcd54
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 18 deletions.
85 changes: 67 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,66 @@ For `Arduino IDE` is a little bit more complicated because the Arduino IDE depen

Note: Nanobp is not included as a dependency because, despite being 25 years after the invention of symbolic links, Arduino IDE does not support these types of files. Consider exploring PlatformIO for your future developments, as it offers a more versatile and modern development environment.

## Examples and Tests
## Usage

**To send** any kind of data, you only need a buffer and the size to send:

```cpp
ESPNowCam radio;

radio.init();
radio.sendData(out_jpg, out_jpg_len);
```

**To receive** the data, you only need to define a buffer and callback:

```cpp
radio.setRecvBuffer(fb);
radio.setRecvCallback(onDataReady);
radio.init();
```

```cpp
void onDataReady(uint32_t lenght) {
tft.drawJpg(fb, lenght , 0, 0, dw, dh);
}
```
It is also possible to define a specific target:
```cpp
uint8_t macRecv[6] = {0xB8,0xF0,0x09,0xC6,0x0E,0xCC};
radio.setTarget(macRecv);
radio.init();
```

**Predefined drivers:**

The library includes some pre-defined camera configs to have an easy implementation, for example:

```cpp
#include <ESPNowCam.h>
#include <drivers/CamFreenove.h>

CamFreenove Camera;
```

for now, it includes drivers for FreenoveS3, XIAOS3, and the TTGO T-Journal cameras, but you are able to define your custom camera like is shown in the [custom-camera-sender](examples/custom-camera-sender/) example. If you can run it in a different camera, please notify me :D

## Examples

[![video demo](https://raw.githubusercontent.com/hpsaturn/esp32s3-cam/master/pictures/youtube.jpg)](https://youtu.be/nhLr7XEUdfU)
[[video]](https://youtu.be/nhLr7XEUdfU)

| ENV Name | Target | Status |
|:-----------------|:--------------:|:----------:|
| tjournal-espnow-sender | ESPNow camera transmitter (QVGA) | TESTING |
| freenove-basic-sender | ESPNow camera transmitter (QVGA) | STABLE |
| freenove-hvga-sender | ESPNow camera transmitter (HVGA) | <6 FPS |
| freenove-nojpg-sender | ESPNow camera transmitter (NOJPG) | DEMO ONLY (<2FPS) |
| freenove-tank | Advanced sample. Sender/Receiver | TESTING |
| xiao-espnow-sender | ESPNow camera transmitter (QVGA) | STABLE |
| xiao-fpv-sender | Power ON/OFF improvement (QVGA) | STABLE |
| tjournal-espnow-sender | Camera without PSRAM (QVGA) | TESTING |
| freenove-tank | Advanced sample. Sender/Receiver | TESTING |
| m5core2-basic-receiver | Video receiver via ESPNow [1] | STABLE |
| m5core2-espnow-receiver | Video receiver via ESPNow [1] | STABLE |
| m5cores3-espnow-receiver | Video receiver via ESPNow [1] | STABLE|
Expand All @@ -87,6 +134,23 @@ pio run -e m5cores3-espnow-receiver --target upload

Some examples, only needs run `pio run --target upload` into each directory

## ESPNow Transmitter and Receiver

The last version has many improvements, and right now is very stable. For now, it supports one transmitter and multiple receivers in real time using broadcast, and also P2P connections using MAC address. It is possible, using IDs, uses of multiple sources to one receiver.

[![ESPNow Camera Video](https://raw.githubusercontent.com/hpsaturn/esp32s3-cam/master/pictures/espnow_video.gif)](https://youtu.be/zXIzP1TGlpA)
[[video]](https://youtu.be/zXIzP1TGlpA)

## Troubleshooting

The **Freenove camera** sometimes needs good power cable and also takes some seconds to stabilization, that means, that not worries for initial video glitches.

The **XIAO camera** experiences thermal issues; after a few minutes, it may stop transmission and won't restart it until it's cooled down.

For **Arduino IDE users**, if you have a compiling error, maybe you forget install NanoPb library. Please see above.

This project was developed and thoroughly tested on PlatformIO. While I did compile and execute it successfully on Arduino IDE using Espressif 2.0.11 and Arduino IDE 2.2.1, with PSRAM enabled, I generally avoid using Arduino IDE due to its tendency to mix everything and its buggy nature. Therefore, **I highly recommend using PlatformIO** for a smoother and more reliable development experience.

## Tested devices

**Cameras:**
Expand Down Expand Up @@ -114,22 +178,7 @@ Some examples, only needs run `pio run --target upload` into each directory
- [ ] Add callback to Radio send action. issue #20
- [ ] Migration to esp_wifi_80211_tx() to improve Payload and Quality

## ESPNow Transmitter and Receiver

The last version has many improvements, and right now is very stable. For now, it supports one transmitter and multiple receivers in real time using broadcast, and also P2P connections using MAC address. It is possible, using IDs, uses of multiple sources to one receiver.

[![ESPNow Camera Video](https://raw.githubusercontent.com/hpsaturn/esp32s3-cam/master/pictures/espnow_video.gif)](https://youtu.be/zXIzP1TGlpA)
[[video]](https://youtu.be/zXIzP1TGlpA)

## Troubleshooting

The **Freenove camera** sometimes needs good power cable and also takes some seconds to stabilization, that means, that not worries for initial video glitches.

The **XIAO camera** experiences thermal issues; after a few minutes, it may stop transmission and won't restart it until it's cooled down.

For **Arduino IDE users**, if you have a compiling error, maybe you forget install NanoPb library. Please see above.

This project was developed and thoroughly tested on PlatformIO. While I did compile and execute it successfully on Arduino IDE using Espressif 2.0.11 and Arduino IDE 2.2.1, with PSRAM enabled, I generally avoid using Arduino IDE due to its tendency to mix everything and its buggy nature. Therefore, **I highly recommend using PlatformIO** for a smoother and more reliable development experience.

## Credits

Expand Down
120 changes: 120 additions & 0 deletions examples/custom-camera-sender/custom-camera-sender.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**************************************************
* ESPNowCam video Transmitter
* by @hpsaturn Copyright (C) 2024
* This file is part ESP32S3 camera tests project:
* https://github.com/hpsaturn/esp32s3-cam
**************************************************/

#include <Arduino.h>
#include <esp_camera.h>
#include <ESPNowCam.h>
#include <Utils.h>

ESPNowCam radio;
camera_fb_t* fb;

bool has_psram = false;

camera_config_t camera_config = {
.pin_pwdn = -1,
.pin_reset = 15,
.pin_xclk = 27,
.pin_sscb_sda = 25,
.pin_sscb_scl = 23,
.pin_d7 = 19,
.pin_d6 = 36,
.pin_d5 = 18,
.pin_d4 = 39,
.pin_d3 = 5,
.pin_d2 = 34,
.pin_d1 = 35,
.pin_d0 = 17,
.pin_vsync = 22,
.pin_href = 26,
.pin_pclk = 21,

.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,

.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_QVGA,
.jpeg_quality = 12,
.fb_count = 1,
.fb_location = CAMERA_FB_IN_DRAM,
.grab_mode = CAMERA_GRAB_WHEN_EMPTY,
};

bool CameraBegin() {
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
return false;
}
return true;
}

bool CameraGet() {
fb = esp_camera_fb_get();
if (!fb) {
return false;
}
return true;
}

bool CameraFree() {
if (fb) {
esp_camera_fb_return(fb);
return true;
}
return false;
}

void processFrame() {
if (CameraGet()) {
if (has_psram) {
uint8_t *out_jpg = NULL;
size_t out_jpg_len = 0;
frame2jpg(fb, 12, &out_jpg, &out_jpg_len);
radio.sendData(out_jpg, out_jpg_len);
free(out_jpg);
}
else{
radio.sendData(fb->buf, fb->len);
delay(30); // ==> weird delay for cameras without PSRAM
}
printFPS("CAM:");
CameraFree();
}
}

void setup() {
Serial.begin(115200);

delay(5000); // only for debugging

if(psramFound()){
has_psram = true;
size_t psram_size = esp_spiram_get_size() / 1048576;
Serial.printf("PSRAM size: %dMb\r\n", psram_size);
// suggested config with PSRAM
camera_config.pixel_format = PIXFORMAT_RGB565;
camera_config.fb_location = CAMERA_FB_IN_PSRAM;
camera_config.fb_count = 2;
}
else{
Serial.println("PSRAM not found! Basic framebuffer setup.");
}

radio.init();

if (!CameraBegin()) {
Serial.println("Camera Init Fail");
delay(1000);
ESP.restart();
}
delay(500);
}

void loop() {
processFrame();
}
6 changes: 6 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ build_src_filter = -<*> -<*common*> +<tjournal-espnow-sender/>
build_flags =
-D CORE_DEBUG_LEVEL=0

[env:custom-camera-sender]
platform = espressif32 @ 4.4.0
extends = env
board = esp32dev
build_src_filter = -<*> -<*common*> +<custom-camera-sender/>

[m5cores3_common]
extends = esp32common
lib_deps =
Expand Down

0 comments on commit c5bcd54

Please sign in to comment.