//All external libraries are added here
#include "Particle.h"
#include "Adafruit_DHT.h"
#include <Air_Quality.h>
#include "Arduino.h"
#include <TinyGPS++/TinyGPS++.h>
#define DHTPIN 2 // what pin DHT11 sensor is connected to
#define DHTTYPE DHT11 // Type of DHT sensor
#define SoundSensorPin A1 //this pin read the analog voltage from the sound level meter
#define VREF 5.0 //voltage on AREF pin, default:operating voltage
//Object declaration for DHT sensor
DHT dht(DHTPIN, DHTTYPE);
//Object declaration for air quality sensor
Air_Quality airqualitysensor;
//Object declaration for GPS
TinyGPSPlus gps;
//Global variables for the sensor data
char air_quality[20] = "";
float temperature = 0.0;
float humidity = 0.0;
float dbValue = 0.0;
float latitude = 0.0;
float longitude = 0.0;
float startTime;
int current_quality =-1;
bool requestSent = false;
void hookResponseHandler(const char *event, const char *data);
void setup() {
Serial1.begin(9600); //default buad rate for NEO-6M gps is 9600
dht.begin(); //initialize dht sensor
airqualitysensor.init(A0);//initialize air quality sensor
//receive response after publishing data to particle cloud
Particle.subscribe("hook-response/Ubidots", hookResponseHandler, MY_DEVICES);
startTime = millis(); //time count start
}
void loop() {
if (millis() > startTime + 30000) { //publish data every 30 second
startTime = millis();
//all the global variables are automatically updated on functions call
read_dht_value();
read_air_quality();
read_sound_level();
publish_data();
delay(1000);
}
while (Serial1.available() > 0){
if (gps.encode(Serial1.read())){
if (gps.location.isValid()){
latitude = gps.location.lat(); //get latitude and longitude
longitude = gps.location.lng();
}
}
}
delay(5000); //Check for gps data every 5 seconds
}
void hookResponseHandler(const char *event, const char *data) {
float elevation = atof(data);
}
//this function reads temperature and humidity from dht11 sensor
void read_dht_value() {
//Reading temperature or humidity takes about 250 milliseconds!
//Sensor readings may also be up to 2 seconds 'old' (its a
// very slow sensor)
float h = dht.getHumidity();
//Read temperature as Celsius
float t = dht.getTempCelcius();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
return;
}
else {
temperature = t;
humidity = h;
}
}
//this function reads the quality of the air
void read_air_quality()
{
current_quality=airqualitysensor.slope();
if (current_quality >= 0)// if a valid data returned.
{
if (current_quality==0)
Serial.println("High pollution! Force signal active");
else if (current_quality==1)
Serial.println("High pollution!");
else if (current_quality==2)
Serial.println("Low pollution!");
else if (current_quality ==3)
Serial.println("Fresh air");
}
}
//interrupt service routine for air quality sensor
ISR (TIMER2_OVF_vect)
{
if(airqualitysensor.counter==122)//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++;
}
}
// This function read the data from sound sensor and convert the value into decibel.
void read_sound_level()
{
float voltageValue;
voltageValue = analogRead(SoundSensorPin) / 1024.0 * VREF;
dbValue = voltageValue * 5.0; //convert voltage to decibel value
}
void publish_data(){
char data[256];
char data1[256];
//I made two data array because ubidots required position value with a context, firebase doesn't
snprintf(data, sizeof(data), "{\"position\": {\"value\":1, \"context\":{\"lat\": %.6f, \"lng\": %.6f}}, \"temp\":%.2f, \"noise\":%.2f, \"air\": {\"value\":1, \"context\":{\"quality\": \"%s\"}}, \"humid\":%.2f}",
latitude, longitude, temperature, dbValue, air_quality, humidity);
snprintf(data1, sizeof(data1), "{\"lat\": %.6f, \"lng\": %.6f, \"temp\":%.2f, \"noise\":%.2f, \"air\":\"%s\", \"humid\":%.2f}",
latitude, longitude, temperature, dbValue, air_quality, humidity);
Particle.publish("Ubidots", data, PRIVATE); //trigger webhooks for Ubidots
Particle.publish("Google_Sheet", data1, PRIVATE); //trigger webhook to Zapier for uploading to Google Sheet
Particle.publish("Firebase", data1, PRIVATE); //Store data to firebase
Particle.publish("Firebase_put", data1, PRIVATE); //Update data to firebase.
//The main difference here is that the requestType is PUT, not POST. The PUT method doesn't create a table of values;
//it just creates a single element to hold the data, overwriting any previous data at that location.
}
Where can I find this library?
Hi @evan91
have you used this .ino as LIB?
RV mineirin
Code i use to read the Dust Sensor.
void fDoParticleDetector( void * parameter )
{
/*
ug/m3 AQI Lvl AQ (Air Quality)
(air Quality Index)
0-35 0-50 1 Excellent
35-75 51-100 2 Average
75-115 101-150 3 Light pollution
115-150 151-200 4 moderate
150-250 201-300 5 heavy
250-500 >=300 6 serious
*/
float ADbits = 4095.0f;
float uPvolts = 3.3f;
float adcValue = 0.0f;
float dustDensity = 0.0f;
float Voc = 0.6f; // Set the typical output voltage in Volts when there is zero dust.
const float K = 0.5f; // Use the typical sensitivity in units of V per 100ug/m3.
xEventGroupWaitBits (eg, evtWaitForBME, pdTRUE, pdTRUE, portMAX_DELAY );
TickType_t xLastWakeTime = xTaskGetTickCount();
const TickType_t xFrequency = 100; //delay for mS
for (;;)
{
//enable sensor led
gpio_set_level( GPIO_NUM_4, HIGH ); // set gpio 4 to high to turn on sensor internal led for measurement
esp_timer_start_once( oneshot_timer, 280 ); // trigger one shot timer for a 280uS timeout, warm up time.
xEventGroupWaitBits (eg, evtDoParticleRead, pdTRUE, pdTRUE, portMAX_DELAY ); // event will be triggered by the timer expiring, wait here for the 280uS
adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading from the dust sensor
gpio_set_level( GPIO_NUM_4, LOW );//Shut off the sensor LED
adcValue = ( adcValue * uPvolts ) / ADbits; //calculate voltage
dustDensity = (adcValue / K) * 100.0; //convert volts to dust density
if ( dustDensity < 0.0f )
{
dustDensity = 0.00f; // make negative values a 0
}
if ( xSemaphoreTake( sema_PublishPM, 0 ) == pdTRUE ) // don't wait for semaphore to be available
{
xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
//log_i( "ADC volts %f Dust Density = %ug / m3 ", adcValue, dustDensity ); // print the calculated voltage and dustdensity
MQTTclient.publish( topicInsidePM, String(dustDensity).c_str() );
xSemaphoreGive( sema_MQTT_KeepAlive );
x_eData.PM2 = dustDensity;
}
xLastWakeTime = xTaskGetTickCount();
vTaskDelayUntil( &xLastWakeTime, xFrequency );
//log_i( " high watermark % d", uxTaskGetStackHighWaterMark( NULL ) );
}
vTaskDelete( NULL );
}// end fDoParticleDetector()
Enable ILED, wait 280us, take A:D reading, shut down ILED, do the rest of the thing.
Hi,
What model Arduino are you using?
Tom....
i using an particle argon
Hi,
What IDE are you using?
Tom...
the ide of particle
//All external libraries are added here
#include "Particle.h"
#include "Adafruit_DHT.h"
#include <Grove_Air_quality_Sensor.h>
#include "Arduino.h"
#include <TinyGPS++/TinyGPS++.h>
#define DHTPIN 2 // what pin DHT11 sensor is connected to
#define DHTTYPE DHT11 // Type of DHT sensor
#define SoundSensorPin A1 //this pin read the analog voltage from the sound level meter
#define VREF 5.0 //voltage on AREF pin, default:operating voltage
//Object declaration for DHT sensor
DHT dht(DHTPIN, DHTTYPE);
//Object declaration for air quality sensor
AirQualitySensor sensor(A0);
//Object declaration for GPS
TinyGPSPlus gps;
//Global variables for the sensor data
char air_quality[20] = "";
float temperature = 0.0;
float humidity = 0.0;
float dbValue = 0.0;
float latitude = 0.0;
float longitude = 0.0;
float startTime;
int current_quality =-1;
bool requestSent = false;
void hookResponseHandler(const char *event, const char *data);
void setup() {
Serial1.begin(9600); //default buad rate for NEO-6M gps is 9600
dht.begin(); //initialize dht sensor
AirQualitySensor init(A0);//initialize air quality sensor
//receive response after publishing data to particle cloud
Particle.subscribe("hook-response/Ubidots", hookResponseHandler, MY_DEVICES);
startTime = millis(); //time count start
}
void loop() {
if (millis() > startTime + 30000) { //publish data every 30 second
startTime = millis();
//all the global variables are automatically updated on functions call
read_dht_value();
read_air_quality();
read_sound_level();
publish_data();
delay(1000);
}
while (Serial1.available() > 0){
if (gps.encode(Serial1.read())){
if (gps.location.isValid()){
latitude = gps.location.lat(); //get latitude and longitude
longitude = gps.location.lng();
}
}
}
delay(5000); //Check for gps data every 5 seconds
}
void hookResponseHandler(const char *event, const char *data) {
float elevation = atof(data);
}
//this function reads temperature and humidity from dht11 sensor
void read_dht_value() {
//Reading temperature or humidity takes about 250 milliseconds!
//Sensor readings may also be up to 2 seconds 'old' (its a
// very slow sensor)
float h = dht.getHumidity();
//Read temperature as Celsius
float t = dht.getTempCelcius();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
return;
}
else {
temperature = t;
humidity = h;
}
}
//this function reads the quality of the air
void read_air_quality()
{
current_quality=AirQualitySensor.slope();
if (current_quality >= 0)// if a valid data returned.
{
if (current_quality==0)
Serial.println("High pollution! Force signal active");
else if (current_quality==1)
Serial.println("High pollution!");
else if (current_quality==2)
Serial.println("Low pollution!");
else if (current_quality ==3)
Serial.println("Fresh air");
}
}
//interrupt service routine for air quality sensor
ISR(TIMER2_OVF_vect)
{
if(airqualitysensor.counter==122)//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++;
}
}
// This function read the data from sound sensor and convert the value into decibel.
void read_sound_level()
{
float voltageValue;
voltageValue = analogRead(SoundSensorPin) / 1024.0 * VREF;
dbValue = voltageValue * 5.0; //convert voltage to decibel value
}
void publish_data(){
char data[256];
char data1[256];
//I made two data array because ubidots required position value with a context, firebase doesn't
snprintf(data, sizeof(data), "{\"position\": {\"value\":1, \"context\":{\"lat\": %.6f, \"lng\": %.6f}}, \"temp\":%.2f, \"noise\":%.2f, \"air\": {\"value\":1, \"context\":{\"quality\": \"%s\"}}, \"humid\":%.2f}",
latitude, longitude, temperature, dbValue, air_quality, humidity);
snprintf(data1, sizeof(data1), "{\"lat\": %.6f, \"lng\": %.6f, \"temp\":%.2f, \"noise\":%.2f, \"air\":\"%s\", \"humid\":%.2f}",
latitude, longitude, temperature, dbValue, air_quality, humidity);
Particle.publish("Ubidots", data, PRIVATE); //trigger webhooks for Ubidots
Particle.publish("Google_Sheet", data1, PRIVATE); //trigger webhook to Zapier for uploading to Google Sheet
Particle.publish("Firebase", data1, PRIVATE); //Store data to firebase
Particle.publish("Firebase_put", data1, PRIVATE); //Update data to firebase.
//The main difference here is that the requestType is PUT, not POST. The PUT method doesn't create a table of values;
//it just creates a single element to hold the data, overwriting any previous data at that location.
}
Hi,
Well its hard to help you if we use the Arduino IDE.
Is there a "particle" forum or QandA site?
What is your electronics, programming, hardware experience?
Did you write this code?
Thanks.. Tom...
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.