I have been asked to build a weather station for a friends kids, it's going to be a teaching aid for them.
I built the main bulk of the anenometer. It makes use of a holed disc, reverse polarity photodiode with an LED as a light source.
The speed output is only based upon the distance between the holes on the disc. I have not been able to calibrated in anyway as yet.
During some thinking and testing using an arduino uno, I thought that using a teensy 4.0 that I had here. This led to setting them up side by side with the signal going to both from a single sensor.
With the disc being spun by a drill so that the speed is consistant-ish, I get a 1-2 tenths variation on speed, but the bigger concern is there is a noticble difference between the uno and the teensy 4.0 readings
Is this likely due to the teensy having a faster clock, or a more accurate floating point facility to do the sums with, or is there something else that I have over looked?
Which one do you folks think is more accurate?
The same code is used on both.
I built the main bulk of the anenometer. It makes use of a holed disc, reverse polarity photodiode with an LED as a light source.
The speed output is only based upon the distance between the holes on the disc. I have not been able to calibrated in anyway as yet.
During some thinking and testing using an arduino uno, I thought that using a teensy 4.0 that I had here. This led to setting them up side by side with the signal going to both from a single sensor.
With the disc being spun by a drill so that the speed is consistant-ish, I get a 1-2 tenths variation on speed, but the bigger concern is there is a noticble difference between the uno and the teensy 4.0 readings
Is this likely due to the teensy having a faster clock, or a more accurate floating point facility to do the sums with, or is there something else that I have over looked?
Which one do you folks think is more accurate?
The same code is used on both.
Code:
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
#define diode 2
unsigned long duration;
double millisec;
double dist = 7.85;
double wind;
double wind_ms;
double average;
byte samples = 20; //20 samples for one rotation
byte fals_samples = 0;
int i;
//#define debug; //if this is enable, dont use LCD instead of serial display
void setup() {
#ifdef debug
Serial.begin(115200);
Serial.println("Running");
#else
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Average: ");
lcd.setCursor(9,0);
lcd.print(average);
lcd.setCursor(0,1);
lcd.print("Speed: ");
lcd.setCursor(9,1);
lcd.print(wind);
#endif
pinMode(diode, INPUT);
}
void loop() {
#ifdef debug
Serial.println("Reading");
#endif
average = 0; //initialise average to 0
fals_samples = 0; //initalise false sample count
for (i = 0; i < samples; i++){
duration = pulseIn(diode, HIGH); //gives reading in us
//no corection for no reading, time out @ 1s/1000ms/1000000us
if(duration == 0){ //count the number of sample @ zero as false samples
fals_samples++;
#ifdef debug
Serial.println("False");
#endif
}
wind_ms = duration/1000.00;
average = average + wind_ms;
#ifdef debug
Serial.print(i);
Serial.print(" : ");
Serial.print(duration);
Serial.print(" : ");
Serial.print(wind_ms);
Serial.print(" : ");
Serial.println(average);
#endif
}
#ifdef debug
Serial.print("Before averaging: ");
Serial.println(average);
#endif
if (fals_samples != 0){
#ifdef debug
Serial.print("False Samples: "); //before correcting sample division
Serial.print(fals_samples);
#endif
//if false sample = 20 then we get div/0 which make the universe explode
//detect it here
//if(x==x){
//this should detect NaN - maybe for future/final project
//}
if (fals_samples >= samples-1){ //we don't want NaN
average = 0.00;
wind = 0.00;
}else{
fals_samples = samples - fals_samples; //No NaN, but not a full sample set
average = average/fals_samples;
wind = dist/average;
}
#ifdef debug
Serial.print(" : ");
Serial.println(fals_samples); //after correcting sample division
#endif
}else{
average = average/samples; //find average of the reading taken
wind = dist/average;
}
#ifdef debug
Serial.println("Reading done");
Serial.print("Average duration: ");
Serial.println(average);
Serial.print("Speed: ");
Serial.print(wind);
Serial.println("mm/ms"); //this is also m/smuliply by 2.23693629 to get mph or 3.6 to get kph
#else
lcd.setCursor(9,0);
lcd.print(" ");
lcd.setCursor(9,1);
lcd.print(" ");
lcd.setCursor(9,0);
lcd.print(average);
lcd.setCursor(9,1);
if(average != 0.00){ //display NaN avoidence
lcd.print(wind);
}else{
lcd.print("0.00");
}
#endif
/*
duration = pulseIn(diode, HIGH);
if (duration > 0){
Serial.print ("Pulse Length: ");
Serial.print(duration);
Serial.print("us");
Serial.print(" : ");
Serial.print(millisec = duration/1000.00);
Serial.print("ms");
Serial.print(" : ");
Serial.print(wind = dist/millisec);
Serial.println("mm/ms"); //this is the same same as m/s
}
*/
}