Things used in this project

Hardware components:
Arduino Ethernet
×1
SeeedStudio Grove - CO2 Sensor
×1
SeeedStudio Temperature sensor with steel head
×1
SeeedStudio Grove - Sound Sensor
×1

Code

Arduino codeC/C++
 /*
Air Quality/Weather station
  |--> device that monitors the temperature, 
       noise and carbon dioxide levels via devicehub.net
 
 Hardware parts:
   1. Microcontroller board     
       ---> Arduino Ethernet
        |-> http://arduino.cc/en/Main/arduinoBoardEthernet
   
   2. Sound sensor              
       ---> Grove - Sound Sensor w/ LM358 amplifier and an electret microphone  
        |-> http://www.seeedstudio.com/wiki/index.php?title=Twig_-_Sound_Sensor
   
   3. Temperature sensor        
       ---> One Wire Temperature Sensor waterproof DS18B20   
       |-> http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf     
 
   4. CO2 sensor               
       ---> Grove - CO2 Sensor
        |-> http://www.seeedstudio.com/wiki/images/c/ca/MH-Z16_CO2_datasheet_EN.pdf
   
   5. Additional parts          
       ---> 4.7K resistor
 
 Connections:
   1. Sound sensor              
       ---> Arduino Analog A0
   
   2. Temperature sensor        
      ----> Arduino Digital 2
       |--> 4.7K resistor between signal and the power pin
   
   3. CO2 sensor               
       ---> Arduino Digital 3 ( TX )
        |-> Arduino Digital 4 ( RX )
 
 Libraries:
   1. OneWire
       ---> http://code.bildr.org/download/997.zip
   
   2. MQTT PubSubClient         
       ---> https://github.com/knolleary/pubsubclient/archive/v1.9.1.zip
   
   3. Dallas Temperature       
       ---> http://www.hacktronics.com/code/DallasTemperature.zip
     
 Web platform:    
   DeviceHUB.net                
       
 23.06.2015                         
 Author: Alexandru Gheorghe
*/


#include <SPI.h>  
#include <OneWire.h>  
#include <Ethernet.h>                            
#include <PubSubClient.h>
#include <SoftwareSerial.h>
#include <DallasTemperature.h>

// MAC Address of Arduino Ethernet (Sheild)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

#define API_KEY           "paste_apikey_here"
#define PROJECT_ID        "paste_projectid_here"
#define TEMPERATURE_NAME  "paste_temp_sensor_name_here"
#define NOISE_NAME        "paste_noise_sensor_name_here"
#define CO2_NAME          "paste_co2_sensor_name_here"
#define DEVICE_UUID       "paste_device_uuid_name_here"

#define sec               1000

char clientId[]        = "write_a_client_name_without_spaces"; // e.g. char clientId[] = "my_arduino"
char TempTopic[]       = "/a/"API_KEY"/p/"PROJECT_ID"/d/"DEVICE_UUID"/sensor/"TEMPERATURE_NAME"/data";
char NoiseTopic[]      = "/a/"API_KEY"/p/"PROJECT_ID"/d/"DEVICE_UUID"/sensor/"NOISE_NAME"/data";
char CO2Topic[]        = "/a/"API_KEY"/p/"PROJECT_ID"/d/"DEVICE_UUID"/sensor/"CO2_NAME"/data";
// server mqtt.devicehub.net ip
char server[]         = "104.155.7.31";
char message_buffer1[20];
char message_buffer2[20];
char message_buffer3[20];

EthernetClient apiClient;

void callback(char* topic, byte* payload, unsigned int length)
{
  // handle message arrived
}

PubSubClient client(server, 1883, callback, apiClient);

boolean conn = false;
unsigned long time;

#define DS18S20_Pin  2        // DS18S20 Signal pin on digital 2
OneWire ds(DS18S20_Pin);      // on digital pin 2
DallasTemperature sensors(&ds);

int counter = 0;

// CO2 sensor
#define pinTx  3
#define pinRx  4
SoftwareSerial sensorCo2(pinTx,pinRx);
const unsigned char cmd_get_sensor[] = {
0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
const unsigned char cmd_c_sensor[] = {
0xff, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78};

// Noise variables
#define noise_pin        A0   // Microphone is connected to Analog 0
const int sampleWindow = 50;  // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
// variables for smoothing the microphone values
const int numReadings = 10;
int readings[numReadings];      
int index = 0;                  
int total = 0;                  
int average = 0;  

void setup(void)  
{
  // init serial for debugging
  Serial.begin(9600);
  initPins();

  if (Ethernet.begin(mac) == 0)  
  {
    Serial.println(F("Failed to configure Ethernet using DHCP"));
    Ethernet.begin(mac);
  }

  Serial.println(F("\nStarting connection to server..."));
  
  if(client.connect(clientId))  
  {
    conn = true;
    Serial.println(F("Successfuly connected and running!"));
  }
  else  
  {
    Serial.println(F("Connection problem"));
  }

  Serial.println(F("Starting..."));
  Serial.println(F("3 minutes warm-up CO2 sensor..."));
  // warm-up time for co2 sensor
  while(counter < 2)  {
    Serial.println(counter);
    delay(sec);
    counter++;
  }

  Serial.print('\n');
  Serial.println(F("Warm-up completed"));
  Serial.print('\n');

  // start a serial communication with the CO2 sensor
  sensorCo2.begin(9600);
  
  // cablibrate the zero point for CO2 sensor  
  Serial.println(F("Calibrating CO2 sensor..."));
    for(int i = 0; i < sizeof(cmd_c_sensor); i++)  {
    sensorCo2.write(cmd_c_sensor[i]);
  }

  delay(3*sec);  
  
  Serial.println(F("Calibration completed"));

}

void loop(void)  
{
  //if client it's not connected or disconnects here we try to reconnect
  if (!client.connected())
  { 
    Serial.println(F("reconnecting ..."));
    client.connect(clientId);
    delay(3*sec); 
    sendData();  
  }

  sendData();
}

void sendData(void) 
{
  float ThermometerTemperature = getTemp();
  float Noise = getNoise();
  int gas;
  int tempCo2;

  // get co2 value from function getCarbonDioxide
  if(getCarbonDioxide(&gas, &tempCo2))  {
    gas;
  }
  
  if(conn) 
  {
    //publishing new value every 5 seconds
    if (millis() > (time + 5*sec)) 
    {
      time = millis();
      
      String pubString1 = "{\"value\": " + String(ThermometerTemperature) + "}";
      String pubString2 = "{\"value\": " + String(Noise) + "}";
      String pubString3 = "{\"value\": " + String(gas) + "}";

      pubString1.toCharArray(message_buffer1, pubString1.length()+1);
      pubString2.toCharArray(message_buffer2, pubString2.length()+1);
      pubString3.toCharArray(message_buffer3, pubString3.length()+1);
    
      Serial.println(F("Publishing new value: "));
      Serial.println(ThermometerTemperature);
      Serial.println(Noise);
      Serial.println(gas);
      
      client.publish(TempTopic,  message_buffer1);
      client.publish(NoiseTopic, message_buffer2);
      client.publish(CO2Topic,   message_buffer3);
    }
    // MQTT client loop processing
    client.loop();
  }

}

void initPins()  
{
  pinMode(noise_pin, INPUT); 
}


// returns the temperature from DS18S20 in DEG Celsius
float getTemp(void)
{
  sensors.requestTemperatures();
  float currentTemp;
  currentTemp = sensors.getTempCByIndex(0);
  
  return currentTemp;
}

void sendcommand(uint8_t *pcommand)  
{
    uint8_t i;
   
    for (i=0;i<9;i++)  
    {
      sensorCo2.write(pcommand[i]);
    }   
}


// returns the gas strength from the CO2 sensor
bool getCarbonDioxide(int *gas_strength, int *temperatureGas)  
{
  for(int i = 0; i < sizeof(cmd_get_sensor); i++)  
  {
    sensorCo2.write(cmd_get_sensor[i]);
  }
  
  long cnt_timeout = 0;
  while(!sensorCo2.available())  
  {
    delay(1);
    cnt_timeout++;    
    if(cnt_timeout > 1000)
      return 0;
  }
  
  int len = 0;
  unsigned char dta[20];
  
  while(sensorCo2.available())  
  {
    dta[len++] = sensorCo2.read();
  }
  
  if((9 == len) && (0xff == dta[0]) && (0x86 == dta[1]))
  {
    *gas_strength = 256*dta[2]+dta[3];
    *temperatureGas = dta[4] - 40;
    delay(5*sec);
    return 1;
  }

  return 0;  

}

// returns the decibels from sound sensor
float getNoise()  
{
  unsigned long startMillis= millis();
  unsigned int peakToPeak = 0;

  unsigned int signalMax = 0;
  unsigned int signalMin = 750;

  while (millis() - startMillis < sampleWindow)  
  {
    sample = analogRead(noise_pin);
    if (sample < 1024)  
    {
      if (sample > signalMax)  
      {
        signalMax = sample;
      }
      else if (sample < signalMin)  
      {
         signalMin = sample;
      }
    }
  }

  peakToPeak = signalMax - signalMin;  
  
  // transform voltage to decibels 
  double dB = 3.1 * 20.0  * log10 (peakToPeak  +1.);
  
  // smoothing the values from sensor
  total= total - readings[index];         
  readings[index] = dB; 
  total= total + readings[index];       
  index = index + 1;                    
  
  if (index >= numReadings) 
    index = 0;               
    
  average = total / numReadings;         
  
  int realdB = map(average, 100, 190, 40,100);
  delay(30);
  // not send false values
  if(realdB > 4)  
  {
    delay(6*sec);
    return realdB;
  }

}

Credits

Constantin craciun
Constantin Craciun
5 projects • 34 followers
Passionate about hardware development and IoT.
__hypernova_render_token[6d7afc784a7fcb8b66550111ae0754bb]__Contact

Comments