嵌入式技术论坛
直播中

贾永世

8年用户 1901经验值
私信 关注
[经验]

如何实现RTT RA2L1 MQTT网络温湿度采集的设计呢

  在这一篇的基础之上,添加串口,AT-Client软件包
  1、添加uart0,波特率为默认的115200。串口回调函数为默认的user_uart_callbakc,TXD、RXD 为P101、P100,刚好适配PMOD2(J7),来接DA16200。
2.jpg
  2、添加AT—client包
2.jpg
  3、打开uart0:
2.jpg
  4、编写DA16200.c的函数:
  主要的思路是先初始化at_clinet客户端,根据da16200的mqtt命令初始化。如果注册成功,向服务器订阅与发布主题,详见代码:
  /*
  * Copyright (c) 2006-2021, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date Author Notes
  * 2023-02-24 Administrator the first version
  */
  #include 《stdlib.h》
  #include 《string.h》
  #include 《rtthread.h》
  #include 《at.h》
  // #ifndef ULOG_USING_SYSLOG
  //#define LOG_TAG “AT_DA16200”
  //#define LOG_LVL LOG_LVL_DBG
  //#include 《ulog.h》
  //#else
  //#include 《syslog.h》
  //#endif /* ULOG_USING_SYSLOG */
  /* 初始化 at_client */
  /* 设置当前 AT 客户端最大支持的一次接收数据的长度 */
  #define AT_CLIENT_RECV_BUFF_LEN 512
  #define AT_CLIENT_DEVICE_NAME “uart0”
  #define AT_WAITE_OK_MAXTIME 3000
  #define WIFI_SSID HUAWEI-H10R9U
  #define WIFI_PWD 18977381885@
  #define AT_ADDR_LEN 32
  static rt_err_t wifi_connect_state = -1;
  char ip[AT_ADDR_LEN] = {0};
  char gateway[AT_ADDR_LEN] = {0}, netmask[AT_ADDR_LEN] = {0};
  static void urc_conn_func(struct at_client *client ,const char *data, rt_size_t size)
  {
  /* WIFI 连 接 成 功 信 息 */
  rt_kprintf(“AT Server device WIFI connect success!”);
  wifi_connect_state = RT_EOK;
  }
  static void urc_recv_func(struct at_client *client ,const char *data, rt_size_t size)
  {
  /* 接收到服务器发送数据 */
  char *ptr;
  char *p;
  rt_kprintf(“AT Client receive AT Server data!”);
  rt_kprintf(“%s”,data);
  ptr = strtok(data, “:”);
  ptr = strtok(NULL, “,”);
  while (ptr != NULL) {
  rt_kprintf(“ptr=%sn”, ptr);
  ptr = strtok(NULL, “,”);
  }
  }
  int da16200_mqtt_pub(char *msg)
  {
  int result = RT_EOK;
  at_response_t resp = RT_NULL;
  if(wifi_connect_state != RT_EOK)
  {
  rt_kprintf(“MQTT_client not ready!”);
  return -1;
  }
  resp = at_create_resp(256, 0, rt_tick_from_millisecond(5000));
  if (resp == RT_NULL)
  {
  rt_kprintf(“No memory for response structure!”);
  return -2;
  }
  result = at_exec_cmd(resp, “AT+NWMQMSG=‘%s’”,msg);
  if(resp 《 0)
  {
  rt_kprintf(“Pub msg ERRO! cord:%d”, result);
  }
  at_delete_resp(resp);
  return result;
  }
  static void urc_func(struct at_client *client ,const char *data, rt_size_t size)
  {
  /* 设备启动信息 */
  rt_kprintf(“AT Server device startup!”);
  rt_kprintf(“%s”,data);
  }
  static struct at_urc urc_table[] = {
  {“+NWMQCL:1”, “rn”, urc_conn_func},
  {“+NWMQMSG:”, “rn”, urc_recv_func},
  {“RDY”, “rn”, urc_func},
  };
  int at_client_port_init(void)
  {
  /* 添加多种 URC 数据至 URC 列表中,当接收到同时匹配 URC 前缀和后缀的数据,执行 URC 函数 */
  at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
  return RT_EOK;
  }
  int at_client_16200_mqtt_init(void)
  {
  int result = RT_EOK;
  at_response_t resp = RT_NULL;
  /* 创建响应结构体,设置最大支持响应数据长度为 256 字节
  (最大响应长度用户根据实际需求自定义),响应数据行数无限制,超时时间为 5 秒 */
  resp = at_create_resp(256, 0, rt_tick_from_millisecond(5000));
  if (resp == RT_NULL)
  {
  rt_kprintf(“No memory for response structure!”);
  return -2;
  }
  result = at_client_init(AT_CLIENT_DEVICE_NAME, AT_CLIENT_RECV_BUFF_LEN);
  if(result != RT_EOK)
  {
  rt_kprintf(“at_clinet init erro %d”,result);
  return result;
  }
  /* 等待AT OK */
  result = at_client_wait_connect(AT_WAITE_OK_MAXTIME);
  if(result != RT_EOK)
  {
  rt_kprintf(“client to da16200 at timeout %d”,result);
  return result;
  }
  /* 设置回显 */
  if(at_exec_cmd(resp, “ATE”) != RT_EOK)
  {
  rt_kprintf(“AT client send ATE failed,response error!”);
  return -RT_ERROR;
  }
  /* 解释返回显状态 如果返回是on 则再发一条关闭 */
  if(at_resp_get_line_by_kw(resp, “on”) != NULL)
  {
  at_exec_cmd(resp, “ATE”);
  }
  /* 设置 station模式 */
  if(at_exec_cmd(resp, “AT+WFMODE=0”) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+WFMODE failed,response error!”);
  return -RT_ERROR;
  }
  /* 连接到 ap */
  if(at_exec_cmd(resp, “AT+WFJAPA=ssid,pwd”) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+WFWFJAPA failed,response error!”);
  return -RT_ERROR;
  }
  rt_thread_delay(2000);
  /* 查看IP服务器 */
  if(at_exec_cmd(resp, “AT+NWIP”) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+NWIP failed,response error!”);
  return -RT_ERROR;
  }
  rt_thread_delay(1000);
  //LOG_D(“recv:%s,recv line:%d”,resp-》buf,resp-》line_num);
  if(at_resp_parse_line_args(resp,2,“%*[^,],%[^,]”,&ip)》0)
  {
  rt_kprintf(“ip:%s ”,ip);
  }
  else{
  rt_kprintf(“NWIP erro”);
  return -RT_ERROR;
  }
  /* 连接MQTT服务器*/
  if(at_exec_cmd(resp, “AT+NWMQBR=%s,%d”,“192.168.3.192”,1883) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+NWMQBR failed,response error!”);
  return -RT_ERROR;
  }
  /* 设置订阅主题 */
  if(at_exec_cmd(resp, “AT+NWMQTS=%d,%s”,1,“lugl_sub”) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+NWMQTS failed,response error!”);
  return -RT_ERROR;
  }
  /* 设置发布主题 */
  if(at_exec_cmd(resp, “AT+NWMQTP=%s”,“lugl_pub”) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+NWMQTP failed,response error!”);
  return -RT_ERROR;
  }
  at_client_port_init();
  /* 使能MQTT */
  if(at_exec_cmd(resp, “AT+NWMQCL=1”) != RT_EOK)
  {
  rt_kprintf(“AT client send AT+NWMQCL failed,response error!”);
  return -RT_ERROR;
  }
  /* 删 除 服 务 器 响 应 结 构 体 */
  at_delete_resp(resp);
  return RT_EOK;
  }
  hal_entry.c:
  extern struct hs300x_device temp_humi_dev;
  void hal_entry(void)
  {
  float temp_f,humi_f;
  char mqtt_send_buf[128] = {0};
  rt_kprintf(“nHello RT-Thread!n”);
  rt_uint32_t led1_pin = rt_pin_get(LED1_PIN);
  at_client_16200_mqtt_init();
  while (1)
  {
  rt_pin_write(led1_pin, PIN_HIGH);
  rt_thread_mdelay(500);
  rt_pin_write(led1_pin, PIN_LOW);
  rt_thread_mdelay(500);
  hs300x_read_data(&temp_humi_dev, &humi_f, &temp_f);
  rt_sprintf(mqtt_send_buf,“{”temp“:”%d.%2d“,”humi“:”%d.%2d“}”,(int)temp_f,(int)(temp_f*100)%100,(int)humi_f,(int)(humi_f*100)%100);
  da16200_mqtt_pub(mqtt_send_buf);
  // rt_kprintf(“HUMI: %d.%2dn”, (int)humi_f, (int)(humi_f*100)%100);
  // rt_kprintf(“HUMI: %d.%2dn”, (int)temp_f, (int)(temp_f*100)%100);
  }
  }
  实现在的效果:
2.jpg
  打开mqtt客户端,收到数据
2.jpg
  【项目总结】作为国产的RT-Thread 实时操作系统,生态系统越来越丰富。同时也有自己的RT-Thread Studio IDE来实现图形化的配置,特别是集合了RASC的图形化配置系统。使得入门非常容易。
  【有待改善的地方】
  1、FSP的更新不向前兼容,导致会出现很多问题,这样新入门的朋友,可能被难倒在起点之处。
  2、包更新后会覆盖掉原来的一起代码,如果不做备份,非常麻烦。
  总之,通过这次DIY项目,加深了瑞萨+RT-Thread的编程印象,以后会经常关注RTT,同时也会贡献自己的力量。



原作者:Lu_盼盼

更多回帖

发帖
×
20
完善资料,
赚取积分