//****************************************************************
//* Name : Air Quality Monitor *
//* Author : Robert Joseph Korn *
//* Notice : Copyright (c) 2015 Open Valley Consulting Corp *
//* Date : 10/18/15 *
//* Version : 1.1 *
//* Notes : *
//* : *
//****************************************************************
#include <LFlash.h>
#include <LSD.h>
#include <LStorage.h>
#include <LGPS.h>
#include "LDHT.h"
#include <Wire.h>
#include "Barometer.h"
#include <BH1750FVI.h>
//uncomment the storage you want to use
// #define Drv LFlash // use Internal 10M Flash
#define Drv LSD // use SD card
#define DEBUG true // Comment to disable debug
#define DHTPIN 6 // what pin we're connected to
// Uncomment whatever type you're using!
#define DHTTYPE DHT22 // DHT 11 21 22
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
gpsSentenceInfoStruct info; //needed to get GPS data
int da = 5; // Device Address
int ck = 3; // Clock
int di = 4; // Data In
int cs = 2; // Chip Select
int val = 0;
int adcv[12];
int val1 = 0;
int val2 = 0;
int val3 = 0;
int val4 = 0;
int val5 = 0;
int val6 = 0;
int val7 = 0;
int val8 = 0;
int val9 = 0;
int val10 = 0;
int val11 = 0;
int dbl = 0;
int tmp = 0;
byte chn = 0;
float hum = 0;
float tem = 0;
float far = 0;
float hi = 0;
float dew = 0;
float temperature = 0;
float pressure = 0;
float alt;
uint16_t lux = 0;
double latitude = 0.00;
double longitude = 0.00;
float altitude = 0.00;
float dop = 100.00; //dilution of precision
float geoid = 0.00;
float k_speed = 0.00, m_speed = 0.00; //speed in knots and speed in m/s
float track_angle = 0.00;
int fix = 0;
int hour = 0, minute = 0, second = 0;
int sat_num = 0; //number of visible satellites
int day = 0, month = 0, year = 0;
String time_format = "00:00:00", date_format = "00:00:0000";
String lat_format = "0.00000", lon_format = "0.00000";
char file[15] = "";
int pause = 5000; //time in milliseconds between two logs
BH1750FVI LightSensor;
Barometer myBarometer;
LDHT dht(DHTPIN, DHTTYPE);
void getadcval() {
for(dbl=0;dbl<2;dbl++) {
val = 0 ;
digitalWrite(cs, LOW);
pulseck(2); //Strobe CS
dataxfer();
digitalWrite(cs, HIGH);
pulseck(50); // Conversion Clock 44 cycles needed
}
}
void dataxfer(){
for(tmp=0;tmp<4;tmp++) {
if (bitRead(chn, 3 - tmp) ){
digitalWrite(da, HIGH);
} else {
digitalWrite(da, LOW);
}
digitalWrite(ck, HIGH);
digitalWrite(ck, LOW);
if(digitalRead(di) > 0){
val++;
}
val=val<<1;
}
for(tmp=0;tmp<6;tmp++) {
digitalWrite(ck, HIGH);
digitalWrite(ck, LOW);
if(digitalRead(di) > 0){
val++;
}
val=val<<1;
}
val=val>>1;
}
void pulseck(uint8_t cnt) {
for(tmp=0;tmp<cnt;tmp++) {
digitalWrite(ck, HIGH);
digitalWrite(ck, LOW);
}
}
void setup()
{
pinMode(ck, OUTPUT);
pinMode(da, OUTPUT);
pinMode(cs, OUTPUT);
pinMode(di, INPUT);
digitalWrite(cs, HIGH);
digitalWrite(ck, LOW);
digitalWrite(da, LOW);
Serial1.begin(9600);
Serial1.println();
Serial1.print("Initializing...");
Serial.begin(115200);
Serial.print("Initializing memory...");
pinMode(10, OUTPUT); //needed for SD card
if(!Drv.begin())
{
Serial.println("Error initalizing memory.");
while(true);
}
Serial.println("OK.");
myBarometer.init();
LightSensor.begin();
/*
Set the address for this sensor
you can use 2 different address
Device_Address_H "0x5C"
Device_Address_L "0x23"
you must connect Addr pin to A3 .
*/
LightSensor.SetAddress(Device_Address_H);//Address 0x5C
// lightMeter.SetAddress(Device_Address_L); //Address 0x23
//-----------------------------------------------
/*
set the Working Mode for this sensor
Select the following Mode:
Continuous_H_resolution_Mode
Continuous_H_resolution_Mode2
Continuous_L_resolution_Mode
OneTime_H_resolution_Mode
OneTime_H_resolution_Mode2
OneTime_L_resolution_Mode
The data sheet recommanded To use Continuous_H_resolution_Mode
*/
LightSensor.SetMode(Continuous_H_resolution_Mode);
LGPS.powerOn();
Serial.println("GPS started.");
dht.begin();
Serial.println("Setup Done");
Serial.println("");
}
void loop()
{
Serial1.println();
Serial1.print("Loop");
Serial.println("");
Serial.println("");
Serial.println("------------------------------------------------------------------");
Serial.println("");
Serial.println("BMP Sensor");
temperature = myBarometer.bmp085GetTemperature(myBarometer.bmp085ReadUT()); //Get the temperature, bmp085ReadUT MUST be called first
pressure = myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP()) ;//Get the ressure
alt = myBarometer.calcAltitude(pressure); //Uncompensated caculation - in Meters
pressure = pressure / 100 ;
alt = alt + 60 ;
Serial.print("Temperature: ");
Serial.print(temperature, 2); //display 2 decimal places
Serial.println(" deg C");
Serial.print("Pressure: ");
Serial.print(pressure, 2); //whole number only.
Serial.println(" KPa");
Serial.print("Altitude: ");
Serial.print(alt, 2); //display 2 decimal places
Serial.println(" m");
Serial.println();
Serial.println("");
Serial.println("DHT Sensor");
if(dht.read())
{
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
hum = dht.readHumidity();
// Read temperature as Celsius
tem = dht.readTemperature();
// Read temperature as Fahrenheit
far = dht.readTemperature(false);
}
// Check if any reads failed and exit early (to try again).
if (isnan(hum) || isnan(tem) || isnan(far)) {
Serial.println("Failed to read from DHT sensor!");
}
else
{
// Compute heat index
// Must send in temp in Fahrenheit!
hi = dht.readHeatIndex(tem, hum);
Serial.print("Humidity: ");
Serial.print(hum);
Serial.println(" %");
Serial.print("Temperature: ");
Serial.print(tem);
Serial.println(" *C ");
Serial.print("Temperature: ");
Serial.print(far);
Serial.println(" *F");
Serial.print("Heat index: ");
Serial.print(hi);
Serial.println(" *C");
Serial.print("DewPoint = ");
dew = dht.readDewPoint(tem,hum);
Serial.print(dew);
Serial.println("C");
}
Serial.println("");
Serial.println("BH1750 Sensor ");
lux = LightSensor.GetLightIntensity();// Get Lux value
Serial.print("Light: ");
Serial.print(lux);
Serial.println(" lux");
Serial.println("");
Serial.println("");
for(chn=0;chn<11;chn++) {
getadcval();
getadcval();
adcv[chn] = val ;
Serial.print("Channel: ");
Serial.print(chn);
Serial.print(" - ");
Serial.println(val);
Serial.println();
}
Serial.println();
if (getData(&info) > 3)
{
String str = "";
str += date_format;
str += ",";
str += time_format;
str += ",";
str += lat_format;
str += ",";
str += lon_format;
str += ",";
str += altitude;
str += ",";
str += dop;
str += ",";
str += geoid;
str += ",";
str += track_angle;
str += ",";
str += m_speed;
str += ",";
str += k_speed;
str += ",";
str += fix;
str += ",";
str += sat_num;
str += ",";
str += hum;
str += ",";
str += tem;
str += ",";
str += far;
str += ",";
str += hi;
str += ",";
str += pressure;
str += ",";
str += temperature;
str += ",";
str += alt;
str += ",";
str += lux;
str += ",";
for(chn=0;chn<11;chn++) {
str += adcv[chn];
str += ",";
}
Serial1.print(str);
Serial.println(str);
String file_name = date_format;
file_name += ".txt";
file_name.toCharArray(file, 15);
Serial.println(file);
LFile dataFile = Drv.open(file, FILE_WRITE);
if (dataFile)
{
dataFile.println(str);
dataFile.close();
Serial.println("File written.");
}
else Serial.println("Error opening file.");
}
else Serial.println("Less then 4 satelites.");
delay(pause);
}
/**
*Converts degrees from (d)ddmm.mmmm to (d)dd.mmmmmm
*@param str the string rappresentation of the angle in (d)ddmm.mmmm format
*@param dir if true the direction is south, and the angle is negative.
*@return the given angle in dd.mmmmmm format.
*/
float convert(String str, boolean dir)
{
double mm, dd;
int point = str.indexOf('.');
dd = str.substring(0, (point - 2)).toFloat();
mm = str.substring(point - 2).toFloat() / 60.00;
return (dir ? -1 : 1) * (dd + mm);
}
/**
*Gets gps informations
*@param info gpsSentenceInfoStruct is a struct containing NMEA sentence infomation
*@return the number of hooked satellites, or 0 if there was an error getting informations
*/
int getData(gpsSentenceInfoStruct* info)
{
Serial.println("Collecting GPS data.");
LGPS.getData(info);
Serial.println((char*)info->GPGGA);
if (info->GPGGA[0] == '$')
{
Serial.print("Parsing GGA data....");
String str = (char*)(info->GPGGA);
str = str.substring(str.indexOf(',') + 1);
hour = str.substring(0, 2).toInt();
minute = str.substring(2, 4).toInt();
second = str.substring(4, 6).toInt();
time_format = "";
time_format += hour;
time_format += ":";
time_format += minute;
time_format += ":";
time_format += second;
str = str.substring(str.indexOf(',') + 1);
latitude = convert(str.substring(0, str.indexOf(',')), str.charAt(str.indexOf(',') + 1) == 'S');
int val = latitude * 1000000;
String s = String(val);
lat_format = s.substring(0, (abs(latitude) < 100) ? 2 : 3);
lat_format += '.';
lat_format += s.substring((abs(latitude) < 100) ? 2 : 3);
str = str.substring(str.indexOf(',') + 3);
longitude = convert(str.substring(0, str.indexOf(',')), str.charAt(str.indexOf(',') + 1) == 'W');
val = longitude * 1000000;
s = String(val);
lon_format = s.substring(0, (abs(longitude) < 100) ? 2 : 3);
lon_format += '.';
lon_format += s.substring((abs(longitude) < 100) ? 2 : 3);
str = str.substring(str.indexOf(',') + 3);
fix = str.charAt(0) - 48;
str = str.substring(2);
sat_num = str.substring(0, 2).toInt();
str = str.substring(3);
dop = str.substring(0, str.indexOf(',')).toFloat();
str = str.substring(str.indexOf(',') + 1);
altitude = str.substring(0, str.indexOf(',')).toFloat();
str = str.substring(str.indexOf(',') + 3);
geoid = str.substring(0, str.indexOf(',')).toFloat();
Serial.println("done.");
if (info->GPRMC[0] == '$')
{
Serial.print("Parsing RMC data....");
str = (char*)(info->GPRMC);
int comma = 0;
for (int i = 0; i < 60; ++i)
{
if (info->GPRMC[i] == ',')
{
comma++;
if (comma == 7)
{
comma = i + 1;
break;
}
}
}
str = str.substring(comma);
k_speed = str.substring(0, str.indexOf(',')).toFloat();
m_speed = k_speed * 0.514;
str = str.substring(str.indexOf(',') + 1);
track_angle = str.substring(0, str.indexOf(',')).toFloat();
str = str.substring(str.indexOf(',') + 1);
day = str.substring(0, 2).toInt();
month = str.substring(2, 4).toInt();
year = str.substring(4, 6).toInt();
date_format = "20";
date_format += year;
date_format += "-";
date_format += month;
date_format += "-";
date_format += day;
Serial.println("done.");
return sat_num;
}
}
else
{
Serial.println("No GGA data");
}
return 0;
}
Comments