【项目简介】
硬禾学堂联合digikey进行的funpack第12期活动,硬件选取了功能强大的wio termial 作为本次活动的硬件平台,wio terminal自身有很多传感器并且有一个320x240TFTLCD,可以实现众多功能,借助arduino丰富的资源实现快速开发, 本期有三个任务,我选取任务一,自己准备至少三个外置传感器,并进行读取显示在wio terminal 的lcd屏上。
【开发环境】
软件:
OS:ubuntu20.04
IDE: Arduino IDE 1.8.16
硬件:
wio terminal 1
ccs811 sensor 1
tcs32745 sensor 1
dht22 sensor 1
【步骤】
1.DHT22也称AM2302,是一款含有已校准数字信号输出的温湿度复合传感器,见图1,湿度量程范围0~99.9%RH,精度±2%RH,而温度量程范围是-40℃~80℃,精度±0.5℃。DHT22是单总线通信的,驱动它只需三根线:电源线、信号线和地线,因此其电路也很简单
导入 DHT22库,附上例程代码,在使用DHT22时要注意,读取间隔最好大于2秒
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 2 // Digital pin connected to the DHT sensor
// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
// Pin 15 can work but DHT must be disconnected during program upload.
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
// See guide for details on sensor wiring and usage:
// https://learn.adafruit.com/dht/overview
DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t delayMS;
void setup() {
Serial.begin(9600);
// Initialize device.
dht.begin();
Serial.println(F("DHTxx Unified Sensor Example"));
// Print temperature sensor details.
sensor_t sensor;
dht.temperature().getSensor(&sensor);
Serial.println(F("------------------------------------"));
Serial.println(F("Temperature Sensor"));
Serial.print (F("Sensor Type: ")); Serial.println(sensor.name);
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
Serial.println(F("------------------------------------"));
// Print humidity sensor details.
dht.humidity().getSensor(&sensor);
Serial.println(F("Humidity Sensor"));
Serial.print (F("Sensor Type: ")); Serial.println(sensor.name);
Serial.print (F("Driver Ver: ")); Serial.println(sensor.version);
Serial.print (F("Unique ID: ")); Serial.println(sensor.sensor_id);
Serial.print (F("Max Value: ")); Serial.print(sensor.max_value); Serial.println(F("%"));
Serial.print (F("Min Value: ")); Serial.print(sensor.min_value); Serial.println(F("%"));
Serial.print (F("Resolution: ")); Serial.print(sensor.resolution); Serial.println(F("%"));
Serial.println(F("------------------------------------"));
// Set delay between sensor readings based on sensor details.
delayMS = sensor.min_delay / 1000;
}
void loop() {
// Delay between measurements.
delay(delayMS);
// Get temperature event and print its value.
sensors_event_t event;
dht.temperature().getEvent(&event);
if (isnan(event.temperature)) {
Serial.println(F("Error reading temperature!"));
}
else {
Serial.print(F("Temperature: "));
Serial.print(event.temperature);
Serial.println(F("°C"));
}
// Get humidity event and print its value.
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) {
Serial.println(F("Error reading humidity!"));
}
else {
Serial.print(F("Humidity: "));
Serial.print(event.relative_humidity);
Serial.println(F("%"));
}
}
编译下载到开发板,并打开串口监视器,对着传感器吹了一口气,瞬间数值发生变化。
2. tcs34725 RGB识别传感器,数据手册比较详细,列出部分内容如下
特性:
所述TCS34725 I2C Arduino的彩色传感器具有高灵敏度,动态范围宽,并包括一个IR阻挡滤波器使其变化的照明条件下使用的理想颜色感测解决方案。TCS34725 颜色传感器还包括四个超亮 LED,允许传感器在没有外部光源的情况下工作。该模块通过您的 Arduino 的 I2C 总线工作,并包括 PH2.0-4P 和 XH2.54(面包板)接口,以满足一系列用户场景。
规格:
工作电压:3.3~5V
工作电流:65 uA
检测范围:3-10 mm
时钟频率:0-400 KHZ
接口:IIC接口
IIC地址:0x29
温度范围: - 30 ℃ ~ + 70 ℃
英尺英寸:18.5 * 23 毫米/ 0.73 * 0.9 英寸
重量:12 克
代码:导入Adafruit_TCS34725库,代码如下
#include <Wire.h>
#include "DFRobot_TCS34725.h"
// Pick analog outputs, for the UNO these three work well
// use ~560 ohm resistor between Red & Blue, ~1K for green (its brighter)
#define redpin 3
#define greenpin 5
#define bluepin 6
// for a common anode LED, connect the common pin to +5V
// for common cathode, connect the common to ground
// set to false if using a common cathode LED
#define commonAnode true
// our RGB -> eye-recognized gamma color
byte gammatable[256];
DFRobot_TCS34725 tcs = DFRobot_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
void setup() {
Serial.begin(115200);
Serial.println("Color View Test!");
if (tcs.begin()) {
Serial.println("Found sensor");
} else {
Serial.println("No TCS34725 found ... check your connections");
while (1); // halt!
}
// use these three pins to drive an LED
pinMode(redpin, OUTPUT);
pinMode(greenpin, OUTPUT);
pinMode(bluepin, OUTPUT);
// thanks PhilB for this gamma table!
// it helps convert RGB colors to what humans see
for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;
if (commonAnode) {
gammatable[i] = 255 - x;
} else {
gammatable[i] = x;
}
//Serial.println(gammatable[i]);
}
}
void loop() {
uint16_t clear, red, green, blue;
tcs.getRGBC(&red, &green, &blue, &clear);
tcs.lock(); // turn off LED
Serial.print("C:\t"); Serial.print(clear);
Serial.print("\tR:\t"); Serial.print(red);
Serial.print("\tG:\t"); Serial.print(green);
Serial.print("\tB:\t"); Serial.print(blue);
Serial.println("\t");
// Figure out some basic hex code for visualization
uint32_t sum = clear;
float r, g, b;
r = red; r /= sum;
g = green; g /= sum;
b = blue; b /= sum;
r *= 256; g *= 256; b *= 256;
Serial.print("\t");
Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.print((int)b, HEX);
Serial.println();
//Serial.print((int)r ); Serial.print(" "); Serial.print((int)g);Serial.print(" "); Serial.println((int)b );
//Set the color lamp
analogWrite(redpin, gammatable[(int)r]);
analogWrite(greenpin, gammatable[(int)g]);
analogWrite(bluepin, gammatable[(int)b]);
}
编译下载到开发板,并打开串口监视器,获取RGB颜色数值
3.ccs811 co2/tvoc传感器,一般用于空气净化器,空调等检测室内空气质量并据此进行新风系统的换气控制。
特性
导入DFRobot_CCS811库,代码如下
#include "DFRobot_CCS811.h"
/*
* IIC address default 0x5A, the address becomes 0x5B if the ADDR_SEL is soldered.
*/
//DFRobot_CCS811 CCS811(&Wire, /*IIC_ADDRESS=*/0x5A);
DFRobot_CCS811 CCS811;
void setup(void)
{
Serial.begin(115200);
/*Wait for the chip to be initialized completely, and then exit*/
while(CCS811.begin() != 0){
Serial.println("failed to init chip, please check if the chip connection is fine");
delay(1000);
}
}
void loop() {
if(CCS811.checkDataReady() == true){
Serial.print("CO2: ");
Serial.print(CCS811.getCO2PPM());
Serial.print("ppm, TVOC: ");
Serial.print(CCS811.getTVOCPPB());
Serial.println("ppb");
} else {
Serial.println("Data is not ready!");
}
/*!
* @brief Set baseline
* @param get from getBaseline.ino
*/
CCS811.writeBaseLine(0x447B);
//delay cannot be less than measurement cycle
delay(1000);
}
编译下载到开发板,并打开串口监视器,co2/tvoc数值如下图所示。
4.为了互动,初始化wio terminial的按键,LCD,直接上代码
先加入按建中断,处理按键事件
button_init();
attachInterrupt(digitalPinToInterrupt(WIO_5S_RIGHT),OnChange,CHANGE);
attachInterrupt(digitalPinToInterrupt(WIO_5S_DOWN),OnChange,CHANGE);
attachInterrupt(digitalPinToInterrupt(WIO_5S_LEFT),OnChange,CHANGE);
attachInterrupt(digitalPinToInterrupt(WIO_5S_UP),OnChange,CHANGE);
void OnChange(){
if(digitalRead(WIO_5S_UP)==LOW||digitalRead(WIO_5S_RIGHT)==LOW)
{
menulist++;
if(menulist>3)
menulist=1;
}
if(digitalRead(WIO_5S_DOWN)==LOW||digitalRead(WIO_5S_LEFT)==LOW)
{
menulist--;
if(menulist<1)
menulist=3;
}
}
导入seeed lcd库,直接调用即可。
5. 实现简单的gui操作,通过第4步的按钮操作实现简单的互动。
switch (menulist){
case 1 : tcs34725_function();
break;
case 2 : DHT_funcion();
break;
case 3 : CCS811_function();
break;
default:
break;
}
6. 加入图表,导入seeed_line_chart库,并在ccs811及DHT22传感器中增加图表
void DHT_funcion(){
// Delay between measurements.
if(menulist!=menuchgflag){
tft.fillScreen(TFT_GREY);
menuchgflag=menulist;}
delay(delayMS);
if (accelerator_readings[0].size() == max_size) {
for (uint8_t i = 0; i<3; i++){
accelerator_readings[i].pop(); //this is used to remove the first read variable
}
}
// Get temperature event and print its value.
sensors_event_t event;
dht.temperature().getEvent(&event);
if (isnan(event.temperature)) {
Serial.println(F("Error reading temperature!"));
}
else {
Serial.print(F("Temperature: "));
Serial.print(event.temperature);
Serial.println(F("°C"));
spr.createSprite(120, 30);
spr.fillSprite(TFT_RED);
spr.setFreeFont(&FreeSansBoldOblique12pt7b);
spr.setTextColor(TFT_BLACK);
spr.drawString("Tmp:",1,0,1);
spr.drawNumber(float(event.temperature), 70 , 0, 1);
spr.drawString("°C",100,0,1);
spr.pushSprite(30 , 5);
spr.deleteSprite();
accelerator_readings[0].push(event.temperature);
}
// Get humidity event and print its value.
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) {
Serial.println(F("Error reading humidity!"));
}
else {
Serial.print(F("Humidity: "));
Serial.print(event.relative_humidity);
Serial.println(F("%"));
spr.createSprite(120, 30);
spr.fillSprite(TFT_GREEN);
spr.setFreeFont(&FreeSansBoldOblique12pt7b);
spr.setTextColor(TFT_BLACK);
spr.drawString("Hum:",1,0,1);
spr.drawNumber(float(event.relative_humidity), 70 , 0, 1);
spr.drawString("%",100,0,1);
spr.pushSprite(150 , 5);
spr.deleteSprite();
accelerator_readings[1].push(event.relative_humidity);
}
spr.createSprite(320, 200);
spr.fillSprite(TFT_WHITE);
//Settings for the line graph title
auto header = text(0, 0)
.value("Temperature/Humidity Readings")
.align(center)
.valign(vcenter)
.width(tft.width())
.thickness(2);
header.height(header.font_height() * 2);
header.draw(); //Header height is the twice the height of the font
//Settings for the line graph
auto content = line_chart(20, header.height()); //(x,y) where the line graph begins
content
.height(tft.height() - header.height() * 1.5) //actual height of the line chart
.width(tft.width() - content.x() * 2) //actual width of the line chart
.based_on(-2.0) //Starting point of y-axis, must be a float
.show_circle(false) //drawing a cirle at each point, default is on.
.value({accelerator_readings[0],accelerator_readings[1]}) //passing through the data to line graph
.color(TFT_RED, TFT_GREEN)
.draw();
spr.pushSprite(5, 30);
spr.deleteSprite();
delay(50);
}
void CCS811_function(){
// tft.fillScreen(TFT_GREY);
if(menulist!=menuchgflag){
tft.fillScreen(TFT_GREY);
menuchgflag=menulist;}
if(CCS811.checkDataReady() == true){
Serial.print("CO2: ");
Serial.print(CCS811.getCO2PPM());
Serial.print("ppm, TVOC: ");
Serial.print(CCS811.getTVOCPPB());
Serial.println("ppb");
if (accelerator_readings[0].size() == max_size) {
for (uint8_t i = 0; i<3; i++){
accelerator_readings[i].pop(); //this is used to remove the first read variable
}
}
accelerator_readings[0].push(CCS811.getCO2PPM());
accelerator_readings[1].push(CCS811.getTVOCPPB());
spr.createSprite(120, 30);
spr.fillSprite(TFT_RED);
spr.setFreeFont(&FreeSansBoldOblique12pt7b);
spr.setTextColor(TFT_BLACK);
spr.drawString("CO2:",1,0,1);
spr.drawNumber(float(CCS811.getCO2PPM()), 70 , 0, 1);
spr.pushSprite(30 , 5);
spr.deleteSprite();
spr.createSprite(120, 30);
spr.fillSprite(TFT_GREEN);
spr.setFreeFont(&FreeSansBoldOblique12pt7b);
spr.setTextColor(TFT_BLACK);
spr.drawString("TVOC:",1,0,1);
spr.drawNumber(float(CCS811.getTVOCPPB()), 70 , 0, 1);
spr.pushSprite(150 , 5);
spr.deleteSprite();
spr.createSprite(320, 200);
spr.fillSprite(TFT_WHITE);
//Settings for the line graph title
auto header = text(0, 0)
.value("CO2/TVOC Readings")
.align(center)
.valign(vcenter)
.width(tft.width())
.thickness(2);
header.height(header.font_height() * 2);
header.draw(); //Header height is the twice the height of the font
//Settings for the line graph
auto content = line_chart(20, header.height()); //(x,y) where the line graph begins
content
.height(tft.height() - header.height() * 1.5) //actual height of the line chart
.width(tft.width() - content.x() * 2) //actual width of the line chart
.based_on(-2.0) //Starting point of y-axis, must be a float
.show_circle(false) //drawing a cirle at each point, default is on.
.value({accelerator_readings[0],accelerator_readings[1]}) //passing through the data to line graph
.color(TFT_RED, TFT_GREEN)
.draw();
spr.pushSprite(5, 30);
spr.deleteSprite();
delay(50);
} else {
Serial.println("Data is not ready!");
}
/*!
* @brief Set baseline
* @param get from getBaseline.ino
*/
CCS811.writeBaseLine(0x447B);
//delay cannot be less than measurement cycle
delay(1000);
}
【综述】
本期活动丰富多彩,三个活动各有侧重,难易不尽相同,任务一传感器的是万物互联的基础,本次选用了3个有代表性的传感器,dht22温湿度,ccs811空气质量传感器,tcs34725色彩传感器,借助arduino丰富的资源库,基本上实现了各个传感器的相应的功能。