ESP32-CAM应用(Micropython+Thonny)

0.废话前言

话说ESP32-CAM有多少人在用呢?

这种东西,属于是......

爱用不想用

虽然说扩展性很强,但是程序是真不爱写。

虽然说能联网,能拍照,但是FPS也太低了...

(话说ov2640是真的辣鸡)

那么回归主题

1.环境搭建

1-~.材料

材料清单
ESP32-CAM(带ov2640摄像头)
CH340 USB转TTL模块
两母头杜邦线
开关(焊有杜邦线,选配)

1-a.安装Thonny

很简单,去Thonny官方下载对于你的系统比较合适的版本,我这里用的是Windows的Python3.10版本,下的慢的可以看我的文章顶部的Thonny下载。

1-b.安装固件

打开Thonny,点击右下角的<No backend>(也有可能是别的):

点击<配置解释器>:

点击<安装或更新 MicroPython (esptool)>:

点击三个小横线(窗口左下角可能会报Error!不用管,我们用不到自带下载的固件):

点击<Select local MicroPython image>:

然后去下载Micropython ES32-CAM固件,国内的GitCode,各位应该能下,或者看文章顶部的资源。

回到刚才的选择文件,选择刚下的固件:

然后将ESP32-CAM连接到USB转TTL模块上,连接方法:

USB转TTL模块ESP32-CAM模块
5V5V
TXD/UOTRXD
RXD/UORTXD
GNDGND
特殊:ESP32-CAM的IO0GND

将USB转TTL模块接到电脑上:

打开设备管理器

查看端口号:

(端口号多数人不会一样)

单击安装:

然后就开始下载固件了:

过程比较慢,稍等一会就好了(如果TimeOut报错或者没有回应数据,就检查你的IO0有没有接到GND上并复位,就是那个复位小按键,接好后上电按下再试试):

完成后拔下IO0接GND的那根线,按下复位键或重新上电,再关闭其他弹窗,点击Thonny右下角的按钮,选择<MicroPython (ESP32) · USB Serial @ 你的端口号>:

 然后就好啦!

2.示例

2-a.拍照

import camera                    # 导入ESP32-CAM专用固件的特殊摄像库


camera.init(0, format=camera.JPEG, fb_location=camera.PSRAM) # 初始化摄像头,fb_location是设置存储在哪个临时RAM(camera.RAM和camera.PSRAM,PSRAM更大但有些设备不支持,可自行设置)

camera.quality(10)               # 设置质量,10为最好,63为最差
camera.framesize(camera.FRAME_SVGA) # 设置分辨率,见官方文档,FHD最佳(1920*1080),此处用到的为800*600
buf = camera.capture()           # 拍照(buf为图片二进制数据,不要晃动摄像头,快门需要时间)
camera.deinit()                  # 反初始化摄像头,释放临时RAM,防止再次运行此程序导致重复初始化报错或RAM占用过多报错
with open(f"Photo.jpg", "wb") as f: # 打开并覆盖文件
    f.write(buf)                 # 写入数据


# 温馨提示:有时初始化后第一张照片会偏色(我的是绿色)可以写程序再次拍照(再次拍照不用反初始化)
# 曝光不足也有可能偏色

2-b.录像

由于文件较大,使用了Micro SD卡,请提前插入Micro SD卡

声明一点:ESP32-CAM最好使用FAT32文件系统,格式化时选择,务必备份,本人不承担任何因为自行格式化导致数据丢失的责任!

.H264文件需要自行转为MP4,ESP32-CAM无法输出MP4

import camera
import time
from machine import SDCard

# 初始化相机
camera.init(0, format=camera.JPEG)

# 挂载 SD 卡(不需要可以注释掉)
uos.mount(SDCard(), '/sd')

# 设置相机参数
camera.framesize(camera.FRAME_SVGA)  # 设置分辨率
camera.quality(10)  # 设置图片质量

# 开始录像
camera.start_recording('/sd/video.h264')  # 指定录像文件路径(不要SD卡可以将"/sd"删除)

# 录像一段时间
time.sleep(10)

# 停止录像
camera.stop_recording()

# 释放资源
camera.deinit()
uos.umount('/sd')        # 不需要可以注释掉

2-c.网络服务器

别忘了改网络SSID和密码

import network
import socket
import camera
import image
import time

# 连接到Wi-Fi网络
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('SSID', 'Password')    # 改为你的网络SSID和密码
while not wlan.isconnected():
    time.sleep(1)

print('WiFi connected')
print('IP address:', wlan.ifconfig()[0])

# 初始化摄像头
camera.init(0, format=camera.JPEG)
camera.framesize(camera.QVGA)  # 设置分辨率为QVGA
camera.quality(90)  # 设置JPEG质量

# 创建Web服务器
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(1)
print('Listening on socket...')
conn, addr = s.accept()
print('Connected by', addr)

while True:
    # 捕获图像
    img = camera.capture()
    img_bytes = img.to_bytes()

    # 发送图像
    conn.send(img_bytes)

2-d.我自己做的微型相机

硬件:按钮两头一端接3.3V(有可能标为3V3,是ESP32-CAM模块上的),一头接IO12

为了防止内存爆炸与偏色,使用了闪光灯、第一次重复拍照以及次数限制(20张),不可使用SD卡,因为会与闪光灯冲突(顺手做了个板载指示灯)

不要忘记提前创建pic文件夹

from machine import Timer, Pin
import os
# enable station interface and connect to WiFi access point
import camera
import time

(ST_INIT, ST_READY, ST_BUSY) = (300, 0, 100)
num = 0
is_t = False

def toggle_led(led_pin):
    led_pin.value(not led_pin.value())

def led_blink_timed(timer, led_pin, state):
    if state == 'READY':
        timer.deinit()
        led_pin.value(ST_READY)
    elif state == 'INIT':
        timer.init(period=ST_INIT, mode=Timer.PERIODIC, callback=lambda t: toggle_led(led_pin))
    elif state == 'BUSY':
        timer.init(period=ST_BUSY, mode=Timer.PERIODIC, callback=lambda t: toggle_led(led_pin))
    else:
        print('not define yet')

# 声明引脚 D2 作为LED的引脚
led_pin = Pin(33, Pin.OUT)
lighter = Pin(4, Pin.OUT)
press = Pin(12, Pin.IN, Pin.PULL_DOWN)
timer = Timer(1)  # 创建定时器对象
# 定时器触发
led_blink_timed(timer, led_pin, state='INIT')

# camera.init(0, format=camera.JPEG, fb_location=camera.PSRAM)
# camera.quality(10)
# camera.framesize(camera.FRAME_SVGA)
led_blink_timed(timer, led_pin, state='READY')

def take_photo():
    camera.init(0, format=camera.JPEG, fb_location=camera.PSRAM)
    camera.quality(10)
    camera.framesize(camera.FRAME_SVGA )
    led_blink_timed(timer, led_pin, state='BUSY')
    global num
    if num >= 20:
        lighter.value(1)
        time.sleep(0.1)
        lighter.value(0)
        time.sleep(0.1)
        lighter.value(1)
        time.sleep(0.1)
        lighter.value(0)
        time.sleep(0.1)
        return
    if num == 0:
        lighter.value(1)
        time.sleep(0.1)
        buf = camera.capture()
        with open(f"Photo{num}.png", "wb") as f:
            f.write(buf)
        print("FA")
        camera.quality(10)
        camera.framesize(camera.FRAME_SVGA)
        time.sleep(0.1)
        buf = camera.capture()
        camera.deinit()
        with open(f"Photo{num}.png", "wb") as f:
            f.write(buf)
        print("Suc")
        num += 1
        time.sleep(0.3)
        lighter.value(0)
        led_blink_timed(timer, led_pin, state='READY')
        return
    lighter.value(1)
    time.sleep(0.1)
    buf = camera.capture()
    camera.deinit()
    with open(f"Photo{num}.png", "wb") as f:
        f.write(buf)
        print("Suc")
        num += 1
    time.sleep(0.3)
    lighter.value(0)
    led_blink_timed(timer, led_pin, state='READY')
    
def copy(std, tdd):
    with open(std, "rb") as fs:
        with open(tdd + "/" + std.split("/")[-1], "wb") as f:
            f.write(fs.read())

def cf(folder_path="./", extension="png", td="./pic"):
    for filename in os.listdir(folder_path):
        if filename.endswith(extension):
            file_path = folder_path + "/" + filename
            copy(file_path, "pic")
    
def df(folder_path="./", extension="png"):
    for filename in os.listdir(folder_path):
        if filename.endswith(extension):
            file_path = folder_path + "/" + filename
            os.remove(file_path)

df(folder_path="./pic")
cf()
df()
while True:
    if press.value() == 1:
        if is_t:
            continue
        take_photo()
        is_t = True
    else:
        is_t = False
        



3.总结

什么也没有......(多看官方文档!)

### 如何使用 Thonny IDE 开发 ESP32-CAM 项目 #### 准备工作 为了确保能够顺利通过 Thonny IDE 对 ESP32-CAM 进行开发,需确认硬件和软件环境已正确设置。 对于硬件部分,移除跳线帽并按下 reset 键可以重启 ESP32-CAM 设备[^1]。这一步骤有助于排除因不当连接引起的通信问题。 关于软件准备,在 Mac 上安装好 Thonny 后,应验证其能否成功识别并连接至 ESP32-CAM 中运行的 MicroPython 解释器。如果发现无法建立稳定连接,则可能是因为所使用的 ESP32-CAM 版本存在问题或是固件不兼容所致[^4]。 #### 配置 Thonny IDE 启动 Thonny 并进入解释器选项页面,选择 `MicroPython (ESP32)` 作为目标平台。此时应当能看到程序尝试自动检测串口设备列表中的可用端口,并允许从中挑选合适的 COM 口来完成后续操作。 当面对 "device is busy or does not respond" 提示时,建议先检查物理连线是否牢固以及波特率设定是否匹配默认值(通常是 115200 bps)。另外,也可以考虑重新刷写官方提供的最新版 MicroPython 固件文件给 ESP32-CAM 板卡,从而提高稳定性与兼容性表现。 #### 编程实践 一旦完成了上述准备工作之后就可以编写 Python 脚本来控制摄像头模块的功能特性了。下面给出一段用于捕捉图像并将数据保存为 JPEG 文件的小例子: ```python import machine, time from esp import EspCam cam = EspCam() # 初始化相机对象 time.sleep(2) try: cam.init() img_data = cam.capture_image() with open('photo.jpg', 'wb') as f: f.write(img_data) finally: cam.deinit() ``` 这段代码展示了如何初始化相机、获取图片帧并且将其存储下来的过程。需要注意的是实际应用过程中还需要处理更多细节比如调整分辨率参数等具体需求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值