# Arduino传感器集成与数据处理
Arduino作为最受欢迎的微控制器平台之一,为传感器集成提供了简单而强大的解决方案。本文将深入探讨各种常用传感器的使用方法、数据处理技巧和实际应用案例。
## 传感器基础
传感器是将物理量转换为电信号的设备。在Arduino项目中,我们通常使用模拟传感器(输出模拟电压)和数字传感器(输出数字信号)。
### 模拟传感器
- 输出连续变化的电压信号
- 需要ADC(模数转换器)读取
- 精度取决于ADC分辨率
### 数字传感器
- 输出离散的数字信号
- 直接通过数字引脚读取
- 通常具有内置的信号处理电路
## 温度传感器
### DHT22温湿度传感器
DHT22是一款高精度的温湿度传感器,使用单总线协议通信。
```cpp
#include <DHT.h>
#define DHT_PIN 2
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
void setup() {
Serial.begin(9600);
dht.begin();
Serial.println("DHT22传感器初始化完成");
}
void loop() {
// 读取温度
float temperature = dht.readTemperature();
// 读取湿度
float humidity = dht.readHumidity();
// 检查读取是否成功
if (isnan(temperature) || isnan(humidity)) {
Serial.println("传感器读取失败");
return;
}
Serial.print("温度: ");
Serial.print(temperature);
Serial.print("°C, 湿度: ");
Serial.print(humidity);
Serial.println("%");
delay(2000);
}
```
### LM35温度传感器
LM35是一款线性温度传感器,输出电压与温度成正比。
```cpp
const int LM35_PIN = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
// 读取模拟值
int sensorValue = analogRead(LM35_PIN);
// 转换为电压(Arduino 5V系统)
float voltage = sensorValue * (5.0 / 1023.0);
// 转换为温度(LM35: 10mV/°C)
float temperature = voltage * 100.0;
Serial.print("温度: ");
Serial.print(temperature);
Serial.println("°C");
delay(1000);
}
```
## 光线传感器
### 光敏电阻(LDR)
光敏电阻的阻值随光照强度变化,通过分压电路读取。
```cpp
const int LDR_PIN = A0;
const int LED_PIN = 13;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
// 读取光线强度
int lightValue = analogRead(LDR_PIN);
// 映射到0-100范围
int lightPercent = map(lightValue, 0, 1023, 0, 100);
Serial.print("光线强度: ");
Serial.print(lightPercent);
Serial.println("%");
// 根据光线强度控制LED
if (lightPercent < 30) {
digitalWrite(LED_PIN, HIGH); // 光线暗时点亮LED
} else {
digitalWrite(LED_PIN, LOW); // 光线亮时熄灭LED
}
delay(500);
}
```
### BH1750数字光照传感器
BH1750是一款高精度的数字光照传感器,使用I2C通信。
```cpp
#include <Wire.h>
#include <BH1750.h>
BH1750 lightMeter;
void setup() {
Serial.begin(9600);
Wire.begin();
if (lightMeter.begin()) {
Serial.println("BH1750传感器初始化成功");
} else {
Serial.println("BH1750传感器初始化失败");
}
}
void loop() {
float lux = lightMeter.readLightLevel();
Serial.print("光照强度: ");
Serial.print(lux);
Serial.println(" lux");
delay(1000);
}
```
## 距离传感器
### HC-SR04超声波传感器
HC-SR04通过超声波测量距离,具有测量范围广、精度高的特点。
```cpp
const int TRIG_PIN = 9;
const int ECHO_PIN = 10;
void setup() {
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
void loop() {
// 发送超声波脉冲
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// 测量回波时间
long duration = pulseIn(ECHO_PIN, HIGH);
// 计算距离(声速340m/s)
float distance = duration * 0.034 / 2;
Serial.print("距离: ");
Serial.print(distance);
Serial.println(" cm");
delay(1000);
}
```
### 红外距离传感器
```cpp
const int IR_PIN = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(IR_PIN);
// 转换为距离(需要根据具体传感器校准)
float distance = map(sensorValue, 0, 1023, 80, 2);
Serial.print("距离: ");
Serial.print(distance);
Serial.println(" cm");
delay(500);
}
```
## 运动传感器
### PIR运动检测传感器
PIR传感器检测红外辐射变化,常用于人体检测。
```cpp
const int PIR_PIN = 2;
const int LED_PIN = 13;
volatile bool motionDetected = false;
void setup() {
Serial.begin(9600);
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
// 设置中断
attachInterrupt(digitalPinToInterrupt(PIR_PIN), motionISR, RISING);
}
void motionISR() {
motionDetected = true;
}
void loop() {
if (motionDetected) {
Serial.println("检测到运动!");
digitalWrite(LED_PIN, HIGH);
delay(2000); // 保持LED亮2秒
digitalWrite(LED_PIN, LOW);
motionDetected = false;
}
delay(100);
}
```
## 压力传感器
### BMP280气压传感器
BMP280可以测量气压、温度和海拔高度。
```cpp
#include <Wire.h>
#include <Adafruit_BMP280.h>
Adafruit_BMP280 bmp;
void setup() {
Serial.begin(9600);
if (!bmp.begin(0x76)) {
Serial.println("BMP280传感器未找到");
while (1);
}
}
void loop() {
Serial.print("温度: ");
Serial.print(bmp.readTemperature());
Serial.println("°C");
Serial.print("气压: ");
Serial.print(bmp.readPressure());
Serial.println(" Pa");
Serial.print("海拔: ");
Serial.print(bmp.readAltitude(1013.25));
Serial.println(" m");
Serial.println("---");
delay(2000);
}
```
## 传感器数据处理
### 数据平滑滤波
```cpp
const int SENSOR_PIN = A0;
const int NUM_READINGS = 10;
int readings[NUM_READINGS];
int readIndex = 0;
int total = 0;
int average = 0;
void setup() {
Serial.begin(9600);
// 初始化数组
for (int i = 0; i < NUM_READINGS; i++) {
readings[i] = 0;
}
}
void loop() {
// 减去最旧的读数
total = total - readings[readIndex];
// 读取新数据
readings[readIndex] = analogRead(SENSOR_PIN);
// 添加到总数
total = total + readings[readIndex];
// 移动到下一个位置
readIndex = readIndex + 1;
// 如果到达数组末尾,重新开始
if (readIndex >= NUM_READINGS) {
readIndex = 0;
}
// 计算平均值
average = total / NUM_READINGS;
Serial.print("原始值: ");
Serial.print(readings[readIndex - 1]);
Serial.print(", 平滑值: ");
Serial.println(average);
delay(100);
}
```
### 卡尔曼滤波
```cpp
class KalmanFilter {
private:
float Q_angle; // 过程噪声
float Q_bias; // 过程噪声
float R_measure; // 测量噪声
float angle; // 角度
float bias; // 偏差
float P[2][2]; // 协方差矩阵
public:
KalmanFilter() {
Q_angle = 0.001;
Q_bias = 0.003;
R_measure = 0.03;
angle = 0;
bias = 0;
P[0][0] = 0;
P[0][1] = 0;
P[1][0] = 0;
P[1][1] = 0;
}
float getAngle(float newAngle, float newRate, float dt) {
// 预测步骤
angle += dt * (newRate - bias);
P[0][0] += dt * (dt * P[1][1] - P[0][1] - P[1][0] + Q_angle);
P[0][1] -= dt * P[1][1];
P[1][0] -= dt * P[1][1];
P[1][1] += Q_bias * dt;
// 更新步骤
float S = P[0][0] + R_measure;
float K[2];
K[0] = P[0][0] / S;
K[1] = P[1][0] / S;
float y = newAngle - angle;
angle += K[0] * y;
bias += K[1] * y;
P[0][0] -= K[0] * P[0][0];
P[0][1] -= K[0] * P[0][1];
P[1][0] -= K[1] * P[0][0];
P[1][1] -= K[1] * P[0][1];
return angle;
}
};
```
## 多传感器融合
### 环境监测站
```cpp
#include <DHT.h>
#include <Wire.h>
#include <BH1750.h>
// 传感器定义
#define DHT_PIN 2
#define DHT_TYPE DHT22
#define LDR_PIN A0
#define PIR_PIN 3
DHT dht(DHT_PIN, DHT_TYPE);
BH1750 lightMeter;
struct SensorData {
float temperature;
float humidity;
float light;
bool motion;
unsigned long timestamp;
};
void setup() {
Serial.begin(9600);
// 初始化传感器
dht.begin();
lightMeter.begin();
pinMode(PIR_PIN, INPUT);
Serial.println("环境监测站启动");
}
SensorData readAllSensors() {
SensorData data;
// 读取温湿度
data.temperature = dht.readTemperature();
data.humidity = dht.readHumidity();
// 读取光照
data.light = lightMeter.readLightLevel();
// 读取运动
data.motion = digitalRead(PIR_PIN);
// 记录时间戳
data.timestamp = millis();
return data;
}
void printSensorData(const SensorData& data) {
Serial.println("=== 传感器数据 ===");
Serial.print("温度: ");
Serial.print(data.temperature);
Serial.println("°C");
Serial.print("湿度: ");
Serial.print(data.humidity);
Serial.println("%");
Serial.print("光照: ");
Serial.print(data.light);
Serial.println(" lux");
Serial.print("运动: ");
Serial.println(data.motion ? "检测到" : "无");
Serial.print("时间戳: ");
Serial.println(data.timestamp);
Serial.println("================");
}
void loop() {
SensorData data = readAllSensors();
printSensorData(data);
// 根据传感器数据进行控制逻辑
if (data.temperature > 30 && data.humidity > 70) {
Serial.println("警告:高温高湿环境");
}
if (data.light < 50 && data.motion) {
Serial.println("检测到夜间活动");
}
delay(5000);
}
```
## 数据记录与传输
### SD卡数据记录
```cpp
#include <SD.h>
#include <SPI.h>
const int CS_PIN = 10;
void setup() {
Serial.begin(9600);
if (!SD.begin(CS_PIN)) {
Serial.println("SD卡初始化失败");
return;
}
Serial.println("SD卡初始化成功");
}
void logData(float temperature, float humidity, float light) {
File dataFile = SD.open("sensor_data.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(millis());
dataFile.print(",");
dataFile.print(temperature);
dataFile.print(",");
dataFile.print(humidity);
dataFile.print(",");
dataFile.println(light);
dataFile.close();
Serial.println("数据已记录");
} else {
Serial.println("无法打开文件");
}
}
```
### WiFi数据传输
```cpp
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "your_wifi_name";
const char* password = "your_wifi_password";
const char* serverURL = "http://your-server.com/api/data";
void setup() {
Serial.begin(9600);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("连接WiFi中...");
}
Serial.println("WiFi连接成功");
}
void sendData(float temperature, float humidity, float light) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverURL);
http.addHeader("Content-Type", "application/json");
String jsonData = "{";
jsonData += "\"temperature\":" + String(temperature) + ",";
jsonData += "\"humidity\":" + String(humidity) + ",";
jsonData += "\"light\":" + String(light);
jsonData += "}";
int httpResponseCode = http.POST(jsonData);
if (httpResponseCode > 0) {
Serial.println("数据发送成功");
} else {
Serial.println("数据发送失败");
}
http.end();
}
}
```
## 总结
Arduino传感器集成是物联网项目的基础。通过合理选择传感器、正确实现数据采集和处理算法,可以构建出功能强大的智能设备。记住以下几点:
1. **选择合适的传感器**:根据应用需求选择精度、范围和成本合适的传感器
2. **正确接线**:注意电源电压、信号电平和接线方式
3. **数据处理**:使用适当的滤波算法提高数据质量
4. **错误处理**:添加传感器故障检测和恢复机制
5. **电源管理**:考虑功耗优化,延长设备运行时间
继续学习更多高级主题,如机器学习在传感器数据处理中的应用、边缘计算和实时系统设计,将帮助你构建更智能的硬件系统。