瑞萨单片机论坛
直播中

jf_01200635

1年用户 26经验值
擅长:测量仪表 嵌入式技术 制造/封装 光电显示 存储技术 接口/总线/驱动 控制/MCU CRF/无线
私信 关注
[经验]

【RA-Eco-RA2E1-48PIN-V1.0开发板试用】4、UART外接WIFI模块获取天气信息

本文描述通过RA2E1的UART接口连接WIFI模块(RTL8710)通过AT指令获取网络天气信息

一、接线图

image.png

使用的WIFI模块为RTL8710,烧录原厂AT固件
RA2E1使用UART2连接RTL8710,波特率38400。
使用UART1连接PC,波特率115200,用作调试打印和结果输出

主要AT指令:
1、 ATSR :模块重启

2、 ATSE=1 :开启回显

3、 ATPW=1: station模式

4、 ATPN=ssid,password,,: 连接到AP

5、 ATPK=1 :设置自动接收

6、 ATPC=0,v1.yiketianqi.com,80: 与网站建立TCP连接

7、**ATPT=128,1:GET /api?unescape=1&version=v61&appid=84681915&appsecret=Vs4dufMa HTTP/1.1\r\nHost: gfeljm.tianqiapi.com:80\r\n\r\n**
向天气API网站发送调用API的url请求,以获取天气信息

二、FSP配置

image.png

UART1:

image.png

UART2:

image.png

三、程序

1、uart2回调函数

void user_uart2_callback (uart_callback_args_t * p_args)
{
   switch (p_args->event)
   {
      case UART_EVENT_RX_CHAR:
      {
        /* 把串口接收到的数据发送回去 */
        if(Uart2_Num>=3000) Uart2_Num=0;
        At_Rx_Buff[Uart2_Num++] = ( char ) p_args->data;
        break;
      }
      case UART_EVENT_RX_COMPLETE:
      {
        uart2_receive_complete_flag=true;
        break;
      }
      case UART_EVENT_TX_COMPLETE:
      {
        uart2_send_complete_flag = true;
        break;
      }
      default:
            break;
   }
}

2、发送AT指令函数

void RTL8710_AT_Send(char *cmd )
 {
    R_SCI_UART_Write(&g_uart2_ctrl, (uint8_t *)cmd, strlen(cmd));
    uart2_receive_complete_flag = false;
 }

3、设置WIFI模块为station模式:

void RTL8710_STA ( uint8_t timeout )
 {
    uint8_t i;
    RTL8710_AT_Send ( "ATPW=1\r\n" );

    for(i = 0; i <= timeout; i++)
    {
        if (strstr( At_Rx_Buff , "OK\r\n" ))
        {
            RTL8710_DEBUG_MSG("\r\nset RTL8710 STA \r\n");
            Clear_Buff();      //
            break;
        }
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }
 }

4、加入AP函数

void RTL8710_STA_JoinAP( char * id ,  char * password , uint8_t timeout )
 {
    char  JoinAP_AT[256];

    uint8_t i,j;

    sprintf( JoinAP_AT , "ATPN=\"%s\",%s,,\r\n" , id , password);

    RTL8710_AT_Send( JoinAP_AT );

    for(i = 0; i <= timeout; i++)
    {
          if ( strstr( At_Rx_Buff , "OK\r\n" ) )
          {
                RTL8710_DEBUG_MSG("\r\nWifi connected\r\n");
                Clear_Buff();
                break;
          }
          if ( strstr( At_Rx_Buff , "ERROR\r\n" ) )
          {
            RTL8710_DEBUG_MSG("\r\nERROR\r\n");
            for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
         }
          if ( i == timeout )
          {
                RTL8710_DEBUG_MSG("\r\nRTL8710_STA_JoinAP timeout\r\n");
                for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
          }
          R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
       }
 }

5、连接到远端网络

void RTL8710_STA_Connect(char mode,char *addr,char *port,uint8_t timeout)
 {
    char  JoinAP_AT[256];
    uint8_t i,j;
    sprintf( JoinAP_AT , "ATPC=%d,%s,%s\r\n",mode,addr,port);
    RTL8710_AT_Send( JoinAP_AT );

    for(i = 0; i <= timeout; i++)
    {
        if ( strstr( At_Rx_Buff , "con_id" ) )
        {
            con_id=getNumber(At_Rx_Buff,"con_id=");
            RTL8710_DEBUG_MSG("\r\nWifi con_id:%d\r\n",con_id);
            Clear_Buff();
            break;
        }
        else if ( strstr( At_Rx_Buff , "ERROR\r\n" ) )
        {
            RTL8710_DEBUG_MSG("\r\nRTL8710_STA_Connect ERROR,ERROR INRO %s\r\n",At_Rx_Buff);
            for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
        }
        if ( i == timeout )
        {
            RTL8710_DEBUG_MSG("\r\nRTL8710_STA_Connect timeout\r\n");
            for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
        }
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }
 }

6、向远端发送数据

void RTL8710_STA_SendData(char *Data,uint8_t timeout)
 {
    char  JoinAP_AT[256];
    uint8_t i,j;
    sprintf( JoinAP_AT , "ATPT=%d,%d:%s\r\n",strlen(Data),con_id,Data);

   
    RTL8710_AT_Send( JoinAP_AT );

    
    for(i = 0; i <= timeout; i++)
    {
        if(uart2_receive_complete_flag)
        {
            uart2_receive_complete_flag=false;
            RTL8710_DEBUG_MSG(At_Rx_Buff);
            Clear_Buff();
        }
        //ERROR:7是断开连接,收到ERROR:7就可以读返回的数据了
        if ( strstr( At_Rx_Buff ,"ERROR:7" ) )
        {
            strcpy(weather_buff,At_Rx_Buff);
            Clear_Buff();      //
            break;
        }
        if ( i == timeout )
        {
            RTL8710_DEBUG_MSG("\r\nRTL8710_STA_SendData TIMEOUT\r\n");
            for(j=0;j<10;j++) RTL8710_ERROR_Alarm();
        }
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }
 }

7、设置或取消自动接收数据

void RTL8710_STA_ATPK(int enable,uint8_t timeout)
{
    char  JoinAP_AT[256];
    uint8_t i;
    sprintf( JoinAP_AT , "ATPK=%d\r\n",enable);
    RTL8710_AT_Send( JoinAP_AT );

    for(i = 0; i <= timeout; i++)
    {
        if ( strstr( At_Rx_Buff , "OK\r\n" ) )
        {
            RTL8710_DEBUG_MSG("\r\nATPK success\r\n");
            Clear_Buff();      //
            break;
        }
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }
}

8、断开连接

void RTL8710_STA_DisConnect(int id,uint8_t timeout)
  {
    char  JoinAP_AT[256];
    uint8_t i;
    sprintf( JoinAP_AT , "ATPD=%d\r\n",id);
    RTL8710_AT_Send( JoinAP_AT );

    for(i = 0; i <= timeout; i++)
    {
        if ( strstr( At_Rx_Buff , "OK\r\n" ) )
        {
            RTL8710_DEBUG_MSG("\r\n disconnected success!\r\n");
            Clear_Buff();
            break;
        }
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }
  }

9、调用前面的函数,获取网络天气数据

void RTL8710_STA_Test(void)
{
    char buff[20];
    char Data[]="GET /api?unescape=1&version=v61&appid=84681915&appsecret=Vs4dufMa HTTP/1.1\r\nHost: gfeljm.tianqiapi.com:80\r\nConnection: close\r\n\r\n";
    //STA mode
    RTL8710_STA(2);
    //join ap
    RTL8710_STA_JoinAP( ID , PASSWORD , 5 );
    //connect server
    RTL8710_STA_Connect(0, SeverIP , SeverPort , 5 );
    //set auto recevice data
    RTL8710_STA_ATPK(1,5);
    //send data to server
    RTL8710_STA_SendData(Data,10);
   
    //从网站返回的信息中提取除json数据段
    getjson(weather_buff);
    //disconnect server
    RTL8710_STA_DisConnect(con_id,5);

    //从json中解析出城市、温度、时间
    extract_item_from_json(weather_json,"\"cityEn\":\"",buff);
    printf("CITY:[%s]\r\n",buff);
	extract_item_from_json(weather_json,"\"tem\":\"",buff);
    printf("tem:[%s]\r\n",buff);
	extract_item_from_json(weather_json,"\"date\":\"",buff);
    printf("date:[%s]\r\n",buff);
}

10、从网站返回的信息中提取除json数据段

void getjson(char *Data)
{
    char *start,*end;
    size_t length;
    start=strstr(Data,"{");
    end=strstr(start,"\n");
    length=end-start-1;
    strncpy(weather_json,start,length);

    start=end;
    end=strstr(start,"[ATPR] OK,");
    start=end;
    end=strstr(start,":");
    start=end+1;
    end=strstr(start,"\n");
    length=end-start-1;
    strncpy(weather_json+strlen(weather_json),start,length);
    weather_json[strlen(weather_json)] = '\0';

}

11、从json中解析出城市、温度、时间
本来想用cjson来解析的,但是一直没有成功,就自己解析了。

void extract_item_from_json(const char *json_str,char *itemname,char *target)
{
	char *start = strstr(json_str, itemname); // 查找"cityEn":"
	char *end;
	size_t len=20;
	char item[20]; // +1 for null terminator

	 if (start != NULL) {
        start += strlen(itemname); // 跳过itemname
        end = strchr(start, '"'); // 查找下一个双引号
        if (end != NULL) {
            // 提取
            len = end - start;
            strncpy(item, start, len);
            item[len] = '\0'; // 添加字符串结束符
            printf("Item: %s\n", item);

			strncpy(target, item, len);
			target[len] = '\0'; // 添加字符串结束符


        }
    } else {
        printf("Item[%s] not found in the JSON string.\n",itemname);
    }
}

四、串口输出

image.png

更多回帖

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