Skip to content

Commit f0d05ed

Browse files
authored
First release candidate (#4)
* Improvements in ESP-HAL * Minor improvements and update readme. Release candidate.
1 parent 1230d79 commit f0d05ed

File tree

3 files changed

+67
-59
lines changed

3 files changed

+67
-59
lines changed

.github/workflows/ESP32.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
name: Build MicroPython Camera for ESP32 Boards
1+
name: ESP32
22

33
on:
44
workflow_dispatch:
55
push:
6+
paths:
7+
- 'src/**'
68
pull_request:
79
branches:
810
- master
@@ -138,4 +140,4 @@ jobs:
138140
with:
139141
name: firmware-${{ matrix.board }}
140142
path: ~/${{ matrix.board }}.bin
141-
retention-days: 1
143+
retention-days: 90

README.md

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,55 @@
1-
# Camera API for micropython.
1+
# Camera API for micropython
2+
[![ESP32 Port](https://github.com/cnadler86/micropython-camera-API/actions/workflows/ESP32.yml/badge.svg)](https://github.com/cnadler86/micropython-camera-API/actions/workflows/ESP32.yml)
3+
24
This project aims to support cameras in different ports in micropython, starting with the ESP32-Port and omnivision (OV2640 & OV5640) cameras. The project implements a general API for cameras in micropython (such as circuitpython have done).
35
At the moment, this is a micropython user module, but it might get in the micropython repo in the future.
46
The API is stable, but it might change without previous anounce.
57

6-
## Precomiled FW (the easy way) (work in progress)
7-
If you are not familiar with building a custom firmware, you can go to the actions tab and start the build workflow by yourself. Then, you can download one of the generic FWs that suits your board.
8+
## Precomiled FW (the easy way)
9+
If you are not familiar with building a custom firmware, you can go to the [releases](https://github.com/cnadler86/micropython-camera-API/releases) page and download one of the generic FWs that suits your board.
10+
11+
## Using the API
12+
```python
13+
from camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling
14+
15+
# Camera construction and initialization
16+
camera = Camera(
17+
data_pins=[1,2,3,4,5,6,7,8],
18+
vsync_pin=9,
19+
href_pin=10,
20+
sda_pin=11,
21+
scl_pin=12,
22+
pclk_pin=13,
23+
xclk_pin=14,
24+
xclk_freq=20000000,
25+
powerdown_pin=-1,
26+
reset_pin=-1,
27+
pixel_format=PixelFormat.RGB565,
28+
frame_size=FrameSize.QVGA,
29+
jpeg_quality=15,
30+
fb_count=1,
31+
grab_mode=GrabMode.WHEN_EMPTY
32+
)
33+
34+
#Camera construction using defaults (if you specified them in mpconfigboard.h)
35+
camera = Camera()
36+
37+
# Capture image
38+
img = camera.capture()
39+
40+
# Camera reconfiguration
41+
camera.reconfigure(pixel_format=PixelFormat.JPEG,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST, fb_count=2)
42+
camera.set_quality(10)
43+
```
44+
45+
You can get and set sensor properties by the respective methods (e.g. camera.get_brightness() or camera.set_vflip(True). See autocompletitions in Thonny in order to see the list of methods.
46+
If you want more insides in the methods and what they actually do, you can find a very good documentation [here](https://docs.circuitpython.org/en/latest/shared-bindings/espcamera/index.html).
47+
Notice that for the methods in here you need to prefix a get/set, depending that you want to do.
848

9-
## Setup build environment (the DIY way)
49+
## Build your custom FW
50+
### Setup build environment (the DIY way)
1051
To build the project, follow the following instructions:
11-
- [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v5.2.2/esp32/get-started/index.html): I used version 5.2.2, but it might work with other versions.
52+
- [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v5.2.3/esp32/get-started/index.html): I used version 5.2.2, but it might work with other versions (see notes).
1253
- Clone the micropython repo and this repo in a folder, e.g. "MyESPCam". I used the actual micropython master branch (between v1.23 and before 1.24).
1354
- You will have to add the ESP32-Camera driver (I used v2.0.12). To do this, add the following to the respective idf_component.yml file (e.g. in micropython/ports/esp32/main_esp32s3/idf_component.yml):
1455
```
@@ -17,7 +58,7 @@ To build the project, follow the following instructions:
1758
```
1859
You can also clone the https://github.com/espressif/esp32-camera repository inside the esp-idf/components folder instead of altering the idf_component.yml file.
1960

20-
## Add camera configurations to your board (Optional, but recomended)
61+
### Add camera configurations to your board (Optional, but recomended)
2162
To make things easier, add the following lines to your board config-file "mpconfigboard.h" with the respective pins and camera parameters. Otherwise you will need to pass all parameters during construction.
2263
Don't forget the empty line at the buttom.
2364
Example for xiao sense:
@@ -46,52 +87,17 @@ Example for xiao sense:
4687
4788
```
4889

49-
## Build the API
90+
### Build the API
5091
To build the project, you could do it the following way:
5192

5293
```bash
5394
$ . <path2esp-idf>/esp-idf/export.sh
5495
$ cd MyESPCam/micropython/ports/esp32
55-
$ make USER_C_MODULES=../../../../mp_camera/src/micropython.cmake BOARD=<Your-Board> clean
56-
$ make USER_C_MODULES=../../../../mp_camera/src/micropython.cmake BOARD=<Your-Board> submodules
57-
$ make USER_C_MODULES=../../../../mp_camera/src/micropython.cmake BOARD=<Your-Board> all
96+
$ make USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=<Your-Board> clean
97+
$ make USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=<Your-Board> submodules
98+
$ make USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=<Your-Board> all
5899
```
59100
if you experience problems, visit [MicroPython external C modules](https://docs.micropython.org/en/latest/develop/cmodules.html).
60101

61-
## Using the API
62-
```python
63-
from camera import Camera, GrabMode, PixelFormat, FrameSize, GainCeiling
64-
65-
# Camera construction and initialization
66-
camera = Camera(
67-
data_pins=[1,2,3,4,5,6,7,8],
68-
vsync_pin=9,
69-
href_pin=10,
70-
sda_pin=11,
71-
scl_pin=12,
72-
pclk_pin=13,
73-
xclk_pin=14,
74-
xclk_freq=20000000,
75-
powerdown_pin=-1,
76-
reset_pin=-1,
77-
pixel_format=PixelFormat.RGB565,
78-
frame_size=FrameSize.QVGA,
79-
jpeg_quality=15,
80-
fb_count=1,
81-
grab_mode=GrabMode.WHEN_EMPTY
82-
)
83-
84-
#Camera construction using defaults (if you specified them in mpconfigboard.h)
85-
camera = Camera()
86-
87-
# Capture image
88-
img = camera.capture()
89-
90-
# Camera reconfiguration
91-
camera.reconfigure(pixel_format=PixelFormat.JPEG,frame_size=FrameSize.QVGA,grab_mode=GrabMode.LATEST, fb_count=2)
92-
camera.set_quality(10)
93-
```
94-
95-
You can get and set sensor properties by the respective methods (e.g. camera.get_brightness() or camera.set_vflip(True). See autocompletitions in Thonny in order to see the list of methods.
96-
If you want more insides in the methods and what they actually do, you can find a very good documentation [here](https://docs.circuitpython.org/en/latest/shared-bindings/espcamera/index.html).
97-
Notice that for the methods in here you need to prefix a get/set, depending that you want to do.
102+
## Notes
103+
If your target board is a ESP32, I recomend using IDF >= 5.2, since older versions may lead to IRAM overflow during build. Alternatively you can modify your sdkconfig-file (see [issue #1](https://github.com/cnadler86/micropython-camera-API/issues/1)).

src/modcamera.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,43 +31,42 @@
3131

3232
#define TAG "ESP32_MPY_CAMERA"
3333

34-
#if !CONFIG_SPIRAM //TODO: Better test if enought RAM is available on runtime?
34+
#if !CONFIG_SPIRAM
3535
#error Camera only works on boards configured with spiram
3636
#endif
3737

38-
//TODO: improve error message
3938
void raise_micropython_error_from_esp_err(esp_err_t err) {
4039
switch (err) {
4140
case ESP_OK:
4241
return;
4342

4443
case ESP_ERR_NO_MEM:
45-
mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("ESP_ERR_NO_MEM: Out of memory"));
44+
mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Out of memory"));
4645
break;
4746

4847
case ESP_ERR_INVALID_ARG:
49-
mp_raise_ValueError(MP_ERROR_TEXT("ESP_ERR_INVALID_ARG: Invalid argument"));
48+
mp_raise_ValueError(MP_ERROR_TEXT("Invalid argument"));
5049
break;
5150

5251
case ESP_ERR_INVALID_STATE:
53-
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("ESP_ERR_INVALID_STATE: Invalid state"));
52+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Invalid state"));
5453
break;
5554

5655
case ESP_ERR_NOT_FOUND:
57-
mp_raise_OSError(MP_ENOENT);
56+
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Camera not found"));
5857
break;
5958

6059
case ESP_ERR_NOT_SUPPORTED:
61-
mp_raise_NotImplementedError(MP_ERROR_TEXT("ESP_ERR_NOT_SUPPORTED: Operation not supported"));
60+
mp_raise_NotImplementedError(MP_ERROR_TEXT("Operation/Function not supported/implemented"));
6261
break;
6362

6463
case ESP_ERR_TIMEOUT:
6564
mp_raise_OSError(MP_ETIMEDOUT);
6665
break;
6766

6867
default:
69-
// mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("ESP_ERR: Unknown error 0x%04x"), err);
70-
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("ESP_ERR: Unknown error"));
68+
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Unknown error 0x%04x"), err);
69+
// mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Unknown error"));
7170
break;
7271
}
7372
}
@@ -151,6 +150,7 @@ void mp_camera_hal_deinit(mp_camera_obj_t *self) {
151150
esp_err_t err = esp_camera_deinit();
152151
raise_micropython_error_from_esp_err(err);
153152
self->initialized = false;
153+
ESP_LOGI(TAG, "Camera deinitialized");
154154
}
155155
}
156156

@@ -290,7 +290,7 @@ const mp_rom_map_elem_t mp_camera_hal_gainceiling_table[] = {
290290
{ MP_ROM_QSTR(MP_QSTR_128X), MP_ROM_INT(GAINCEILING_128X) },
291291
};
292292

293-
//OPEN: Makros with convertion function, since the API will use standarized values.
293+
//TODO: Makros with convertion function, since the API will use standarized values.
294294
// Helper functions to get and set camera and sensor information
295295
#define SENSOR_STATUS_GETSET_IN_RANGE(type, name, status_field_name, setter_function_name, min_val, max_val) \
296296
SENSOR_GETSET_IN_RANGE(type, name, status.status_field_name, setter_function_name, min_val, max_val)

0 commit comments

Comments
 (0)