导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页

    【XR806开发板试用】基于XR806实现智能小车

    Wireless & Analog Series
    基于xr806实现智能小车
    1
    1
    1174
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • B
      boarmy LV 2 最后由 编辑

      一、实验功能:
      1、 基于XR806实现WIFI连接路由器
      2、 XR806设备创建TCP socket服务器,局域网内通过PC端TCP客服端连接XR806 TCP服务器进行指令控制小车运行(指令A:前进、B:后退、C:左转、D:右转、I:停止)。
      3、 小车行进由GPIO控制电机转动,行进速度通过XR806硬件定时器实现GPIO的PWM脉宽调制来控制小车行进速度。
      4、 创建双线程实现智能小车,一个线程负责小车运行,一个线程主要用于TCP socket服务器完成与TCP客服端的指令收发。
      实物图:
      替代文字
      二、开发环境安装配置
      开发环境安装配置参考https://aijishu.com/a/1060000000291606博文,实现基于优麒麟ubuntukylin-20.04,使用的OpenHarmony代码版本是1.0.1_release。

      鸿蒙系统固件烧录参考了下面这个贴子:
      https://aijishu.com/a/1060000000287250 全志 XR806 OpenHarmony 鸿蒙系统固件烧录。
      tcp socket通信参考帖子:
      https://aijishu.com/a/1060000000286948 【XR806开发板试用】xr806使用tcp socket与手机通信

      三、硬件连接电路
      小车驱动板电路图
      电源电路:输入7.2V-12V电源,通过LM2596S稳压IC输出5V电源
      替代文字
      车轮驱动电路,采用L293芯片驱动电机。EN使能默认悬空为高电平,只需控制电机的GPIO口输出高低电平即可实现车轮的转动,如车轮电机T1,控制GPIO口为PD
      替代文字
      XR806开发板接口图如下:
      替代文字
      电机控制信号与XR806开发板IO口定义:
      替代文字
      四、项目实现
      参考了官方的点灯教程
      创建工程
      在device/xradio/xr806/ohosdemo中新建一个文件夹,并命令为smart_car。
      在文件夹中新建文件

      ~/share/XR806/openharmony/device/xradio/xr806/ohosdemo/smart_car$ tree -L 2
      .
      ├── BUILD.gn
      └── smart_car
          ├── BUILD.gn
          └── main.c
          ├── motor.h
          └── motor.c
          ├── tcp_net_socket.h
          └── tcp_net_socket.c`
      

      修改device/xradio/xr806/ohosdemo/smart_car/BUILD.gn

      import("//device/xradio/xr806/liteos_m/config.gni")
      
      static_library("app_smart_car") {
         configs = []
      
         sources = [
            "src/main.c",
            "src/tcp_net_socket.c",
            "src/motor.c",
         ]
      
         cflags = board_cflags
      
         include_dirs = board_include_dirs
         include_dirs += [
            "//kernel/liteos_m/kernel/arch/include",
            "//base/iot_hardware/peripheral/interfaces/kits",
            "//utils/native/lite/include",
            "//foundation/communication/wifi_lite/interfaces/wifiservice",
            "//third_party/lwip/src/include",
            "//third_party/cJSON",
         ]
      }
      

      电机控制信号与XR806开发板IO口定义:

      #define GPIO_ID_PA11 11
      #define GPIO_ID_PA12 12
      #define GPIO_ID_PA13 13
      #define GPIO_ID_PA19 19
      #define GPIO_ID_PA20 20
      #define GPIO_ID_PA21 21
      #define GPIO_ID_PA22 22
      #define GPIO_ID_PA23 23
      
      #define GPIO_ID_PB3 27
      #define GPIO_ID_PB4 28
      #define GPIO_ID_PB5 29
      #define GPIO_ID_PB6 30
      #define GPIO_ID_PB7 31
      #define GPIO_ID_PB14 38
      #define GPIO_ID_PB15 39
      
      #define FRONT_LEFT_F_PIN        GPIO_ID_PA12 
      #define FRONT_LEFT_F_SET        IoTGpioSetOutputVal(FRONT_LEFT_F_PIN,1);
      #define FRONT_LEFT_F_RESET      IoTGpioSetOutputVal(FRONT_LEFT_F_PIN,0);
      								
      #define FRONT_LEFT_B_PIN        GPIO_ID_PA13 
      #define FRONT_LEFT_B_SET        IoTGpioSetOutputVal(FRONT_LEFT_B_PIN,1);
      #define FRONT_LEFT_B_RESET      IoTGpioSetOutputVal(FRONT_LEFT_B_PIN,0);
      								
      #define FRONT_RIGHT_F_PIN       GPIO_ID_PB7
      #define FRONT_RIGHT_F_SET       IoTGpioSetOutputVal(FRONT_RIGHT_F_PIN,1);
      #define FRONT_RIGHT_F_RESET     IoTGpioSetOutputVal(FRONT_RIGHT_F_PIN,0);
      								
      #define FRONT_RIGHT_B_PIN       GPIO_ID_PB5
      #define FRONT_RIGHT_B_SET       IoTGpioSetOutputVal(FRONT_RIGHT_B_PIN,1);
      #define FRONT_RIGHT_B_RESET     IoTGpioSetOutputVal(FRONT_RIGHT_B_PIN,0);
      								
      #define BEHIND_LEFT_F_PIN       GPIO_ID_PA19
      #define BEHIND_LEFT_F_SET       IoTGpioSetOutputVal(BEHIND_LEFT_F_PIN,1);
      #define BEHIND_LEFT_F_RESET     IoTGpioSetOutputVal(BEHIND_LEFT_F_PIN,0);
      								
      #define BEHIND_LEFT_B_PIN       GPIO_ID_PA20
      #define BEHIND_LEFT_B_SET       IoTGpioSetOutputVal(BEHIND_LEFT_B_PIN,1);
      #define BEHIND_LEFT_B_RESET     IoTGpioSetOutputVal(BEHIND_LEFT_B_PIN,0);
      								
      #define BEHIND_RIGHT_F_PIN      GPIO_ID_PB6
      #define BEHIND_RIGHT_F_SET      IoTGpioSetOutputVal(BEHIND_RIGHT_F_PIN,1);
      #define BEHIND_RIGHT_F_RESET    IoTGpioSetOutputVal(BEHIND_RIGHT_F_PIN,0);
      								
      #define BEHIND_RIGHT_B_PIN      GPIO_ID_PB4
      #define BEHIND_RIGHT_B_SET      IoTGpioSetOutputVal(BEHIND_RIGHT_B_PIN,1);
      #define BEHIND_RIGHT_B_RESET    IoTGpioSetOutputVal(BEHIND_RIGHT_B_PIN,0);
      

      小车电机驱动配置

      //左前
      #define FRONT_LEFT_GO    FRONT_LEFT_F_SET; FRONT_LEFT_B_RESET//前进
      #define FRONT_LEFT_BACK  FRONT_LEFT_F_RESET; FRONT_LEFT_B_SET//后退
      #define FRONT_LEFT_STOP  FRONT_LEFT_F_RESET; FRONT_LEFT_B_RESET//停止
      
      //右前
      #define FRONT_RIGHT_GO     FRONT_RIGHT_F_SET;  FRONT_RIGHT_B_RESET
      #define FRONT_RIGHT_BACK   FRONT_RIGHT_F_RESET;FRONT_RIGHT_B_SET
      #define FRONT_RIGHT_STOP   FRONT_RIGHT_F_RESET;FRONT_RIGHT_B_RESET
      
      //左后
      #define BEHIND_LEFT_GO     BEHIND_LEFT_F_SET;BEHIND_LEFT_B_RESET
      #define BEHIND_LEFT_BACK   BEHIND_LEFT_F_RESET;BEHIND_LEFT_B_SET
      #define BEHIND_LEFT_STOP   BEHIND_LEFT_F_RESET;BEHIND_LEFT_B_RESET
      
      //右后
      #define BEHIND_RIGHT_GO    BEHIND_RIGHT_F_SET;BEHIND_RIGHT_B_RESET
      #define BEHIND_RIGHT_BACK  BEHIND_RIGHT_F_RESET;BEHIND_RIGHT_B_SET
      #define BEHIND_RIGHT_STOP  BEHIND_RIGHT_F_RESET;BEHIND_RIGHT_B_RESET
      
      
      //全局变量定义
      #define SPEED_DUTY 40//默认占空比 按1ms最小分辨率 周期50ms计算
      unsigned int speed_count=0;//占空比计数器 50次一周期
      char front_left_speed_duty=SPEED_DUTY;
      char front_right_speed_duty=SPEED_DUTY;
      char behind_left_speed_duty=SPEED_DUTY;
      char behind_right_speed_duty=SPEED_DUTY;
      

      定时器实现小车PWM控制

      void timer_callback(void *arg)
      {
          /*sec_count++;
          printf(" timer irq: %d\n\r", sec_count);
          IoTGpioSetOutputVal(11, sec_count%2);*/
      	
      	tick_1ms++;
      	if(tick_1ms >= 10)
      	{
      		tick_1ms = 0;
      		speed_count++;
      		tick_5ms++;
      		if(speed_count >= 50)
      		{
      			speed_count = 0;
      		}
      		CarMove();
      	}	
      }
      int timer_init(void)
      {
          HAL_Status status = HAL_ERROR;
          TIMER_InitParam param;
      
          param.arg = NULL;
          param.callback = timer_callback;
          param.cfg = HAL_TIMER_MakeInitCfg(TIMER_MODE_REPEAT,      /*timer mode*/
                                            TIMER_CLK_SRC_HFCLK,      /*HFCLOCK*/
                                            TIMER_CLK_PRESCALER_4); /*CLK_PRESCALER*/
          param.isEnableIRQ = 1;
          param.period = COUNT_TIME * (HFCLOCK / CLK_PRESCALER);
      
          status = HAL_TIMER_Init(TIMERID, &param);
          if (status != HAL_OK)
              printf("timer int error %d\n", status);
      
          return status;
      }
      

      小车前进函数,根据占空比驱动电机转动

      void CarMove(void)
      {   
        //左前轮
      	if(front_left_speed_duty > 0)//向前
      	{
      		if(speed_count < front_left_speed_duty)
      		{
      			FRONT_LEFT_GO;
      		}else
      		{
      			FRONT_LEFT_STOP;
      		}
      	}
      	else if(front_left_speed_duty < 0)//向后
      	{
      		if(speed_count < (-1)*front_left_speed_duty)
      		{
      			FRONT_LEFT_BACK;
      		}else
      		{
      			FRONT_LEFT_STOP;
      		}
      	}
      	else                //停止
      	{
      		FRONT_LEFT_STOP;
      	}
      	
      		//右前轮
      	if(front_right_speed_duty > 0)//向前
      	{
      		if(speed_count < front_right_speed_duty)
      		{
      			FRONT_RIGHT_GO;
      		}else                //停止
      		{
      			FRONT_RIGHT_STOP;
      		}
      	}
      	else if(front_right_speed_duty < 0)//向后
      	{
      		if(speed_count < (-1)*front_right_speed_duty)
      		{
      			FRONT_RIGHT_BACK;
      		}else                //停止
      		{
      			FRONT_RIGHT_STOP;
      		}
      	}
      	else                //停止
      	{
      		FRONT_RIGHT_STOP;
      	}
      	
      	//左后轮
      	if(behind_left_speed_duty > 0)//向前
      	{
      		if(speed_count < behind_left_speed_duty)
      		{
      			BEHIND_LEFT_GO;
      		}	else                //停止
      		{
      			BEHIND_LEFT_STOP;
      		}
      	}
      	else if(behind_left_speed_duty < 0)//向后
      	{
      		if(speed_count < (-1)*behind_left_speed_duty)
      		{
      			BEHIND_LEFT_BACK;
      		}	else                //停止
      		{
      			BEHIND_LEFT_STOP;
      		}
      	}
      	else                //停止
      	{
      		BEHIND_LEFT_STOP;
      	}
      	
      		//右后轮
      	if(behind_right_speed_duty > 0)//向前
      	{
      		if(speed_count < behind_right_speed_duty)
      		{
      			BEHIND_RIGHT_GO;
      		}	else                //停止
      		{
      			BEHIND_RIGHT_STOP;
      		}
      	}
      	else if(behind_right_speed_duty < 0)//向后
      	{
      		if(speed_count < (-1)*behind_right_speed_duty)
      		{
      			BEHIND_RIGHT_BACK;
      		}	else                //停止
      		{
      			BEHIND_RIGHT_STOP;
      		}
      	}
      	else                //停止
      	{
      		BEHIND_RIGHT_STOP;
      	}
      }
      
      //向前
      void CarGo(void)
      {
      	front_left_speed_duty=25;//SPEED_DUTY 50
      	front_right_speed_duty=25;
      	behind_left_speed_duty=25;
      	behind_right_speed_duty=25;
      }
      
      //后退
      void CarBack(void)
      {
      	front_left_speed_duty=-50;//SPEED_DUTY
      	front_right_speed_duty=-50;
      	behind_left_speed_duty=-50;
      	behind_right_speed_duty=-50;
      }
      
      //向左
      void CarLeft(void)
      {
      	front_left_speed_duty=-20;
      	front_right_speed_duty=SPEED_DUTY;
      	behind_left_speed_duty=-20;
      	behind_right_speed_duty=SPEED_DUTY+10;//增加后轮驱动力
      }
      
      //向右
      void CarRight(void)
      {
      	front_left_speed_duty=SPEED_DUTY;
      	front_right_speed_duty=-20;
      	behind_left_speed_duty=SPEED_DUTY+10;//增加后轮驱动力
      	behind_right_speed_duty=-20;
      }
      
      //停止
      void CarStop(void)
      {
      	front_left_speed_duty=0;
      	front_right_speed_duty=0;
      	behind_left_speed_duty=0;
      	behind_right_speed_duty=0;
      }
      

      项目编译
      替代文字

      下载固件
      device\xradio\xr806\xr_skylark\out\xr_system.img
      替代文字

      PC端TCP客服端边连接小车下发指令。
      替代文字
      小车指令接收串口打印
      替代文字

      五、碰到问题
      编译报数据溢出错误:

      [OHOS ERROR] chmod 777 ../../../../../tools/mkimage && ../../../../../tools/mkimage  -c .image.cfg -o xr_system.img
      [OHOS ERROR] err: bin 1 and bin 2 were overlaped!
      [OHOS ERROR] Overlapped size: 1024 Byte(1kB)
      [OHOS ERROR] bin 1 name:app.bin    begin: 0x00008000    end: 0x00018000
      [OHOS ERROR] bin 2 name:app_xip.bin    begin: 0x00017C00
      [OHOS ERROR] 
      [OHOS ERROR] We've rearranged bin files and generated new cfg file 'image_auto_cal.cfg', the new one is recommended.
      [OHOS ERROR] Generate image file failed
      [OHOS ERROR] cfg string:
      [OHOS ERROR] /*
      [OHOS ERROR]  *
      [OHOS ERROR]  * Automatically generated file; DO NOT EDIT.
      [OHOS ERROR]  * XR806 SDK Configuration
      [OHOS ERROR]  *
      [OHOS ERROR]  */
      [OHOS ERROR] {
      [OHOS ERROR]     "magic" : "AWIH",
      [OHOS ERROR]     "version" : "0.5",
      [OHOS ERROR]     "image" : {"max_size": "1532K"},
      [OHOS ERROR]     "section" :[
      [OHOS ERROR]   {"id": "0xa5ff5a00", "bin" :"boot_40M.bin", "cert": "null", "flash_offs": "0K", "sram_offs": "0x00230000", "ep": "0x00230101", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5fe5a01", "bin" :"app.bin", "cert": "null", "flash_offs": "32K", "sram_offs": "0x00201000", "ep": "0x00201101", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5fd5a02", "bin" :"app_xip.bin", "cert": "null", "flash_offs": "95K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x2"},
      [OHOS ERROR]   {"id": "0xa5fa5a05", "bin" :"wlan_bl.bin", "cert": "null", "flash_offs": "1166K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5f95a06", "bin" :"wlan_fw.bin", "cert": "null", "flash_offs": "1169K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      [OHOS ERROR]   {"id": "0xa5f85a07", "bin" :"sys_sdd_40M.bin", "cert": "null", "flash_offs": "1194K", "sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      [OHOS ERROR]   {}
      [OHOS ERROR]  ]
      [OHOS ERROR] }
      

      查找出错点:
      openharmony$ grep "1532K" device/xradio/xr806/xr_skylark/project -rn

      device/xradio/xr806/xr_skylark/project/example/audio_play/image/xr806/image.cfg:6:    "image"   : {"max_size": "1532K", "xz_max_size": "1200K"},
      device/xradio/xr806/xr_skylark/project/example/audio_play/image/xr806/image.cfg:8:    "image"   : {"max_size": "1532K"},
      device/xradio/xr806/xr_skylark/project/demo/audio_demo/image/xr806/image.cfg:4:    "image" : {"max_size": "1532K"},
      device/xradio/xr806/xr_skylark/project/demo/audio_demo/image/xr806/image_auto_cal.cfg:10:    "image" : {"max_size": "1532K"},
      device/xradio/xr806/xr_skylark/project/demo/audio_demo/image/xr806/.image.cfg:10:    "image" : {"max_size": "1532K"},
      

      XR806/openharmony/device/xradio/xr806/xr_skylark/project/demo/audio_demo/image/xr806$ ls -l

      总用量 2404
      -rwxrwxr-x 1 boarmy boarmy   64456 1月  17 20:01 app.bin
      -rwxrwxr-x 1 boarmy boarmy 1095680 1月  17 20:01 app_xip.bin
      -rwxrwxr-x 1 boarmy boarmy   25024 1月  17 20:01 boot_40M.bin
      -rw-rw-r-- 1 boarmy boarmy    1067 1月  17 20:01 image_auto_cal.cfg
      -rwxrwxr-x 1 boarmy boarmy     982 1月   9 12:51 image.cfg
      -rwxrwxr-x 1 boarmy boarmy     792 1月  17 20:01 sys_sdd_40M.bin
      -rwxrwxr-x 1 boarmy boarmy    2320 1月  17 20:01 wlan_bl.bin
      -rwxrwxr-x 1 boarmy boarmy   25492 1月  17 20:01 wlan_fw.bin
      -rw-rw-r-- 1 boarmy boarmy 1223512 1月  17 19:51 xr_system.img
      

      可找到image.cfg

      {
          "magic" : "AWIH",
          "version" : "0.5",
          "image" : {"max_size": "1532K"},
          "section" :[
      		{"id": "0xa5ff5a00", "bin" :"boot_40M.bin",	"cert": "null",	"flash_offs": "0K",	"sram_offs": "0x00230000", "ep": "0x00230101", "attr":"0x1"},
      		{"id": "0xa5fe5a01", "bin" :"app.bin",	"cert": "null",	"flash_offs": "32K",	"sram_offs": "0x00201000", "ep": "0x00201101", "attr":"0x1"},
      		{"id": "0xa5fd5a02", "bin" :"app_xip.bin",	"cert": "null",	"flash_offs": "95K",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x2"},
      		{"id": "0xa5fa5a05", "bin" :"wlan_bl.bin",	"cert": "null",	"flash_offs": "1166K",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      		{"id": "0xa5f95a06", "bin" :"wlan_fw.bin",	"cert": "null",	"flash_offs": "1169K",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      		{"id": "0xa5f85a07", "bin" :"sys_sdd_40M.bin",	"cert": "null",	"flash_offs": "1194K",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      		{}
      	]
      }
      

      将image.cfg修改为:

      {
          "magic" : "AWIH",
          "version" : "0.5",
          "image" : {"max_size": "1532K"},
          "section" :[
      		{"id": "0xa5ff5a00", "bin" :"boot_40M.bin",	"cert": "null",	"flash_offs": "0K",	"sram_offs": "0x00230000", "ep": "0x00230101", "attr":"0x1"},
      		{"id": "0xa5fe5a01", "bin" :"app.bin",	"cert": "null",	"flash_offs": "32K",	"sram_offs": "0x00201000", "ep": "0x00201101", "attr":"0x1"},
      		{"id": "0xa5fd5a02", "bin" :"app_xip.bin",	"cert": "null",	"flash_offs": "",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x2"},
      		{"id": "0xa5fa5a05", "bin" :"wlan_bl.bin",	"cert": "null",	"flash_offs": "",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      		{"id": "0xa5f95a06", "bin" :"wlan_fw.bin",	"cert": "null",	"flash_offs": "",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      		{"id": "0xa5f85a07", "bin" :"sys_sdd_40M.bin",	"cert": "null",	"flash_offs": "",	"sram_offs": "0xffffffff", "ep": "0xffffffff", "attr":"0x1"},
      		{}
      	]
      }
      

      flash_offs - 该段bin文件存放在 FLASH 中的位置偏移,若不填写,则软件自动放在上一个文件结束的位置,以1024 byte对齐。问题解决。

      1 条回复 最后回复 回复 引用 分享 0
      • 1 / 1
      • First post
        Last post

      Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

      行为准则 | 用户协议 | 隐私权政策