Seeed Wio Terminal 多传感器环境监测站:实时数据采集与显示

项目概述和目标

本项目利用 Seeed Studio 的 Wio Terminal 开发板,结合 Grove 传感器模块,构建一个多传感器环境监测站,用于实时采集和显示环境数据。项目面向电子初学者、创客和教育工作者,目标是展示 Wio Terminal 的多功能性,帮助用户快速上手 Seeed 生态系统,同时提供一个可扩展的环境监测解决方案。

为什么做这个项目?

  • 实际需求:环境监测在农业、教育和家庭场景中有广泛应用,例如监测空气质量、气体浓度、光照和噪音水平,帮助用户了解周围环境状况。
  • 学习价值:通过本项目,初学者可以学习 Wio Terminal 的硬件连接、Arduino 编程基础,以及如何使用多种传感器。
  • Seeed 产品展示:展示 Wio Terminal 和 Grove 模块的易用性和强大功能,体现 Seeed 在创客生态中的优势。

项目功能
  • 实时采集以下数据: 空气质量:使用 Grove - Air Quality Sensor v1.3 检测环境空气质量。
    • 气体浓度:使用 Grove - Gas Sensor (MQ2) 检测可燃气体(如 LPG、甲烷)。
    • 光照强度:使用 Wio Terminal 内置光传感器。
    • 声音强度:使用 Wio Terminal 内置麦克风。
  • 在 Wio Terminal 的屏幕上交替显示两个界面: 界面 1:空气质量和 MQ2 气体的数值、状态和建议。
    • 界面 2:光照和声音的数值、状态和建议。
  • 每个界面显示 10 秒,自动切换,持续循环。

材料清单与环境设置

硬件需求

  • Wio Terminal:Seeed Studio 开发板,带屏幕和内置传感器(加速度、光照、麦克风)。
  • Grove - Air Quality Sensor v1.3:用于检测空气质量,连接到 A0/A1 端口。
  • Grove - Gas Sensor (MQ2):用于检测气体浓度,连接到 A2 端口
  • USB-C 数据线:用于供电和上传代码。
  • 电脑:用于编写和上传代码。

软件需求

  • Arduino IDE
  • Wio Terminal 板卡支持包:通过 Arduino IDE 的板卡管理器安装。
  • 库文件

#define MQ2_PIN A1 // MQ2 Gas Sensor

#define LIGHT_PIN WIO_LIGHT // Built-in Light Sensor

#define MIC_PIN WIO_MIC // Built-in Microphone

#include <TFT_eSPI.h> // Wio Terminal LCD library

#include <Air_Quality_Sensor.h> // Air Quality Sensor library

环境设置

  1. 安装 Arduino IDE: 下载并安装 Arduino IDE(Software | Arduino)。
    1. 启动 Arduino IDE。
  2. 添加 Wio Terminal 板卡支持: 打开 Arduino IDE,进入 File > Preferences
    1. Additional Boards Manager URLs 中添加以下链接: text

Copy

https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json

    1. 进入 Tools > Board > Boards Manager,搜索 Seeeduino SAMD,安装最新版本。
  1. 安装库: 进入 Tools > Manage Libraries
    1. 搜索 LIS3DHTR,安装 Grove-3-Axis-Digital-Accelerometer-2g-to-16g-LIS3DHTR 库。
    2. TFT_eSPI 库随板卡支持包自动安装。
  2. 硬件连接: 使用 Grove 连接线将 Grove - Air Quality Sensor v1.3 连接到 Wio Terminal 的 A0/A1 端口。
    1. 使用 Grove 连接线将 Grove - Gas Sensor (MQ2) 连接到 Wio Terminal 的 A2 端口。
    2. 用 USB-C 数据线连接 Wio Terminal 和电脑。

连接示意图

运行代码,测试结果截图

应用示例和扩展思路

实际应用场景

  • 家庭环境监测:放置在客厅或卧室,实时监测空气质量和气体浓度,提醒用户通风。
  • 教育实验:用于学校课堂,教学生如何使用传感器和 Arduino 编程。
  • 工业安全:部署在工厂,检测气体泄漏,触发报警。

扩展思路

  1. 联网功能: 使用 Wio Terminal 的 Wi-Fi 功能,将数据上传到云端(如 ThingSpeak)。
    1. 扩展代码示例: cpp

Copy

#include <WiFiNINA.h>

char ssid[] = "your-SSID";

char pass[] = "your-password";

WiFiClient client;

void connectWiFi() {

while (WiFi.status() != WL_CONNECTED) {

WiFi.begin(ssid, pass);

delay(5000);

}

}

  1. 数据存储: 使用 microSD 卡模块存储历史数据。
  2. 远程控制: 通过红外发射器(WIO_IR)控制家电,例如在空气质量超标时自动打开风扇。
  3. 声音提醒: 超标时播放不同音调的报警声: cpp

Copy

void playAlarm(int frequency, int duration) {

tone(WIO_BUZZER, frequency, duration);

delay(duration);

}

参考资源

参考代码:

以下是完整的 Arduino 代码,用于采集传感器数据并在屏幕上显示:

cpp

#include <TFT_eSPI.h> // Wio Terminal LCD library

#include <Air_Quality_Sensor.h> // Air Quality Sensor library

// Initialize TFT display

TFT_eSPI tft = TFT_eSPI();

// Initialize Air Quality Sensor on A0

AirQualitySensor airSensor(A0);

// Pin definitions

#define MQ2_PIN A1 // MQ2 Gas Sensor

#define LIGHT_PIN WIO_LIGHT // Built-in Light Sensor

#define MIC_PIN WIO_MIC // Built-in Microphone

// Display mode

enum DisplayMode { AIR_GAS, LIGHT_SOUND };

DisplayMode currentMode = AIR_GAS;

// Setup

void setup() {

  Serial.begin(9600);

  while (!Serial);

  // Initialize sensor pins

  pinMode(LIGHT_PIN, INPUT);

  pinMode(MIC_PIN, INPUT);

  pinMode(MQ2_PIN, INPUT);

  // Initialize TFT display

  tft.begin();

  tft.setRotation(3); // Landscape mode

  tft.fillScreen(TFT_BLACK);

  tft.setTextSize(1); // Smallest font size for compact display

  // Initialize Air Quality Sensor

  Serial.println("Initializing Air Quality Sensor...");

  tft.setTextColor(TFT_ORANGE, TFT_BLACK);

  tft.drawString("Initializing...", 10, 10);

  delay(20000); // Wait for sensor stabilization

  if (airSensor.init()) {

    Serial.println("Air Quality Sensor ready.");

    tft.fillScreen(TFT_BLACK);

    tft.drawString("Air Quality: OK", 10, 10);

  } else {

    Serial.println("Air Quality Sensor error!");

    tft.fillScreen(TFT_BLACK);

    tft.drawString("Air Quality: Error", 10, 10);

    while (1);

  }

  // Initialize MQ2 Gas Sensor

  Serial.println("MQ2 Gas Sensor ready.");

  tft.drawString("MQ2 Gas: OK", 10, 20);

  delay(1000);

  // Initialize Light and Sound Sensors

  Serial.println("Light and Sound Sensors ready.");

  tft.drawString("Light & Sound: OK", 10, 30);

  delay(1000);

  // Clear screen for data display

  tft.fillScreen(TFT_BLACK);

}

// Main loop

void loop() {

  // Display current mode

  if (currentMode == AIR_GAS) {

    displayAirGas();

  } else {

    displayLightSound();

  }

  // Wait for 10 seconds

  delay(10000);

  // Switch to next mode

  currentMode = (currentMode == AIR_GAS) ? LIGHT_SOUND : AIR_GAS;

}

// Display Air Quality and MQ2 Gas

void displayAirGas() {

  // Clear screen

  tft.fillScreen(TFT_BLACK);

  // Draw decorative border and separator

  tft.drawRect(5, 5, 310, 230, TFT_CYAN);

  tft.drawFastHLine(10, 115, 300, TFT_CYAN);

  // Air Quality

  int airQuality = airSensor.slope();

  int airValue = airSensor.getValue();

  String airStatus, airAdvice;

  uint16_t statusColor;

  if (airQuality == AirQualitySensor::FORCE_SIGNAL) {

    airStatus = "Critical Pollution";

    airAdvice = "Ventilate immediately!";

    statusColor = TFT_RED;

    Serial.println("Critical pollution! Force signal active.");

  } else if (airQuality == AirQualitySensor::HIGH_POLLUTION) {

    airStatus = "High Pollution";

    airAdvice = "Ventilate now!";

    statusColor = TFT_RED;

    Serial.println("High pollution!");

  } else if (airQuality == AirQualitySensor::LOW_POLLUTION) {

    airStatus = "Moderate Pollution";

    airAdvice = "Consider ventilation.";

    statusColor = TFT_YELLOW;

    Serial.println("Moderate pollution!");

  } else {

    airStatus = "Fresh Air";

    airAdvice = "Air quality is good.";

    statusColor = TFT_GREEN;

    Serial.println("Fresh air.");

  }

  // MQ2 Gas

  int mq2Value = analogRead(MQ2_PIN);

  float mq2Voltage = (mq2Value / 1023.0) * 5.0;

  String mq2Status, mq2Advice;

  uint16_t mq2Color;

  if (mq2Value > 1000) {

    mq2Status = "Dangerous";

    mq2Advice = "Evacuate and check for leaks!";

    mq2Color = TFT_RED;

  } else if (mq2Value > 700) {

    mq2Status = "High";

    mq2Advice = "Possible gas leak!";

    mq2Color = TFT_RED;

  } else if (mq2Value > 300) {

    mq2Status = "Moderate";

    mq2Advice = "Check environment.";

    mq2Color = TFT_YELLOW;

  } else if (mq2Value > 100) {

    mq2Status = "Low";

    mq2Advice = "Monitor periodically.";

    mq2Color = TFT_GREEN;

  } else {

    mq2Status = "Normal";

    mq2Advice = "Gas level normal.";

    mq2Color = TFT_GREEN;

  }

  // Display data

  int yPos = 10;

  // Air Quality

  tft.setTextColor(TFT_ORANGE, TFT_BLACK);

  tft.drawString("Air Quality", 10, yPos);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Data: " + String(airValue) + " units", 10, yPos + 15);

  tft.setTextColor(statusColor, TFT_BLACK);

  tft.drawString("Status: " + airStatus, 10, yPos + 30);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Advice: " + airAdvice, 10, yPos + 45);

 

  // MQ2 Gas

  yPos += 65;

  tft.setTextColor(TFT_ORANGE, TFT_BLACK);

  tft.drawString("MQ2 Gas", 10, yPos);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Data: " + String(mq2Value) + ", " + String(mq2Voltage, 2) + "V", 10, yPos + 15);

  tft.setTextColor(mq2Color, TFT_BLACK);

  tft.drawString("Status: " + mq2Status, 10, yPos + 30);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Advice: " + mq2Advice, 10, yPos + 45);

  // Serial output

  Serial.print("Air Quality Value: ");

  Serial.println(airValue);

  Serial.print("MQ2 Value: ");

  Serial.println(mq2Value);

  Serial.print("MQ2 Voltage: ");

  Serial.println(mq2Voltage);

  Serial.println();

}

// Display Light and Sound

void displayLightSound() {

  // Clear screen

  tft.fillScreen(TFT_BLACK);

  // Draw decorative border and separator

  tft.drawRect(5, 5, 310, 230, TFT_CYAN);

  tft.drawFastHLine(10, 115, 300, TFT_CYAN);

  // Light

  int lightValue = analogRead(LIGHT_PIN);

  String lightStatus, lightAdvice;

  uint16_t lightColor;

  if (lightValue < 100) {

    lightStatus = "Very Dark";

    lightAdvice = "Add strong lighting.";

    lightColor = TFT_RED;

  } else if (lightValue < 200) {

    lightStatus = "Low Light";

    lightAdvice = "Increase lighting.";

    lightColor = TFT_YELLOW;

  } else if (lightValue < 600) {

    lightStatus = "Moderate Light";

    lightAdvice = "Lighting is normal.";

    lightColor = TFT_GREEN;

  } else if (lightValue < 1000) {

    lightStatus = "Bright Light";

    lightAdvice = "Lighting is sufficient.";

    lightColor = TFT_GREEN;

  } else {

    lightStatus = "Very Bright";

    lightAdvice = "Reduce lighting.";

    lightColor = TFT_YELLOW;

  }

  // Sound

  long soundSum = 0;

  const int samples = 50;

  for (int i = 0; i < samples; i++) {

    soundSum += analogRead(MIC_PIN);

    delay(5);

  }

  int soundValue = soundSum / samples;

  String soundStatus, soundAdvice;

  uint16_t soundColor;

  if (soundValue < 50) {

    soundStatus = "Very Quiet";

    soundAdvice = "Environment is calm.";

    soundColor = TFT_GREEN;

  } else if (soundValue < 100) {

    soundStatus = "Quiet";

    soundAdvice = "Sound level is good.";

    soundColor = TFT_GREEN;

  } else if (soundValue < 300) {

    soundStatus = "Moderate Sound";

    soundAdvice = "Sound level is normal.";

    soundColor = TFT_GREEN;

  } else if (soundValue < 500) {

    soundStatus = "Loud";

    soundAdvice = "Consider reducing noise.";

    soundColor = TFT_YELLOW;

  } else {

    soundStatus = "Noisy";

    soundAdvice = "Reduce noise immediately.";

    soundColor = TFT_RED;

  }

  // Display data

  int yPos = 10;

  // Light

  tft.setTextColor(TFT_ORANGE, TFT_BLACK);

  tft.drawString("Light", 10, yPos);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Data: " + String(lightValue) + " units", 10, yPos + 15);

  tft.setTextColor(lightColor, TFT_BLACK);

  tft.drawString("Status: " + lightStatus, 10, yPos + 30);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Advice: " + lightAdvice, 10, yPos + 45);

 

  // Sound

  yPos += 65;

  tft.setTextColor(TFT_ORANGE, TFT_BLACK);

  tft.drawString("Sound", 10, yPos);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Data: " + String(soundValue) + " units", 10, yPos + 15);

  tft.setTextColor(soundColor, TFT_BLACK);

  tft.drawString("Status: " + soundStatus, 10, yPos + 30);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.drawString("Advice: " + soundAdvice, 10, yPos + 45);

  // Serial output

  Serial.print("Light Value: ");

  Serial.println(lightValue);

  Serial.print("Sound Value: ");

  Serial.println(soundValue);

  Serial.println();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值