适用于 Linux 的 Windows 子系统安装指南 (Windows 10)
注意:如果安装Ubuntu20.04LTS,需使用wsl,不要安装wsl2
$ sudo apt-get install git wget libncurses-dev flex bison gperf python3 python3-pip python3-setuptools python3-serial python3-click python3-cryptography python3-future python3-pyparsing python3-pyelftools cmake ninja-build ccache libffi-dev libssl-dev python-is-python3
我是用的v4.3的分支,v4.3以前的wifi会出现自动休眠的情况,具体情况为工作一段时间后出现:
E (234871) wifi:ieee80211_ioctl.c 1443
下载并安装编译工具:
$ mkdir ~/esp/ #创建安装目录
$ cd ~/esp/
$ git clone https://github.com/espressif/esp-idf.git #克隆idf
$ cd esp-idf
$ git checkout v4.3 #切换分支,或者使用md5 git checkout c9646ff0beffc86d2c6d1bfbad34da16e328e0e3
$ git submodule update --init --recursive #更新子模块
# 克隆并检出 IDF 到正确版本后,运行 install.sh脚本:
$ ./install.sh #安装工具
#此处python会报错,不用管它,那是python的问题,与此次项目无关,有兴趣的朋友可以自己解决
$ source export.sh #配置环境变量
更新工具时github下载慢的解决方案:
$ vi ~/esp/esp-idf/tools/tools.json
#将https://github.com全部替换成https://hub.fastgit.org
下载esp-idf工具的相机驱动
$ cd ~/esp/esp-idf/components
$ git clone https://github.com/espressif/esp32-camera #下载相机驱动
克隆micropython
$ cd ~/esp
$ git clone --recursive https://github.com/micropython/micropython.git #下载并更新子目录
由于官方的固件不带camera库,所以我们要手动配置,以便支持摄像头
下载micropython的camera
$ cd micropython/ports/esp32
$ git clone https://github.com/lemariva/micropython-camera-driver
将micropython-camera-driver文件夹中的文件复制到ports/esp32文件夹内
$ cp -r ~/esp/micropython/ports/esp32/micropython-camera-driver/* ~/esp/micropython/ports/esp32/
修改配置文件
#打开第一个文件
$ vi mpconfigport.h
# 在// extra built in modules to add to the list of known ones下加入
extern const struct _mp_obj_module_t mp_module_camera;
# 在#define MICROPY_PORT_BUILTIN_MODULES \下加入
{ MP_OBJ_NEW_QSTR(MP_QSTR_camera), (mp_obj_t)&mp_module_camera }, \
#打开第二个文件
$ vi main.c
修改 #if CONFIG_ESP32_SPIRAM_SUPPORT || CONFIG_SPIRAM_SUPPORT
至 #elif CONFIG_ESP32S2_SPIRAM_SUPPORT || CONFIG_ESP32S3_SPIRAM_SUPPORT
之间的代码替换如下:
size_t mp_task_heap_size;
mp_task_heap_size = 2 * 1024 * 1024;
void *mp_task_heap = malloc(mp_task_heap_size);
ESP_LOGI("main", "Allocated %dK for micropython heap at %p", mp_task_heap_size/1024, mp_task_heap);
#打开第三个文件
$ vi main/CMakeLists.txt
在set(IDF_COMPONENTS下添加:esp32-camera
在set(MICROPY_SOURCE_PORT下添加:${PROJECT_DIR}/modcamera.c
将一些内置脚本预编译为字节码
$ cd ~/esp/micropython
$ make -C mpy-cross
编译microPython固件
$ cd ~/esp/micropython/ports/esp32
$ make -j4 BOARD=GENERIC_CAM
#查看固件
$ cd ~/esp/micropython/ports/esp32/build-GENERIC_CAM
$ ls
固件名为firmware.bin,由bootloader.bin、partitions.bin 和 micropython.bin 组成
# 安装esptool.py
$ pip install esptool
# 擦除设备flash
$ esptool.py --chip esp32 --port (你的串口一般为COM3) erase_flash
#烧录
$ cd ~/esp/micropython/ports/esp32/build-GENERIC_CAM
$ esptool.py --chip esp32 --port (你的串口一般为COM3) --baud 460800 write_flash -z 0x1000 firmware.bin
使用串口工具连接板子(自行百度下载)
烧录后的板子内有个boot.py文件,可以将连接wifi和其它需要开机启动的脚本放在此处
创建一个main.py的文件,这个文件可以用来写设备工作的内容,比如下方的拍照及图传
系统的执行顺序为boot.py->main.py
连接wifi
# 连接wifi
import network
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
# 扫描wifi
sta_if.scan()
# 连接wifi
sta_if.connect("WIFI名", "密码")
# 查看连接状态
sta_if.isconnected()
拍照
import camera
#ESP32-CAM(默认配置)
camera.init(0, format=camera.JPEG)
#其他设置:
#上翻下翻
camera.flip(0)
#左/右
camera.mirror(1)
# 分辨率
camera.framesize(camera.FRAME_SVGA)
# 选项如下:
# FRAME_96X96 FRAME_QQVGA FRAME_QCIF FRAME_HQVGA FRAME_240X240
# FRAME_QVGA FRAME_CIF FRAME_HVGA FRAME_VGA FRAME_SVGA
# FRAME_XGA FRAME_HD FRAME_SXGA FRAME_UXGA FRAME_FHD
# FRAME_P_HD FRAME_P_3MP FRAME_QXGA FRAME_QHD FRAME_WQXGA
# FRAME_P_FHD FRAME_QSXGA
# 有关详细信息,请查看此链接:https://bit.ly/2YOzizz
#特效
camera.speffect(camera.EFFECT_NONE)
#选项如下:
# 效果\无(默认)效果\负效果\ BW效果\红色效果\绿色效果\蓝色效果\复古效果
# EFFECT_NONE (default) EFFECT_NEG \EFFECT_BW\ EFFECT_RED\ EFFECT_GREEN\ EFFECT_BLUE\ EFFECT_RETRO
#白平衡
camera.whitebalance(camera.WB_HOME)
#选项如下:
# WB_NONE (default) WB_SUNNY WB_CLOUDY WB_OFFICE WB_HOME
#饱和
camera.saturation(0)
#-2,2(默认为0). -2灰度
# -2,2 (default 0). -2 grayscale
#亮度
camera.brightness(0)
#-2,2(默认为0). 2亮度
# -2,2 (default 0). 2 brightness
#对比度
camera.contrast(0)
#-2,2(默认为0).2高对比度
#-2,2 (default 0). 2 highcontrast
#质量
camera.quality(10)
#10-63数字越小质量越高
#拍照,buf为jpg二进制数据,可以直接存储为jpg
buf = camera.capture()
传输,使用socket UDP方式
# 客户端(esp32 cam)
import socket
#服务端地址和端口,127.0.0.1改成你的服务端地址
ADDR = ('127.0.0.1',10086)
print ("发送UDP包...")
#socket连接
sendSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
#拍照发送
while True:
buf = camera.capture()
#发送数据
sendSock.sendto(buf,ADDR)
print ("发送完毕...")
#关闭socket连接
sendSock.close()
#服务端
import socket,time
# 客户端ip及端口,为空则接收任意客户端发来的数据
ADDR = ('',10086)
recvSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
recvSock.bind(ADDR)
# 这里时间戳用来命名图片文件
time_e = int(time.time())
# 当前时间戳的第N帧
zz = 0
#总帧数,此次为测试,可具体参考帧数来设置(我测试的效果大概为每秒6帧,录制20s,所以达到120张照片停止循环)
num = 0
print ("等待数据...")
while True:
#接收的数据大小,建议比图片本身大,不然无法传输
data = recvSock.recv(100000)
#每次检查时间戳
time_b = int(time.time())
#每次循环帧数加1
zz = zz + 1
#如果时间戳+1秒,则帧数序号归零
if time_b != time_e:
time_e = time_b
zz = 0
#存储图片
filename = str(time_e) + str(zz) + '.jpg'
with open (filename,'wb') as f :
f.write(data)
f.close()
print(filename)
#总帧数
num = num + 1
if num == 120:
break
#将图片合成视频
import os,cv2
pic_path = '.'
pics_list = [i for i in os.listdir(pic_path) if i.endswith('.jpg')]
fps = 7 # 帧率,自行参考文件命名,我的大概是7
size = (800, 600) # 视频尺寸,请根据图片实际尺寸设置,不然无法合成,SVGA为800*600
out_file_name = '{0}.mp4'.format('示例视频') # 输出视频名称
out_path = '.' # 输出视频路径
out_file = os.path.join(out_path, out_file_name)
fourcc = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
video = cv2.VideoWriter(out_file, fourcc, fps, size)
for item in pics_list:
item = out_path + '/' + item
img = cv2.imread(item)
video.write(img)
video.release()
接下来可以播放视频测试效果了,项目还在开发中,上述只为测试效果,请勿用于生产环境,关于UDP发送乱序的问题,可以将包编序,以字典的方式发送
另,官版固件不自带urequests,需要自行安装
# 使用upip安装
import upip
upip.install("urequests")
测试urequests
import urequests
urequests.get('https://www.baidu.com').text
欢迎指正
end.