13浏览
查看: 13|回复: 2

[项目] 【Arduino 动手做】使用 Nano 的综合环境监测系统

[复制链接]
使用 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 构建此项目,它将放置到位,无需任何代码修改。

【Arduino 动手做】使用 Nano 的综合环境监测系统图1

【Arduino 动手做】使用 Nano 的综合环境监测系统图2

【Arduino 动手做】使用 Nano 的综合环境监测系统图3

【Arduino 动手做】使用 Nano 的综合环境监测系统图5

【Arduino 动手做】使用 Nano 的综合环境监测系统图6

【Arduino 动手做】使用 Nano 的综合环境监测系统图4

【Arduino 动手做】使用 Nano 的综合环境监测系统图7

【Arduino 动手做】使用 Nano 的综合环境监测系统图8

【Arduino 动手做】使用 Nano 的综合环境监测系统图9

【Arduino 动手做】使用 Nano 的综合环境监测系统图10

驴友花雕  中级技神
 楼主|

发表于 昨天 20:54

【Arduino 动手做】使用 Nano 的综合环境监测系统

项目代码

  1. #include <NMEAGPS.h>
  2. #include <GPSport.h>
  3. #include <U8x8lib.h>
  4. #include <Adafruit_NeoPixel.h>
  5. #include <Adafruit_Sensor.h>
  6. #include "Adafruit_BME680.h"
  7. #include "Adafruit_VEML6070.h"
  8. #include <BH1750.h>
  9. #define PIN 12
  10. #define NUMPIXELS 8
  11. int delayval = 50;
  12. static NMEAGPS  gps;
  13. static gps_fix  fix;
  14. Adafruit_BME680 bme;
  15. BH1750 lightMeter;
  16. Adafruit_VEML6070 uv = Adafruit_VEML6070();
  17. U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
  18. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
  19. void setup() {
  20.   pixels.begin();
  21.   gpsPort.begin(9600);
  22.   bme.begin();
  23.   lightMeter.begin();
  24.   uv.begin(VEML6070_1_T);
  25.   //Serial.begin(9600);
  26.   
  27.   u8x8.begin();
  28.   u8x8.setFont(u8x8_font_chroma48medium8_r);
  29.   u8x8.clearDisplay();
  30.   delay(10);
  31.   u8x8.drawString(4,3,"LocAware");
  32.   u8x8.drawString(3,4,"by PyreMage");
  33.   u8x8.drawString(6,5,"v4.0");
  34.   delay(1500);
  35.   u8x8.clearDisplay();
  36.   u8x8.drawString(0,0," Acquiring Fix");
  37.   u8x8.inverse();
  38.   
  39.   u8x8.drawString(0, 1, "T");//Temp
  40.   u8x8.drawString(8, 1, "P");//Pressure
  41.   
  42.   u8x8.drawString(0, 2, "H");//Humidity
  43.   u8x8.drawString(8, 2, "P");//Pressure
  44.   u8x8.drawString(0, 3, "L");//Lux
  45.   u8x8.drawString(8, 3, "UVI");//UV index
  46.   u8x8.drawString(0, 4, "CO");//CO Gas
  47.   u8x8.drawString(8, 4, "AQI");//AQI
  48.   u8x8.drawString(0, 5, "Sp");//Speed
  49.   u8x8.drawString(11, 5, "Hd");//Heading
  50.   
  51.   u8x8.drawString(0, 6, "A");//Altitude
  52.   
  53.   u8x8.drawString(0, 7, "F");//Fix
  54.   u8x8.drawString(3, 7, "T");//Tracking
  55.   u8x8.drawString(6, 7, "A");//Acquired
  56.   u8x8.drawString(10, 7, "U");//UTC Time
  57.   
  58.   u8x8.noInverse();
  59.   /*
  60.   Neopixels definition
  61.   0=Temp
  62.   1=Pressure
  63.   2=Humidity
  64.   4=Lux
  65.   3=GPS Fix
  66.   5=UVI
  67.   6=CO
  68.   7=AQI  
  69.   */
  70.   bme.setTemperatureOversampling(BME680_OS_8X);
  71.   bme.setHumidityOversampling(BME680_OS_2X);
  72.   bme.setPressureOversampling(BME680_OS_4X);
  73.   bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  74.   bme.setGasHeater(320, 150); // 320*C for 150 ms
  75.     for(int i=0;i<NUMPIXELS;i++){
  76.     pixels.setPixelColor(i, pixels.Color(0,255,0));
  77.     pixels.show();
  78.     delay(delayval);}
  79.     for(int i=0;i<NUMPIXELS;i++){
  80.     pixels.setPixelColor(i, pixels.Color(0,0,0));
  81.     pixels.show();
  82.     delay(delayval);}
  83. }
  84.   
  85. void loop() {
  86.     uint16_t lux = lightMeter.readLightLevel();
  87.    
  88.     char tmpchar[4];
  89.     int bmetmp=(bme.readTemperature() * 9/5 + 32-10);
  90.     dtostrf((bme.readTemperature() * 9/5 + 32-10), 3, 2, tmpchar);
  91.     if (bmetmp>100){pixels.setPixelColor(1, pixels.Color(255,0,0));//red
  92.     pixels.show();}else
  93.     if (bmetmp>90  && bmetmp<99){pixels.setPixelColor(0, pixels.Color(255,125,0));//orange
  94.     pixels.show();}else
  95.     if (bmetmp>80  && bmetmp<89){pixels.setPixelColor(0, pixels.Color(255,255,0));//yellow
  96.     pixels.show();}else
  97.     if (bmetmp>70  && bmetmp<79){pixels.setPixelColor(0, pixels.Color(0,255,125));//turquiose
  98.     pixels.show();}else
  99.     if (bmetmp>60  && bmetmp<69){pixels.setPixelColor(0, pixels.Color(0,255,0));//green
  100.     pixels.show();}else
  101.     if (bmetmp<59){pixels.setPixelColor(0, pixels.Color(0,0,255));//blue
  102.     pixels.show();}else
  103.     if (bmetmp<1){pixels.setPixelColor(0, pixels.Color(0,0,0));pixels.show();}//off
  104.     u8x8.drawString(1, 1, tmpchar);
  105.     u8x8.drawString(6, 1, "F");
  106.     delay(10);
  107.     char prschar[4];
  108.     dtostrf((bme.readPressure()/3365.3*1+.15), 3, 2, prschar);
  109.     u8x8.drawString(9, 1, prschar);
  110.     u8x8.drawString(14, 1, "Hg");
  111.     char prs2char[4];
  112.     dtostrf(bme.readPressure()*.01+12, 4, 2, prs2char);
  113.     int bmeprs=(bme.readPressure()*.01+12);
  114.     dtostrf((bme.readTemperature() * 9/5 + 32-10), 3, 2, tmpchar);
  115.     if (bmeprs>1020){pixels.setPixelColor(1, pixels.Color(255,125,0));//orange
  116.     pixels.show();}else
  117.     if (bmeprs>1010  && bmeprs<1019){pixels.setPixelColor(1, pixels.Color(0,255,0));//green
  118.     pixels.show();}else
  119.     if (bmeprs>1000  && bmeprs<1009){pixels.setPixelColor(1, pixels.Color(0,255,125));//turquiose
  120.     pixels.show();}else
  121.     if (bmeprs>990  && bmeprs<9999){pixels.setPixelColor(1, pixels.Color(255,125,0));//orange
  122.     pixels.show();}else
  123.     if (bmeprs>970  && bmeprs<989){pixels.setPixelColor(1, pixels.Color(255,255,0));//yellow
  124.     pixels.show();}else
  125.     if (bmeprs<969){pixels.setPixelColor(1, pixels.Color(255,0,0));//red
  126.     pixels.show();}else
  127.     if (bmeprs<1){pixels.setPixelColor(1, pixels.Color(0,0,0));pixels.show();}//off
  128.     u8x8.drawString(9, 2, prs2char);
  129.     //u8x8.drawString(14, 1, "mB");
  130.     char humchar[4];
  131.     int bmehum=(bme.readHumidity()+14.5);
  132.     dtostrf(bme.readHumidity()+14.5, 3, 2, humchar);
  133.     if (bmehum>100){pixels.setPixelColor(2, pixels.Color(255,0,0));//red
  134.     pixels.show();}else
  135.     if (bmehum>90  && bmehum<99){pixels.setPixelColor(2, pixels.Color(255,125,0));//orange
  136.     pixels.show();}else
  137.     if (bmehum>80  && bmehum<89){pixels.setPixelColor(2, pixels.Color(255,255,0));//yellow
  138.     pixels.show();}else
  139.     if (bmehum>70  && bmehum<79){pixels.setPixelColor(2, pixels.Color(0,0,255));//blue
  140.     pixels.show();}else
  141.     if (bmehum>60  && bmehum<69){pixels.setPixelColor(2, pixels.Color(0,255,125));//turquiose
  142.     pixels.show();}else
  143.     if (bmehum<59){pixels.setPixelColor(2, pixels.Color(0,255,0));//green
  144.     pixels.show();}else
  145.     if (bmehum<1){pixels.setPixelColor(2, pixels.Color(0,0,0));pixels.show();}//off
  146.     u8x8.drawString(1, 2, humchar);
  147.     u8x8.drawString(6, 2, "%");
  148.     char luxchar[5];
  149.     dtostrf(lux, 5, 0, luxchar);
  150.     //Serial.println(luxchar);
  151.     if (lux>34001){pixels.setPixelColor(4, pixels.Color(255,0,0));//red
  152.     pixels.show();}else
  153.     if (lux>20001  && lux<34000){pixels.setPixelColor(4, pixels.Color(255,125,0));//orange
  154.     pixels.show();}else
  155.     if (lux>10001  && lux<20000){pixels.setPixelColor(4, pixels.Color(255,255,0));//yellow
  156.     pixels.show();}else
  157.     if (lux>5001  && lux<10000){pixels.setPixelColor(4, pixels.Color(0,0,255));//blue
  158.     pixels.show();}else
  159.     if (lux>2000  && lux<5000){pixels.setPixelColor(4, pixels.Color(0,255,125));//turquiose
  160.     pixels.show();}else
  161.     if (lux<2000){pixels.setPixelColor(4, pixels.Color(0,255,0));//green
  162.     pixels.show();}else
  163.     if (lux<1){pixels.setPixelColor(4, pixels.Color(0,0,0));pixels.show();}//off
  164.     u8x8.drawString(1, 3, "     ");
  165.     u8x8.drawString(1, 3, luxchar);
  166.     char uvchar[4];
  167.     uv.readUV();
  168.     if (uv.readUV()>2055) {u8x8.drawString(11, 3, "      ");u8x8.drawString(11, 3, "Extre");
  169.     pixels.setPixelColor(5, pixels.Color(255,0,0));//red
  170.     pixels.show();}else
  171.     if (uv.readUV()>1494  && uv.readUV()<2054) {u8x8.drawString(11, 3, "     ");u8x8.drawString(11, 3, "VHigh");
  172.     pixels.setPixelColor(5, pixels.Color(255,125,0));//orange
  173.     pixels.show();}else
  174.     if (uv.readUV()>1121  && uv.readUV()<1493) {u8x8.drawString(11, 3, "     ");u8x8.drawString(11, 3, "High");
  175.     pixels.setPixelColor(5, pixels.Color(255,255,0));//yellow
  176.     pixels.show();}else
  177.     if (uv.readUV()>561  && uv.readUV()<1120) {u8x8.drawString(11, 3, "     ");u8x8.drawString(11, 3, "Moder");
  178.     pixels.setPixelColor(5, pixels.Color(0,0,255));//blue
  179.     pixels.show();}else
  180.     if (uv.readUV()<560) {u8x8.drawString(11, 3, "     ");u8x8.drawString(11, 3, "Low");
  181.     pixels.setPixelColor(5, pixels.Color(0,255,0));//green
  182.     pixels.show();}else
  183.     if (uv.readUV()<1){pixels.setPixelColor(5, pixels.Color(0,0,0));pixels.show();}//off
  184.     char vocchar[5];
  185.     dtostrf(bme.gas_resistance, 5, 0, vocchar);
  186.    
  187.     if (bme.gas_resistance>140901) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "Good");
  188.     pixels.setPixelColor(7, pixels.Color(0,255,0));//green
  189.     pixels.show();}else
  190.     if (bme.gas_resistance>75001  && bme.gas_resistance<140900) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "Moder");
  191.     pixels.setPixelColor(7, pixels.Color(0,255,125));//turquiose
  192.     pixels.show();}else
  193.     if (bme.gas_resistance>37400  && bme.gas_resistance<75000) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "USG");
  194.     pixels.setPixelColor(7, pixels.Color(0,0,255));//blue
  195.     pixels.show();}else
  196.     if (bme.gas_resistance>18770  && bme.gas_resistance<37399) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "Unhlt");
  197.     pixels.setPixelColor(7, pixels.Color(255,0,255));//magenta
  198.     pixels.show();}else
  199.     if (bme.gas_resistance>9001  && bme.gas_resistance<18771) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "VUnhl");
  200.     pixels.setPixelColor(7, pixels.Color(225,125,0));//orange
  201.     pixels.show();}else
  202.     if (bme.gas_resistance>8371  && bme.gas_resistance<9000) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "Hazar");
  203.     pixels.setPixelColor(7, pixels.Color(255,0,0));//red
  204.     pixels.show();}else
  205.     if (bme.gas_resistance<8370) {u8x8.drawString(11, 4, "     ");u8x8.drawString(11, 4, "Vacat");
  206.     pixels.setPixelColor(7, pixels.Color(255,0,0));//red
  207.     pixels.show();}else
  208.     if (bme.gas_resistance<1){pixels.setPixelColor(7, pixels.Color(0,0,0));pixels.show();}//off
  209.     char gaschar[4];
  210.     int reading = analogRead(A0);
  211.     dtostrf(reading, 3, 0, gaschar);
  212.     u8x8.drawString(2, 4, gaschar);
  213.     u8x8.drawString(5, 4, "PPM");  
  214.     //Serial.println(reading);
  215.     if (reading>1000){pixels.setPixelColor(6, pixels.Color(255,0,0));pixels.show();}//red
  216.     if (reading>501 && reading<999){pixels.setPixelColor(6, pixels.Color(225,125,0));pixels.show();}else//orange
  217.     if (reading>151 && reading<500){pixels.setPixelColor(6, pixels.Color(255,255,0));pixels.show();}else//yellow
  218.     if (reading>71 && reading<150){pixels.setPixelColor(6, pixels.Color(0,0,255));pixels.show();}else//blue
  219.     if (reading>1 && reading<70){pixels.setPixelColor(6, pixels.Color(0,255,0));pixels.show();}else//green
  220.     if (reading<1){pixels.setPixelColor(6, pixels.Color(0,0,0));pixels.show();}//off
  221.   GPSloop();
  222. }
  223. static void GPSloop()
  224. {
  225.   pixels.setPixelColor(3, pixels.Color(255,0,0));pixels.show();//red
  226.   while (gps.available( gpsPort )) {
  227.     pixels.setPixelColor(3, pixels.Color(0,255,0));pixels.show();//green
  228.     GetGPS();
  229.   }
  230. }
  231. static void GetGPS()
  232. {
  233.   fix = gps.read();
  234.   int totalSatellites, trackedSatellites;
  235.   totalSatellites = gps.sat_count;
  236.   for (uint8_t w = 0; w < totalSatellites; w++) {
  237.     if (gps.satellites[w].tracked) {
  238.       trackedSatellites++;
  239. }
  240. }
  241.   
  242.     enum {BufSizeTracked = 3}; //Space for 2 characters + NULL
  243.     char trackedchar[BufSizeTracked];
  244.     snprintf (trackedchar, BufSizeTracked, "%d", trackedSatellites);
  245.     u8x8.drawString(4, 7, "  ");
  246.     u8x8.drawString(4, 7, trackedchar);
  247.   
  248.     enum {BufSizeTotal = 3};
  249.     char availchar[BufSizeTotal];
  250.     snprintf (availchar, BufSizeTotal, "%d", totalSatellites);
  251.     u8x8.drawString(7, 7, "  ");
  252.     u8x8.drawString(8, 7, availchar);
  253.   if (fix.valid.time) {
  254.     enum {BufSizeTime = 3};
  255.     int hour = fix.dateTime.hours;
  256.     int minute = fix.dateTime.minutes;
  257.     char hourchar[BufSizeTime];
  258.     char minutechar[BufSizeTime];
  259.     snprintf (hourchar, BufSizeTime, "%d", hour);
  260.     snprintf (minutechar, BufSizeTime, "%d", minute);
  261.     if ( hour < 10 )
  262.     {
  263.       snprintf (hourchar, BufSizeTime, "%02d", hour);
  264.     }
  265.     if ( minute < 10 )
  266.     {
  267.       snprintf (minutechar, BufSizeTime, "%02d", minute);
  268.     }
  269.     u8x8.drawString(11, 7, hourchar);
  270.     u8x8.drawString(13, 7, ":");
  271.     u8x8.drawString(14, 7, minutechar);
  272.   }
  273.     char latchar[7]; // Buffer big enough for 4-character float
  274.     dtostrf(fix.latitude(), 3, 4, latchar);
  275.     u8x8.drawString(0, 0, "               ");
  276.     u8x8.drawString(0, 0, latchar);
  277.     char longchar[7];
  278.     dtostrf(fix.longitude(), 3, 4, longchar);
  279.     u8x8.drawString(8, 0, longchar);
  280.     char altchar[5]; // Buffer big enough for 4-character float
  281.     dtostrf((fix.altitude()*3.28084), 3, 2, altchar);
  282.     u8x8.drawString(1, 6, "      ");
  283.     u8x8.drawString(1, 6, altchar);
  284.     u8x8.drawString(7, 6, "ft");
  285.     char headchar[3];
  286.     dtostrf (fix.heading(), 3, 0, headchar);
  287.     if (headchar<10){u8x8.drawString(12, 5, "00");u8x8.drawString(14, 5, headchar);}else
  288.     if (headchar<99){u8x8.drawString(12, 5, "0");u8x8.drawString(13, 5, headchar);}else
  289.     u8x8.drawString(12, 5, headchar);   
  290.     char spdchar[4];
  291.     dtostrf((fix.speed_kph()*0.621371), 2, 2, spdchar);
  292.     u8x8.drawString(2, 5, spdchar);
  293.     u8x8.drawString(7, 5, "Mph");
  294.     char satchar2[3];
  295.     dtostrf(fix.satellites, 2, 0, satchar2);
  296.     u8x8.drawString(1, 7, "  ");
  297.     u8x8.drawString(1, 7, satchar2);
  298. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 20:56

【Arduino 动手做】使用 Nano 的综合环境监测系统

【Arduino 动手做】使用 Nano 的综合环境监测系统
项目链接:https://www.hackster.io/PyreMage ... itoring-tool-2ebf0a
项目作者:柴堆法师

项目视频 :https://www.youtube.com/watch?v=jhZbnQCLt0w
项目代码:https://www.hackster.io/code_files/213798/download

【Arduino 动手做】使用 Nano 的综合环境监测系统图1

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail