基于esp32s2实现网页远程遥控装置
本项目基于esp32s2,使用arduino框架,并借助python代码作为中继器,实现了远程控制点击网页按钮。
标签
嵌入式系统
网络与通信
2022寒假在家练
sytnocui
更新2022-03-02
哈尔滨工业大学
2650

1 项目需求

项目8 远程遥控

  • 利用板上的红外接收器,用遥控器控制网页界面上的按钮

2 完成的功能2.1 接收红外遥控信号

FjLduln8dkqwqhBRLqfJMiiIkoA_

2.2 UDP通信

Fpl6s2qUgliFngQFOZ5UZmfjES6H

2.3 python图像识别自动点击网页

Ft2c_DQc63MP-CmtTOWW8s9XKkSj

(注:图为程序自动点击,无手动操作,详情请参考b站视频)

3 实现思路

  • esp32采用arduino框架进行开发,可调用开源的接收红外信号库,仿照例程可获取红外遥控器发出的信号。

  • 使esp32连入局域网(可为PC端分享的热点),使esp32发送UDP请求并由PC端接收,即可向PC端传递红外信号信息。

  • PC端需要有中继器解析UDP信息,并控制鼠标移动,这部分功能使用python实现。

4 实现过程4.1 程序架构图

Fue-r4mh-6Y6DZGkhVscB_VZmoW4

4.2 环境配置-esp32部分

由于arduino开发具有调用函数方便,结构清晰,硬件配置简单等优点,项目采用arduino进行开发。

arduino-esp32s2环境配置教程参考了硬核学堂的培训教程:【课程】基于ESP32-S2模块的物联网/音频信号处理平台 (eetree.cn)。注意esp32与esp32s2的环境配置方法不太一样,使用esp32的环境会导致软件开发出现问题,最好参考上述视频链接进行配置。

(注:我在项目配置时,使用Arduino IDE,即Arduino2.0 配置时,存在卡死在启动页面无法进入的情况,如果读者也出现这种情况可以在Ardunio1.8环境下进行配置,步骤基本相同)

配置好后,需要在库管理器中安装IRremote库,如下所示。

FgQkcKDsO-QiUHc50aFc7TUhmWDw

然后选择开发板为ESP32S2 Dev Module,并选择相应的端口,即可烧录程序

4.3 环境配置-python部分

python环境配置部分可参考附件中/esp-web-remote/py_remote/使用说明书1.docx 文件,该文件为b站up主不高兴就喝水撰写的,包括安装python与下载python关于图像识别的包——pyautogui。

另外,该文件夹中waterRPA.py文件是不高兴就喝水给的例程,供参考。udpRPA.py是我在其基础上修改得到的最终文件,复现时请运行udpRPA.py。

4.4 接收红外信号

esp32s2使用Arduino框架,调用IRremote库实现接受红外信号,该函数是阻塞型的,写在loop()的最前端:

if (irrecv.decode(&results)) { //检查是否接收到红外遥控信号
   Serial.println(results.value, HEX); //输出指令信息
   irrecv.resume();                    //接收下一指令
   
   //后续代码  
}

其中,results.value即为读取到的红外信号,可表示为16位整型变量,后续操作即围绕此变量展开。

4.5 UDP通信

由于esp32s2接收到的红外数据需要传给PC端,为了降低项目开发难度,接受端采用python编写。由于tcp通信在通信之前需要建立连接,比较复杂,为了提高项目的灵活性,采用udp通信协议。

esp32s2为udp通信协议的发送方,调用了arduino的"WiFIUdp.h"库,发送的内容即为复制接收到的红外信号,关于UDP发送的代码如下:

Udp.beginPacket("255.255.255.255", localUdpPort); //准备发送数据
   switch(results.value){
     case 0xFF02FD:
       Udp.print("FF02FD");    //复制数据到发送缓存
       break;
     case 0xFFA857:
       Udp.print("FFA857");    //复制数据到发送缓存
       break;
     case 0xFF906F:
       Udp.print("FF906F");    //复制数据到发送缓存
       break;
     case 0xFFC23D:
       Udp.print("FFC23D");    //复制数据到发送缓存
       break;
  }
   
   Udp.endPacket();            //发送数据

python为udp数据的接受端,采用阻塞式接收方法,接收到的数据为字符串,接收后即根据字符串数据向相应字典里查找图像匹配所需的图像名称,拼接出图像路径,交由后续代码调用,python端udp接收代码如下:

# 初始化UDP通信
   server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
   address = ("0.0.0.0", 8888)
   server_socket.bind(address)  # 为服务器绑定一个固定的地址,ip和端口
​
   # 存储图片路径的字典
   imgDict = {
       b"FF02FD": "bilibili.png",
       b"FFA857": "csdn.png",
       b"FF906F": "gitee.png",
       b"FFC23D": "zhihu.png"
  }
​
   while True:
       # 阻塞等待UDP接收到数据
       receive_data, client = server_socket.recvfrom(1024)
       print(receive_data, client)
​
       # 执行点击任务
       imgName = imgDict.get(receive_data)
       if imgName != None :
           imgPath = "img/"+imgName
           print(imgPath)
           mouseClick(1, "left", imgPath, 1)
​
       time.sleep(0.1)
       print("等待0.1秒")

4.6 图像识别与鼠标点击

python代码需要根据UDP接收到的信号操纵鼠标点击。而针对寻找目标网页按钮,项目使用图像匹配的方式,用户需事先对需要点击的网页按钮进行截图,然后放入img文件夹下,由python调用pyautogui包的方法进行自动化图像匹配与操作鼠标,具体代码如下:

def mouseClick(clickTimes,lOrR,img,reTry):
   if reTry == 1:
       while True:
           location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
           if location is not None:
               pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
               break
           print("未找到匹配图片,0.1秒后重试")
           time.sleep(0.1)
   elif reTry == -1:
       while True:
           location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
           if location is not None:
               pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
           time.sleep(0.1)
   elif reTry > 1:
       i = 1
       while i < reTry + 1:
           location=pyautogui.locateCenterOnScreen(img,confidence=0.9)
           if location is not None:
               pyautogui.click(location.x,location.y,clicks=clickTimes,interval=0.2,duration=0.2,button=lOrR)
               print("重复")
               i += 1
           time.sleep(0.1)

相关讲解可参考up主:不高兴就喝水的视频:https://www.bilibili.com/video/BV1T34y1o73U

5 复现时的注意事项

  • 不同的红外遥控器的编码值可能不同,针对不同编码值的遥控器,esp32s2代码与python代码均需要进行配置,具体配置方法可参考B站视频

  • esp32s2需要在连接局域网的情况下才能进行操作,务必注意检查网络连接情况

  • python代码读取的截图需要与目标按钮完全相同,请截图的时候算准按钮的正中心,并确保截图中不包含一些变化的动态背景

6 改进措施

本项目已经成功实现了简易的红外遥控网页的功能,但还有许多可以提升与扩展的地方:

  • 调用板载OLED,对系统状态,接收信号的内容等进行显示,提高用户体验。

  • 目前如果更换红外遥控器,更换目标网页按钮时,需要配置的过程太过繁琐,可利用C++/python的一些高级编程技巧,提高代码复用性,简化配置的流程。

7 收获与感想

因为我大二参加了智能车竞赛,负责航天组别的网络通信工作,大二的大创项目是空地一体化协同探测平台,也是对局域网内通信的综合应用,所以现在我对局域网下的使用各种编程语言编写的TCP/UDP通信不能说是略懂一点吧,至少也可以说是烂熟于心。再加上这个项目的复杂度并不是很大,总体并没有给我造成什么困难。

寒假我主攻的就是java及其一系列web应用课程,跟随尚硅谷的教程基本学完了javaweb,本来是想着在这个项目上应用一下,写个专门为这个项目设计的网页,但是其中有一些技术原理的问题不好解决(请参考b站视频,有所讲解),其实通过后端的httpSession获取application,是可以定位到别的httpSession,进而对别的客户端进行相应的,但互联网上只要是个网页都不会这么设计,这么做并不符合网页设计的逻辑。而且还要配置tomcat等,复现难度极大,最终还是选择了图像匹配的方案。

针对项目的需求,我个人只想到了图像匹配和自己写服务器后端两种思路,如果小伙伴们有其他思路,欢迎评论区交流。

我这一期参加了ESP32和FPGA两条赛道,由于自己不是电类专业的,之前也没接触过FPGA,所以把大量精力放在了FPGA开发上,后续的话,也会利用这个好不容易嫖到的板子好好研究一下esp32,也争取用esp-idf实现一下项目的功能吧。

软硬件
元器件
ESP32-S2-MINI-1
2.4GHz Wi­Fi (802.11 b/g/n) 模组, 内置ESP32­S2系列芯片,Xtensa® 单核32位LX7微处理器, 内置芯片叠封4MB flash,可叠封2MB PSRAM, 37个GPIO,丰富的外设, 板载PCB天线或外部天线连接器
附件下载
esp-web-remote.zip
包括esp32s2的arduino代码文件和python中继器的代码文件
团队介绍
来自哈尔滨工业大学的宋以拓
团队成员
sytnocui
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号