Peter MaSarah HanShin Ae HongGrace HanKevin Vo
Published © LGPL

SPCPM (Solar Powered City Pollution Monitor)

Low maintenance, high output air pollution, sound pollution that put throughout the city without wiring.

IntermediateFull instructions provided12 hours19,005

Things used in this project

Story

Read more

Schematics

Helium Architecture

This is Helium IoT Architecture

Code

Arduino Air Quality Code

Arduino
Arduino Code with Helium Breakout Board
#include "AirQuality.h"
#include "Arduino.h"
#include "Board.h"
#include "Helium.h"
#include "HeliumUtil.h"
#include <TH02_dev.h>
#include "Arduino.h"
#include "Wire.h" 
#include <SeeedGrayOLED.h>
#include <avr/pgmspace.h>


AirQuality airqualitysensor;

#define CHANNEL_NAME "SPAQM"

Helium  helium(&atom_serial);
Channel channel(&helium);

void setDisplayToOriginalState()
{
    SeeedGrayOled.init(SSD1327);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(150);
  /* Reset HP20x_dev */
  TH02.begin();
  delay(100);
  Serial.println("TH02_dev is available.\n");    
  DBG_PRINTLN(F("Starting"));

  // Begin communication with the Helium Atom
  // The baud rate differs per supported board
  // and is configured in Board.h
  helium.begin(HELIUM_BAUD_RATE);

  // Connect the Atom to the Helium Network
  helium_connect(&helium);

  // Begin communicating with the channel. This should only need to
  // be done once. The HeliumUtil functions add simple retry logic
  // to re-create a channel if it disconnects.
  channel_create(&channel, CHANNEL_NAME);
  Wire.begin();
  airqualitysensor.init(14);
}

void loop() {
  //Set quality from 0 to 255, with one to 100 being normal
  //Air Quality Pollution
//  int sensorValue = analogRead(A0);
//  int airquality = map(sensorValue, 0, 1023, 0, 255);
    int airquality = airqualitysensor.slope();
  
    //Sound Pollution
    long sound = 0;
    for(int i=0; i<32; i++)
    {
        sound += analogRead(A1);
    }
  
    float temper = TH02.ReadTemperature(); 
    float humidity = TH02.ReadHumidity();
  
    
    String dataString = "air=" + String(airquality) + "&noise=" + String(sound) + "&temperature=" + String(temper) + "&humidity=" + String(humidity);
    char data[dataString.length()];
    dataString.toCharArray(data, dataString.length());
    channel_send(&channel, CHANNEL_NAME, data, strlen(data));
    Serial.println(data);
  
    setDisplayToOriginalState();
    SeeedGrayOled.clearDisplay();     //Clear Display.
    SeeedGrayOled.setNormalDisplay(); //Set Normal Display Mode
    SeeedGrayOled.setVerticalMode();  // Set to vertical mode for displaying text
    SeeedGrayOled.setTextXY(0,0);           //Set the cursor to 0th line, 0th Column  
    if (airquality==0)
      SeeedGrayOled.putString("High pollution!!!!");
    else if (airquality==1)
      SeeedGrayOled.putString("High pollution!");
    else if (airquality==2)
      SeeedGrayOled.putString("Low pollution!");
    else if (airquality==3)
      SeeedGrayOled.putString("Fresh Air");

    SeeedGrayOled.setTextXY(2,0);
    String temperaturestring = String(temper) + " C";
    char tempbuffer[temperaturestring.length()];
    temperaturestring.toCharArray(tempbuffer, temperaturestring.length());
    SeeedGrayOled.putString(tempbuffer);

    SeeedGrayOled.setTextXY(3,0);
    String humidstring = "Humid: " + String(humidity);
    char humidbuffer[temperaturestring.length()];
    humidstring.toCharArray(humidbuffer, humidstring.length());
    SeeedGrayOled.putString(humidbuffer);

    SeeedGrayOled.setTextXY(5,0);
    
    if(sound > 5000)
    {
      SeeedGrayOled.putString("Very Loud");
    }
    else if(sound < 4000)
    {
      SeeedGrayOled.putString("Very Quiet");
    }
    else
    {
      SeeedGrayOled.putString("Sound: Normal");
    }
    delay(60000);
}
ISR(TIMER1_OVF_vect)
{
  if(airqualitysensor.counter==61)//set 2 seconds as a detected duty
  {

      airqualitysensor.last_vol=airqualitysensor.first_vol;
      airqualitysensor.first_vol=analogRead(A0);
      airqualitysensor.counter=0;
      airqualitysensor.timer_index=1;
      PORTB=PORTB^0x20;
  }
  else
  {
    airqualitysensor.counter++;
  }
}

Board.h

Arduino
Board.h is needed to run the code
/*
 * Copyright 2017, Helium Systems, Inc.
 * All Rights Reserved. See LICENCE.txt for license information
 */

#ifndef BOARD_H
#define BOARD_H


#if defined(ARDUINO_AVR_UNO)
#include "SoftwareSerial.h"
SoftwareSerial atom_serial(8, 9);
#define HELIUM_BAUD_RATE helium_baud_b9600

#elif defined(ARDUINO_AVR_MEGA2560)
#include "SoftwareSerial.h"
SoftwareSerial atom_serial(10,11);
#define HELIUM_BAUD_RATE helium_baud_b9600 

#elif defined(ARDUINO_SAM_ZERO)
// Arduino M0 Pro
#define atom_serial Serial5

#elif defined(ARDUINO_SAMD_ZERO)
// Arduino Zero
#define atom_serial Serial1

#elif defined(ARDUINO_SAM_DUE)
// Arduino Due with Serial3 (pin 15, 14)
// mapped to pin 8, 9 on the adapter
#define atom_serial Serial3
#endif

#if defined(CORE_TEENSY)
//Teensy with Serial1 (pin 0, 1)
#define atom_serial Serial1
extern "C"{

    int _write(int f, char *ptr,int len){
        int i;
        for(i=0;i<len;i++)
            {
                atom_serial.write(*ptr++);
            }
        return len;
    }
    int _read (int f, char *ptr, int len)
    {
        *ptr=atom_serial.read();  
        
        return len;
    }
}

#elif defined(ARDUINO_AVR_PRO)
//ProMini/Micro with Serial pins (8,9)
#include "SoftwareSerial.h"
SoftwareSerial atom_serial(8,9);

#endif

#ifndef HELIUM_BAUD_RATE
#define HELIUM_BAUD_RATE helium_baud_b115200
#endif

#endif // BOARD_H

SPCPM Node.js

SPCPM Node.js from GCP

Credits

Peter Ma

Peter Ma

49 projects • 393 followers
Prototype Hacker, Hackathon Goer, World Traveler, Ecological balancer, integrationist, technologist, futurist.
Sarah Han

Sarah Han

13 projects • 78 followers
Software Engineer, Design, 3D
Shin Ae Hong

Shin Ae Hong

5 projects • 35 followers
Global Startup Incubation Specialist @Innoway
Grace Han

Grace Han

2 projects • 3 followers
Kevin Vo

Kevin Vo

4 projects • 3 followers

Comments