Code: Select all
#include <SPI.h>
#include <Wire.h>
#include "RTClib.h"
#include <DHT.h>
#include <Ethernet.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
#include <Adafruit_BMP085.h>
//Colors for the RGB Backlight
#define OFF 0x0
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7
//DHT22
#define ANEMOMETER 2 // Receive the data from sensor
#define DHTTYPE DHT22 // Tell the Duino which DHT ver you have 11 or 22
#define DHTPIN (A2) // Tell the Duino that the DHT is on Dig pin 2
//COSM
#define APIKEY "d5acRBGU12Y0jGMK5rGi_65vri2SAKxTWDFqNkg5c3dIND0g" // your cosm api key
#define FEEDID 72737 // feed ID
#define USERAGENT "Cosm Arduino Example (72737 )" // user agent is the project name
//DHT
DHT dht(DHTPIN, DHTTYPE);
//RGB Shield
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
//BARO/TEMP
Adafruit_BMP085 bmp;
// Reading the System Voltage
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
// Heat Index Function
// http://en.wikipedia.org/wiki/Heat_index
double heatIndex(double Temperature, double Humidity)
{
double c1 = -42.38, c2 = 2.049, c3 = 10.14, c4 = -0.2248, c5= -6.838e-3, c6=-5.482e-2, c7=1.228e-3, c8=8.528e-4, c9=-1.99e-6 ;
double T = Temperature;
double R = Humidity;
double T2 = T*T;
double R2 = R*R;
double TR = T*R;
double rv = c1 + c2*T + c3*R + c4*T*R + c5*T2 + c6*R2 + c7*T*TR + c8*TR*R + c9*T2*R2;
return rv;
}
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm
double dewPoint(double Temperature, double Humidity)
{
double A0= 373.15/(273.15 + Temperature);
double SUM = -7.90298 * (A0-1);
SUM += 5.02808 * log10(A0);
SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
SUM += log10(1013.246);
double VP = pow(10, SUM-3) * Humidity;
double T = log(VP/0.61078); // temp var
return (241.88 * T) / (17.558-T);
}
RTC_DS1307 RTC;// Real Time Clock
byte mac[] = {
0x90, 0xA2, 0xDA, 0x00, 0xC1, 0xE1};
IPAddress ip(192,168,1,106);
EthernetClient client;
IPAddress server(64,94,18,121);
unsigned long lastConnectionTime = 0;
boolean lastConnected = false;
const unsigned long postingInterval = 3*1000; //10 Second Cosm Upload Interval adding to the delay's in the sketch
// Constants definitions
const float pi = 3.14159265; // pi number
int period = postingInterval; // Measurement period (miliseconds)
int delaytime = postingInterval; // Time between samples (miliseconds)
int radio = 70; // Radio from vertical anemometer axis to a cup center (mm)
char* winds[] = {
"Calm", "Light air", "Light breeze", "Gentle breeze", "Moderate breeze", "Fresh breeze", "Strong breeze", "Moderate gale", "Fresh gale", "Strong gale", "Storm", "Violent storm", "Hurricane"};
// Variable definitions
unsigned int Sample = 0; // Sample number
unsigned int counter = 0; // B/W counter for sensor
unsigned int RPM = 0; // Revolutions per minute
float speedwind = 0; // Wind speed (m/s)
unsigned short windforce = 0; // Beaufort Wind Force Scale
void setup()
{
pinMode(2, INPUT);
digitalWrite(2, HIGH);
Serial.begin(9600);
dht.begin();// Connect the DHT22 sensor
RTC.begin();// Connect the RTC bob
bmp.begin();// Connect the Baro/Tmp bob
lcd.begin(16, 2);// start the LCD:
lcd.setBacklight(WHITE);
lcd.setCursor(4,1);
lcd.print("BOOTING!");
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
//RTC.adjust(DateTime(__DATE__, __TIME__)); // following line sets the RTC to the date & time this sketch was compiled
}
if (Ethernet.begin(mac) == 0) {
Ethernet.begin(mac, ip);
}
}
void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}
if (!client.connected() && lastConnected) {
Serial.println("disconnecting.");
Serial.println();
client.stop();
}
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
float Alt = (bmp.readAltitude(101000)/3.3);// adjust barometric pressure for altitude(Im at sea level) and convert meters to feet
float Baro = (bmp.readPressure()) * 0.0002953;//convert Pa to inches of Hg
float Humidity = (dht.readHumidity()); //Read the DHT humidity sensor
float Inside = (bmp.readTemperature)() * 9.0 / 5.0 + 32.0;// (inside)covnert deg C to deg F
float Light = analogRead(A0) * (5.0 / 1023.0 ); //Convert Raw Solar voltage
float Temperature = (dht.readTemperature()* 9.0 / 5.0 + 32.0); //Read the DHT Temp sensor (OutSide)convert deg C to deg F
float Time = millis() / 60000;
float Dew = (dewPoint(Temperature, Humidity));
//Temperature = (Temperature * 9.0 / 5.0) + 32.0; // (OutSide)convert deg C to deg F
float HI = (heatIndex(Temperature, Humidity));
float wind = (speedwind)/2 / 0.3;
DateTime now = RTC.now();
const uint8_t h = now.hour();
const uint8_t hr_12 = h%12;
Serial.print("Time : ");
if(hr_12 < 10){ // Zero padding if value less than 10 ie."09" instead of "9"
Serial.print(" ");
Serial.print((h > 12) ? h - 12 : ((h == 0) ? 12 : h), DEC); // Conversion to AM/PM
}
else{
Serial.print((h > 12) ? h - 12 : ((h == 0) ? 12 : h), DEC); // Conversion to AM/PM
}
Serial.print(':');
if(now.minute() < 10){ // Zero padding if value less than 10 ie."09" instead of "9"
Serial.print("0");
Serial.print(now.minute(), DEC);
}
else{
Serial.print(now.minute(), DEC);
}
if(h < 12){ // Adding the AM/PM sufffix
Serial.print(" AM");
}
else{
Serial.print(" PM");
}
Serial.println();
Serial.print("Date : " );
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.println();
Serial.print(": Starting measurements...");
windvelocity();
Serial.println(" finished.");
Sample++;
Serial.print("Sample# :");
Serial.println(Sample);
Serial.print("RPM : ");
RPMcalc();
Serial.println(RPM);
Serial.print("Wind speed : ");
WindSpeed();
Serial.println(wind);
Serial.print("Wind force : ");
Serial.println(winds[windforce]);
Serial.print("System Volts: ");
Serial.println(readVcc() / 1000. , DEC);
Serial.print("Light : ");
Serial.println(Light);
Serial.print("UpTime : ");
Serial.println(Time);
Serial.print("Altitude : ");
Serial.println(Alt);
Serial.print("Baro : ");
Serial.println(Baro);
Serial.print("heatIndex : ");
Serial.println(heatIndex(Temperature, Humidity));
Serial.print("Outside : ");
Serial.println(Temperature);
Serial.print("Humidity : ");
Serial.println(Humidity);
Serial.print("Dew Point : ");
Serial.println(Dew);
Serial.print("Inside : ");
Serial.println(Inside);
Serial.println();
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Inside: ");
lcd.setCursor(11,0);
lcd.println(Inside);
lcd.setCursor(0,1);
lcd.print("UpTime:");
lcd.setCursor(9,1);
lcd.print(Time);
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Outside :");
lcd.setCursor(11,0);
lcd.print(Temperature);
lcd.setCursor(0,1);
lcd.print("Heat Index:");
lcd.setCursor(11,1);
lcd.print(HI);
delay(3000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Barometer:");
lcd.setCursor(11,0);
lcd.print(Baro);
lcd.setCursor(0,1);
lcd.print("Humidity :");
lcd.setCursor(11,1);
lcd.print(Humidity);
//delay(3000);
}
sendData(Time, Temperature, Humidity, Inside, Light, Baro, HI, Alt, Dew, wind);
}
lastConnected = client.connected();
}
void sendData( float Time, float Temperature, float Humidity, float Inside, float Light, float Baro, float HI, float Alt, float Dew, float wind) {
if (client.connected()) client.stop();
if (client.connect(server, 80)) {
Serial.println("connecting...");
Serial.println();
client.print("PUT /v2/feeds/");
client.print(FEEDID);
client.println(".csv HTTP/1.1");
client.println("Host: api.cosm.com");
client.print("X-ApiKey: ");
client.println(APIKEY);
client.print("User-Agent: ");
client.println(USERAGENT);
client.print("Content-Length: ");
int length = 5 + countDigits(Time,2) + 9 + 12 + countDigits(Temperature,2)
+ 2 + 9 + countDigits(Humidity,2) + 2 + 6 + countDigits(Light,2) + 2 + 5 + countDigits(Baro,2)
+ 2 + 3 + countDigits(HI,2) + 2 + 7 + countDigits(Inside,2)
+ 2 + 4 + countDigits(Alt,2) + 2 + 4 + countDigits(Dew,2) + 2 + 5 + countDigits(wind,2);
client.println(length);
client.println("Content-Type: text/csv");
client.println("Connection: close");
client.println();
client.print("Wind,");
client.println(wind);
client.print("Alt,");
client.println(Alt);
client.print("Baro,");
client.println(Baro);
client.print("DewPoint,");
client.println(Dew);
client.print("HeatIndex,");
client.println(HI);
client.print("Humidity,");
client.println(Humidity);
client.print("Inside,");
client.println(Inside);
client.print("Outside,");
client.println(Temperature);
client.print("Solar,");
client.println(Light);
client.print("Time,");
client.println(Time);
}
else {
// if we couldn't make a connection to "Cosm.com":
Serial.print("connection failed: ");
Serial.println();
Serial.print(Time);
client.stop();
}
lastConnectionTime = millis();
}
int countDigits(double number, int digits) {
int n = 0;
if (number < 0.0)
{
n++; // "-";
number = -number;
}
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i) {
rounding /= 10.0;
}
number += rounding;
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
while (int_part > 0) {
int_part /= 10;
n++;
}
if (digits > 0) {
n++; //".";
}
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
n ++;
remainder -= toPrint;
}
return n;
}
// Measure wind speed
void windvelocity(){
speedwind = 0;
counter = 0;
attachInterrupt(0, addcount, CHANGE);
unsigned long millis();
long startTime = millis();
while(millis() < startTime + period) {
}
detachInterrupt(1);
}
void RPMcalc(){
RPM=((counter/2)*60)/(period/1000); // Calculate revolutions per minute (RPM)
}
void WindSpeed(){
speedwind = ((2 * pi * radio * RPM)/60) / 1000; // Calculate wind speed on m/s
if (speedwind <= 0.3){ // Calculate Wind force depending of wind velocity
windforce = 0; // Calm
}
else if (speedwind <= 1.5){
windforce = 1; // Light air
}
else if (speedwind <= 3.4){
windforce = 2; // Light breeze
}
else if (speedwind <= 5.4){
windforce = 3; // Gentle breeze
}
else if (speedwind <= 7.9){
windforce = 4; // Moderate breeze
}
else if (speedwind <= 10.7){
windforce = 5; // Fresh breeze
}
else if (speedwind <= 13.8){
windforce = 6; // Strong breeze
}
else if (speedwind <= 17.1){
windforce = 7; // High wind, Moderate gale, Near gale
}
else if (speedwind <= 20.7){
windforce = 8; // Gale, Fresh gale
}
else if (speedwind <= 24.4){
windforce = 9; // Strong gale
}
else if (speedwind <= 28.4){
windforce = 10; // Storm, Whole gale
}
else if (speedwind <= 32.6){
windforce = 11; // Violent storm
}
else {
windforce = 12; // Hurricane (from this point, apply the Fujita Scale)
}
}
void addcount(){
counter++;
}