Skip to content

Commit 3495aa7

Browse files
authored
Merge develop into master for mpy 1.27.0 release (#46)
- Add esp32-driver as submodule - Add property handles instead of get and set - Add i2c object to construction arguments (optional instead of sda and scl pins) - Add build script - Integrates legacy and new i2c driver option - Moved some files - Small bugs corrected Deprecated: get and set methos are deprecated.
1 parent ab114fa commit 3495aa7

File tree

16 files changed

+1042
-272
lines changed

16 files changed

+1042
-272
lines changed

.github/workflows/ESP32.yml

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -52,46 +52,37 @@ jobs:
5252
run: |
5353
sudo apt-get update
5454
sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
55-
55+
56+
# Clone MicroPython (if not cached)
57+
- name: Clone MicroPython
58+
id: clone-micropython
59+
if: steps.cache_esp_idf.outputs.cache-hit != 'true'
60+
run: |
61+
cd ~
62+
if [ "${{ github.ref }}" == "refs/heads/master" ]; then
63+
echo "Master branch detected - cloning MicroPython release: $MPY_RELEASE"
64+
git clone --depth 1 --branch ${{ env.MPY_RELEASE }} https://github.com/micropython/micropython.git
65+
else
66+
echo "Development branch detected - cloning latest MicroPython master"
67+
git clone --depth 1 https://github.com/micropython/micropython.git
68+
fi
69+
cd micropython
70+
cd mpy-cross
71+
make
72+
73+
echo "Micropython setup successfully"
74+
5675
# Download and set up ESP-IDF (if not cached)
5776
- name: Set up ESP-IDF
5877
id: export-idf
5978
if: steps.cache_esp_idf.outputs.cache-hit != 'true'
6079
run: |
6180
cd ~
62-
git clone --depth 1 --branch v5.4.2 https://github.com/espressif/esp-idf.git
63-
# git clone --depth 1 --branch ${{ env.IDF_VER }} https://github.com/espressif/esp-idf.git
81+
git clone --depth 1 --branch v5.5.1 https://github.com/espressif/esp-idf.git
6482
git -C esp-idf submodule update --init --recursive --filter=tree:0
6583
cd esp-idf
6684
./install.sh all
67-
cd components
68-
# latest_cam_driver=$(curl -s https://api.github.com/repos/espressif/esp32-camera/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
69-
# git clone --depth 1 --branch $latest_cam_driver https://github.com/espressif/esp32-camera.git
70-
git clone https://github.com/cnadler86/esp32-camera.git
71-
cd ~/esp-idf/
72-
source ./export.sh
73-
cd ~
74-
git clone https://github.com/espressif/esp-adf-libs.git
75-
cp -r ~/esp-adf-libs/esp_new_jpeg ~/esp-idf/components/
76-
77-
# Clone the latest MicroPython release (if not cached)
78-
- name: Clone MicroPython latest release
79-
id: clone-micropython
80-
if: steps.cache_esp_idf.outputs.cache-hit != 'true'
81-
run: |
82-
echo "Cloning MicroPython release: $MPY_RELEASE"
83-
cd ~/esp-idf/
8485
source ./export.sh
85-
cd ~
86-
git clone --depth 1 --branch ${{ env.MPY_RELEASE }} https://github.com/micropython/micropython.git
87-
cd micropython
88-
# git submodule update --init --depth 1
89-
cd mpy-cross
90-
make
91-
cd ~/micropython/ports/esp32
92-
make submodules
93-
echo "Micropython setup successfully"
94-
source ~/micropython/tools/ci.sh && echo "IDF_VER=$IDF_VER" >> $GITHUB_ENV
9586
9687
# Dynamically create jobs for each board
9788
build:
@@ -147,6 +138,8 @@ jobs:
147138

148139
- name: Checkout repository
149140
uses: actions/checkout@v4
141+
with:
142+
submodules: recursive
150143

151144
- name: Install ESP-IDF dependencies
152145
run: |
@@ -159,28 +152,32 @@ jobs:
159152
cd ${{ github.workspace }}
160153
cd ..
161154
git clone https://github.com/cnadler86/mp_jpeg.git
162-
cd ~/esp-idf/components/esp32-camera
163-
CAM_DRIVER=$(git describe --tags --always --dirty)
155+
# cd ~/esp32-camera
156+
# CAM_DRIVER=$(git describe --tags --always --dirty)
164157
cd ~/micropython/ports/esp32
165158
source ~/esp-idf/export.sh
166159
167160
# Check if a variant is defined and adjust the idf.py command
168161
IFS='@' read -r BUILD_TARGET CAMERA_MODEL <<< "${{ matrix.board }}"
169162
IFS='-' read -r BOARD_NAME BOARD_VARIANT <<< "${BUILD_TARGET}"
170163
164+
# Build command step by step
165+
IDF_CMD="idf.py -D MICROPY_BOARD=$BOARD_NAME -D USER_C_MODULES=${{ github.workspace }}/micropython.cmake -B build-$BUILD_TARGET -D EXTRA_COMPONENT_DIRS=${{ github.workspace }}"
166+
171167
if [ -n "${BOARD_VARIANT}" ]; then
172-
IDF_CMD="idf.py -D MICROPY_BOARD=$BOARD_NAME -D USER_C_MODULES=${{ github.workspace }}/src/micropython.cmake -D MICROPY_BOARD_VARIANT=$BOARD_VARIANT -B build-$BUILD_TARGET -D MP_CAMERA_DRIVER_VERSION=$CAM_DRIVER"
173-
else
174-
IDF_CMD="idf.py -D MICROPY_BOARD=$BOARD_NAME -D USER_C_MODULES=${{ github.workspace }}/src/micropython.cmake -B build-$BUILD_TARGET -D MP_CAMERA_DRIVER_VERSION=$CAM_DRIVER"
168+
IDF_CMD="${IDF_CMD} -D MICROPY_BOARD_VARIANT=$BOARD_VARIANT"
175169
fi
170+
176171
if [ -n "${CAMERA_MODEL}" ]; then
177172
echo "FW_NAME=${CAMERA_MODEL}" >> $GITHUB_ENV
178-
FINAL_CMD="${IDF_CMD} -D MICROPY_CAMERA_MODEL=${CAMERA_MODEL} build"
173+
IDF_CMD="${IDF_CMD} -D MICROPY_CAMERA_MODEL=${CAMERA_MODEL}"
179174
else
180175
echo "FW_NAME=${BUILD_TARGET}" >> $GITHUB_ENV
181-
FINAL_CMD="${IDF_CMD} build"
182176
fi
183-
make USER_C_MODULES=${{ github.workspace }}/src/micropython.cmake BOARD=$BOARD_NAME submodules
177+
178+
FINAL_CMD="${IDF_CMD} build"
179+
180+
make BOARD=$BOARD_NAME submodules
184181
echo "Running command: $FINAL_CMD"
185182
eval $FINAL_CMD
186183
cd ~/micropython/ports/esp32/build-${BUILD_TARGET}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#.vscode folder
77
.vscode/
88

9+
# Build
10+
/build/
11+
912
# User-specific files
1013
*.rsuser
1114
*.suo

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "esp32-camera"]
2+
path = esp32-camera
3+
url = https://github.com/cnadler86/esp32-camera.git

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# IDF component wrapper for micropython-camera-API user module
2+
# This allows the IDF component manager to process idf_component.yml
3+
# The actual MicroPython module is built via micropython.cmake
4+
5+
idf_component_register(
6+
REQUIRES esp32-camera
7+
)

README.md

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ If you want to play arround with AI, take a look at the [micropython binding for
2323
- [Freeing the buffer](#freeing-the-buffer)
2424
- [Is a frame available](#is-frame-available)
2525
- [Additional methods](#additional-methods)
26+
- [I2C Integration](#i2c-integration)
2627
- [Additional information](#additional-information)
2728
- [Build your custom firmware](#build-your-custom-firmware)
2829
- [Setting up the build environment (DIY method)](#setting-up-the-build-environment-diy-method)
@@ -209,6 +210,42 @@ import camera
209210
vers = camera.Version()
210211
```
211212

213+
### I2C Integration
214+
215+
The camera uses I2C (SCCB protocol) to communicate with the camera sensor. You can share this I2C bus with other devices by passing an external I2C object (SoftI2C not supported) to the camera:
216+
217+
#### Sharing I2C with Camera
218+
219+
```python
220+
import machine
221+
222+
# Create your own I2C object first
223+
i2c = machine.I2C(0, scl=22, sda=21, freq=400000)
224+
225+
# Pass it to the camera (no need for sda_pin/scl_pin)
226+
cam = camera.Camera(i2c=i2c, data_pins=..., pclk_pin=..., ...)
227+
228+
# The same I2C object can be used for other devices on the same bus!
229+
devices = i2c.scan()
230+
print(f"I2C devices found: {devices}")
231+
232+
# You can communicate with other I2C devices while camera is running
233+
i2c.writeto(0x42, b'\x00\x01') # Write to another device
234+
235+
# Camera sensor communication works too
236+
cam.set_saturation(1) # Uses the shared I2C bus
237+
```
238+
239+
#### Alternative: Camera Creates Its Own I2C (Default)
240+
241+
```python
242+
# Camera creates and manages its own I2C internally
243+
cam = camera.Camera(sda_pin=21, scl_pin=22, ...)
244+
245+
# In this mode, you cannot share I2C with other devices
246+
# Use the first method if you need to share I2C
247+
```
248+
212249
### Additional information
213250

214251
The firmware images support the following cameras out of the box, but is therefore big: OV7670, OV7725, OV2640, OV3660, OV5640, NT99141, GC2145, GC032A, GC0308, BF3005, BF20A6, SC030IOT
@@ -221,21 +258,19 @@ To build the project, follow these instructions:
221258

222259
- [ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/v5.2.3/esp32/get-started/index.html): I used version 5.2.3, but it might work with other versions (see notes).
223260
- Clone the micropython repo and this repo in a folder, e.g. "MyESPCam". MicroPython version 1.24 or higher is required (at least commit 92484d8).
224-
- You will have to add the ESP32-Camera driver from my fork. To do this, add the following to the respective idf_component.yml file (e.g. in micropython/ports/esp32/main_esp32s3/idf_component.yml):
261+
- You will have to add the ESP32-Camera driver. To do this, add the following to the respective idf_component.yml file (e.g. in micropython/ports/esp32/main/idf_component.yml):
225262

226263
```yml
227264
espressif/esp32-camera:
228265
git: https://github.com/cnadler86/esp32-camera.git
229266
```
230267
231-
Alternatively, you can clone the <https://github.com/cnadler86/esp32-camera> repository inside the esp-idf/components folder instead of altering the idf_component.yml file.
232-
233268
### Add camera configurations to your board (optional, but recommended)
234269
235270
#### Supported camera models
236271
237272
This project supports various boards with camera interface out of the box. You typically only need to add a single line to your board config file ("mpconfigboard.h).
238-
Example (don't forget to add the empty line at the bottom):
273+
Example:
239274
240275
```c
241276
#define MICROPY_CAMERA_MODEL_WROVER_KIT 1
@@ -303,17 +338,13 @@ If you also want to include the [mp_jpeg module](https://github.com/cnadler86/mp
303338

304339
### Build the API
305340

306-
To build the project, you could do it the following way:
341+
To build the project, just use the buils script with the path to your micropython folder:
307342

308343
```bash
309-
. <path2esp-idf>/esp-idf/export.sh
310-
cd MyESPCam/micropython/ports/esp32
311-
make USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=<Your-Board> clean
312-
make USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=<Your-Board> submodules
313-
make USER_C_MODULES=../../../../micropython-camera-API/src/micropython.cmake BOARD=<Your-Board> all
344+
./build.sh -m path/to/micropython -b ESP32_GENERIC_S3
314345
```
315346

316-
Micropython and camera-api folders are at the same level. Note that you need those extra "/../"s while been inside the esp32 port folder.
347+
Use `./build.sh -h` to see all available options.
317348
If you experience problems, visit [MicroPython external C modules](https://docs.micropython.org/en/latest/develop/cmodules.html).
318349

319350
## Notes

build.sh

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Default values
5+
IDF_PATH_DEFAULT="$HOME/esp/esp-idf"
6+
MICROPYTHON_PATH=""
7+
IDF_PATH="$IDF_PATH_DEFAULT"
8+
BOARD="ESP32_GENERIC_S3"
9+
BOARD_VARIANT=""
10+
CAMERA_MODEL=""
11+
BUILD_DIR="build-mp_camera"
12+
13+
# Parse arguments
14+
usage() {
15+
echo "Usage: $0 <micropython_path> [-i <idf_path>] [-b <board>] [-v <board_variant>] [-c <camera_model>]"
16+
echo ""
17+
echo "Arguments:"
18+
echo " <path> Path to MicroPython directory (required)"
19+
echo ""
20+
echo "Options:"
21+
echo " -i <path> Path to ESP-IDF directory (optional, default: $IDF_PATH_DEFAULT)"
22+
echo " -b <board> Board name (optional, e.g. ESP32_GENERIC_S3, default: $BOARD)"
23+
echo " -v <variant> Board variant (optional, e.g. SPIRAM_OCT)"
24+
echo " -c <model> Camera model (optional, e.g. FREENOVE_ESP32S3_CAM)"
25+
echo " -h Show this help message"
26+
echo ""
27+
echo "Examples:"
28+
echo " $0 ~/privat/micropython"
29+
echo " $0 ~/privat/micropython -i ~/esp/esp-idf"
30+
echo " $0 ~/privat/micropython -b ESP32_GENERIC_S3"
31+
echo " $0 ~/privat/micropython -b ESP32_GENERIC_S3 -v SPIRAM_OCT"
32+
echo " $0 ~/privat/micropython -b ESP32_GENERIC_S3 -c FREENOVE_ESP32S3_CAM"
33+
exit 1
34+
}
35+
36+
# Check required arguments first
37+
if [ -z "$1" ]; then
38+
echo "Error: MicroPython path is required as first argument"
39+
echo ""
40+
usage
41+
fi
42+
43+
MICROPYTHON_PATH="$1"
44+
shift
45+
46+
# Parse command line options
47+
while getopts "i:b:v:c:h" opt; do
48+
case $opt in
49+
i) IDF_PATH="$OPTARG" ;;
50+
b) BOARD="$OPTARG" ;;
51+
v) BOARD_VARIANT="$OPTARG" ;;
52+
c) CAMERA_MODEL="$OPTARG" ;;
53+
h) usage ;;
54+
*) usage ;;
55+
esac
56+
done
57+
58+
# Validate paths
59+
if [ ! -d "$MICROPYTHON_PATH" ]; then
60+
echo "Error: MicroPython directory not found: $MICROPYTHON_PATH"
61+
exit 1
62+
fi
63+
64+
if [ ! -d "$IDF_PATH" ]; then
65+
echo "Error: ESP-IDF directory not found: $IDF_PATH"
66+
exit 1
67+
fi
68+
69+
if [ ! -f "$IDF_PATH/export.sh" ]; then
70+
echo "Error: ESP-IDF export.sh not found in: $IDF_PATH"
71+
exit 1
72+
fi
73+
74+
# Get absolute paths
75+
MICROPYTHON_PATH=$(realpath "$MICROPYTHON_PATH")
76+
IDF_PATH=$(realpath "$IDF_PATH")
77+
MODULE_PATH=$(dirname "$(realpath "$0")")
78+
79+
echo "=========================================="
80+
echo "Building MicroPython with Camera Module"
81+
echo "=========================================="
82+
echo "MicroPython path: $MICROPYTHON_PATH"
83+
echo "ESP-IDF path: $IDF_PATH"
84+
echo "Module path: $MODULE_PATH"
85+
if [ -n "$BOARD" ]; then
86+
echo "Board: $BOARD"
87+
BUILD_DIR="${BUILD_DIR}-${BOARD}"
88+
if [ -n "$BOARD_VARIANT" ]; then
89+
echo "Board variant: $BOARD_VARIANT"
90+
BUILD_DIR="${BUILD_DIR}_${BOARD_VARIANT}"
91+
fi
92+
fi
93+
if [ -n "$CAMERA_MODEL" ]; then
94+
echo "Camera model: $CAMERA_MODEL"
95+
fi
96+
echo "Build directory: $BUILD_DIR"
97+
echo "=========================================="
98+
echo ""
99+
100+
# Source ESP-IDF environment
101+
echo "Setting up ESP-IDF environment..."
102+
source "$IDF_PATH/export.sh"
103+
104+
# Check and initialize camera API submodules if needed
105+
cd "$MODULE_PATH"
106+
if git submodule status | grep -q '^-'; then
107+
echo "Initializing camera API submodules ..."
108+
git submodule update --init --depth 1
109+
fi
110+
111+
# Change to MicroPython ESP32 port directory
112+
cd "$MICROPYTHON_PATH/ports/esp32"
113+
make BOARD=$BOARD submodules
114+
115+
# Build idf.py command with optional parameters
116+
IDF_CMD="idf.py -B $BUILD_DIR"
117+
118+
if [ -n "$BOARD" ]; then
119+
IDF_CMD="$IDF_CMD -D MICROPY_BOARD=$BOARD"
120+
fi
121+
122+
if [ -n "$BOARD_VARIANT" ]; then
123+
IDF_CMD="$IDF_CMD -D MICROPY_BOARD_VARIANT=$BOARD_VARIANT"
124+
fi
125+
126+
if [ -n "$CAMERA_MODEL" ]; then
127+
IDF_CMD="$IDF_CMD -D MICROPY_CAMERA_MODEL=$CAMERA_MODEL"
128+
fi
129+
130+
IDF_CMD="$IDF_CMD -D USER_C_MODULES=$MODULE_PATH/micropython.cmake"
131+
IDF_CMD="$IDF_CMD -D EXTRA_COMPONENT_DIRS=$MODULE_PATH"
132+
IDF_CMD="$IDF_CMD build"
133+
134+
# Build MicroPython with IR Learn module
135+
echo ""
136+
echo "Building MicroPython..."
137+
echo "Command: $IDF_CMD"
138+
eval $IDF_CMD
139+
140+
# Create firmware images
141+
echo ""
142+
echo "Creating firmware images..."
143+
cd "$BUILD_DIR"
144+
145+
python "$MICROPYTHON_PATH/ports/esp32/makeimg.py" \
146+
sdkconfig \
147+
bootloader/bootloader.bin \
148+
partition_table/partition-table.bin \
149+
micropython.bin \
150+
firmware.bin \
151+
micropython.uf2
152+
153+
echo ""
154+
echo "Build completed successfully!"
155+
echo "Firmware files in: $MICROPYTHON_PATH/ports/esp32/$BUILD_DIR"
156+
echo "=========================================="
157+
158+
# Clean up build directory
159+
cd "$MODULE_PATH"
160+
rm -rf build

esp32-camera

Submodule esp32-camera added at b9c5c51

0 commit comments

Comments
 (0)