同步操作将从 小熊派开源社区/BearPi-HM_Nano 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
本示例将分析和演示如何在BearPi-HM_Nano开发板上使用E53_IA1和“护花使者”双扩展板。
由上图可以看出,在Nano板上许多引脚在出厂前已经被连接到了一起,所以我们想要实现两块拓展板的集成,首先必须要注意的点就是不能出现接口同时占用的情况,例如:当我们在代码中定义了GPIO 00/01分别复用为IIC_SDA和IIC_SCL是给E53_IA1用的,那么“护花使者”想要使用IIC就不能将“护花使者”底板的IIC接口接到GPIO 00/01上,否则就会出现信息传输错误的情况,原因在于GPIO 00/01接口被两个拓展板所占用,而主板不知道该读哪一块拓展板所传来的信息。所以如何解决接口同时占用的问题就成为了解决双拓展板集成的关键问题。
序号 | 名称 | 方向 | 功能 |
---|---|---|---|
1 | LED_SW | OUT | LED控制线 |
2 | INT | OUT | 传感器数据信号中断 |
3 | Moter_SW | OUT | 微型电机控制线 |
4 | IIC_SCL | OUT/IN | 时钟线,传输时钟信号 |
5 | IIC_SDA | OUT/IN | 数据线,传输数据信号 |
6 | GND | PWR | 电源地 |
7 | V3.3 | PWR | 电源,可输入 3.1V~4.2V,建议 3.3V,电源能够提供 500mA 驱动能力 |
8 | GND | PWR | 电源地 |
9 | V5.0 | PWR | 电源,建议5.0V |
由E53_IA1原理图分析可得,当我们只使用E53_IA1拓展板时会占用Nano主板上的GPIO 00/01/08/07/14以及GND和VCC,共9个接口。
序号 | 名称 | 方向 | 功能 |
---|---|---|---|
1 | Motor_SW | OUT | 抽水电机控制线(USB控制线) |
2 | ADC6 | OUT | AD转换(土壤湿度传感器) |
3 | INT | OUT | 传感器数据信号中断 |
4 | IIC_SCL | OUT/IN | 时钟线,传输时钟信号 |
5 | IIC_SDA | OUT/IN | 数据线,传输数据信号 |
6 | ADC2 | OUT | AD转换 |
7 | GND | PWR | 电源地 |
8 | V3.3 | PWR | 电源,可输入 3.1V~4.2V,建议 3.3V,电源能够提供 500mA 驱动能力 |
9 | GND | PWR | 电源地 |
10 | V5.0 | PWR | 电源,建议5.0V |
由“护花使者”原理图分析可得,当我们只使用“护花使者”拓展板时会占用Nano主板上的GPIO 00/01/07/13/14/05以及GND和VCC,共10个接口。
由上述分析不难看出当我们想要实现双拓展板集成时,E53_IA1和“护花使者”会同时占用GPIO 00/01/07/14以及GND和VCC,共8个接口,不过我们可以不用考虑GND和VCC,所以接下来我们需要解决的问题就明确许多,在此就有两种解决方式:1、改变E53_IA1的GPIO 00/01/07/14接口;2、改变“护花使者”的GPIO 00/01/07/14接口。建议使用第二种方法,由于设备结构的原因,改变“护花使者”接口相对容易一些。
分析“护花使者”的GPIO 00/01/07/14接口,分别是IIC_SDA、IIC_SCL、INT、Motor_SW。在此我们需要先了解一下BearPi_HM Nano 芯片手册 ,在Nano主板上IIC有两种IIC0和IIC1,当接口是GPIO 00/01时复用的IIC为IIC1,而IIC1已经挂载了E53_IA1,所以我们想要挂载“护花使者”就必须找到IIC0的接口,查看芯片手册可知GPIO 09/10复用的IIC为IIC0,以此类推解决别的接口占用也是同样的道理。
*值得注意的一点:在E53_IA1和“护花使者”上都具备了SHT30(温湿度传感器模块)但“护花使者”没有HB1750(光照强度传感器模块),所以如何取舍还得看个人如何分析。
驱动的编写有两种方式:1、将两个模块分开编写;2、将两个模块看做整体一起编写。方式一的优点在于代码的可裁剪性强,但代码量就相对较多;方式二则相反。小编采取了相对轻松的方式二来解决驱动编写的问题。
接口定义:
/***************************************************************
* 函数名称: Flower_IO_Init
* 说 明: Flower_GPIO初始化
* 参 数: 无
* 返 回 值: 无
***************************************************************/
static void Flower_IO_Init(void)
{
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);//设置GPIO_5的复用功能为普通GPIO
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_GPIO_DIR_OUT);//设置GPIO_5为输出模式
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);//设置GPIO_8的复用功能为普通GPIO
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_GPIO_DIR_OUT);//设置GPIO_8为输出模式
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_GPIO);//设置GPIO_14的复用功能为普通GPIO
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_GPIO_DIR_OUT);//设置GPIO_14为输出模式
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_10, WIFI_IOT_IO_FUNC_GPIO_10_I2C0_SDA); // GPIO_10复用为I2C1_SDA
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_9, WIFI_IOT_IO_FUNC_GPIO_9_I2C0_SCL); // GPIO_9复用为I2C1_SCL
I2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
I2cSetBaudrate(WIFI_IOT_I2C_IDX_1, 400000);
I2cInit(WIFI_IOT_I2C_IDX_0, 400000); /* baudrate: 400kbps */
I2cSetBaudrate(WIFI_IOT_I2C_IDX_0, 400000);
}
HB1750(光照强度传感器模块)来自E53_IA1
/***************************************************************
* 函数名称: Init_BH1750
* 说 明: 写命令初始化BH1750
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void Init_BH1750(void)
{
WifiIotI2cData bh1750_i2c_data = { 0 };
uint8_t send_data[1] = { 0x01 };
bh1750_i2c_data.sendBuf = send_data;
bh1750_i2c_data.sendLen = 1;
I2cWrite(WIFI_IOT_I2C_IDX_1,(BH1750_Addr<<1)|0x00,&bh1750_i2c_data);
}
/***************************************************************
* 函数名称: Start_BH1750
* 说 明: 启动BH1750
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void Start_BH1750(void)
{
WifiIotI2cData bh1750_i2c_data = { 0 };
uint8_t send_data[1] = { 0x10 };
bh1750_i2c_data.sendBuf = send_data;
bh1750_i2c_data.sendLen = 1;
I2cWrite(WIFI_IOT_I2C_IDX_1,(BH1750_Addr<<1)|0x00,&bh1750_i2c_data);
}
SHT30(空气温湿度传感器模块)来自“护花使者”
/***************************************************************
* 函数名称: SHT30_reset
* 说 明: SHT30复位
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void SHT30_reset(void)
{
WifiIotI2cData sht30_i2c_data = { 0 };
uint8_t send_data[2] = { 0x30,0xA2 };
sht30_i2c_data.sendBuf = send_data;
sht30_i2c_data.sendLen = 2;
I2cWrite(WIFI_IOT_I2C_IDX_0,(SHT30_Addr<<1)|0x00,&sht30_i2c_data);
}
/***************************************************************
* 函数名称: Init_SHT30
* 说 明: 初始化SHT30,设置测量周期
* 参 数: 无
* 返 回 值: 无
***************************************************************/
void Init_SHT30(void)
{
WifiIotI2cData sht30_i2c_data = { 0 };
uint8_t send_data[2] = { 0x22,0x36 };
sht30_i2c_data.sendBuf = send_data;
sht30_i2c_data.sendLen = 2;
I2cWrite(WIFI_IOT_I2C_IDX_0,(SHT30_Addr<<1)|0x00,&sht30_i2c_data);
}
/***************************************************************
* 函数名称: SHT3x_CheckCrc
* 说 明: 检查数据正确性
* 参 数: data:读取到的数据
nbrOfBytes:需要校验的数量
checksum:读取到的校对比验值
* 返 回 值: 校验结果,0-成功 1-失败
***************************************************************/
static uint8_t SHT3x_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{
uint8_t crc = 0xFF;
uint8_t bit = 0;
uint8_t byteCtr ;
const int16_t POLYNOMIAL = 0x131;
//calculates 8-Bit checksum with given polynomial
for(byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr)
{
crc ^= (data[byteCtr]);
for ( bit = 8; bit > 0; --bit)
{
if (crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL;
else crc = (crc << 1);
}
}
if(crc != checksum)
return 1;
else
return 0;
}
/***************************************************************
* 函数名称: SHT3x_CalcTemperatureC
* 说 明: 温度计算
* 参 数: u16sT:读取到的温度原始数据
* 返 回 值: 计算后的温度数据
***************************************************************/
static float SHT3x_CalcTemperatureC(uint16_t u16sT)
{
float temperatureC = 0; // variable for result
u16sT &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate temperature [℃] --
temperatureC = (175 * (float)u16sT / 65535 - 45); //T = -45 + 175 * rawValue / (2^16-1)
return temperatureC;
}
/***************************************************************
* 函数名称: SHT3x_CalcRH
* 说 明: 湿度计算
* 参 数: u16sRH:读取到的湿度原始数据
* 返 回 值: 计算后的湿度数据
***************************************************************/
static float SHT3x_CalcRH(uint16_t u16sRH)
{
float humidityRH = 0; // variable for result
u16sRH &= ~0x0003; // clear bits [1..0] (status bits)
//-- calculate relative humidity [%RH] --
humidityRH = (100 * (float)u16sRH / 65535); // RH = rawValue / (2^16-1) * 10
return humidityRH;
}
设置抽水电机、风扇电机、补光灯
/***************************************************************
* 函数名称: Motor_StatusSet
* 说 明: 电机状态设置
* 参 数: status,ENUM枚举的数据
* CLOSE,关
* OPEN,开
* 返 回 值: 无
***************************************************************/
void Motor_Flower_StatusSet(Flower_Status_ENUM status)
{
if (status == OPEN)
//设置GPIO_5输出高电平打开抽水电机
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_5, WIFI_IOT_GPIO_VALUE0);
if (status == CLOSE)
//设置GPIO_5输出低电平关闭抽水电机
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_5, WIFI_IOT_GPIO_VALUE1);
}
void Motor_Fan_StatusSet(Flower_Status_ENUM status)
{
if (status == OPEN)
//设置GPIO_8输出高电平打开风扇电机
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_8, WIFI_IOT_GPIO_VALUE1);
if (status == CLOSE)
//设置GPIO_8输出低电平关闭风扇电机
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_8, WIFI_IOT_GPIO_VALUE0);
}
void LED_Light_StatusSet(Flower_Status_ENUM status){
if (status == OPEN)
//设置GPIO_14输出高电平打开补光灯
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_14, WIFI_IOT_GPIO_VALUE1);
if (status == CLOSE)
//设置GPIO_14输出低电平关闭补光灯
GpioSetOutputVal(WIFI_IOT_GPIO_IDX_14, WIFI_IOT_GPIO_VALUE0);
}
读取土壤湿度,光照强度,空气温湿度
void Flower_Read_Data()
{
unsigned int ret;
unsigned short adc;
ret = AdcRead(WIFI_IOT_ADC_CHANNEL_6, &adc, WIFI_IOT_ADC_EQU_MODEL_8, WIFI_IOT_ADC_CUR_BAIS_DEFAULT, 0xff); //读取土壤湿度
if (ret != WIFI_IOT_SUCCESS)
{
printf("ADC Read Fail\n");
}
Flower_Data.Smo = (float)adc/1500*100;
Start_BH1750(); // 启动光照强度传感器采集数据
usleep(180000);
WifiIotI2cData bh1750_i2c_data = { 0 };
uint8_t recv_data[2] = { 0 };
bh1750_i2c_data.receiveBuf = recv_data;
bh1750_i2c_data.receiveLen = 2;
I2cRead(WIFI_IOT_I2C_IDX_1, (BH1750_Addr<<1)|0x01,&bh1750_i2c_data); // 读取光照强度传感器数据
Flower_Data.Lux = (float)(((recv_data[0]<<8) + recv_data[1])/1.2);
uint8_t data[3]; //data array for checksum verification
uint16_t dat,tmp;
uint8_t SHT3X_Data_Buffer[6]; //byte 0,1 is temperature byte 4,5 is humidity
WifiIotI2cData sht30_i2c_data = { 0 };
uint8_t send_data[2] = { 0xE0,0x00};
sht30_i2c_data.sendBuf = send_data;
sht30_i2c_data.sendLen = 2;
sht30_i2c_data.receiveBuf = SHT3X_Data_Buffer;
sht30_i2c_data.receiveLen = 6;
I2cWriteread(WIFI_IOT_I2C_IDX_0,(SHT30_Addr<<1)|0x00,&sht30_i2c_data); //Read SHT30 sensor data
// /* check tem */
data[0] = SHT3X_Data_Buffer[0];
data[1] = SHT3X_Data_Buffer[1];
data[2] = SHT3X_Data_Buffer[2];
tmp=SHT3x_CheckCrc(data, 2, data[2]);
if( !tmp ) /* value is ture */
{
dat = ((uint16_t)data[0] << 8) | data[1];
Flower_Data.Temperature = SHT3x_CalcTemperatureC( dat );
}
// /* check humidity */
data[0] = SHT3X_Data_Buffer[3];
data[1] = SHT3X_Data_Buffer[4];
data[2] = SHT3X_Data_Buffer[5];
tmp=SHT3x_CheckCrc(data, 2, data[2]);
if( !tmp ) /* value is ture */
{
dat = ((uint16_t)data[0] << 8) | data[1];
Flower_Data.Humidity = SHT3x_CalcRH( dat );
}
}
当中启动了读取土壤湿度、光照强度、空气温湿度以及启动风扇电机,其余的可自行扩展。
static void Example_Task(void)
{
Flower_Init();
while (1)
{
printf("\r\n=======================================\r\n");
printf("\r\n*************E53_FLOWER_IA1_example***********\r\n");
printf("\r\n=======================================\r\n");
Flower_Read_Data();
printf("\r\n******************************Smo is %.2f\r\n", Flower_Data.Smo);
printf("\r\n******************************Lux Value is %.2f\r\n", Flower_Data.Lux);
printf("\r\n******************************Humidity is %.2f\r\n", Flower_Data.Humidity);
printf("\r\n******************************Temperature is %.2f\r\n", Flower_Data.Temperature);
if(Flower_Data.Temperature>10){
Motor_Fan_StatusSet(OPEN);
}else{
Motor_Fan_StatusSet(CLOSE);
}
usleep(1000000);
}
}
在BUILD.gn中添加如下代码:
#"C1_e53_sf1_mq2:e53_sf1_example",
#"C2_e53_ia1_temp_humi_pls:e53_ia1_example",
#"C3_e53_sc1_pls:e53_sc1_example",
#"C4_e53_sc2_axis:e53_sc2_example",
#"C5_e53_is1_infrared:e53_is1_example",
"C6_e53_flower_ia1:e53_flower_ia1_example",
数据采集:
实验演示:
因为E53_IA1原装的风扇小不方便观察,所以小编改造了一下。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。