传感器数据结构统一封装方法(结构体的使用)

传感器数据结构统一封装方法


在嵌入式开发中,经常遇到大量传感器数据需要获取,有可能这些传感器都是串口通信,IIC通信,或是485通信,区别仅仅是地址不同,数据量不一样,或是解析方式不同。为了增加程序可扩展性或是调试方便,往往会将有关传感器的数据统一进行管理,在C语言中,最常用的莫过于结构体了。


封装传感器结构体

我这里使用的传感器都是通过RS485进行通信的,是标准的ModBus RTU协议。每个传感器区别为地址不同,寄存器不同,寄存器长度不同。于是乎封装了以下结构体,可以将同一传感器数据进行统一管理。

typedef struct 
{
    
    
	uint8_t id; //设备地址
	uint16_t reg_addr; //寄存器地址
	uint16_t size; //寄存器长度
	uint16_t data[4];//数据
	uint8_t type[15];//传感器类型,描述性字符串
} SensorDataTypeDef ;

定义传感器

利用枚举类型定义我们的传感器地址。

typedef enum
{
    
    
	RESERVE = 0x00,//保留
	LIGHT         = 0x01,
	WINDSPEED     = 0x02,
	SOIL_TEMP_HUM = 0x03,
	RAINFALL      = 0x04,
	SOIL_TEMP_HUM2 = 0x05,
	AIR_TEMP_HUM = 0x06,
} SensorTypeDef;

然后使用刚刚的结构体定义我们的传感器。因为数组从0开始,传感器地址从1开始,所以使用一个保留字段。

SensorDataTypeDef sensorData[]=
{
    
    
	{
    
    .id = RESERVE,          .reg_addr = 0x02, .size = 2,  .type = " "             }, //保留
	{
    
    .id = LIGHT,          	 .reg_addr = 0x02, .size = 2,  .type = "light"         },
	{
    
    .id = WINDSPEED,      	 .reg_addr = 0x00, .size = 1,  .type = "windspeed"     },
	{
    
    .id = SOIL_TEMP_HUM,  	 .reg_addr = 0x00, .size = 2,  .type = "soil_sensor_1" },
	{
    
    .id = RAINFALL,         .reg_addr = 0x0C, .size = 1,  .type = "rainfall"      },
	{
    
    .id = SOIL_TEMP_HUM,  	 .reg_addr = 0x00, .size = 2,  .type = "soil_sensor_2" },
	{
    
    .id = AIR_TEMP_HUM2,    .reg_addr = 0x00, .size = 2,  .type = "air_sensor"    }
};

这样我们在获取传感器数据时将会非常方便,使用统一的函数接口即可获取到不同传感器的数据,非常方便。

uint8_t sensor_state = 0;
uint8_t readSensor(SensorTypeDef sensor)
{
    
    
	uint16_t id = 0;
	uint16_t addr=0;
	uint16_t size=0;

	id = sensorData[sensor].id;
	addr = sensorData[sensor].reg_addr;
	size = sensorData[sensor].size;

	if ( ! ModbusMaster_readHoldingRegisters(id,addr, size) ) //读传感器寄存器
	{
    
    
		sensorData[sensor].data[0] = ModbusMaster_getResponseBuffer(0x00);
		sensorData[sensor].data[1] = ModbusMaster_getResponseBuffer(0x01);
		
		sensor_state &= (~( 1 << sensor )); //清零传感器出错标志位
		return 0;
	}
	LOG("[systerm]:read error :%s\r\n", sensorData[sensor].type);
	sensor_state |= ( 1 << sensor ); //置位传感器出错标志位
	return sensor;
}

最后,这儿的sensor_state 变量占用一个字节,却可以表示8种不同类型的传感器状态,既节约空间又方便。
欢迎讨论~

猜你喜欢

转载自blog.csdn.net/qq_27350133/article/details/114786025