
This is a good starting project for people who are interested in Internet of Things devices and wishing to start with something both simple and fun.
An air quality or weather station that pushes the data on the Internet is a low complexity fun project to explore the Internet of Things revolution and understand the main concepts and protocols used.
For the device, Arduino Ethernet was opted because of the strong community support and large base of supported sensors. The device measures the CO2 concentration in the air, the temperature and noise level and compare it between two locations. So, the author had two of this devices with the same components and only sending the data to different endpoints. Speaking of endpoints, for the cloud solution, DeviceHub.net is used to offer both data in and data out in the form of gathering data from sensors and remote control devices by defining actuators on the platform first and then linking them to the hardware by using the API.
Here is a snapshot from both locations of the sensors and their current data.
Code
/* 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; } }
For more detail, please visit below link.
https://www.hackster.io/devicehub-net/air-quality-weather-station
COMMENTS