ag27.com: 【RTOS】+ 基于云的远程小车控制

禁止游客赌场登入
2597|3
楼主
来自 2楼
 楼主 | 2020-6-15 11:33 | 只看该作者
本帖最后由 wlxn 于 2020-7-2 22:46 编辑

龙芯板子+rt-thread实现web远程控制四轮小车
硬件方案硬件清单
  • 板子:龙芯机器人控制器(ls1c) / 龙芯派(ls2k1000)
  • 四轮小车套件:包括车体、四驱电机、电机驱动板()、电池组、充电宝
  • 正点电子 ESP8266  WIFI模块 一个





小车套件(含电池组、电机控制器)



龙芯机器人控制器(ls1c)

串口wifi模块(es8266)


部署架构



软件方案
整个软件方案的架构分为3部分:
  • WEB服务端(运行在云端),主要提供手机上可访问的控制界面,并将手机端发出的控制动作转换成mqtt的消息发布出去,这个程序需要开发,本次采用python WEB框架flask开发,前端采用html5 技术开发。
  • mqtt服务器、(运行在云端),负责接收WEB服务端发送的消息,转发给板子上的控制程序,这个程序不用开发,直接安装开源的
  • 控制器程序 ,运行在板子上,负责监听mqtt服务发来的消息,根据不同的消息来控制电机的转动,实现前进、后退、左转、右转等控制动作,这个程序需要开发,将采用c语言开发,操作系统采用rt-thread4.0.3

此处将有示意图
实现步骤一、搭建云端环境
本次云服务器,我用的是我自已在腾讯云申请的云主机,云主机运行的操作系统如下:
  1. [root@VM_0_4_centos ~]# uname -a
  2. Linux VM_0_4_centos 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
复制代码
在上面安装了docker环境,并用docker 下载并运行了eclipse-mosquitto容器。服务端口为1883。命令如下
  1. $[root@VM_0_4_centos ~]# docker pull eclipse-mosquitto
  2. $[root@VM_0_4_centos ~]# docker run -d  -p 1883:1883  eclipse-mosquittop
  3. --查看是否正常启动
  4. $[root@VM_0_4_centos ~]# docker ps
  5. CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
  6. b78bb919034d        eclipse-mosquitto   "/docker-entrypoin..."   3 seconds ago       Up 3 seconds        0.0.0.0:1883->1883/tcp              keen_goldstine
  7. --可以看到mqtt服务器已经正常运行了
复制代码
下载python镜象并启动容器,但需要安装flask框架及mqtt客户端插件,命令如下:
  1. [root@VM_0_4_centos ~]# docker pull python
  2. Using default tag: latest
  3. Trying to pull repository docker.io/library/python ...
  4. ... ...

  5. --因默认该环境没有flask及mqtt插件,所以需要进行一步安装,且为了保证下次重启可用,需要将镜象保存更新
  6. [root@VM_0_4_centos ~]# docker run -i -t python /bin/bash
  7. ... ...
  8. --进入容器后,安装flask
  9. root@b45cbfa11dfb:/# pip install flask
  10. ... ...
  11. -- 然后再安装flask-mqtt
  12. root@b45cbfa11dfb:/# pip install flask-mqtt

  13. -- 最后将当前容器保存为新的镜象,这样以后用这个镜象启动容器,即实现一个可用的开发环境。
  14. [root@VM_0_4_centos python]# docker ps -a
  15. CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS                               NAMES
  16. b45cbfa11dfb        python              "/bin/bash"              8 minutes ago       Exited (127) 7 seconds ago                                       jovial_mirzakhani
  17. ... ...
  18. [root@VM_0_4_centos python]# docker commit b45cbfa11dfb  flask_mqtt:v1
  19. sha256:00993b203a7db9becc53ff7a642664ee3bfed3ac36432878357ce245ada7dd0b
复制代码
二、开发云端程序开发web界面
为达到较好的移动端显示效果,并且由于我们这个项目非常的简单,也不必要用重量级的框架,只要容易实现方便的自适应终端屏幕就可以 了,因此我采用bootstrap+jquery 框架实现,源码mygui.html 如下:
  1. <!DOCTYPE html>
  2. <html>
  3.         <head>
  4.                 <meta charset="utf-8">
  5.                 <title>远程小车控制</title>
  6.                 <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.                 <meta name="viewport" content="width=device-width, initial-scale=1">
  8.                 <link rel="stylesheet" >  
  9.                 <script src="http://326.ib955.com/jquery/2.1.1/jquery.min.js"></script>
  10.                 <script src="http://326.ib955.com/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
  11.         
  12.           <style >
  13.                   body {
  14.                           background-color: darkkhaki;
  15.                   }
  16.                   table {
  17.                           text-align: center;
  18.                           width:100%;
  19.                           height:100%;
  20.                           
  21.                   }
  22.                   
  23.                   td {
  24.                           text-align: center;
  25.                           margin: 5px 5px 5px 5px;
  26.                           padding:5px 5px 5px 5px;
  27.                   }
  28.           </style>
  29.         </head>
  30.         <body >
  31.                
  32.                 <div align="center">
  33.                         <h2 align="center">远程小车控制</h2>
  34.                         <hr>
  35.                
  36.                         <table  >
  37.                                 <tr><td></td><td ><button id="forward" type="button" class="btn btn-primary">前进</button></td><td></td></tr>
  38.                                 <tr><td><button id="left" type="button" class="btn btn-primary">左转</button></td><td><button id="stop" type="button" class="btn btn-primary">停车</button></td><td><button type="button" id="right" class="btn btn-primary">右转</button></td></tr>
  39.                                 <tr><td></td><td><button id="back" type="button" class="btn btn-primary">后退</button></td><td></td></tr>
  40.                         </table>
  41.                
  42.                 </div>
  43.                 <br><hr>
  44.            <div align="center">作者:11680838@qq.com</div>
  45.            
  46.            <script>
  47.                   
  48.                    function mysubmit(ops){
  49.                            $.get("http://www.ib955.com/425:5000/drive?ops="+ops,function(data,status){
  50.                               if(console){
  51.                                     console.log("数据: " + data + "\n状态: " + status);
  52.                               }else{
  53.                                           alert("数据: " + data + "\n状态: " + status);
  54.                                           
  55.                                   }
  56.                                 });
  57.                    }
  58.                    $(document).ready(function(){
  59.                      $("#forward").click(function(){
  60.                       //alert("前进");
  61.                           mysubmit("forward") ;
  62.                      });
  63.                          $("#back").click(function(){
  64.                           //alert("后退");
  65.                           mysubmit("back") ;
  66.                          });
  67.                          $("#left").click(function(){
  68.                            // alert("左转");
  69.                            mysubmit("left") ;
  70.                          });
  71.                          $("#right").click(function(){
  72.                            // alert("右转");
  73.                            mysubmit("right") ;
  74.                          });
  75.                          $("#stop").click(function(){
  76.                             //alert("停车");
  77.                                 mysubmit("stop") ;
  78.                          });
  79.                    });
  80.            </script>
  81.         </body>
  82. </html>
复制代码

手机端界面效果图
开发flask服务程序
myserver.py
  1. #!/bin/python3
  2. # fileName: myserver.py


  3. from flask import Flask,request
  4. import paho.mqtt.client as mqtt
  5. import time

  6. app = Flask(__name__)


  7. @app.route("/")

  8. def hello_world():
  9.         return 'hello world'

  10. @app.route("/drive")
  11. def drive():
  12.         ops = request.args['ops']
  13.         #print(ops)
  14.         sendMsg(ops)
  15.         return 'success'

  16. def sendMsg(ops):
  17.         print(ops)
  18.         HOST = 'www.iloveai.club'
  19.         PORT = 1883
  20.         client = mqtt.Client()
  21.         client.connect(HOST, PORT, 60)
  22.         client.loop_start()
  23.         client.publish("driver",ops,2)
  24.         client.loop_stop()
  25.         client.disconnect()
  26.         #client.loop_forever()



  27. if __name__ == '__main__':

  28.         app.run(host='0.0.0.0')
复制代码
云端子系统验证
用一个mqtt测试工具mqttfx,订阅我们发布的主题消息,然后用手机打开我们开发的web网页,分别点击前进、后退、左转、右转等按钮,然后查看mqtt测试工具是否接收到正确的信息。


三、搭建rt-thread开发环境



下载、安装env编译环境下载、安装交叉编译环境下载rt-thread 源码
方法请参考rt-thread官网。
(略)



四、配置内核

1、配置添加AT组件支持
     首先在 env 中运行 menuconfig,在界面中找到 AT 组件,并勾选,如图所示。

  

       RT-Thread 配置 AT 主界面 进入 AT 配置界面后,具体配置项如图  所示。

   
   RT-Thread 配置 AT 组件界面 添加 SAL组件,启用 SAL(Socket抽象层),路径如图 所示。
     

启用 SAL(Socket 抽象层)配置图 将 SAL(Socket抽象层)配置为支持 AT指令,如图所示。


2、配置添加ESP8266模夫支持
ESP8266模块是一个标准的 AT 设备,能够使用 RT-Thread 组件进行操作。 首先添加 IOT中的 AT DEVICE包支持,如图 所示。


然后配置 ESP8266,添加该模块,如图 所示


然后选择ES8266这个设备,对使用的





2、配置添加mqtt客户端支持




五、开发控制器程序
  1. /*
  2. 代码 mycontrol.c
  3. 负责从云端mqtt服务器订阅控制消息,根据不同消息来驱动gpio接口来驱动
  4. 小车电机不同的转动,实现前进、后退、左转和右转

  5. */

  6. #include <rtthread.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdint.h>
  10. #include <drivers/pin.h>
  11. #include "../drivers/drv_gpio.h"
  12. #include "paho_mqtt.h"

  13. #define DBG_ENABLE
  14. #define DBG_SECTION_NAME    "mqtt.sample"
  15. #define DBG_LEVEL           DBG_LOG
  16. #define DBG_COLOR
  17. #include <rtdbg.h>

  18. /* 定义gpio接口编号,对应电机驱动器的4个逻辑接线口*/
  19. #define IN4 (rt_uint8_t)49  //控制电机B
  20. #define IN3 (rt_uint8_t)51
  21. #define IN2 (rt_uint8_t)54 //控制电机A
  22. #define IN1 (rt_uint8_t)56

  23. /*定义mqtt服务器地址,端口等信息*/
  24. #define MQTT_URI                "tcp://www.iloveai.club:1883"
  25. #define MQTT_USERNAME           "admin"
  26. #define MQTT_PASSWORD           "admin"
  27. #define MQTT_SUBTOPIC           "driver"
  28. #define MQTT_PUBTOPIC           "/mqtt/test"
  29. #define MQTT_WILLMSG            "Goodbye!"

  30. /* define MQTT client context */
  31. static MQTTClient client;
  32. static int is_started = 0;



  33. /* 根据str的值来驱动电机进行不同的转动组合,实现前进、后退、左转、右转*/
  34. void drive(char *str)
  35. {
  36.     // pin 初始化

  37.     hw_pin_init();
  38.    
  39.     // 把相应 gpio 设为输出模式
  40.     rt_pin_mode(IN4, PIN_MODE_OUTPUT);
  41.     rt_pin_mode(IN3, PIN_MODE_OUTPUT);
  42.     rt_pin_mode(IN2, PIN_MODE_OUTPUT);
  43.     rt_pin_mode(IN1, PIN_MODE_OUTPUT);  

  44.     if(strcmp(str,"forward") == 0){  //AB电机都正转

  45.         rt_pin_write(IN1,PIN_HIGH);
  46.         rt_pin_write(IN2,PIN_LOW);
  47.         rt_pin_write(IN3,PIN_HIGH);
  48.         rt_pin_write(IN4,PIN_LOW);

  49.     }else if(strcmp(str,"back") == 0){ //AB电机都倒转

  50.         rt_pin_write(IN1,PIN_LOW);
  51.         rt_pin_write(IN2,PIN_HIGH);
  52.         rt_pin_write(IN3,PIN_LOW);
  53.         rt_pin_write(IN4,PIN_HIGH);

  54.     }else if(strcmp(str,"left") == 0){ //A电机倒转,B电机正转
  55.        rt_pin_write(IN3,PIN_HIGH);
  56.         rt_pin_write(IN4,PIN_LOW);
  57.         rt_pin_write(IN1,PIN_LOW);
  58.         rt_pin_write(IN2,PIN_HIGH);

  59.     }else if(strcmp(str,"right") == 0){ //A电机正转,B电机倒转
  60.         rt_pin_write(IN1,PIN_HIGH);
  61.         rt_pin_write(IN2,PIN_LOW);
  62.         rt_pin_write(IN3,PIN_LOW);
  63.         rt_pin_write(IN4,PIN_HIGH);


  64.     }else if(strcmp(str,"stop") == 0){  //AB都不转

  65.         rt_pin_write(IN1,PIN_HIGH);
  66.         rt_pin_write(IN2,PIN_HIGH);
  67.         rt_pin_write(IN3,PIN_LOW);
  68.         rt_pin_write(IN4,PIN_LOW);

  69.     }



  70. }


  71. static void mqtt_sub_callback(MQTTClient *c, MessageData *msg_data)
  72. {
  73.     *((char *)msg_data->message->payload + msg_data->message->payloadlen) = '\0';
  74.     LOG_D("mqtt sub callback: %.*s %.*s",
  75.                msg_data->topicName->lenstring.len,
  76.                msg_data->topicName->lenstring.data,
  77.                msg_data->message->payloadlen,
  78.                (char *)msg_data->message->payload);
  79.    
  80.     drive((char *)msg_data->message->payload);
  81.    
  82. }

  83. //启动mqtt客户端
  84. static int mqtt_start(void)
  85. {
  86.     /* init condata param by using MQTTPacket_connectData_initializer */
  87.     MQTTPacket_connectData condata = MQTTPacket_connectData_initializer;
  88.     static char cid[20] = { 0 };

  89.    

  90.     if (is_started)
  91.     {
  92.         LOG_D("mqtt client is already connected.");
  93.         return -1;
  94.     }
  95.     /* config MQTT context param */
  96.     {
  97.         client.isconnected = 0;
  98.         client.uri = MQTT_URI;

  99.         /* generate the random client ID */
  100.         rt_snprintf(cid, sizeof(cid), "rtthread%d", rt_tick_get());
  101.         /* config connect param */
  102.         memcpy(&client.condata, &condata, sizeof(condata));
  103.         client.condata.clientID.cstring = cid;
  104.         client.condata.keepAliveInterval = 30;
  105.         client.condata.cleansession = 1;
  106.         client.condata.username.cstring = MQTT_USERNAME;
  107.         client.condata.password.cstring = MQTT_PASSWORD;

  108.         /* config MQTT will param. */
  109.         client.condata.willFlag = 1;
  110.         client.condata.will.qos = 1;
  111.         client.condata.will.retained = 0;
  112.         client.condata.will.topicName.cstring = MQTT_PUBTOPIC;
  113.         client.condata.will.message.cstring = MQTT_WILLMSG;

  114.         /* malloc buffer. */
  115.         client.buf_size = client.readbuf_size = 1024;
  116.         client.buf = rt_calloc(1, client.buf_size);
  117.         client.readbuf = rt_calloc(1, client.readbuf_size);
  118.         if (!(client.buf && client.readbuf))
  119.         {
  120.             LOG_D("no memory for MQTT client buffer!");
  121.             return -1;
  122.         }

  123.       
  124.         /* set subscribe table and event callback */
  125.         client.messageHandlers[0].topicFilter = rt_strdup(MQTT_SUBTOPIC);
  126.         client.messageHandlers[0].callback = mqtt_sub_callback;
  127.         client.messageHandlers[0].qos = QOS1;

  128.       
  129.     }

  130.     /* run mqtt client */
  131.     paho_mqtt_start(&client);
  132.     is_started = 1;

  133.     return 0;
  134. }




  135. void mycontrol(void)
  136. {
  137.    
  138.     mqtt_start();
  139. }

  140. /* 导出到 msh 命令列表中 */
  141. MSH_CMD_EXPORT(mycontrol, mycontrol);
复制代码



六、联调测试


成果展示

照片:

所有部件的“全家福”

组装起来的样子,绿板是龙芯板,前面是WIFI模块。上面一大块大家伙是充电宝。

这是前视图,可以看到电机驱动模块在中间夹层,还有电池组(看不到)



将写做好的内核下载、运行,并启动mycontrol程序


视频
最后的效果演示视频请看下面链接:
http://326.ib955.com/video/BV1rZ4y1H7iR
总结
1、本次开发最大的难度在于龙芯板子的驱动不全,在研究内核 与驱动开发时,最大的不足就是对硬件组成原理的不熟悉。这一方面需要进一步深入学习
2、这一次幸亏我有龙芯1c的板子,其rt-thread移值的较好,为了保证完成方案,在龙芯2k驱动开发遇到极大困难时,我及时用1c板子先行把整个方案的其它部分完成并测试成功。
3、特别感谢群里bigmagic flygoat等几个网友的帮助,没有他们的指点,我是完不成这个作业的。最后感谢主办方,龙芯公司给提供的这次学习机会

389815ee83c778c907.png (53.87 KB, 下载次数: 0)

389815ee83c778c907.png

微信图片_20200618093609.jpg (447.35 KB, 下载次数: 0)

微信图片_20200618093609.jpg

微信图片_20200618093614.jpg (219.41 KB, 下载次数: 0)

微信图片_20200618093614.jpg

源码.zip

3.41 KB, 下载次数: 2

龙芯板子+rt-thread实现web远程控制四轮小车.zip

1.01 MB, 下载次数: 3

板凳
| 2020-6-17 23:13 | 只看该作者
nice job!
地板
| 2020-6-30 08:31 | 只看该作者
wlxn 发表于 2020-6-15 11:33
龙芯板子+rt-thread实现web远程控制四轮小车硬件方案硬件清单
  • 板子:龙芯机器人控制器(ls1c) / 龙芯派 ...

  • 谢谢分享,,,,,,,,,
    扫描二维码,随时随地手机跟帖
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    我要发帖 投诉建议 创建版块 申请版主

    快速回复

    您需要登录后才可以回帖
    登录 | 注册
    高级模式

    论坛热帖

    关闭

    ag27.com: 热门推荐

    禁止游客赌场登入 永利游戏开户直营 返回顶部 返回列表
    玛雅棋牌导航 博猫游戏网址直营网 9号彩票娱乐直营网 娱乐城哪家好 菲律宾申博太阳城公司游戏下载网上娱乐场
    797tyc.com 139sb.com msc697.com 96yh.com sb279.com
    58xpj.com 92sb.com 必發集團OG棋牌 乐虎国际GPK棋牌 888真人棋牌外围
    www.88msc.com 纽约棋牌网站 太阳城现金娱乐网 澳门网上赌场DT电子 千亿棋牌现金网