用Ai-M61实现物联网开发(1)---连接巴法云

[复制链接]
查看1107 | 回复8 | 2023-12-25 15:48:59 | 显示全部楼层 |阅读模式
本帖最后由 zzbinfo 于 2023-12-26 14:02 编辑

     收到安信可送出的M61已经有一段时间了,一直在考虑用这块板子做些什么。之前用ESP32和ESP8266通过Arduino 下开发都实现过连接巴法云,达到远程控制的功能,由简入手,自然也想到用M61实现同样的功能会比较容易。
    通过熟悉和安装M61在Arduino 下的开发环境后发现,由于缺少Arduino 必要wifi连接库的支持,短期内在Arduino 下开发M61的应用还是比较困难的,通过尝试移植WiFi库等一系列的失败后,重新返回到用Visual Studio Code+BL616_SDK开发。
    今天终于依葫芦画瓢的通过修改自带的例程实现了连接巴法云的功能,赶快发帖分享一下。在此声明一下,我的代码水平比较菜,只是记录我的学习过程,希望高手不吝赐教。
  1. static struct bflb_device_s *uart0;
  2. static uint32_t sta_ConnectStatus = 0;
  3. static uint8_t sta_ConnectStatus1 = 0;
  4. static TaskHandle_t wifi_fw_task;
  5. int sock_client = -1;
  6. #define MAXSIZE 1024
  7. #define beserver_ip    "bemfa.com"  //"192.168.110.233" //"bemfa.com" //巴法云服务器地址默认即可
  8. #define beserver_port "8344" //服务器端口,tcp创客云端口8344
  9. //static const char* UID = "********";  //用户私钥,可在控制台获取,修改为自己的UID
  10. //static const char* TOPIC = "******";         //主题名字,可在控制台新建
  11. static const char subscribe[] = "cmd=1&uid=******&topic=******\r\n"; //构建订阅指令
  12. static const char Keep_alive_str[] = "cmd=7&uid=****&type=1\r\n";//心跳数据
  13. struct sockaddr_in  client_addr;
复制代码
有关巴法云的编程接口可以参照官网的说明,应该跟很多物联网平台类似。
  1. uint8_t wifi_connect()
  2. {
  3.     char* ssid = "******";
  4.     char* passwd = "*****";

  5.     uint32_t ipv4_addr = 0;

  6.     if (wifi_mgmr_sta_state_get() == 1) {
  7.         wifi_sta_disconnect();
  8.     }
  9.     if (wifi_sta_connect(ssid, passwd, NULL, NULL, 0, 0, 0, 1)) {
  10.         return 4;
  11.     }

  12.     //等待连接成功
  13.     sta_ConnectStatus = 0;
  14.     for (int i = 0;i<10*30;i++)
  15.    // while(true)
  16.     {
  17.         vTaskDelay(100);
  18.         switch (sta_ConnectStatus)
  19.         {
  20.             case CODE_WIFI_ON_CONNECTED:        //连接成功(表示wifi sta状态的时候表示同时获取IP(DHCP)成功,或者使用静态IP)
  21.                 LOG_I("CODE_WIFI_ON_CONNECTED\r\n");
  22.                 break;
  23.             case CODE_WIFI_ON_DISCONNECT:        //连接失败(超过了重连次数还没有连接成功的状态)
  24.                 wifi_sta_disconnect();
  25.                 return 4;
  26.                 break;
  27.             case CODE_WIFI_ON_GOT_IP:       //获取IP
  28.                 wifi_sta_ip4_addr_get(&ipv4_addr, NULL, NULL, NULL);
  29.                 LOG_I("CODE_WIFI_ON_GOT_IP\r\n");
  30.                 //LOG_I("wifi_sta_ip4_addr_get = %X\r\n",ipv4_addr);
  31.                 LOG_I("wifi_sta_ip4_addr_get = %d.%d.%d.%d\r\n",(uint8_t)ipv4_addr,(uint8_t)(ipv4_addr>>8),(uint8_t)(ipv4_addr>>16),(uint8_t)(ipv4_addr>>24));//uint8_t
  32.                 return 0;
  33.             default:
  34.                 //等待连接成功
  35.                 break;
  36.         }
  37.     }
  38.     return -1; //连接超时
  39. }



  40. static void wifi_connection()
  41. {
  42.     while (1)
  43.     {
  44.         if (sta_ConnectStatus == CODE_WIFI_ON_MGMR_DONE)
  45.         { // WIFI管理初始化完毕
  46.           if(wifi_connect()==0){
  47.             sta_ConnectStatus1 = 1;
  48.             LOG_I("wifi_connect() \r\n");
  49.           }
  50.          
  51.          //   wifi_connect();
  52.         }        
  53.         vTaskDelay(3000/portTICK_PERIOD_MS);
  54.     }
  55. }
复制代码
有关WiFi的连接部分,大家可以参照论坛中的配网知识来做成网页自动配网,我还没来得及学习,只能代码里面写成固定的了。

  1. static void wifi_tcp_client_close()
  2. {
  3.     if (sock_client) {
  4.         closesocket(sock_client);
  5.     }

  6. }

  7. static void wifi_tcp_client_init(char *host_name,char *port)
  8. {
  9.     LOG_I("tcp client task start ...\r\n");
  10.     char *addr;

  11.     ip4_addr_t dns_ip;
  12.     netconn_gethostbyname(host_name, &dns_ip);
  13.     addr = ip_ntoa(&dns_ip);

  14.    // while (1) {
  15.         if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  16.             LOG_E("TCP Client create socket error\r\n");
  17.             return;
  18.         }
  19.         client_addr.sin_family = AF_INET;
  20.         client_addr.sin_port = htons(atoi(port));
  21.         client_addr.sin_addr.s_addr = inet_addr(addr);
  22.         memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));

  23.         printf("Server ip Address : %s:%s\r\n", addr, port);

  24.         if (connect(sock_client, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) != 0) {
  25.             LOG_E("TCP client connect server falied!\r\n");
  26.             closesocket(sock_client);
  27.             return;
  28.         }

  29.         LOG_I("TCP client connect server success!\r\n");

  30.    // }
  31. }
  32. int wifi_tcp_client_send(const char *send_buf,uint8_t buf_size)
  33. {   
  34.    int cont = 0;
  35.    if(sock_client){
  36.       cont = write(sock_client, send_buf, buf_size) ;
  37.             if (cont < 0) {
  38.                 LOG_E("write socket falied!\r\n");
  39.                 wifi_tcp_client_close();
  40.                 sock_client = -1;
  41.             }

  42.    }
  43.    return cont;
  44. }

  45. int wifi_tcp_client_recv(uint8_t *recv_buf)
  46. {   
  47.    int cont = 0;
  48.    if(sock_client){
  49.       cont = read(sock_client, recv_buf, MAXSIZE) ;
  50.             if (cont < 0) {
  51.                 LOG_E("read socket falied!\r\n");
  52.             }

  53.    }
  54.    return cont;
  55. }

  56. static void wifi_tcp_client_read()
  57. {
  58.     uint8_t recv_buf[1024]={0};
  59.     while (1)
  60.     {
  61.         if((sock_client > 0)&&(sta_ConnectStatus1 ==  1)){

  62.             int  bufsize = wifi_tcp_client_recv(recv_buf);  //这里原来是uint8_t 类型,需要改成int,有bug。
  63.             if(bufsize>0){          //处理接收到的数据
  64.                 recv_buf[bufsize+1]=0;
  65.                LOG_I("read socket msg = [%s]\r\n",recv_buf);

  66.             }else {
  67.                 LOG_I("wifi_tcp_client_close\r\n");
  68.                 wifi_tcp_client_close();
  69.                sock_client = -1;
  70.             }
  71.         }
  72.         vTaskDelay(1000/portTICK_PERIOD_MS);
  73.     }
  74.    
  75. }
  76. static void wifi_tcp_client_creat()
  77. {
  78.    
  79.     static uint8_t delay_cont = 0;
  80.      while (1)
  81.     {
  82.         delay_cont++;
  83.         if (sta_ConnectStatus1 ==  1)        //连接成功(表示wifi sta状态的时候表示同时获取IP(DHCP)成功,或者使用静态IP)
  84.         {
  85.         if(sock_client < 0){

  86.                 LOG_I("wifi_tcp_client_init\r\n");
  87.                 wifi_tcp_client_init(beserver_ip,beserver_port);
  88.                 if(sock_client){
  89.                  wifi_tcp_client_send(subscribe,sizeof(subscribe)); //发送注册指令  
  90.                 }
  91.         }
  92.         if(delay_cont >=60){
  93.             delay_cont = 0;
  94.             if(sock_client){
  95.               LOG_I("wifi_tcp_client_send\r\n");
  96.               wifi_tcp_client_send(Keep_alive_str,sizeof(Keep_alive_str)); //发送心跳数据  
  97.             }
  98.             
  99.         }        
  100.         }  


  101.         vTaskDelay(1000/portTICK_PERIOD_MS);
  102.     }
  103.      wifi_tcp_client_close();   
  104. }
复制代码
这部分代码实现了类似于Arduino 下的WiFiClient的功能,用来连接巴法云并发送和接收数据。编译和下载以后,启动M61,在巴法云的管理页面已经可以看到设备已经在线了。 QQ图片20231225153912.png
通过调试工具发送指令,M61也已经可以接收到数据。
QQ图片20231225154144.png

我会把完整的代码放到帖子后面,大家编译的时候注意sdk目录。我也会抽时间把完整的远程控制代码慢慢的用M61实现。
wifi_tcp_client.rar (11.42 KB, 下载次数: 13)

本帖被以下淘专辑推荐:

回复

使用道具 举报

zzbinfo | 2023-12-25 15:51:46 | 显示全部楼层
终于交作业了
回复 支持 反对

使用道具 举报

爱笑 | 2023-12-25 16:06:52 | 显示全部楼层
不错不错
用心做好保姆工作
回复

使用道具 举报

1084504793 | 2023-12-25 18:54:59 | 显示全部楼层
回复

使用道具 举报

lazy | 2023-12-26 11:01:18 | 显示全部楼层
写的很好
回复

使用道具 举报

zzbinfo | 2023-12-26 14:04:49 | 显示全部楼层
昨天传的代码有两个地方有bug,今天稍微修改了一下。附件和正文已经更正了。
回复 支持 反对

使用道具 举报

曹县 | 2024-1-16 14:03:25 | 显示全部楼层
回复

使用道具 举报

lza | 2024-2-11 00:43:04 | 显示全部楼层
回复

使用道具 举报

lza | 2024-2-23 18:35:26 | 显示全部楼层
这个我有几个问题:
1、怎么配置巴法云平台的订阅,还有代码#include "FreeRTOS.h"这行报错。
2、ai-m61直接通过type-c连接电脑烧录main.c文件就可以了么
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则