Pulsin Difference from Uno

orac

Member
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.

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
  }
  */
}
 

Attachments

  • Screenshot_20220626-144341.jpg
    Screenshot_20220626-144341.jpg
    89.7 KB · Views: 32
  • PXL_20220624_114649597.jpg
    PXL_20220624_114649597.jpg
    128 KB · Views: 26
Possibly the difference is due to the difference in VIH, VIL of the Arduino vs the Teensy, one being a 5 volt input and the other 3.3 volt . They will detect high and low at different levels of signal. A slow slew rate of the signal out of your photo diode would make the difference more pronounced.
 
I did hook my cheap USB scope up to the the diode, seemed fast enough. But for some reason I did not think threshhold.

Thinking about it, i could have the teesny produce a PWM signal and have them both read that back and see what the discrepency is.
Thanks.
 
Sorry for the double post, but i have tested with using a pwm signal.
Both seem to produce about the same results, although the uno is a lot less stable. The uno shows a result flickering between .30 and and .40, while the teensy 4 flickers in such a way that it cant really be read but i think it might be between .46 and .67 with a the teensy producing a PWM - analogWrite(1, 128);
Using a potentiometer to adjust the PWM on the fly shows that they produce the near enough the same results.
My conclusion is that, rcarr, you were right on the money.

However the fact that the teensy produced the more stable result would lend to my thinking that the teensy was producing more accurate result and more consistanly.
 
Back
Top