Funpack第12期:基于Wio Terminal的环境监测器
主控制板Wio Terminal循环读取当前温湿度、光照强度和距离的环境监测器
标签
嵌入式系统
显示
大写DDG
更新2021-12-30
中北大学
890

基于Wio Terminal的环境监测仪

 

一、系统硬件构成

FhwwuZW7TP59zXj22xTUNDVQkGkp

  • Wio Terminal:基于SAMD51的微控制器,支持蓝牙和WIFI,主要做物联网开发使用
  • SHT30:温湿度传感器,使用IIC通讯方式读取温度和湿度信息
  • BH1750:光照强度传感器,使用IIC通讯方式读取当前的光照强度
  • SR04:超声波测距仪,使用电平触发,读取脉冲的方式读取当前距离

二、开发环境介绍

Arduino是一款便捷灵活、方便上手的开源电子原型平台。包含硬件(各种型号的Arduino板)和软件(ArduinoIDE)。

没有电路基础的初学者:Arduino上手方便,容易开发。

模数电,51/32基础的人:Arduino简单,但是由于其函数库封装性高,无法便捷的深入到硬件层次,不习惯。

Arduino程序逻辑:

void setup() {
  // put your setup code here, to run once:
  // 初始化代码放在此处,只运行一次
}

void loop() {
  // put your main code here, to run repeatedly:
  // 主要程序放在此处,反复运行,类似于C中的while(1)
}

三、传感器模块介绍

(一)温湿度传感器SHT30模块

1.基本介绍

通讯数字型传感器

湿度测量范围 0~100%RH
湿度测量精度 ±3&RH
温度测量范围 -40~125℃
温度测量精度 ±0.3℃
工作电压 2.4~5.5VDC(宽电压)
通讯方式 IIC(0X44)

2.引脚介绍

  • VCC   电源正极     直接连接主控板的3.3V/5V
  • GND   电源负极    直接连接主控板的GND
  • SDA   IIC数据      直接连接主控板的I2C1_SDA(PIN3)
  • SCL    IIC时钟      直接连接主控板的I2C1_SCL(PIN5)

 

3.基本程序介绍

前提:先在个人的Arduino ide中预安装SHT30的库(本文档后附)

#include <Wire.h>
#include <ClosedCube_SHT3XD.h>

ClosedCube_SHT3XD sht3xd;

void setup()
{
	Serial.begin(9600);
	Serial.println("ClosedCube SHT3XD Library - Single Shot Mode Example");
	
	sht3xd.begin(0x44);
	Serial.print("SHT3XD Serial #");
	Serial.println(sht3xd.readSerialNumber());	
}

void loop()
{
	printResult("ClockStrech Mode", sht3xd.readTempAndHumidity(REPEATABILITY_LOW, MODE_CLOCK_STRETCH, 50));  
  	delay(250);
	printResult("Pooling Mode", sht3xd.readTempAndHumidity(REPEATABILITY_HIGH, MODE_POLLING, 50));
	delay(250);
}

void printResult(String text, SHT3XD result) {
	if (result.error == NO_ERROR) {
		Serial.print(text);
		Serial.print(": T=");
		Serial.print(result.t);
		Serial.print("C, RH=");
		Serial.print(result.rh);
		Serial.println("%");
	}
	else {
		Serial.print(text);
		Serial.print(": [ERROR] Code #");
		Serial.println(result.error);
	}
}

连接侯硬件的连线后,将代码烧录,打开串口监视器查看信息。

 

(二)光照强度传感器BH1750模块

1.基本介绍

通讯数字型传感器

光照强度范围 0~65535lx
测量精度 1lx
工作电压 3~5VDC(宽电压)
通讯方式 IIC

2.引脚介绍

  • VCC   电源正极     直接连接主控板的3.3V/5V
  • GND   电源负极    直接连接主控板的GND
  • SDA   IIC数据      直接连接主控板的I2C1_SDA(PIN3)
  • SCL    IIC时钟      直接连接主控板的I2C1_SCL(PIN5)
  • ADD   IIC地址      直接连接主控板的VCC/GND,则IIC地址为0x5C/0x23

3.基本程序介绍

#include <Wire.h> //IIC
#include <math.h> 
/*
 * ADDR引脚=“H”  IIC_address=0x5c
 * ADDR引脚=“L”  IIC_address=0x23
 */
int BH1750address = 0x23; 
byte buff[2];
void setup(){
  Wire.begin();
  Serial.begin(9600);
}

void loop(){
  int i;
  uint16_t val=0;
  BH1750_Init(BH1750address);
  delay(200);
  if(2==BH1750_Read(BH1750address))
  {
    val=((buff[0]<<8)|buff[1])/1.2;    
    Serial.print(val,DEC);         
    Serial.println("[lx]");   
  }  
  delay(150);
}




int BH1750_Read(int address) 
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) 
  {
    buff[i] = Wire.read();  // receive one byte
    i++;
  }
  Wire.endTransmission();  
  return i;
}

void BH1750_Init(int address) 
{
  Wire.beginTransmission(address);
  Wire.write(0x10);//1lx reolution 120ms
  Wire.endTransmission();
}

连接侯硬件的连线后,将代码烧录,打开串口监视器查看信息。

 

(三)超声波测距仪SR04模块

1.基本介绍

通讯数字型传感器

射程范围 2cm~4m
工作频率 40KHz
工作电压 DC5V
工作电流 15mA
输入触发信号 10us的TTL脉冲
输出回响信号 输出TTL信号,与脉冲成比例

2.引脚介绍

  • VCC      电源正极    直接连接主控板的3.3V/5V
  • GND     电源负极     直接连接主控板的GND
  • TRIG     触发端       直接连接主控板的数字输出引脚 D2(PIN16)
  • ECHO    接收端       直接连接主控板的数字输入引脚 D3(PIN28)

3.基本程序介绍

/*
 * SR04超声波传感器驱动
 * 串口显示检测距离 
*/
//设定 WIO_Terminal 与HC-SR04 超声波测距模块的 的引脚连接
#define trigPin  D2
#define echoPin  D3

void setup() {
  //初始化串口 
  Serial.begin(9600);
  //初始化引脚状态
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  Serial.println("Ultrasonic sensor:");
}

void loop() {
  // 产生一个10us的高脉冲去触发teigpin 
  digitalWrite(trigPin,LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin,HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin,LOW);
  
  //检测脉冲宽度并且计算距离
  float distance;
  distance = pulseIn(echoPin,HIGH)/58.00;

  //串口输出距离
  Serial.print(distance);
  Serial.println("cm");
  delay(1000);   
}

 

四、系统总体程序

/****************LCD屏幕头文件**************************/
#include <TFT_eSPI.h> // Hardware-specific library
#include "Seeed_FS.h"
#include "Free_Fonts.h" //免费字体头文件
#include <SPI.h>
/*****************************************************/

/****************温度传感器sht30头文件*******************/
#include <Wire.h> // IIC协议
#include <ClosedCube_SHT3XD.h> //sht30头文件
/*****************************************************/


/******设定 主控板 与HC-SR04 超声波测距模块的 的引脚连接****/
#define trigPin  D2 //(PIN16)
#define echoPin  D3 //(PIN28)
/*****************************************************/

//组定义
TFT_eSPI tft = TFT_eSPI();  //lcd     
ClosedCube_SHT3XD  sht3xd;  //sht30

//IIC协议从设备地址
int BH1750address = 0x23; //BH1750
int SHT30address = 0x44;  //SHT30

byte buff[2];

void setup(void) {

  Serial.begin(9600); //串口波特率9600
  lcd_init();
  //设定 超声波测距模块SR04 的引脚模式
  pinMode(trigPin,OUTPUT); //触发端为输出
  pinMode(echoPin,INPUT);  //接收端为输入
}

void loop() {
  
  TEMP_HUMI_display();  //读取并显示温湿度信息
  delay(200);
  Light_BH1750_display(); //读取并显示光照强度信息
  delay(200);
  Distance_SR04_display(); //读取并显示距离信息
  delay(200);
}

/******************************************************
 ********************* lcd屏幕初始化 *******************
 *****************************************************/
void lcd_init() 
{
  tft.init();
  tft.setRotation(3);   //TFT_LCD的旋转,确定四个角哪个角为(0,0)坐标原点, 0~3  3为正面    
  tft.fillScreen(TFT_BLACK); //填充背景为黑色
  tft.setFreeFont(FM18); 
  //设定不同信息的具体含义显示
  tft.drawString("TEMP:  . *C",10,10); // temperature   温度
  tft.drawString("HUMI:  . %R",10,50); // humidity      湿度
  tft.drawString("ILLU:    Lx",10,90); // illumination  光照强度
  tft.drawString("DIST:   . cm",10,130); //distance     距离
}

/****************************************************
 **************** SHT30温湿度传感器 *******************
 ***************************************************/
void TEMP_HUMI_display()
{
  SHT3XD result;
  sht3xd.begin(0x44);
  result = sht3xd.readTempAndHumidity(REPEATABILITY_LOW, MODE_CLOCK_STRETCH, 50);
  int Tz_pre,Tx_pre,Hz_pre,Hx_pre;
  int Tz = (int)result.t;
  int Tx = (int)(result.t*10)%10;
  int Hz = (int)result.rh;
  int Hx = (int)(result.rh*10)%10;
  
  //温度整数
  if(Tz_pre != Tz){
    tft.drawNumber(Tz,116,10);
    Tz_pre = Tz;
  }
  //温度小数
  if(Tx_pre != Tx){
    tft.drawNumber(Tx,176,10);
    Tx_pre = Tx;
  }

  //湿度整数
  if(Hz_pre != Hz){
    tft.drawNumber(Hz,116,50);
    Hz_pre = Hz;
  }
  //湿度小数
  if(Hx_pre != Hx){
    tft.drawNumber(Hx,176,50);
    Hx_pre = Hx;
  }
  Wire.endTransmission();
}

/****************************************************
 *************  BH170 光照强度 传感器 **  *************
 ***************************************************/
int BH1750_Read(int address) //
{
  int i=0;
  Wire.beginTransmission(address);
  Wire.requestFrom(address, 2);
  while(Wire.available()) //
  {
    buff[i] = Wire.read();  // receive one byte
    i++;
  }
  Wire.endTransmission();  
  return i;
}

void BH1750_Init(int address) 
{
  Wire.beginTransmission(address);
  Wire.write(0x10);//1lx reolution 120ms
  Wire.endTransmission();
}

void Light_BH1750_display(){
  
  int i;  
  uint16_t val=0; 
  BH1750_Init(BH1750address);  
  delay(200);  
  if(2==BH1750_Read(BH1750address))
  {  
    val=((buff[0]<<8)|buff[1])/1.2;    
    Serial.print(val,DEC);         
    Serial.println("[lx]");
    if(val/10==0)
    {
      tft.fillRect(116, 90, 60, 30, TFT_BLACK);
      tft.drawNumber(val,176,90);
    }
    else if(val/100==0)
    {
      tft.fillRect(116, 90, 40, 30, TFT_BLACK);
      tft.drawNumber(val,156,90); 
    }
    else if(val/1000==0)
    {
      tft.fillRect(116, 90, 20, 30, TFT_BLACK);
      tft.drawNumber(val,136,90); 
    }
    else if(val/10000==0)
      tft.drawNumber(val,116,90);   
  }
}


/**************************************
 ********* SR04超声波测距 **************
 *************************************/
void Distance_SR04_display() {
  
  // 产生一个10us的高脉冲去触发teigpin 
  digitalWrite(trigPin,LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin,HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin,LOW);
  
  //检测脉冲宽度并且计算距离
  float distance;
  distance = pulseIn(echoPin,HIGH)/58.00;
  int d01 = (int)(distance*10)%10;
  int d1 = (int)distance%10;
  int d10 = (int)(distance/10)%10;
  int d100 = (int)(distance/100)%10;
  
  if(d100!=0)
  {
    tft.drawNumber(d100,116,130);
    tft.drawNumber(d10 ,136,130);
    tft.drawNumber(d1  ,156,130);
    tft.drawNumber(d01,196,130);
  }
  else if(d10!=0)
  {
    tft.fillRect(116, 130, 20, 30, TFT_BLACK);
    tft.drawNumber(d10 ,136,130);
    tft.drawNumber(d1  ,156,130);
    tft.drawNumber(d01,196,130); 
  }
  else
  {
    tft.fillRect(116, 130, 40, 30, TFT_BLACK);
    tft.drawNumber(d1  ,156,130);
    tft.drawNumber(d01,196,130);
  }

  //串口输出距离
  Serial.print(distance);
  Serial.println("cm"); 
}

程序编写过程中遇到的问题:

  1. 对于lcd库的很多函数无法正确使用,库程序里面不明白其含义(看了示例程序后)。
  2. 浮点型数据的显示,小数点后位数太多,最后先将浮点型数据强制转换为整型才使得每一个位显示。
  3. 该开始接线的时候,不知道IIC总线该接哪个IIC口。

五、功能展示

  Fi1xPMbs6Pv8ChZbspdQU9DiJpRH

六、心得体会

  1. Arduino的开源性,简单明了的程序编程非常适合纯小白上手。本人是熟悉模数电硬件和FPGA的学生,对这种风格不太容易接受,但是也被它的简单性给吸引到了。
  2. Wio Treminal内部资源非常丰富,本程序几乎没有怎么使用,等到有充足时间的时候一定要认真都做一遍。
  3. 对于嵌入式的图形界面GUI一直没有接触过,求大佬帮忙推荐个学习资源。

建议!!!

活动后期或者最后可以请优秀成员(每个题目)仔细讲解其每一个模块内容(纯干货那种),对于我这种菜鸟会更加喜欢。

 

附件下载
MAIN.zip
直接烧录的文件代码
实例代码和库.zip
需要添加的库文件和一些模块的示例代码
团队介绍
中北大学信息与通信工程学院
团队成员
董殿国
中北大学信息与通信工程学院电子信息
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号