Arduino 中多传感器数据采集的写法

时间:2021-11-13 03:50:32

今天拿出家里的Arduino又出来玩了一下,也看了一下近期网上的一些资料。感觉目前网上的文章还停留在这个怎么用,那个怎么用的阶段。合在一起的例子很少。那么,我就把今天写的代码贴出来,供大家参考拍砖。

Arduino毕竟是C语言的基础。所以程序的结构还是很重要的。在loop函数中,还是秉持了取得和具体的处理分开的写法。这对程序后续的维护应该是很重要的。

另外一个就是C函数返回数组。这个问题在传统的C中解决过,不过似乎在Arduino C中略有不同。如果读者有更好的办法,欢迎指正。

下面废话少说,直接代码贴出。

/**
* 桌面工作伴侣
* 功能: 1、反馈桌面的温度和湿度
* 2、判断人是否坐下
* 3、警告自己不要保持一个姿势太长时间
* 版本号:1.0
* 作 者:田辛
* 日 期:2015年12月18日
*/


/* 针脚定义 */
#define DHT_PIN 2 /* IO 温湿度传感器数据 */
#define TRG_PIN 3 /* O 距离传感器启动 */
#define ECH_PIN 12 /* I 距离传感器数据输入 */
#define ALM_PIN 4 /* O 蜂鸣器输出 */
#define HMC_PIN 8 /* I 人体感应传感器数据输入 */

/* 全局变量声明 */
#define ALARM_COUNTER 180; /* 监视不到人体的报警周期,15分钟 */

void setup() {
Serial.begin(9600);
Serial.println("===SETUPED===");
}

void loop() {

/* 每5秒执行一次 */
delay(5000);

/* 获得温度和湿度信息 */
int *DHT = getTemperatureAndHumidity();
/* 获得距离信息 */
int distance = getDistance();
/* 监视人体并报警 */
int humanCheck = getHumanInfo();

/* 人体传感器感受太久没有活动的话,开始报警 */
if(humanCheck <= 0){
digitalWrite(ALM_PIN, HIGH);
}else{
digitalWrite(ALM_PIN, LOW);
}

/* 参数输出 */
/* 距离 */
Serial.print("Distance:");
Serial.print(distance);
Serial.println("cm.");
/* 湿度 */
Serial.print("Humidity:");
Serial.print(*DHT);
Serial.println("%.");
/* 温度 */
Serial.print("Temperature:");
Serial.print(*(DHT+1));
Serial.println("C.");
/* 运动倒计时 */
Serial.print("Nobody Check Counter:");
Serial.println(humanCheck);

/* 清理内存 */
delete[] DHT;
}

/**
* 取得人体感应传感器的状态
* 参数: 无
* 返回值:人体当前是否在运动
* 返回值=预定义常数ALARM_COUNTER则是在运动
* 返回值<预定义常数则没有在运动
* 版本号:1.0
*/

int getHumanInfo(){
static int alarmCounter = ALARM_COUNTER; // 设置静态参数

/* 针脚定义 */
pinMode(ALM_PIN, OUTPUT);
pinMode(HMC_PIN, INPUT);

/* 如果检测到人体的话,认为人体在动。报警计数器重新开始 */
if(digitalRead(HMC_PIN) == HIGH){
alarmCounter = ALARM_COUNTER;
}else{
/* 未检测到人体的话,报警计数器开始倒数计数 */
alarmCounter--;
/* 报警计数器下限设定 */
if(alarmCounter <= 0){
alarmCounter = 0;
}
}

/* 返回报警计数器的值 */
return alarmCounter;
}

/**
* 取得DHT11的湿度和问题信息
* 参数:无
* 返回值:数组[0]湿度,[1]温度
* 版本:1.0
* 说明:学习用,所以没有调用库
*/

int* getTemperatureAndHumidity(){
int temperature; /* 温度 */
int humidity; /* 湿度 */
int tokenCheck; /* 校验位 */
int chr[40] = {0}; /* 传感器返回值数组 */
unsigned long time; /* 采样时间记录 */
int *DHT = new int[2]; /* 返回数组对象 */

/* 持续向传感器发送时序序列,直到收到正确反馈为止 */
while(pushSingle4DHT11()){};

/* 开始接收传感器反馈(40字节)*/
for(int i = 0; i < 40; i++){
/* 监视低电平,直到其结束 */
while(digitalRead(DHT_PIN) == LOW){}
/* 记录高电平的初始时间 */
time = micros();
/* 监视高电平,直到其结束 */
while(digitalRead(DHT_PIN) == HIGH){}
/* 如果高电平的持续时间大于50um,则认为是1,否则是0 */
if(micros() - time > 50){
chr[i] = 1;
}else{
chr[i] = 0;
}
}

/* 获得湿度的具体值 */
humidity = chr[0] * 128 + chr[1] * 64 + chr[2] * 32 + chr[3] * 16 + chr[4] * 8 + chr[5] * 4 + chr[6] * 2 + chr[7];
/* 获得温度的具体值 */
temperature = chr[16] * 128 + chr[17] * 64 + chr[18] * 32 + chr[19] * 16 + chr[20] * 8 + chr[21] * 4 + chr[22] * 2 + chr[23];
/* 获得校验位的值 */
tokenCheck = chr[32] * 128 + chr[33] * 64 + chr[34] * 32 + chr[35] * 16 + chr[36] * 8 + chr[37] * 4 + chr[38] * 2 + chr[39];

/* 校验检查通过,将温湿度的值放入返回数组 */
if( humidity + temperature == tokenCheck){
DHT[0] = humidity;
DHT[1] = temperature;
}

/* 返回值 */
return DHT;
}

/**
* 发送测量请求信号
* 参数:无
* 返回值:true -- 请求失败重新请求
*/

boolean pushSingle4DHT11(){
int waitingCounter; /* 等待计数器 */

/* 与上次发送测量信号间隔40毫秒 */
delay(40);
/* 设置向传感器发送请求信号的IO模式 */
pinMode(DHT_PIN, OUTPUT);
/* 1、一个持续20毫秒的低电平 */
digitalWrite(DHT_PIN, LOW);
delay(20);
/* 2、一个持续40微秒的高电平 */
digitalWrite(DHT_PIN, HIGH);
delayMicroseconds(40);
/* 3、恢复低电平,并等待传感器反馈 */
digitalWrite(DHT_PIN, LOW);
pinMode(DHT_PIN, INPUT);

/* 等待传感器返回一高一低两个信号 */
/* 当高低电平信号任意一个找不到的时候,返回真,则会重新开始此函数 */
/* 等待高电平信号 */
waitingCounter = 10000;
while(digitalRead(DHT_PIN) != HIGH){
if(waitingCounter-- == 0){
return true;
}
}

/* 等待低电平信号 */
waitingCounter = 30000;
while(digitalRead(DHT_PIN) != LOW){
if(waitingCounter-- == 0){
return true;
}
}
}

/**
* 从距离传感器取得距离
* 参数:无
* 返回值:距离的数值,单位厘米,精确到两位小数
*/

float getDistance(){
/* 设置针脚 */
pinMode(TRG_PIN, OUTPUT);
pinMode(ECH_PIN, INPUT);

/* 设置两微秒的低电平 */
digitalWrite(TRG_PIN, LOW);
delayMicroseconds(2);
/* 发送10微秒的高电平 */
digitalWrite(TRG_PIN, HIGH);
delayMicroseconds(10);
/* 返回高电平 */
digitalWrite(TRG_PIN, LOW);

/* 取得传感器的值并计算距离 */
return pulseIn(ECH_PIN, HIGH) / 58.00;
}