1.项目介绍
本项目是基于瑞萨芯片RA4M2,开发的智慧农业监测系统。此项目主要是通过DHT11温湿度模块把环境的温湿度采集出来,然后通过esp8266连接路由器,把采集到的数据上传到阿里云云平台,这个云平台还配套手机app,可以实现在外面随时随地监测温湿度状态。为了便于查看温湿度数据,利用oled屏幕在上面做了一个实时显示的小菜单界面。部分效果图如下
硬件结构:
2.环境配置
去官网下载软件:https://ramcu.cn/lists/21.html
下载最新4.0版本
下载最新的pack
下载完成后 分别安装,一路next即可
创建工程具体可参考
【瑞萨RA4系列开发板体验】开发环境搭建及点灯 - 瑞萨单片机论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛!
3.dht11数据读取
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。。
dht11.h
#ifndef __DHT11_H
#define __DHT11_H
#include "hal_data.h"
#define dht11_port BSP_IO_PORT_04_PIN_05
#define dht11_high R_BSP_PinWrite(dht11_port, BSP_IO_LEVEL_HIGH);
#define dht11_low R_BSP_PinWrite(dht11_port, BSP_IO_LEVEL_LOW);
#define Read_Data R_BSP_PinRead(dht11_port)
struct rec_data {
unsigned int rec_data[4];
};
void DHT11_Start(void);
unsigned char DHT11_REC_Byte(void);
struct rec_data DHT11_REC_Data(void);
#endif
dht11.c
#include "dht11.h"
void delay_us(uint32_t delay){
R_BSP_SoftwareDelay(delay, BSP_DELAY_UNITS_MICROSECONDS);
}
void delay_ms(uint32_t delay){
R_BSP_SoftwareDelay(delay, BSP_DELAY_UNITS_MILLISECONDS);
}
void DHT11_Start(void)
{
dht11_high;
delay_us(30);
dht11_low;
delay_ms(20);
dht11_high;
delay_us(30);
}
char DHT11_Rec_Byte(void)
{
unsigned char i = 0;
unsigned char data;
for(i=0;i<8;i++)
{
while( Read_Data == 0);
delay_us(30);
data <<= 1;
if( Read_Data == 1 )
{
data |= 1;
}
while( Read_Data == 1 );
}
return data;
}
struct rec_data DHT11_REC_Data(void)
{
unsigned int R_H,R_L,T_H,T_L;
unsigned char RH,RL,TH,TL,CHECK;
struct rec_data data;
DHT11_Start();
dht11_high;
if( Read_Data == 0 )
{
while( Read_Data == 0);
while( Read_Data == 1);
R_H = DHT11_Rec_Byte();
R_L = DHT11_Rec_Byte();
T_H = DHT11_Rec_Byte();
T_L = DHT11_Rec_Byte();
CHECK = DHT11_Rec_Byte();
dht11_low;
delay_us(55);
dht11_high;
if(R_H + R_L + T_H + T_L == CHECK)
{
RH = R_H;
RL = R_L;
TH = T_H;
TL = T_L;
}
}
data.rec_data[0] = RH;
data.rec_data[1] = RL;
data.rec_data[2] = TH;
data.rec_data[3] = TL;
return data;
}
4.oled 屏幕IIC驱动
4.1配置IIC
参考文章
置RA4M2的I2C接口,使其作为I2C master进行通信。
查看开发板原理图,对应的IIC为P408和P409。
点击Stacks->New Stack->Connectivity -> I2C Master(r_sci_i2c)。
设置IIC的配置,需要注意从机的地址,这里的地址位数是7位,0x3c。
4.2R_SCI_I2C_Open()函数原型
R_SCI_I2C_Open()函数为执行IIC初始化,开启配置如下所示。
err = R_SCI_I2C_Open(&g_i2c3_ctrl, &g_i2c3_cfg);
assert(FSP_SUCCESS == err);
4.3R_SCI_I2C_Write()函数原型
R_SCI_I2C_Write()函数是向IIC设备中写入数据,写入格式如下所示。
err = R_SCI_I2C_Write(&g_i2c_device_ctrl_1, &g_i2c_tx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
4.4 sci_i2c_master_callback()回调函数
对于数据是否发送完毕,可以查看是否获取到I2C_MASTER_EVENT_TX_COMPLETE字段。
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
i2c_event = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
i2c_event = p_args->event;
}
}
4.5控制与发送数据
对于发送数据,可以使用R_SCI_I2C_Write()函数,对于是否发送完毕,可以判断I2C_MASTER_EVENT_TX_COMPLETE != i2c_event,并且引入超时机制。
向0x3c设备写命令0x00的IIC_Command指令。
/**********************************************
IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
uint8_t ii[2]={0x00,0x00};
ii[1] = IIC_Command;
err = R_SCI_I2C_Write(&g_i2c3_ctrl, ii, 0x02, true);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(100U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 100000;
}
IIC写数据
向0x3c设备写数据0x40的IIC_Data指令。
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
uint8_t ii[2]={0x40,0x00};
ii[0] = 0x40;
ii[1] = IIC_Data;
err = R_SCI_I2C_Write(&g_i2c3_ctrl, ii, 0x02, true);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(100U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 100000;
}
实物效果如下
5 串口配置
配置UART引脚功能
默认创建的RASC项目中,P109、P110为JTAG功能,因此,首先需要关闭JTAG功能,或者修改为SWD模式;
将调试模式从JTAG改为SWD
在RASC中,切换到Pins标签页;找到System:DEBUG -> DEBUG0,将其设置修改为SWD,引脚修改为P108、P300,如下图所示:
P108、P300引脚也正是和开发板原理图相对应的。
继续找到Connectivity:SCI -> SCI9,将其设置修改如下图所示:
添加UART HAL配置
在RASC中,切换到Stacks标签页,依次点击“New Stack”->“Connectivity”->“UART”,添加一个uart组件,如下图所示:
选中之后,在Properties视图中,修改如下几个属性:
重定向printf输出到UART
在Keil中,实现UART打印到printf需要重新实现C标准库的putc函数
volatile bool uart_tx_done = false;
void hal_uart9_init()
{
R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
}
int fputc(int ch, FILE* f)
{
(void) f;
uart_tx_done = false;
R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
while (uart_tx_done == false);
return ch;
}
void g_uart9_callback(uart_callback_args_t* p_args)
{
switch (p_args->event)
{
case UART_EVENT_RX_CHAR:
break;
case UART_EVENT_TX_COMPLETE:
uart_tx_done = true;
break;
default:
break;
}
}
这样,在hal_entry中调用了hal_uart9_init之后,就可以使用printf输出到串口了。
6.阿里云配置
创建产品和设备
登录物联网平台,选择:设备管理 -->产品 -->创建产品
选择标准品类搜索温湿度选择第一个
确定创建产品
选择设备,添加设备
查看设备 mqtt连接参数
保存下来后面会用到
AT指令让 ESP8266 连接阿里云
第一步 AT+RST
第二步 AT+CWMODE=1
第三步 AT+CIPSNTPCFG=1.8"ntp1.alivun.com"
第四步 AT+CWJAP="WiFi 名字""WiFi 密码"
第五步 AT+MQTTUSERCFG=0,1,"NULL","用户名","密码",0,0,"
第六步 AT+MQTTCLIENTID=0,"Clienld" //clientld 第二个参数注意每个逗号
前加分隔符
第七步 AT+MQTTCONN=0,"连接域名",1883,1
AT+MQTTSUB=0,"topic",1 //订阅指令
AT+MQTTPUB=0,"topic","Json格式内容",1,0 //发布指令
AT+MQTTCLEAN=O //断开连接
连接WiFi和阿里云
void AT(void){
printf("AT\r\n");
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+RST\r\n");
R_BSP_SoftwareDelay(4500, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+CWMODE=1\r\n");
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pswd);
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+CIPSNTPCFG=1,8,\"%s\"\r\n",aliyun);
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTUSERCFG=0,1,\"NULL\",\"RA4M2&gjkfDbjlzOa\",\"2690e3ffeb901d01fd4732336a1bbf985294e3fd51321d41b36fa1b8bcd2998d\",0,0,\"\"\r\n");
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTCLIENTID=0,\"gjkfDbjlzOa.RA4M2|securemode=2\,signmethod=hmacsha256\,timestamp=1676456300908|\"\r\n");
R_BSP_SoftwareDelay(2000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTCONN=0,\"iot-06z00dpzxbgxfgc.mqtt.iothub.aliyuncs.com\",%d,%d\r\n",1883,1);
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
}
发送温湿度数据到阿里云
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTPUB=0,\"/sys/gjkfDbjlzOa/RA4M2/thing/event/property/post\",\"{\\"method\\":\\"thing.event.property.post\\"\\,\\"id\\":\\"1234\\"\\,\\"params\\":{\\"CurrentTemperature\\":%d}\\,\\"version\\":\\"1.0.0\\"}\",1,0\r\n",data.rec_data[2]);
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
printf("AT+MQTTPUB=0,\"/sys/gjkfDbjlzOa/RA4M2/thing/event/property/post\",\"{\\"method\\":\\"thing.event.property.post\\"\\,\\"id\\":\\"1234\\"\\,\\"params\\":{\\"CurrentHumidity\\":%d}\\,\\"version\\":\\"1.0.0\\"}\",1,0\r\n",data.rec_data[0]);
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
效果如下
视频演示:
Gitee代码仓库 https://gitee.com/gerhardt1024/ra4m2.git
硬声视频演示链接
目前仅添加温湿度监测上传 ,其他功能后期完善....