Anemometro e datalogger – datalogger and anemometer

In attesa di cominciare le sperimentazioni (domani) riportiamo di seguito lo schema elettrico dei sensori utilizzati per la misurazione della velocità del vento e della velocità di rotazione della turbina, sensori peraltro già utilizzati questa estate e poi a Jambiani. Abbiamo previsto la possibilità di sfruttare un sensore reed (recuperato da un tachimetro da bicicletta) in luogo di un optoswitch (recuperato da una stampante) per limitare il consumo di corrente e permetterci di collegare l’alimentazione della scheda Arduino a una semplice batteria, ricaricata da un pannellino solare (in fututo, perchè no, dalla turbina stessa).

vortex datalogger


Per completezza riportiamo anche il listato: in sostanza si utilizzano due interrupt e una scheda SD e si incrementano i relativi contatori associati. il codice è molto grezzo e migliorabile, i suggerimenti sono i benvenuti!

vortex anemometer

reed sensor: how it works

Waiting for testing the VentolINO turbine (tomorrow) this is the electric scheme with the sensors we use for measuring wind speed and turbine angular speed: we used these sensors this summer, too, and in Jambiani, and they works well. We just added a reed sensor instead of optoswitch to lower the power consuption and to be able to use a simple battery as power line for Arduino. Following the code, too: it is quite rough, but it works! Suggestions are welcomed!

// update: 11 gen 2012
#include <SD.h>
#include <Wire.h>
#include “RTClib.h”
// A simple data logger for the Arduino analog pins
// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  10000 // mills between entries (reduce to take more/faster data)
// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 10000 // mills between calls to flush() – to write data to the card  ***
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
//- #define redLEDpin 2
//- #define greenLEDpin 3

// The analog pins that connect to the sensors
//- #define photocellPin 0           // analog 0
//- #define tempPin 1                // analog 1
//- #define BANDGAPREF 14            // special indicator that we want to measure the bandgap
//int ledPin = 13;                // il LED emettitore del sensore di presenza della stampante (sensore a forcella)   ***
                                  //  è collegato al pin 13 (senza resistenza, perchè l’uscita 13 è già limitata in corrente)
//int statusPin = 12;             // il LED di stato è connesso al pin 12: cambia stato on/off a ogni passaggio delle linguette dell’albero della turbina
double rpmcount;  // rpmcount tiene conto dei passaggi delle linguette attraverso il sensore di posizione, per calcolare la velocità angolare della turbina
double rpmpass;  // rpmpass è la variabile in cui si parcheggia il valore di rpmcount, quando si calcola la velocità angolare rpm (intanto la turbina continua a girare…!)
double rpm;  // rpm è il valore della velocità angolare calcolata a partire da rpmcount –> rpmpass, in giri/min
double omega;  // rpm è il valore della velocità angolare, in rad/sec
//volatile int status;  ***
double count;  // count tiene conto dei passaggi sul sensore reed dentro l’anemometro Vortex, e serve a calcolare la velocità del vento
double pass;  // pass è la variabile in cui si parcheggia il valore di count, quando si calcola la velocità del vento (intanto l’anemometro continua a girare…!)
unsigned long timePrevious;  // istante dell’ultimo polling di misura
unsigned long duration;  // tempo trascorso dall’ultimo polling di misura
double interval=LOG_INTERVAL;  // intervallo di polling
float windSpeed = 0;

//- #define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
//- #define bandgap_voltage 1.1      // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print(“error: “);
  Serial.println(str);

  // red LED indicates error
//-  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup(void)
{
  Serial.begin(9600);

#if WAIT_TO_START
  Serial.println(“Type any character to start”);
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print(“Initializing SD card…”);
  // make sure that the default chip select pin is set to
  // output, even if you don’t use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error(“Card failed, or not present”);
  }
  Serial.println(“card initialized.”);

  // create a new file
  char filename[] = “LOGGER00.CSV”;
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + ‘0’;
    filename[7] = i%10 + ‘0’;
    if (! SD.exists(filename)) {
      // only open a new file if it doesn’t exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }

  if (! logfile) {
    error(“couldnt create file”);
  }

  Serial.print(“Logging to: “);
  Serial.println(filename);

  // connect to RTC
  Wire.begin(); 
  if (!RTC.begin()) {
    logfile.println(“RTC failed”);
#if ECHO_TO_SERIAL
    Serial.println(“RTC failed”);
#endif  //ECHO_TO_SERIAL
  }
  logfile.println(“millis,datetime,delta_t,n_Vortex,numero_di_passaggi”);  
#if ECHO_TO_SERIAL
  Serial.println(“millis,datetime,delta_t,n_Vortex,numero_di_passaggi”);
#endif //ECHO_TO_SERIAL

  // If you want to set the aref to something other than 5v
//  analogReference(EXTERNAL);

 duration = 0;
  count = 0;
  timePrevious = 0;
  rpmcount = 0;
  rpm = 0;

  attachInterrupt(1, arduino_anemometer, FALLING);  // l’interrupt dell’anemometro è collegato al pin 1, attraverso la function arduino_anemometer
  attachInterrupt(0, rpm_fun, FALLING);  // l’interrupt del sensore a forcella è collegato al pin 0, attraverso la function rpm_fun    ***

  //pinMode(ledPin, OUTPUT);  // pone in uscita il pin dell’emettitore del sensore a forcella  ***
  //digitalWrite(ledPin, HIGH);  // accende l’emettitore del sensore a forcella  ***

  //pinMode(statusPin, OUTPUT);    // pone in uscita il pin del LED di stato  *** 
  //status = LOW;  ***
  //digitalWrite(statusPin, status);  ***

  // use debugging LEDs
  //- pinMode(redLEDpin, OUTPUT);
  //- pinMode(greenLEDpin, OUTPUT);
}

void loop(void)
{
  DateTime now;
  duration = (millis() – timePrevious);
  if (duration >= interval) {
//
//  // delay for the amount of time we want between readings
//  delay((LOG_INTERVAL -1) – (millis() % LOG_INTERVAL));

  //- digitalWrite(greenLEDpin, HIGH);

  // log milliseconds since starting
  uint32_t m = millis();
  logfile.print(m);           // milliseconds since start
  logfile.print(“, “);   
#if ECHO_TO_SERIAL
  Serial.print(m);         // milliseconds since start
  Serial.print(“,”); 
#endif

  // fetch the time
  now = RTC.now();
  // log time
  logfile.print(‘”‘);
  logfile.print(now.year(), DEC);
  logfile.print(“/”);
  logfile.print(now.month(), DEC);
  logfile.print(“/”);
  logfile.print(now.day(), DEC);
  logfile.print(” “);
  logfile.print(now.hour(), DEC);
  logfile.print(“:”);
  logfile.print(now.minute(), DEC);
  logfile.print(“:”);
  logfile.print(now.second(), DEC);
  logfile.print(‘”‘);
#if ECHO_TO_SERIAL
  Serial.print(‘”‘);
  Serial.print(now.year(), DEC);
  Serial.print(“/”);
  Serial.print(now.month(), DEC);
  Serial.print(“/”);
  Serial.print(now.day(), DEC);
  Serial.print(‘ ‘);
  Serial.print(now.hour(), DEC);
  Serial.print(“:”);
  Serial.print(now.minute(), DEC);
  Serial.print(“:”);
  Serial.print(now.second(), DEC);
  Serial.print(‘”‘);
#endif //ECHO_TO_SERIAL

    pass=count;  // salva il valore presente di count in pass
    rpmpass=rpmcount;  // salva il valore presente di rpmcount in rpmpass
    duration = (millis() – timePrevious);  // calcola il tempo trascorso
    timePrevious = millis();  // aggiorna timePrevious all’istante presente
    windSpeed = (pass/(duration/1000)*2.5);  // calcola la velocità del vento a partire dal numero di passaggi, dal tempo trascorso, con il coefficiente 2,5 (vedi Vortex + Caleb), in mph
    rpm = (rpmpass/4)/(duration/1000)*60;  // calcola la velocità angolare della turbina, tenendo conto di 4 linguette sull’albero, in giri/min
    omega=2*3.1416*rpmpass/duration*1000;  // converte la velocità angolare in rad/sec
#if ECHO_TO_SERIAL
    Serial.print(“,    “);
    Serial.print(duration);
    Serial.print(“,    “);
    Serial.print(pass);
    Serial.print(“,    “);
    //Serial.println(rpmpass);
    Serial.print(rpmpass);
    Serial.print(“,  –  “);
    Serial.print(windSpeed);
    Serial.print(“,    “);
    Serial.println(rpm);
    #endif //ECHO_TO_SERIAL
// azzera i contatori di misura
    count = 0;
    rpmcount = 0; 

    logfile.print(“, “);
    logfile.print(duration);
    logfile.print(“, “);
    logfile.print(pass);
    logfile.print(“, “);  
    logfile.println(rpmpass);

  // Now we write data to disk! Don’t sync too often – requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() – syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  // blink LED to show we are syncing data to the card & updating FAT!
  //- digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  //- digitalWrite(redLEDpin, LOW);

  }
  }
void arduino_anemometer()
{
  count++;
//if (status == LOW) {  // a ogni passaggio inverte lo stato del LED di stato, on/off
//    status = HIGH;
//  }
//  else {
//    status = LOW;
//  }
//digitalWrite(statusPin, status);
}

void rpm_fun()
{
  rpmcount++;  // incrementa il numero di passaggi delle linguette attraverso il sensore a forcella
//  if (status == LOW) {  // a ogni passaggio inverte lo stato del LED di stato, on/off
//    status = HIGH;
//  }
//  else {
//    status = LOW;
//  }
//  digitalWrite(statusPin, status);
}