站内搜索
发作品签到
专业版

#第九届立创电赛#ESP32S3摄像遥控小车

工程标签

3.3k
0
0
1

简介

ESP32S3摄像遥控小车具有地面移动摄像的功能,能用于开展农业作物观察、动植物观察、危险区域或无人区域探险、狭窄区域搜索、科学研究等活动。

简介:ESP32S3摄像遥控小车具有地面移动摄像的功能,能用于开展农业作物观察、动植物观察、危险区域或无人区域探险、狭窄区域搜索、科学研究等活动。
第九届立创电子设计开源大赛
复刻成本:100

开源协议

GPL 3.0

创建时间:2024-08-19 16:02:41更新时间:2024-11-01 19:47:08

描述

注:* 为必填项

请在报名阶段填写 ↓

 

* 1、项目功能介绍


最近在网上看到一款《废旧安卓手机暴改遥控坦克,支持画面传输,成品470元》的创意,这款遥控坦克是基于ESP32设计的,通过废旧安卓手机显示坦克拍摄的画面。如下图:

于是我们想着基于去年的ESP32-C3蓝牙小车,做一个蓝牙遥控的摄像小车,遥控和拍摄画面都通过微信小程序来实现,降低制作的难度和成本。

本项目基于立创·ESP32S3R8N8开发板、DRV8833直流电机驱动板、OV2640摄像头、OLED显示屏、锂电池、电机、橡胶轮等元件,成本不到100元(详见BOM表)。小车采用两路电源供电,具有低成本、静音、稳定、长续航等特点,适合中小学生学习、二次开发。

ESP32S3摄像遥控小车具有地面移动摄像的功能,能用于开展农业作物观察、动植物观察、危险区域或无人区域探险、狭窄区域搜索、科学研究等活动。比如我们就尝试开展了农田作物生长情况观察(详见视频)、寻找躲在床底下的猫猫(详见下图)、乐高城探险等应用测试(详见视频)。

*2、项目属性


本项目首次公开,为原创项目。

 

 

* 3、开源协议


使用GPL3.0开源协议。100%开源,便于中小学生学习和二次开发。

 

 

请在竞赛阶段填写 ↓

 

*4、硬件部分


1)主控芯片

采用立创·ESP32S3R8N8开发板,高性能随身WiFi与蓝牙开发板,所有资料全开源,丰富教程案例,轻松上手,项目式学习。支持以下功能:

详见官方文档:https://lckfb.com/project/detail/lckfb-esp32s3r8n8

 

2)电机驱动

采用一块国产小体积DRV8833电机驱动模块。

本项目采用橡胶轮,橡胶轮不能像麦克纳姆轮一样左右水平移动,左边的两个轮子和右边的两个轮子都是同向转动的,所以可以将左边两个电机并联组成一组,右边两个电机并联组成一组,只采用一块国产小体积DRV8833电机驱动模块驱动4个直流减速电机。

 

3)电源方案

采用两路电源方案,一路为ESP32S3开发板供电,一路为电机供电,避免互相干扰。特别是摄像头,需要更稳定的电压,当电压低时,图像会有水波纹。

ESP32S3开发板的供电参考《常用开发板的供电设计方案(3.3V、5V供电方案)》,直接将3.7V锂电池接入ESP32S3开发板的5V引脚,开发板会将3.7V降压到3.3V供MCU使用。

电机供电采用一个3.7V锂电池通过DRV8833直接供电,不需要降压。如果要让小车的速度更快,可以考虑采用2个3.7V锂电池供电,7.4V的电压能让小车速度更快。

因摄像头还需要用到2.8V和1.2V,所以增加了两路降压电路,分别采用XC6206P282MR、XC6206P122MR的LDO将3.3V降到2.8V和1.2V,供摄像头使用。

 

4)小车主板

因需要使用到OV2640摄像头,PCB板增加了不省贴片电容、电阻,以及LDO、SD卡等,增加了焊接难度。ESP32S3、DRV8833、OV2640摄像头等模块采用2.54排针固定,电池、电机采用XH2.54插件连接,方便焊接、组装,以及元件重复利用。

PCB板原理图如下:

PCB图:

焊接图:

PCB板焊接的难度在于那一排的贴片LDO、电容、电阻,其他都简单。

 

5)OV2640摄像头模块

包含三个模块:OV2640模块、转接板、M12镜头和镜头座。

这是我们做的一个开源工程,详见:https://oshwhub.com/cnas2023/camera-zhuan

摄像头转接板比较简单,只有一个24脚转接口和一个FPC接口。我们又在网上买了个镜头和镜头座,让摄像头拍摄的照片更清晰些。这块转接板是24脚的,没有去掉不用的引脚,适用于OV2640和OV5640,需要更高分辨率也可以用OV5640。

6)电机、橡胶轮、固定支架

某宝上买的,电机、车轮、固定支架各4个,不超过15元。

麦克纳姆轮具有随意改变行驶方向的特性,但稳定性较差,容易打滑,而且噪声较大。使用橡胶轮代替后,行驶稳定,且轮胎几乎没有噪声(噪声来自减速电机)。

7)电池

3.7V锂电池两颗,带XH2.54接线端子。我们用的是从坏的小米电动牙刷上拆下来的。

8)成果图

组装好的成品:

 

注:请前往嘉立创EDA 生成/上传设计文件,文件完成后,相关文稿将自动生成至项目详情;这里可以详细说明您的项目实现原理和机制、注意事项、调试方法、测试方法等。推荐图文并茂的形式向别人介绍您的想法。

 

*5、软件部分


 

1)遥控器(微信小程序)

我们开发的一个微信小程序,用来控制蓝牙小车行动并实时显示摄像头拍摄的画面。小程序二维码:

——小程序主界面

——小程序使用的UUID与Bluefruit Connect一致,默认是:

service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'

——小程序的6个按键,分别为上、下、左、右、A、B,按下按键分别向连接的蓝牙小车发送"upup"、"down"、"left"、"right"、"act1"、"bac2"。

——小程序的浏览窗口用于实时显示摄像头拍摄的画面,浏览窗口地址为"http://"+文本框输入的地址+":5000/video_feed"

小程序的操作详见视频。

 

2)小车程序(基于Micropython)

小车程序一共包含电机控制、摄像头、SD卡、OLED等模块,当接收到微信小程序发送的"upup"、"down"、"left"、"right"指令时,做出前进、后退、左转、右转的动作,当接收到"act1"指令时,拍摄一张照片并存储在SD卡上。

因小车需要使用蓝牙遥控,并使用WIFI进行图像传输,所以我们使用了双线程,分别控制,避免干扰。参考代码如下:

from machine import Pin,freq,SDCard,Timer,SoftI2C
from time import sleep_ms,sleep
import bluetooth,network,camera,_thread,ssd1306,ufont
from microdot import Microdot

# 设置CPU的工作频率为 240 MHz
freq(240000000)

# 初始化OLED
i2c = SoftI2C(scl=Pin(4), sda=Pin(5))          
display = ssd1306.SSD1306_I2C(128, 64, i2c)       # 定义oled
font = ufont.BMFont("unifont-14-12917-16.v3.bmf") # 定义字体库

# 初始化SD卡
sd = SDCard(
   slot=1 , width=1, cd=None, wp=None,
   sck=1,miso=3,mosi=2,
   cs=None ,freq=20000000
  )                                             #定义SD卡
os.mount(sd, '/sd')                               #挂载SD卡

# 初始化
BLE_MSG = ""
i=0

''' 定义小车电机引脚和动作函数 '''
Left0 = Pin(6,Pin.OUT)      # O6引脚,左前轮电机向前
Left1 = Pin(7,Pin.OUT)     # O7引脚,左前轮电机向后
Right0 = Pin(41,Pin.OUT)     # 41引脚,右前轮电机向前
Right1 = Pin(42,Pin.OUT)      # 42引脚,右前轮电机向后

# 车向前进
def cargo():
   Left1.value(1)
   Left0.value(0)
   Right1.value(1)
   Right0.value(0)
   
# 车向后退
def carback():    
   Left1.value(0)
   Left0.value(1)
   Right1.value(0)
   Right0.value(1)  
   
# 车停止
def carstop():
   Left1.value(0)
   Left0.value(0)
   Right1.value(0)
   Right0.value(0)

# 车向左转
def carleft():  
   Left1.value(0)
   Left0.value(1)
   Right1.value(1)
   Right0.value(0)  

# 车向右转
def carright():  
   Left1.value(1)
   Left0.value(0)
   Right1.value(0)
   Right0.value(1)
   
   
'''定义网页图传相关函数,以及一些定义'''
#拍照
def take_picture():
   global i
   i = i+1
   buf = camera.capture()
   with open('/sd/{}.jpg'.format(i),'wb') as f:
       f.write(buf)
   print("拍照成功!")
   sleep(0.01)

def connect():
   wlan = network.WLAN(network.STA_IF)# 定义模式为连接热点
   wlan.active(True)
   if not wlan.isconnected(): #是否连接热点
       wlan.connect('SSID', 'password')#连接网络,SSID和password改成目前的2.4G网络的名称(SSID)和密码(password)
       while not wlan.isconnected():
           pass
   

connect() # 联网
wlan = network.WLAN(network.STA_IF)# 定义模式为连接热点
ifconfig = wlan.ifconfig() # 获取网络信息
font.text(display, '请在浏览器打开:', 0, 0, show=True,clear=True, auto_wrap=True)
font.text(display, str('{}:5000'.format(ifconfig[0])), 0, 16,show=True, auto_wrap=True) # 提示网页图传的对应网址
app = Microdot() # 定义构建网站变量。


# 初始化摄像头
cam = camera.init(0, d0=38, d1=47, d2=14, d3=13, d4=12, d5=11, d6=10, d7=9,
       format=camera.JPEG, framesize=camera.FRAME_HVGA,fb_location=camera.PSRAM,
       xclk_freq=camera.XCLK_20MHz,
       href=18, vsync=17, reset=8, pwdn=-1,
       sioc=16, siod=15, xclk=40, pclk=39)#y2-d0
#调整camera参数        
camera.brightness(2)
camera.contrast(2)
camera.quality(10)
camera.speffect(camera.EFFECT_NONE)
#camera.whitebalance(camera.WB_CLOUDY)


# 定义网站html代码。
@app.route('/')
def index(request):
   return '''


  ESP32S3蓝牙小车网页图传
 


 

ESP32S3蓝牙小车网页图传:


 

''', 200, {'Content-Type': 'text/html; charset=utf-8'}

# 网页图传
@app.route('/video_feed')
def video_feed(request):
   def stream():
       yield b'--frame\r\n'
       while True:
           frame = camera.capture()
           yield b'Content-Type: image/jpeg\r\n\r\n' + frame + \
               b'\r\n--frame\r\n'
           

   return stream(), 200, {'Content-Type':
                          'multipart/x-mixed-replace; boundary=frame'}


class ESP32_BLE():
   #蓝牙初始化
   def __init__(self, name):
       self.led = Pin(48, Pin.OUT)     #配置LED灯引脚为输出模式
       self.timer1 = Timer(0)          #配置定时器
       self.name = name
       self.ble = bluetooth.BLE()      #创建蓝牙对象
       self.ble.active(True)           #开启蓝牙
       self.ble.config(gap_name=name)  #配置蓝牙信息
       self.disconnected()             #设置定时器中断
       self.ble.irq(self.ble_irq)      #蓝牙时间处理
       self.register()                 #配置蓝牙的uuid
       self.ble.gatts_write(self.rx, bytes(100))#默认蓝牙只接收20字节,这里更改为接收100字节
       self.advertiser()               #蓝牙广播
       self.ok = 0

   #蓝牙连接,关闭LED灯
   def connected(self):
       self.timer1.deinit()
       self.led.value(0)
       print("connected ok")

   #蓝牙未连接,LED闪烁
   def disconnected(self):        
       self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.value(not self.led.value()))

   #蓝牙事件处理
   def ble_irq(self, event, data):
       global BLE_MSG
       if event == 1: #_IRQ_CENTRAL_CONNECT 手机连接了此设备
           self.connected()
       elif event == 2: #_IRQ_CENTRAL_DISCONNECT 手机断开此设备
           if self.ok==0:
               self.advertiser()
               self.disconnected()
       elif event == 3: #_IRQ_GATTS_WRITE 手机发送了数据
           buffer = self.ble.gatts_read(self.rx)
           BLE_MSG = buffer.decode('UTF-8').strip()
           
   #蓝牙UUID配置
   def register(self):
       service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
       reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
       sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'

       services = (
          (
               bluetooth.UUID(service_uuid),
              (
                  (bluetooth.UUID(sender_uuid), bluetooth.FLAG_NOTIFY),
                  (bluetooth.UUID(reader_uuid), bluetooth.FLAG_WRITE),
              )
          ),
      )

      ((self.tx, self.rx,), ) = self.ble.gatts_register_services(services)


   #蓝牙广播配置
   def advertiser(self):
       name = bytes(self.name, 'UTF-8')
       adv_data = bytearray(b'\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name
       self.ble.gap_advertise(100, adv_data)
       print("等待连接:%s" % adv_data)
       print("\r\n")
       
       
'''定义线程1网页图传函数'''
def main_cam(*args, **kwargs):
   app.run(debug=True)#启动网页,并执行前面的网页图传相关函数
   

'''定义线程2蓝牙小车函数'''
def main_car(*args, **kwargs):
   global BLE_MSG,e
   
   try:
       # 车先待命
       carstop()
       
       # 配置蓝牙
       ble = ESP32_BLE("ESP32S3BLE")

       # 配置LED
       led = Pin(48, Pin.OUT)
     

       while True:
           if len(BLE_MSG)>0:
               if BLE_MSG in ["!B507","!B606","!B705","!B804","!B10;","!B20:","!B309","!B408","stop"]: #松开按键停止
                   print(">>%s<<————停止" % BLE_MSG)
                   carstop()
               elif BLE_MSG in ["!B516","upup"]:  # 按下小程序的上键向前
                   print(">>%s<<————向前" % BLE_MSG)
                   cargo()
               elif BLE_MSG in ["!B615","down"]:  # 按下小程序的下键向后
                   print(">>%s<<————向后" % BLE_MSG)
                   carback()
               elif BLE_MSG in ["!B714","left"]:  # 按下小程序的左键向左运动
                   print(">>%s<<————向左" % BLE_MSG)
                   carleft()
               elif BLE_MSG in ["!B813","right"]:  # 按下小程序的右键向右运动
                   print(">>%s<<————向右" % BLE_MSG)
                   carright()
               elif BLE_MSG in ["!B11:","act1"]:  # 按下小程序的A键拍照
                   print(">>%s<<————拍照" % BLE_MSG)
                   take_picture()
               BLE_MSG = ""
           sleep_ms(100)
       
   except KeyboardInterrupt:
       pass

'''定义主函数'''
def main():
   thread_1 = _thread.start_new_thread(main_cam, (None,)) #定义线程1
   thread_2 = _thread.start_new_thread(main_car, (None,)) #定义线程2
   

'''运行'''
if __name__ == "__main__":    
   try:        
       main()
   except KeyboardInterrupt: #当出现KeyboardInterrupt异常
       camera.deinit() #释放摄像头避免运行第二次出先错误提示
       print("ok")
       

相关驱动(microdot、ssd1306、ufont)详见附件。

小车遥控和摄像效果详见视频。

 

注:若您的项目涉及软件开发,请在附件上传对应的工程源码。这里可以详细说明您的软件流程图、功能模块框图、相关算法的解释或科普、源码结构、编译环境的搭建和配置、源码编译方法、程序烧录方法等。推荐图文并茂的形式向别人介绍您的想法。

 

*6、BOM清单


自己统计的费用表:

注:项目涉及的BOM清单。在嘉立创EDA 生成/上传设计文件后,BOM将自动生成至项目详情;建议包括型号、品牌、名称、封装、采购渠道、用途等内容。具体内容和形式应以表达清楚项目构成为准。

 

*7、大赛LOGO验证


 

* 8、演示您的项目并录制成视频上传


ESP32S3摄像遥控小车具有地面移动摄像的功能,能用于开展农业作物观察、动植物观察、危险区域或无人区域探险、狭窄区域搜索、科学研究等活动。比如我们就尝试开展了农田作物生长情况观察(详见视频)、寻找躲在床底下的猫猫(详见下图)、乐高城探险等应用测试(详见视频)。

 

前往查看更多详情 >

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

3D模型

序号文件名称下载次数
暂无数据

附件

序号文件名称下载次数
1
microdot.py
25
2
ssd1306.py
19
3
ufont.py
10
4
unifont-14-12917-16.v3.bmf
13
克隆工程
添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航