使用 Nano 的环境监测系统,具有 GPS、BME680、VEML6070、MiCS-5524、BH1750、128x64 OLED 和 NeoPixels。
我创建这个设备是为了个人的。它最终将与带有 3.5 英寸 LCD 的 Raspberry Pi 配对,以显示雷达。最终产品将使我无论身在何处都能看到当前的天气状况,包括使用当前 GPS 数据的实时雷达。
它目前使用:
• Arduino 纳米 (Rev3.0)
• Adafruit BME680(温度、湿度、气压和 AQI)
• Adafruit MiCS-5524 气体传感器(一氧化碳水平)
• Adafruit VEML6070(紫外线指数)
• BH1750(光强度)
• NEO 6M GPS(定位服务)
• OLED 单色 2.4 英寸 128x64 I2C(数值显示)
• Adafruit NeoPixel Stick(一目了然的显示屏)
它将显示温度、湿度、气压、空气质量指数(以 inHg 和 mb 为单位)空气质量指数、紫外线指数和光度;以及当前纬度/经度、高度、速度、航向和时间(UTC)。
Nano、BME680 和 CO 传感器目前安装在安装在塑料工艺容器中的 Adafruit Perma-Proto 四分之一尺寸板上。紫外线和勒克斯传感器安装在一块原型板上,并放置在设备内部的顶部。
我在代码中遇到了一个我还没有弄清楚的错误......似乎每当 BME680 代码运行时,高度、FIX、ACQUIRED 和 TRACKED 卫星的 GPS 值都会丢失。我还在努力弄清楚。
NeoPixels 以颜色编码格式显示当前值,通常遵循 NWS 格式。
• 0=温度水平(主观颜色)
• 1=压力读数(主观颜色)
• 2=湿度水平(主观颜色)
• 3= GPS 修复(绿色固定/红色无修复)
• 4=光强度(主观颜色)
• 5= 紫外线指数(遵循 NWS 指南)
• 6= 以 PPM 为单位的 CO 水平(主观颜色)
• 7=空气质素指数(遵循新创建指引)
我尝试将 NeoPixels 放在白标后面,图 1.1,但它太亮了。我最终在 NeoPixels 上放置了一条黑色电工胶带以扩散亮度,因此它们的外观,如图。
BME680 和 CO 传感器都安装在内部和接头上,而 UV 和 Lux 传感器安装在设备顶部的预备板上,并切出一块用于曝光,GPS 天线就坐在那里。
我的最后一步是在内部安装一个 5 毫米风扇,以使空气穿过内部传感器。
仅供参考,您可以使用 .96 英寸 128x64 IIC OLED 构建此项目,它将放置到位,无需任何代码修改。










项目代码
#include <NMEAGPS.h>
#include <GPSport.h>
#include <U8x8lib.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include "Adafruit_VEML6070.h"
#include <BH1750.h>
#define PIN 12
#define NUMPIXELS 8
int delayval = 50;
static NMEAGPS gps;
static gps_fix fix;
Adafruit_BME680 bme;
BH1750 lightMeter;
Adafruit_VEML6070 uv = Adafruit_VEML6070();
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
gpsPort.begin(9600);
bme.begin();
lightMeter.begin();
uv.begin(VEML6070_1_T);
//Serial.begin(9600);
u8x8.begin();
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.clearDisplay();
delay(10);
u8x8.drawString(4,3,"LocAware");
u8x8.drawString(3,4,"by PyreMage");
u8x8.drawString(6,5,"v4.0");
delay(1500);
u8x8.clearDisplay();
u8x8.drawString(0,0," Acquiring Fix");
u8x8.inverse();
u8x8.drawString(0, 1, "T");//Temp
u8x8.drawString(8, 1, "P");//Pressure
u8x8.drawString(0, 2, "H");//Humidity
u8x8.drawString(8, 2, "P");//Pressure
u8x8.drawString(0, 3, "L");//Lux
u8x8.drawString(8, 3, "UVI");//UV index
u8x8.drawString(0, 4, "CO");//CO Gas
u8x8.drawString(8, 4, "AQI");//AQI
u8x8.drawString(0, 5, "Sp");//Speed
u8x8.drawString(11, 5, "Hd");//Heading
u8x8.drawString(0, 6, "A");//Altitude
u8x8.drawString(0, 7, "F");//Fix
u8x8.drawString(3, 7, "T");//Tracking
u8x8.drawString(6, 7, "A");//Acquired
u8x8.drawString(10, 7, "U");//UTC Time
u8x8.noInverse();
/*
Neopixels definition
0=Temp
1=Pressure
2=Humidity
4=Lux
3=GPS Fix
5=UVI
6=CO
7=AQI
*/
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i, pixels.Color(0,255,0));
pixels.show();
delay(delayval);}
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i, pixels.Color(0,0,0));
pixels.show();
delay(delayval);}
}
void loop() {
uint16_t lux = lightMeter.readLightLevel();
char tmpchar[4];
int bmetmp=(bme.readTemperature() * 9/5 + 32-10);
dtostrf((bme.readTemperature() * 9/5 + 32-10), 3, 2, tmpchar);
if (bmetmp>100){pixels.setPixelColor(1, pixels.Color(255,0,0));//red
pixels.show();}else
if (bmetmp>90 && bmetmp<99){pixels.setPixelColor(0, pixels.Color(255,125,0));//orange
pixels.show();}else
if (bmetmp>80 && bmetmp<89){pixels.setPixelColor(0, pixels.Color(255,255,0));//yellow
pixels.show();}else
if (bmetmp>70 && bmetmp<79){pixels.setPixelColor(0, pixels.Color(0,255,125));//turquiose
pixels.show();}else
if (bmetmp>60 && bmetmp<69){pixels.setPixelColor(0, pixels.Color(0,255,0));//green
pixels.show();}else
if (bmetmp<59){pixels.setPixelColor(0, pixels.Color(0,0,255));//blue
pixels.show();}else
if (bmetmp<1){pixels.setPixelColor(0, pixels.Color(0,0,0));pixels.show();}//off
u8x8.drawString(1, 1, tmpchar);
u8x8.drawString(6, 1, "F");
delay(10);
char prschar[4];
dtostrf((bme.readPressure()/3365.3*1+.15), 3, 2, prschar);
u8x8.drawString(9, 1, prschar);
u8x8.drawString(14, 1, "Hg");
char prs2char[4];
dtostrf(bme.readPressure()*.01+12, 4, 2, prs2char);
int bmeprs=(bme.readPressure()*.01+12);
dtostrf((bme.readTemperature() * 9/5 + 32-10), 3, 2, tmpchar);
if (bmeprs>1020){pixels.setPixelColor(1, pixels.Color(255,125,0));//orange
pixels.show();}else
if (bmeprs>1010 && bmeprs<1019){pixels.setPixelColor(1, pixels.Color(0,255,0));//green
pixels.show();}else
if (bmeprs>1000 && bmeprs<1009){pixels.setPixelColor(1, pixels.Color(0,255,125));//turquiose
pixels.show();}else
if (bmeprs>990 && bmeprs<9999){pixels.setPixelColor(1, pixels.Color(255,125,0));//orange
pixels.show();}else
if (bmeprs>970 && bmeprs<989){pixels.setPixelColor(1, pixels.Color(255,255,0));//yellow
pixels.show();}else
if (bmeprs<969){pixels.setPixelColor(1, pixels.Color(255,0,0));//red
pixels.show();}else
if (bmeprs<1){pixels.setPixelColor(1, pixels.Color(0,0,0));pixels.show();}//off
u8x8.drawString(9, 2, prs2char);
//u8x8.drawString(14, 1, "mB");
char humchar[4];
int bmehum=(bme.readHumidity()+14.5);
dtostrf(bme.readHumidity()+14.5, 3, 2, humchar);
if (bmehum>100){pixels.setPixelColor(2, pixels.Color(255,0,0));//red
pixels.show();}else
if (bmehum>90 && bmehum<99){pixels.setPixelColor(2, pixels.Color(255,125,0));//orange
pixels.show();}else
if (bmehum>80 && bmehum<89){pixels.setPixelColor(2, pixels.Color(255,255,0));//yellow
pixels.show();}else
if (bmehum>70 && bmehum<79){pixels.setPixelColor(2, pixels.Color(0,0,255));//blue
pixels.show();}else
if (bmehum>60 && bmehum<69){pixels.setPixelColor(2, pixels.Color(0,255,125));//turquiose
pixels.show();}else
if (bmehum<59){pixels.setPixelColor(2, pixels.Color(0,255,0));//green
pixels.show();}else
if (bmehum<1){pixels.setPixelColor(2, pixels.Color(0,0,0));pixels.show();}//off
u8x8.drawString(1, 2, humchar);
u8x8.drawString(6, 2, "%");
char luxchar[5];
dtostrf(lux, 5, 0, luxchar);
//Serial.println(luxchar);
if (lux>34001){pixels.setPixelColor(4, pixels.Color(255,0,0));//red
pixels.show();}else
if (lux>20001 && lux<34000){pixels.setPixelColor(4, pixels.Color(255,125,0));//orange
pixels.show();}else
if (lux>10001 && lux<20000){pixels.setPixelColor(4, pixels.Color(255,255,0));//yellow
pixels.show();}else
if (lux>5001 && lux<10000){pixels.setPixelColor(4, pixels.Color(0,0,255));//blue
pixels.show();}else
if (lux>2000 && lux<5000){pixels.setPixelColor(4, pixels.Color(0,255,125));//turquiose
pixels.show();}else
if (lux<2000){pixels.setPixelColor(4, pixels.Color(0,255,0));//green
pixels.show();}else
if (lux<1){pixels.setPixelColor(4, pixels.Color(0,0,0));pixels.show();}//off
u8x8.drawString(1, 3, " ");
u8x8.drawString(1, 3, luxchar);
char uvchar[4];
uv.readUV();
if (uv.readUV()>2055) {u8x8.drawString(11, 3, " ");u8x8.drawString(11, 3, "Extre");
pixels.setPixelColor(5, pixels.Color(255,0,0));//red
pixels.show();}else
if (uv.readUV()>1494 && uv.readUV()<2054) {u8x8.drawString(11, 3, " ");u8x8.drawString(11, 3, "VHigh");
pixels.setPixelColor(5, pixels.Color(255,125,0));//orange
pixels.show();}else
if (uv.readUV()>1121 && uv.readUV()<1493) {u8x8.drawString(11, 3, " ");u8x8.drawString(11, 3, "High");
pixels.setPixelColor(5, pixels.Color(255,255,0));//yellow
pixels.show();}else
if (uv.readUV()>561 && uv.readUV()<1120) {u8x8.drawString(11, 3, " ");u8x8.drawString(11, 3, "Moder");
pixels.setPixelColor(5, pixels.Color(0,0,255));//blue
pixels.show();}else
if (uv.readUV()<560) {u8x8.drawString(11, 3, " ");u8x8.drawString(11, 3, "Low");
pixels.setPixelColor(5, pixels.Color(0,255,0));//green
pixels.show();}else
if (uv.readUV()<1){pixels.setPixelColor(5, pixels.Color(0,0,0));pixels.show();}//off
char vocchar[5];
dtostrf(bme.gas_resistance, 5, 0, vocchar);
if (bme.gas_resistance>140901) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "Good");
pixels.setPixelColor(7, pixels.Color(0,255,0));//green
pixels.show();}else
if (bme.gas_resistance>75001 && bme.gas_resistance<140900) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "Moder");
pixels.setPixelColor(7, pixels.Color(0,255,125));//turquiose
pixels.show();}else
if (bme.gas_resistance>37400 && bme.gas_resistance<75000) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "USG");
pixels.setPixelColor(7, pixels.Color(0,0,255));//blue
pixels.show();}else
if (bme.gas_resistance>18770 && bme.gas_resistance<37399) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "Unhlt");
pixels.setPixelColor(7, pixels.Color(255,0,255));//magenta
pixels.show();}else
if (bme.gas_resistance>9001 && bme.gas_resistance<18771) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "VUnhl");
pixels.setPixelColor(7, pixels.Color(225,125,0));//orange
pixels.show();}else
if (bme.gas_resistance>8371 && bme.gas_resistance<9000) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "Hazar");
pixels.setPixelColor(7, pixels.Color(255,0,0));//red
pixels.show();}else
if (bme.gas_resistance<8370) {u8x8.drawString(11, 4, " ");u8x8.drawString(11, 4, "Vacat");
pixels.setPixelColor(7, pixels.Color(255,0,0));//red
pixels.show();}else
if (bme.gas_resistance<1){pixels.setPixelColor(7, pixels.Color(0,0,0));pixels.show();}//off
char gaschar[4];
int reading = analogRead(A0);
dtostrf(reading, 3, 0, gaschar);
u8x8.drawString(2, 4, gaschar);
u8x8.drawString(5, 4, "PPM");
//Serial.println(reading);
if (reading>1000){pixels.setPixelColor(6, pixels.Color(255,0,0));pixels.show();}//red
if (reading>501 && reading<999){pixels.setPixelColor(6, pixels.Color(225,125,0));pixels.show();}else//orange
if (reading>151 && reading<500){pixels.setPixelColor(6, pixels.Color(255,255,0));pixels.show();}else//yellow
if (reading>71 && reading<150){pixels.setPixelColor(6, pixels.Color(0,0,255));pixels.show();}else//blue
if (reading>1 && reading<70){pixels.setPixelColor(6, pixels.Color(0,255,0));pixels.show();}else//green
if (reading<1){pixels.setPixelColor(6, pixels.Color(0,0,0));pixels.show();}//off
GPSloop();
}
static void GPSloop()
{
pixels.setPixelColor(3, pixels.Color(255,0,0));pixels.show();//red
while (gps.available( gpsPort )) {
pixels.setPixelColor(3, pixels.Color(0,255,0));pixels.show();//green
GetGPS();
}
}
static void GetGPS()
{
fix = gps.read();
int totalSatellites, trackedSatellites;
totalSatellites = gps.sat_count;
for (uint8_t w = 0; w < totalSatellites; w++) {
if (gps.satellites[w].tracked) {
trackedSatellites++;
}
}
enum {BufSizeTracked = 3}; //Space for 2 characters + NULL
char trackedchar[BufSizeTracked];
snprintf (trackedchar, BufSizeTracked, "%d", trackedSatellites);
u8x8.drawString(4, 7, " ");
u8x8.drawString(4, 7, trackedchar);
enum {BufSizeTotal = 3};
char availchar[BufSizeTotal];
snprintf (availchar, BufSizeTotal, "%d", totalSatellites);
u8x8.drawString(7, 7, " ");
u8x8.drawString(8, 7, availchar);
if (fix.valid.time) {
enum {BufSizeTime = 3};
int hour = fix.dateTime.hours;
int minute = fix.dateTime.minutes;
char hourchar[BufSizeTime];
char minutechar[BufSizeTime];
snprintf (hourchar, BufSizeTime, "%d", hour);
snprintf (minutechar, BufSizeTime, "%d", minute);
if ( hour < 10 )
{
snprintf (hourchar, BufSizeTime, "%02d", hour);
}
if ( minute < 10 )
{
snprintf (minutechar, BufSizeTime, "%02d", minute);
}
u8x8.drawString(11, 7, hourchar);
u8x8.drawString(13, 7, ":");
u8x8.drawString(14, 7, minutechar);
}
char latchar[7]; // Buffer big enough for 4-character float
dtostrf(fix.latitude(), 3, 4, latchar);
u8x8.drawString(0, 0, " ");
u8x8.drawString(0, 0, latchar);
char longchar[7];
dtostrf(fix.longitude(), 3, 4, longchar);
u8x8.drawString(8, 0, longchar);
char altchar[5]; // Buffer big enough for 4-character float
dtostrf((fix.altitude()*3.28084), 3, 2, altchar);
u8x8.drawString(1, 6, " ");
u8x8.drawString(1, 6, altchar);
u8x8.drawString(7, 6, "ft");
char headchar[3];
dtostrf (fix.heading(), 3, 0, headchar);
if (headchar<10){u8x8.drawString(12, 5, "00");u8x8.drawString(14, 5, headchar);}else
if (headchar<99){u8x8.drawString(12, 5, "0");u8x8.drawString(13, 5, headchar);}else
u8x8.drawString(12, 5, headchar);
char spdchar[4];
dtostrf((fix.speed_kph()*0.621371), 2, 2, spdchar);
u8x8.drawString(2, 5, spdchar);
u8x8.drawString(7, 5, "Mph");
char satchar2[3];
dtostrf(fix.satellites, 2, 0, satchar2);
u8x8.drawString(1, 7, " ");
u8x8.drawString(1, 7, satchar2);
}
【Arduino 动手做】使用 Nano 的综合环境监测系统
项目链接:https://www.hackster.io/PyreMage/an-environmental-monitoring-tool-2ebf0a
项目作者:柴堆法师
项目视频 :https://www.youtube.com/watch?v=jhZbnQCLt0w
项目代码:https://www.hackster.io/code_files/213798/download

评论