LoRa 智慧牧场项目集成开发
在前面的课程内容当中,我们已经学习完了一整套 LoRa 开发的过程,并且在前面一节实现了基于时分复用 MAC 协议的自组网络设计,可以说已经具备了 LoRa 集成开发的基础。为了更加巩固我们所学习的成果,我们就拿应用比较多的智慧牧场项目来真正将我们所学习的内容应用在实操上。
开始设计智慧牧场项目之前,我们回顾一下之前学习的 LoRa 自组网络设计的步骤。传输数据确定 → LoRa PingPang 系统 → LoRa 透传系统 → LoRa 自组网。我们可以模仿这个步骤,先规划一下智慧牧场项目我们大概需要以下几步:数据采集 → 数据发送 → 数据接收处理 → 闭环控制。
体征数据采集
需求分析及传感器原理
需求分析——如何获取奶牛计步信息?
采集传感器——六轴运动处理传感器 MPU6050
三轴加速度测量原理:加速度测量计反应的加速向量与当前的受力方向是相反,单位为 g。
三轴陀螺仪测量:陀螺仪,是用来测量角速度的,单位为度每秒(deg/s)。
MPU6050 是使用 IIC 进行数据传输的,其初始化过程如下:
读取加速度初始值过程如下:
读取加速度数据过程如下:
功能配置及源码分析
首先我们需要打开 .ioc 文件,对 STM32 芯片的 IIC 通信接口进行配置。查询原理图可知,芯片的 PB8(SCL)和 PB7(SDA)是 IIC 的数据引脚。
然后生成代码即可。
在项目工程的 User 文件夹里面新建一个 Sensor 文件夹,将 MPU6050 传感器的配置代码放在里面。
- /* mpu6050 */
- #include "mpu6050.h"
- #include "string.h"
- #include "stdio.h"
- #include "i2c.h"
- int16_t Accx,Accy,Accz;
- // 初始化MPU6050
- void InitMpu6050(void){
- uint8_t WriteCmd = 0;
- //解除休眠状态
- WriteCmd = 0x00;
- HAL_I2C_Mem_Write(&hi2c1, ADDRESS_Write, PWR_MGMT_1, I2C_MEMADD_SIZE_8BIT, &WriteCmd, 1, 0x10);
- //时钟速率0x06(1Khz)陀螺仪采样率0x07(125Hz)
- WriteCmd = 0x07;
- HAL_I2C_Mem_Write(&hi2c1, ADDRESS_Write, SMPLRT_DIV, I2C_MEMADD_SIZE_8BIT, &WriteCmd, 1, 0x10);
- WriteCmd = 0x06;
- HAL_I2C_Mem_Write(&hi2c1, ADDRESS_Write, CONFIG, I2C_MEMADD_SIZE_8BIT, &WriteCmd, 1, 0x10);
- //不自检,2000deg/s
- WriteCmd = 0x18;
- HAL_I2C_Mem_Write(&hi2c1, ADDRESS_Write, GYRO_CONFIG, I2C_MEMADD_SIZE_8BIT, &WriteCmd, 1, 0x10);
- //(不自检,2G,5Hz)
- WriteCmd = 0x01;
- HAL_I2C_Mem_Write(&hi2c1, ADDRESS_Write, ACCEL_CONFIG, I2C_MEMADD_SIZE_8BIT, &WriteCmd, 1, 0x10);
- HAL_Delay(10);
- mpu6050_verify(&Accx, &Accy, &Accz); //读取第一次的值
- }
- // MPU6050校验
- void mpu6050_verify(int16_t *x, int16_t *y, int16_t *z){
- uint8_t ReadBuffer[10] = {0};
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_XOUT_L, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[0],1, 0x10);
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_XOUT_H, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[1],1, 0x10);
- *x = (ReadBuffer[1]<<8)+ReadBuffer[0];
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_YOUT_L, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[0],1, 0x10);
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_YOUT_H, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[1],1, 0x10);
- *y = (ReadBuffer[1]<<8)+ReadBuffer[0];
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_ZOUT_L, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[0],1, 0x10);
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_ZOUT_H, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[1],1, 0x10);
- *z = (ReadBuffer[1]<<8)+ReadBuffer[0];
- }
- // MPU6060获取三轴数据
- void mpu6050_ReadData(float *Mx, float *My, float *Mz){
- int16_t x,y,z;
- uint8_t ReadBuffer[10] = {0};
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_XOUT_L, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[0],1, 0x10);
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_XOUT_H, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[1],1, 0x10);
- x = (ReadBuffer[1]<<8)+ReadBuffer[0];
- x -= Accx;
- *Mx = ((float)x)/16384;
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_YOUT_L, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[0],1, 0x10);
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_YOUT_H, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[1],1, 0x10);
- y = (ReadBuffer[1]<<8)+ReadBuffer[0];
- y -= Accy;
- *My = ((float)y)/16384;
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_ZOUT_L, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[0],1, 0x10);
- HAL_I2C_Mem_Read(&hi2c1, ADDRESS_Read, ACCEL_ZOUT_H, I2C_MEMADD_SIZE_8BIT,&ReadBuffer[1],1, 0x10);
- z = (ReadBuffer[1]<<8)+ReadBuffer[0];
- z -= Accz;
- *Mz = ((float)z)/16384;
- }
更多有关 MPU6050 的配置可以查阅数据手册来理解。
然后我们需要在 main.c 当中对数据读取进行配置:定义全局变量 Mx、My、Mz,初始化 IIC,初始化 MPU6050,然后每两秒钟读取一次加速度值即可。
- float Mx,My,Mz;
- ...
- int main(void){
- MX_I2C1_Init();
- InitMpu6050();
- ...
- while(1){
- ...
- mpu6050_ReadData(&Mx,&My,&Mz);
- printf("Mx = %.3f\n",Mx);
- printf("My = %.3f\n",My);
- printf("Mz = %.3f\n",Mz);
- ...
- }
- ...
- }
实验现象:
将传感器安装在奶牛腿上,其体征数据会每两秒返回一次,主机可获得接收并通过串口助手打印出来。
饲养环境采集
需求分析及传感器原理
需求分析——如何获取牛舍温湿度信息?
采集传感器——DHT11 数字式空气温湿度传感器
DHT11 数据传输原理:一次完整的数据传输为 40 bit,高位先出
8bit 湿度整数数据+ 8bit 湿度小数数据;
8bit 温度整数数据+ 8bit 温度小数数据;
8bit 校验和。
由于 DHT11 是单总线协议传输数据,所以是通过高低电平持续的时间长短来进行数据的传输。
启动采集的过程:
获取数据的过程:
数字 0 信号的高低电平状态:
数字 1 信号的高低电平状态: