Pyre Mage
Published © GPL3+

An Environmental Monitoring Tool

An environmental monitoring system using a Nano, with GPS, BME680, VEML6070, MiCS-5524, BH1750, a 128x64 OLED, and NeoPixels.

IntermediateWork in progress4 hours3,239
An Environmental Monitoring Tool

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
Monochrome 128x32 I2C OLED graphic display
Actually using 128x64 I2C OLED.
×1
Adafruit VEML6070 UV Index Sensor Breakout
×1
Adafruit BME680 - Temperature, Humidity, Pressure and Gas Sensor
×1
Adafruit MiCS5524 CO, Alcohol and VOC Gas Sensor Breakout
×1
NeoPixel Stick - 8 x 5050 RGB LED with Integrated Drivers
×1
DFRobot Light Sensor - BH1750
×1
GYNEO6MV2 GPS Module NEO-6M
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Breadboard images

Here is a breadboard of the basic circuit.
Locaware v4 bb uiethiew0j

Code

LocAware v4

Arduino
#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);

}

Credits

Pyre Mage

Pyre Mage

1 project • 7 followers
Do with what'cha got!

Comments