
上一节我已经讲解了如何获取RA-Eco-RA6M4的片内温度值,这节我就讲解如何通过手机远程获取RA-Eco-RA6M4的板子温度,它的工作原理就是运用到了互联网IOT的MQTT协议,使用MQTT协议,只要设备和手机都在联网的情况下,实现无距离全世界控制读取数据。

创建工程我就不讲了, 直接去看我之前写的帖子,里面写的非常清楚,不重复早轮子了。
这里这接将核心代码
#include "hal_data.h"
#include "usart9.h"
#include "usart6.h"
#include "modbusSlave.h"
#include "esp8266.h"
#include "onenet.h"
#include "MqttKit.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;
/*******************************************************************************************************************//**
-
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();
while(OneNet_DevLink() == 1) // 循环连接服务器
{delay_ms(500);}
OneNet_Subscribe(devSubTopic, 1); // 参数1:
//printf("modbus_slave test\r\n");
while(1)
{
if(++timeCount >= 40) // 五秒发送间隔
{
printf("OneNet_Publish \r\n");
sprintf(PUB_BUF, "{\"Temp\":%d.%d, \"Hum\":%d.%d, \"Light\":%.1f, \"LED\":%d, \"BEEP\":%d}",
22,3,33,4,1,1?0:1,alarmFlag);
OneNet_Publish(devPubTopic, "35.78c");
timeCount = 0;
ESP8266_Clear();
}
dataPtr = ESP8266_GetIPD(3);
if(dataPtr != NULL)
OneNet_RevPro(dataPtr);
delay_ms(10);
// 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

在手机上输入这个


初始化ESP8266和MQTT网络连接

#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 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不用改)
#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"
//GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_RESET)
//DelayXms(250)
//GPIO_WriteBit(GPIOC, GPIO_Pin_14, Bit_SET)
//DelayXms(500)
ESP8266_Clear()
ESP8266_SendCmd("AT+RST\r\n", "")
delay_ms(1200)
while(ESP8266_SendCmd("AT\r\n", "OK"))
delay_ms(500)
/*
ESP8266_SendCmd("AT+CIPCLOSE\r\n", "");
delay_ms(500);
*/
while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))
delay_ms(500)
while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))
delay_ms(500)
while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP"))
delay_ms(500)
while(ESP8266_SendCmd(ESP8266_ONENET_INFO, "CONNECT"))
delay_ms(500)
printf("ESP8266 Initialization [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
编译后烧录代码

打开串口助手


打开苹果手机APP


可以看上板子的温度值已经上传到了手机APP,不限距离,全世界通用!!!非常的强悍。。。。