Arduino/NRG #40C Anemometer

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
fmbfla
 
Posts: 110
Joined: Fri Jun 08, 2012 6:48 pm

Arduino/NRG #40C Anemometer

Post by fmbfla »

This Modifies an NRG #40C Anemometer
An "NRG #40C Anemometer" can be found on Ebay for less than $30.oo
Remove the two screws that hold the cup's/Magnet, Remove the Ac coil and Stud's.
Drill one stud hole slightly larger so you can fit an Adafruit Hall switch http://www.adafruit.com/products/158.
Hot glue it in place after making sure the Mag field is close enough for the sensor to work.
Replace the two screws holding the Cup's/Magnet.
Connect Hall switch according to Adafruit tutorial (add an LED in line to make sure your pulsing)
Test it with someone in a car/truck (don't think about it).

The code and More about the original QRD1114 IR Sensor on a cups anemometer
* Authors: M.A. de Pablo & C. de Pablo S., 2010 can be found here http://arduino.cc/forum/index.php/topic,8310.0.html
See it in action next to the A/C in the Gameroom!https://cosm.com/users/fmbfla
This is an Arduino R3 putting 10 readings to Cosm.

Code: Select all

/* QRD1114 IR Sensor on an cups anemometer
 * Authors: M.A. de Pablo & C. de Pablo S., 2010
 Changed to Hall Effect 10/2012
 * version: 1.0   20100823
 * Wind speed information: http://en.wikipedia.org/wiki/Beaufort_scale
 */


// Pin definitions
# define ANEMOMETER 2                 // Receive the data from sensor

// Constants definitions
const float pi = 3.14159265;  // pi number
int period = 2000;           // Measurement period (miliseconds)
int delaytime = 2000;        // 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()
{
  // Set the pins
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
 
  // sets the serial port to 115200 
  Serial.begin(9600);
  
  // Splash screen
  Serial.println("ANEMOMETER");
  Serial.println("**********");
  Serial.println("Based on NRG #40C ANEMOMETER Modified with a Hall Effect Sensor 2 pulse per 1 RPM");
  Serial.print("Sampling period: ");
  Serial.print(period/1000);
  Serial.print(" seconds every ");
  Serial.print(delaytime/1000);
  Serial.println(" seconds.");
  Serial.println("** You could modify those values on code **");
  Serial.println();
}

void loop() 
{
  float wind =  (speedwind) /2 / 0.445; //Change to 2 pulse per REV and conver m/s to mph
  Sample++;
  Serial.print(Sample);
  Serial.print(": Start measurement...");
  windvelocity();
  Serial.println("   finished.");
  Serial.print("Counter: ");
  Serial.print(counter);
  Serial.print(";  RPM: ");
  RPMcalc();
  Serial.print(RPM);
  Serial.print(";  Wind speed: ");
  WindSpeed();
  Serial.print(wind);
  Serial.print(" [mph]  ;  Wind force (Beaufort Scale): ");
  Serial.print(windforce);
  Serial.print(" - ");
  Serial.println(winds[windforce]);
  Serial.println();
  delay(10000);
}

// 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++;
}

User avatar
fmbfla
 
Posts: 110
Joined: Fri Jun 08, 2012 6:48 pm

Re: Arduino/NRG #40C Anemometer

Post by fmbfla »

My Cosm code,

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++;
}



Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”