手头上有一个ESP8266,闲置了很久,突然想起来可以和RA6M4开发板连接起来,使用AT指令来获取网络天气预报,于是就把它们连接起来。就有了这个帖子。
开始创建工程,打开

RA smart 配置软件

1.取名RA6M4_ESP

2。选择芯片

3。继续

4。finish完成


5。设置通信串口

首先P110和P109用来打印调试
配置好参数

ESP8266选择P100和P101

6。生成代码

打开KEIL工程

编译工程

两处报错,需要修改代码
#include "usart9.h"
uint8_t U1_RxBuff[RXBUFFLENGTH];
uint16_t U1_Rxlen = 0;
uint16_t U1_RxlencntPre = 0;
static volatile bool uart_send_complete_flag = false;
void UART9_Init(void)
{
fsp_err_t err = FSP_SUCCESS;
err = R_SCI_UART_Open(&g_uart9_ctrl,&g_uart9_cfg);
assert(err == FSP_SUCCESS);
}
void uart9_Send_Byte(uint8_t ch)
{
/* 发送一个字节数据到UART */
R_SCI_UART_Write(g_uart9.p_ctrl, (uint8_t *)&ch, 1);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
}
void uart9_Send_Bytes(uint8_t data, uint32_t len)
{
/ 发送一个字节数据到UART */
R_SCI_UART_Write(g_uart9.p_ctrl, data, len);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
}
void uart9_Send_String_Length(uint8_t str,uint32_t strlen)
{
unsigned int k=0;
do
{
uart9_Send_Byte ((str + k));
k++;
} while(k < strlen);
}
void uart9_Send_String(uint8_t str)
{
unsigned int k=0;
do
{
uart9_Send_Byte ((str + k));
k++;
} while(*(str + k)!='\0');
}
void user_uart_clear(void)
{
memset(U1_RxBuff, 0, sizeof(U1_RxBuff));
U1_Rxlen = 0;
}
uint8_t user_uart_wait_receive(void)
{
if(U1_Rxlen == 0)
return REV_WAIT;
if(U1_Rxlen == U1_RxlencntPre)
{
U1_Rxlen = 0;
return REV_OK;
}
U1_RxlencntPre = U1_Rxlen;
return REV_WAIT;
}
void user_uart_callback (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
if(p_args->event == UART_EVENT_RX_CHAR)
{
if(U1_Rxlen >= sizeof(U1_RxBuff)) U1_Rxlen = 0;
U1_RxBuff[U1_Rxlen++] = (uint8_t)p_args->data;
}
}
#if 1
/* 重定向 printf 输出 */
#if defined GNUC && !defined clang
int _write(int fd, char *pBuffer, int size); //防止编译警告
int _write(int fd, char *pBuffer, int size)
{
(void)fd;
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return size;
}
#else
int fputc(int ch, FILE *f)
{
(void)f;
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return ch;
}
#endif
#endif
#include "esp8266.h"
static volatile bool uart_send_complete_flag = false;
uint8_t esp8266_buf[RXBUFFLENGTH];
uint16_t esp8266_cnt = 0;
uint16_t esp8266_cntPre = 0;
char tx_buffer[150];
void UART0_Init(void)
{
fsp_err_t err = FSP_SUCCESS;
err = R_SCI_UART_Open(&g_uart7_ctrl,&g_uart7_cfg);
assert(err == FSP_SUCCESS);
}
void ESP8266_Send(char command)
{
R_SCI_UART_Write(g_uart7.p_ctrl, (uint8_t)command, strlen(command));
}
void WIFI_Send_Byte(uint8_t ch)
{
/* 发送一个字节数据到UART */
R_SCI_UART_Write(g_uart7.p_ctrl, (uint8_t *)&ch, 1);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
}
void WIFI_Send_Bytes(uint8_t data, uint32_t len)
{
/ 发送一个字节数据到UART */
R_SCI_UART_Write(g_uart7.p_ctrl, data, len);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
}
void WIFI_Send_String_Length(uint8_t str,uint32_t strlen)
{
unsigned int k=0;
do
{
WIFI_Send_Byte ((str + k));
k++;
} while(k < strlen);
}
void WIFI_Send_String(uint8_t str)
{
unsigned int k=0;
do
{
WIFI_Send_Byte ((str + k));
k++;
} while(*(str + k)!='\0');
}
void ESP8266_Clear(void)
{
memset(esp8266_buf, 0, sizeof(esp8266_buf));
esp8266_cnt = 0;
}
uint8_t ESP8266_WaitRecive(void)
{
if(esp8266_cnt == 0)
return REV_WAIT;
if(esp8266_cnt == esp8266_cntPre)
{
esp8266_cnt = 0;
return REV_OK;
}
esp8266_cntPre = esp8266_cnt;
return REV_WAIT;
}
//==========================================================
// 函数名称: ESP8266_SendCmd
//
// 函数功能: 发送命令
//
// 入口参数: cmd:命令
// res:需要检查的返回指令
//
// 返回参数: 0-成功 1-失败
//
// 说明:
//==========================================================
_Bool ESP8266_SendCmd(char *cmd, char *res)
{
unsigned char timeOut = 200;
WIFI_Send_Bytes((uint8_t *)cmd, strlen((uint8_t *)cmd));
while(timeOut--)
{
if(ESP8266_WaitRecive() == REV_OK)
{
if(strstr((const char *)esp8266_buf, res) != NULL)
{
printf("%s\r\n",esp8266_buf);
ESP8266_Clear();
return 0;
}
}
delay_ms(10);
}
return 1;
}
//==========================================================
// 函数名称: ESP8266_SendData
//
// 函数功能: 发送数据
//
// 入口参数: data:数据
// len:长度
//
// 返回参数: 无
//
// 说明:
//==========================================================
void ESP8266_SendData(uint8_t*data, uint32_t len)
{
char cmdBuf[32];
ESP8266_Clear();
sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len);
if(!ESP8266_SendCmd(cmdBuf, ">"))
{
WIFI_Send_Bytes(data, len);
}
}
//==========================================================
// 函数名称: ESP8266_GetIPD
//
// 函数功能: 获取平台返回的数据
//
// 入口参数: 等待的时间(乘以10ms)
//
// 返回参数: 平台返回的原始数据
//
// 说明: 不同网络设备返回的格式不同,需要去调试
// 如ESP8266的返回格式为 "+IPD,x:yyy" x代表数据长度,yyy是数据内容
//==========================================================
uint8_t *ESP8266_GetIPD(uint16_t timeOut)
{
char *ptrIPD = NULL;
do
{
if(ESP8266_WaitRecive() == REV_OK)
{
ptrIPD = strstr((char *)esp8266_buf, "IPD,");
if(ptrIPD == NULL)
{
}
else
{
ptrIPD = strchr(ptrIPD, ':');
if(ptrIPD != NULL)
{
ptrIPD++;
return (unsigned char *)(ptrIPD);
}
else
return NULL;
}
}
delay_ms(5);
} while(timeOut--);
return NULL;
}
//==========================================================
// 函数名称: ESP8266_Init
//
// 函数功能: 初始化ESP8266
//
// 入口参数: 无
//
// 返回参数: 无
//
// 说明:
//==========================================================
void ESP8266_Init(void)
{
#define WIFI_SSID "CMCC-c2H2" // WIFI的名称 必须用2.4G的wifi不能用5G的,且不能用中文、空格
#define WIFI_PSWD "62x9wttb" // WIFI密码
#define SERVER_HOST "broker.emqx.io" // MQTT服务器域名或IP
#define SERVER_PORT "1883" // MQTT服务器端口(一般为1883不用改)
char WIFI_Start[]="AT+CWJAP="CMCC-42A3","u2Kn7bm3"\r\n";
#define ESP8266_WIFI_INFO "AT+CWJAP="" WIFI_SSID "","" WIFI_PSWD ""\r\n"
#define ESP8266_ONENET_INFO "AT+CIPSTART="TCP","" SERVER_HOST ""," SERVER_PORT "\r\n"
ESP8266_Clear();
while(ESP8266_SendCmd("AT\r\n", "OK\r\n"));
while(ESP8266_SendCmd("ATE1\r\n", "OK\r\n"));
while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK\r\n"));
while(ESP8266_SendCmd(WIFI_Start, "OK\r\n"));
while(ESP8266_SendCmd("AT+CIPMUX=0\r\n", "OK\r\n"));
}
void Wifi_connect(char *SSID, char *Password)
{
uint8_t err = 0;
ESP8266_SendCmd("AT+CWQAP\r\n", "OK");
delay_ms(1500);
sprintf(tx_buffer, "AT+CWJAP=\"%s\",\"%s\"\r\n", SSID, Password);
ESP8266_SendCmd(tx_buffer,"OK");
}
void MQTT_Connect(char *ip,char *port)
{
sprintf(tx_buffer,"AT+MQTTUSERCFG=0,1,"1","1","1",0,0,""\r\n");
ESP8266_SendCmd(tx_buffer,"OK");
sprintf(tx_buffer,"AT+MQTTCONN=0,\"%s\",%s,0\r\n",ip,port);
ESP8266_SendCmd(tx_buffer,"OK");
}
/*******************************************************
函数名:void MQTT_Subscribe(char *tipname)
功能:订阅MQTT主题
参数:
@tipname:主题字
*******************************************************/
void MQTT_Subscribe(char *tipname)
{
sprintf(tx_buffer,"AT+MQTTSUB=0,"%s",0\r\n",tipname);
ESP8266_SendCmd(tx_buffer,"OK");
}
void MQTT_Publish(char *topicName,char *message)
{
sprintf(tx_buffer,"AT+MQTTPUB=0,"%s","%s",0,0\r\n",topicName,message);
ESP8266_SendCmd(tx_buffer,"OK");
}
void Read_Message(char message)
{
char buff = esp8266_buf;
/----------- 处理数据 ---------------/
if(strstr(buff,"+MQTTSUBRECV:0") == NULL) return ;
buff = strstr(buff,"",")+2;
buff = strstr(buff,",")+1;
strcpy(message,buff);
printf("收到的数据是: %s\r\n",message);
}
void esp8266_wifi (uart_callback_args_t * p_args)
{
if(p_args->event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
if(p_args->event == UART_EVENT_RX_CHAR)
{
if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //防止串口被刷爆
esp8266_buf[esp8266_cnt++] = (uint8_t)p_args->data;
}
}
#if 0
/* 重定向 printf 输出 */
#if defined GNUC && !defined clang
int _write(int fd, char *pBuffer, int size); //防止编译警告
int _write(int fd, char *pBuffer, int size)
{
(void)fd;
R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return size;
}
#else
int fputc(int ch, FILE *f)
{
(void)f;
R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
while(uart_send_complete_flag == false);
uart_send_complete_flag = false;
return ch;
}
#endif
#endif
下面是获取天气预报核心代码
#include "hal_data.h"
#include "usart9.h"
#include "usart6.h"
#include "modbusSlave.h"
#include "esp8266.h"
#include "onenet.h"
#include "MqttKit.h"
#include "cJSON.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
void delay_ms(uint32_t ms)
{
R_BSP_SoftwareDelay(ms, BSP_DELAY_UNITS_MILLISECONDS);
}
uint16_t timeCount = 0;
char PUB_BUF[256];//上传数据的buf(温度,湿度,光照强度,LED和蜂鸣器)
const char *devSubTopic[] = {"LED"}; // 设备订阅命令地址,MQTTX发送命令到服务器,stm32接收命令
const char devPubTopic[] = "RA6M4-Temperature"; // 设备上行数据地址,stm32传感器向服务器传输数据并使用MQTTX接收
uint8_t alarmFlag;//是否报警的标志
uint8_t alarm_is_free;
char TX_Data[]="GET https://api.seniverse.com/v3/weather/now.json?key=SfobYEEioM5L6dRce&location=wuhan&language=zh-Hans&unit=c\r\n";
char Data[]="AT+CIPSEND\r\n";
/*******************************************************************************************************************//**
-
main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
-
is called by main() when no RTOS is used.
*********************************************************************************************************************/
void hal_entry(void)
{
/ TODO: add your own code here */
UART9_Init();UART6_Init();UART0_Init();
uint8_t *dataPtr = NULL;
ESP8266_Init();
unsigned char wifi_flag = 0;
char ipaddr[16];
char gateway[16];
uint32_t latest_time = 0;
int rv = -1;
printf("很高兴使用瑞萨RA6M4开发板********\r\n");
printf("串口输出打印 波特率115200\r\n\r\n");
#if 1
printf("\r\nESP8266城市天气预报 \r\n\r\n");
ESP8266_Init();
printf("INFO:Enable ESP8266_Init successfully ==================初始化完成\r\n");
while(ESP8266_SendCmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n", "CONNECT\r\n"));
while(ESP8266_SendCmd("AT+CIPMODE=1\r\n", "OK"));
ESP8266_SendData(TX_Data,strlen(TX_Data));
delay_ms(500);
printf("%d\r\n",esp8266_cnt);
printf("%d\r\n",strlen(esp8266_buf));
printf("原始天气数据\r\n");
printf("*****************************************************************************\r\n");
printf("%s\r\n",esp8266_buf);
printf("*****************************************************************************\r\n");
cJSON *json;
cJSON *Array_obj1;
cJSON *Array_obj2;
cJSON *Array_obj3;
cJSON *Array_obj4;
cJSON *Array_obj5;
cJSON *Array_obj6;
cJSON *Array_obj7;
cJSON *Array_obj8;
cJSON *Array;
json = cJSON_Parse((const char *) esp8266_buf );
Array_obj1=cJSON_GetObjectItem(json,"results");
int size=cJSON_GetArraySize(Array_obj1);
printf("\r\nCJSON解析后的数据\r\n");
printf("=============================================================================\r\n");
if(json == NULL)
printf("\njson fmt error:%s\n.", cJSON_GetErrorPtr());
else
{
Array=cJSON_GetArrayItem(Array_obj1,0);
Array_obj2=cJSON_GetObjectItem(Array,"now");
Array_obj3=cJSON_GetObjectItem(Array_obj2,"code");
Array_obj4=cJSON_GetObjectItem(Array_obj2,"temperature");
Array_obj5=cJSON_GetObjectItem(Array_obj2,"text");
Array_obj6=cJSON_GetObjectItem(Array,"location");
Array_obj7=cJSON_GetObjectItem(Array_obj6,"name");
Array_obj8=cJSON_GetObjectItem(Array,"last_update");
printf("城市: %s ",Array_obj7->valuestring);
printf("天气: %s ",Array_obj5->valuestring);
printf("气温: %s度 ",Array_obj4->valuestring);
printf("时间: %s\r\n",Array_obj8->valuestring);
printf("=============================================================================\r\n");
}
cJSON_Delete(json);
ESP8266_Send("+++");
#endif
while(1)
{
// if(user_uart6_wait_receive( ) == REV_OK)
// {
// modbus_slave();
// user_uart6_clear();
// }
//
// //printf("ruisa dizn zi ---------------\n");
// R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/*******************************************************************************************************************//**
-
This function is called at various points during the startup process. This implementation uses the event that is
-
called right before main() to set up the pins.
-
@param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart (bsp_warm_start_event_t event)
{
if (BSP_WARM_START_RESET == event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
R_FACI_LP->DFLCTL = 1U;
#endif
}
if (BSP_WARM_START_POST_C == event)
{
R_IOPORT_Open(&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
#if BSP_CFG_SDRAM_ENABLED
R_BSP_SdramInit(true);
#endif
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif

编译工程,烧录代码带RA6M4


打开串口助手

{"results":[{"location":{"id":"WT3Q0FW9ZJ3Q","name":"武汉","country":"CN","path":"武汉,武汉,湖北,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"多云","code":"4","temperature":"33"},"last_update":"2025-07-25T21:27:40+08:00"}]}
CJSON解析后的数据
城市: 武汉 天气: 多云 气温: 33度 时间: 2025-07-25T21:27:40+08:00
可以看到获取了武汉天气预报
打开手机,进行比较

可以看到和手机上的天气预报一样准确
切换城市到 三亚
char TX_Data[]="GET https://api.seniverse.com/v3/weather/now.json?key=SfobYEEioM5L6dRce&location=sanya&language=zh-Hans&unit=c\r\n";


{"results":[{"location":{"id":"W7JZGDR3YYTF","name":"三亚","country":"CN","path":"三亚,三亚,海南,中国","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"阴","code":"9","temperature":"26"},"last_update":"2025-07-25T21:30:19+08:00"}]}
CJSON解析后的数据
城市: 三亚 天气: 阴 气温: 26度 时间: 2025-07-25T21:30:19+08:00
打开手机查看三亚天气预报

通过比较,天气预报非常的准确!!!!!!