[CW32F030系列] 【CW32F030CxTx StartKit测评】+ 建立WIFI连接,通过手机控制小车

[复制链接]
 楼主| suncat0504 发表于 2022-7-14 14:49 | 显示全部楼层 |阅读模式
本帖最后由 suncat0504 于 2022-7-25 08:12 编辑

#申请原创# @21小跑堂  
上次测试中,简单搭建了一个通过串口控制小车移动的测试环境。在确认没有问题的基础上,把相关模块组装起来,形成一个独立的小车。
图片1.png
  这一次,引入ESP8266WIFI模块,通过编程ESP8266,使之工作于AP模式并启动WEB服务。ESP8266会建立一个名为“WIFI_CAR_ESP8266”的WIFI网络,访问密码为“12345678”。 使用手机接入ESP8266Wifi网络(访问网址192.168.4.1),进入指定网址后,在这个网页提供了5个按钮,分别对应于小车的前进、后退、左转、右转、停止这五个简单的操作。
图片2.png
在网页点击对应的按钮时,ESP8266WIFI模块收到无线指令后,会通过ESP8266WIFI模块本身提供的一个串口,发出对应于小车动作的操作命令串。这个命令串遵循上次测试中的串口接收指令,这样原来的程序不需要做改动,就能直接用于测试。前提是把ESP8266的串口输出接到开发板的PA09上。
网页主代码如下:
  1. #include <ESP8266WiFi.h>

  2. const char index_html[] PROGMEM = R"=====(
  3. <!DOCTYPE html>
  4. <html>

  5. <head>
  6.   <meta charset="UTF-8">
  7.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8.   <meta http-equiv="X-UA-Compatible" content="ie=edge">
  9.   <link rel="stylesheet" href="/css/bootstrap.css">
  10.   <title>wifi 遥控小车</title>
  11. </head>

  12. <body>
  13.   <div id="app">
  14.     <div class="alert alert-primary" role="alert">
  15.       <h1 class="display-4">WIFI car</h1>
  16.     </div>
  17.     <div class="container">
  18.       <div>
  19.         <div class="row justify-content-center">
  20.           <div class="col col-2">
  21.             <button class="btn btn-primary btn-lg" @click="forward()">
  22.               <span>前进</span>
  23.             </button>
  24.           </div>
  25.         </div>
  26.         <div class="row justify-content-center my-3">
  27.           <div class="col col-2">
  28.             <button class="btn btn-primary btn-lg" @click="left()">
  29.               <span>左转</span>
  30.             </button>
  31.           </div>
  32.           <div class="col col-2">
  33.             <button class="btn btn-primary btn-lg" @click="stop()">
  34.               <span>停止</span>
  35.             </button>
  36.           </div>
  37.           <div class="col col-2">
  38.             <button class="btn btn-primary btn-lg" @click="right()">
  39.               <span>右转</span>
  40.             </button>
  41.           </div>
  42.         </div>
  43.         <div class="row justify-content-center">
  44.           <div class="col col-2">
  45.             <button class="btn btn-primary btn-lg" @click="backward()">
  46.               <span>后退</span>
  47.             </button>
  48.           </div>
  49.         </div>
  50.       </div>
  51.     </div>
  52.   </div>

  53.   <script src="/js/vue.js"></script>
  54.   <script src="/js/jquery.js"></script>
  55.   <script src="/js/popper.js"></script>
  56.   <script src="/js/bootstrap.js"></script>
  57.   <script src="/js/axios.js"></script>
  58.   <script>
  59.     new Vue({
  60.       el: '#app',
  61.       methods: {
  62.         forward() {
  63.           axios.get('/move?dir=F')
  64.             .then((res) => console.log(res.data))
  65.             .catch(() => console.log('出错了。'))
  66.         },
  67.         backward() {
  68.           axios.get('/move?dir=B')
  69.             .then((res) => console.log(res.data))
  70.             .catch(() => console.log('出错了。'))
  71.         },
  72.         left() {
  73.           axios.get('/move?dir=L')
  74.             .then((res) => console.log(res.data))
  75.             .catch(() => console.log('出错了。'))
  76.         },
  77.         right() {
  78.           axios.get('/move?dir=R')
  79.             .then((res) => console.log(res.data))
  80.             .catch(() => console.log('出错了。'))
  81.         },
  82.         stop() {
  83.           axios.get('/move?dir=S')
  84.             .then((res) => console.log(res.data))
  85.             .catch(() => console.log('出错了。'))
  86.         }
  87.       },
  88.     });
  89.   </script>
  90. </body>

  91. </html>
  92. )=====";
复制代码
可以看到五个按钮对应的五个动作中,分别执行了forward、left、right、backward、stop函数,函数处理中向服务器端发动的数据中心,对dir参数进行不同的赋值。这样在服务器端通过request->getParam(“dir”),就可以获得操作网页上的按钮按下的情况。服务器端收到数据后,根据解析结果,向串口发出ATCx数据。其中的“ATCx”(x=0-9,A-Z),就是模拟上次测试中用到的串口通讯指令。Serial.println本身会提供换行符,所以就不用专门追加“\n”了。
在开发板的处理程序中,串口收到的数据经过以下处理函数,向电机驱动板发出动作指令:
  1. // 执行串口发过来的指令
  2. void executeComCommand(void) {
  3.     if (cmdRxBuf[0]=='A' && cmdRxBuf[1]=='T') {
  4.         if (cmdRxBuf[2]=='C') {
  5.             if (cmdRxBuf[3]=='0') {
  6.                 // 驱动向小车向前走1S, 此处暂时不设置时间, TODO
  7.                 LED2_TOG();
  8.                 car_forward();
  9.                 display_string_16x16(0, 2, "forward        ");
  10.             } else if (cmdRxBuf[3]=='1') {
  11.                 LED2_TOG();
  12.                 car_back();
  13.                 display_string_16x16(0, 2, "Back          ");
  14.             } else if (cmdRxBuf[3]=='2') {
  15.                 LED2_TOG();
  16.                 car_forward_left();
  17.                 display_string_16x16(0, 2, "forward left     ");
  18.                
  19.             } else if (cmdRxBuf[3]=='3') {
  20.                 LED2_TOG();
  21.                 car_forward_right();
  22.                 display_string_16x16(0, 2, "forward right     ");
  23.                
  24.             } else if (cmdRxBuf[3]=='4') {
  25.                 LED2_TOG();
  26.                 car_fast_forward_left();
  27.                 display_string_16x16(0, 2, "fast forward left ");
  28.                
  29.             } else if (cmdRxBuf[3]=='5') {
  30.                 LED2_TOG();
  31.                 car_fast_forward_right();
  32.                 display_string_16x16(0, 2, "fast forward right ");

  33.             } else if (cmdRxBuf[3]=='6') {
  34.                 LED2_TOG();
  35.                 car_forward_left();
  36.                 display_string_16x16(0, 2, "back left     ");
  37.                
  38.             } else if (cmdRxBuf[3]=='7') {
  39.                 LED2_TOG();
  40.                 car_forward_right();
  41.                 display_string_16x16(0, 2, "back right     ");
  42.                
  43.             } else if (cmdRxBuf[3]=='8') {
  44.                 LED2_TOG();
  45.                 car_fast_forward_left();
  46.                 display_string_16x16(0, 2, "fast back left  ");
  47.                
  48.             } else if (cmdRxBuf[3]=='9') {
  49.                 LED2_TOG();
  50.                 car_fast_forward_right();
  51.                 display_string_16x16(0, 2, "fast back right  ");
  52.             
  53.             } else if (cmdRxBuf[3]=='A' || cmdRxBuf[3]=='a') {
  54.                 LED2_TOG();
  55.                 car_stop();
  56.                 display_string_16x16(0, 2, "stop          ");
  57.             }
  58.         }
  59.         
  60.         delay1ms(1000);
  61.         car_stop();
  62.     }
  63. }
复制代码
程序中,利用LED2来显示串口数据的解析情况,同时通过display_string_16x16把解析结果显示在液晶上。因为每个动作被执行1000毫秒后,就停止,所以对“stop”的解析处理就没有什么实际意义了。这么做的原因是为了调试时,避免小车跑不停,毕竟是连着JLINK调试的嘛。脱离JLINK测试时,可以把这两行代码注释掉。
图片4.png
为了节省空间,这个小车只用一节18650电池,通过升压模块提高输出电压为8V,然后在通过7805降压得到5V电源。之所以这么做,而不是直接升压到5V给开发板工作,是因为以下2个原因:
1、直接使用升压的5V,如果升压模块出异常导致输出电压升高,会烧毁开发板。
2、电机驱动板也使用5V电源,电压也不能太高。
开发板本身提供了一个DC输入的接口CN24,根据资料:
图片3.png
本来预计通过开发板提供DCIN接口,在不改动J24的跳线,依旧默认给微处理器提供3.3V电压。我的液晶显示模块也是用3.3V,电压不能用5V,以免烧坏液晶(其实有没有液晶,都不会影响遥控小车的运行,只是考虑到调试目的以及查看中间处理结果,由液晶显示会方便很多)。结果实测,在DCIN端接入5V后,开发板本身的电源时指示灯LED3并没有亮。
通过和芯源的工程师沟通,了解到:
使用DCIN作为输入电源的时候,J24需要改跳线到5-6上,这时开发板及微处理器的电源为5V,开发板提供的VDD输出针脚也是5V。但此时J241脚因为是接在3.3V稳压器的输出上,所以使用这个针脚是可以得到3.3V(实测只有1.1V左右)。但是考虑到我的液晶只能工作于3.3V,其数据接口最好也工作于3.3V的逻辑电平上,基于这个考虑,还是要准备一块能提供3.3V的电源板,为开发板专门提供3.3V的电源吧。目前这种调试状态,暂时使用JLINK提供的工作电源。
因为是简单的动作,在电机转动过程中,并没有统计转动角度或者计数脉冲,所以还无法精确控制前进/后退的步数以及左右转动的角度,必须要追加更多的检测装置才行。只有亲自自己动手了,才会发现哪怕做一件小事儿也没那么容易。很多细节的东西,只有在实践中,才会得到深切的体会。进而想到,这个社会上的任何一点科技的进步,都是靠着工程师们在技术上的一点一点积累而实现的,从没有一蹴而就的强大。在此,向那些硬件工程师们致以真诚的敬意!

以下附上所有代码(含wifi端Arduino代码)



code.zip

370.42 KB, 下载次数: 14

duo点 发表于 2022-7-15 14:45 来自手机 | 显示全部楼层
感谢分享,非常不错的测评贴
burgessmaggie 发表于 2022-7-24 21:29 | 显示全部楼层
这个可以,好玩一些。   
pklong 发表于 2022-7-24 23:00 | 显示全部楼层
不能直接AT操作esp8266吗   

评论

这个我就不清楚了。因为需要设置服务器、编程控制用网页。我觉得AT可能不太容易实现  发表于 2022-7-25 08:10
olivem55arlowe 发表于 2022-7-25 07:31 | 显示全部楼层
Arduino需要按照环境吗  

评论

需要啊,不然咋编程esp8266啊  发表于 2022-7-25 08:08
eefas 发表于 2022-8-18 18:46 | 显示全部楼层
ESP8266WIFI需要自己开发吗?   
dspmana 发表于 2022-8-18 18:59 | 显示全部楼层
arduino做的固件吗     
 楼主| suncat0504 发表于 2022-8-19 08:35 | 显示全部楼层
本帖最后由 suncat0504 于 2022-8-19 08:42 编辑

统一回复,小车运动侧,使用Keil开发。通过串口接受来自ESP8266的控制指令。
ESP8266侧,作为WEB服务器使用,建立网页,提供运动指令的输入控制,转化为控制指令,通过串口输出到控制主机。ESP8266侧使用Arduino开发。提供的源码中是包含了两个开发端的代码的。其中INO结尾的文件,是Arduino的工程文件,如果安装了Arduino,可以直接打开查看工程相关的源码。
fengm 发表于 2022-8-19 21:45 | 显示全部楼层
这个ESP8266为什么不使用串口呢   

评论

用了串口啊。通过串口和主控板通讯的啊  发表于 2022-8-20 18:28
updownq 发表于 2022-8-20 15:28 | 显示全部楼层
pwm调速搞起来吧。   
macpherson 发表于 2022-8-20 21:35 | 显示全部楼层
esp8266串口通信吗  
pmp 发表于 2022-9-7 21:14 | 显示全部楼层
服务器是怎么建立的呢  
dzfansman 发表于 2022-9-7 21:40 | 显示全部楼层
以后可以扩展到4G通信的。
10299823 发表于 2022-9-8 09:21 | 显示全部楼层
ESP8266WIFI如何通信呢
plsbackup 发表于 2022-9-8 10:28 | 显示全部楼层
这里的wifi使用的是at控制的吗

评论

@suncat0504 :好的,谢谢。  发表于 2022-11-23 20:58
不是啊,使用Arduino开发的,类似于C语言的,你可以看看代码  发表于 2022-9-8 11:19
robincotton 发表于 2022-9-8 11:59 | 显示全部楼层
用到了服务器了吗?
febgxu 发表于 2022-9-8 13:57 | 显示全部楼层
这个通信的速度可以到多少呢
朝生 发表于 2022-9-8 14:01 | 显示全部楼层
开发板接收串口数据,然后控制两个轮子的电机。有用到PWM吗?

评论

@suncat0504 :那就期待你后期添加PWM了~想看看效果~  发表于 2022-9-13 14:41
没有,因为涉及东西比较多,暂时还没有改造为pwm  发表于 2022-9-8 14:51
mattlincoln 发表于 2022-9-8 15:10 | 显示全部楼层
在分布式热点环境下控制wifi小车
quickman 发表于 2022-9-8 17:07 | 显示全部楼层
如何创建一个Android应用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:大连伊飞特信息技术有限公司软件工程师
简介:本人于1993年毕业于大连理工大学。毕业后从事单片机开发工作5年,之后转入软件开发工作至今。

158

主题

4505

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部