Hallo Forum,
ich werte das Signal meines Anemometers mit einem Hallsensor TLE4905 aus.
Bei jeder vollen Umdrehung fährt einmal ein Magnet über den Hallsensor welcher dann über einen open Collector Ausgang das HIGH Signal ( via 10k Pull UP ) auf Masse zieht.
http://img96.imageshack.us/img96/8223/unbenanntwpk.jpg
Dieses Rechtecksignal möchte ich mit PulseIn auswerten, sodass ich die Pulselänge vom HIGH Impuls bzw LOW Impuls messen kann und daraus Rückschlüsse auf die Windgeschwindigkeit zu ziehen.
Was ich aber bemerke ist, dass ich zwar "schnelle Signale" damit verarbeiten kann, jedoch größer als zB 180µS HIGH Impulslänge schafft er nicht mehr zu messen.
Im Default ist ja bei pulseIn 1 Sekunde als Timeout eingestellt.
Lt Referenz müsst ich bis zu 3min lange Impulse messen können.
Um auch sehr geringe Windgeschwindigkeiten ( ab 1km/h ) messen zu können, müsste ich Signale mit bis zu 2sek Periodendauer verarbeiten können.
Doch wieso bekomme ich dass mit pulseIn nicht hin? Gibt es da einen BUG ( entweder bei mir im Code oder in den Arduino Libs? )
/*
Testprogramm für Windgeschwindigkeitsmessung
*/
float g_wind;
void setup()
{
Serial.begin(19200);
pinMode(10,INPUT);
pinMode(2,INPUT);
}
void loop()
{
g_wind = windSpeed();
Serial.print("\t Windgeschwindigkeit [m/s] = ");Serial.print(g_wind);Serial.print("\t Windgeschwindigkeit [km/h] = ");Serial.println(g_wind/3.6);
}
float windSpeed()
{
// Umfang Kreisbahn für Windmessschale => U = 2.pi.R = 2.pi.0,08m =>0,5m==>500mm==500000µm (notwendig damit gleich durch µS dividiert werden kann )
const unsigned long Umfang = 500000;
// unsigned long timeoutH = 2000000; // Wert in µS
// unsigned long timeoutL = 2000000; // Wert in µS
unsigned long timeHigh = pulseIn(10,HIGH); //time in µs für HIGH Impulsdauer
unsigned long timeLow = pulseIn(2,LOW); //time in µS für LOW Impulsdauer
unsigned long time = timeHigh+timeLow; // Gesamtdauer für eine Umdrehung in µS
Serial.print(" Debug Time HIGH:");Serial.print(timeHigh);Serial.print("\t Debug Time LOW: ");Serial.print(timeLow);
float wind = float(Umfang) / float(time); //Ergebnis in km/h ==> div durch 10 muss entfernt werden hier nur für Testzwecke
return wind;
}
Bevor ihr euch fragts, wieso ich den LOW Impuls mit einem andern PIN messe.... also mit dem gleichen PIN wie bei PulseIn (.. High) bekomme ich es nicht hin. Da misst er mir dann den HIGH Impuls nicht, sondern nur den LOW Impuls. ![]()
Wäre für Antworten dankbar.
Gäbe es nicht eine elegantere Lösung?
Ich hätte mir sowas in der Art vorgestellt.
Ich starte einen Hardwaretimer.
Von der Main Loop springe ich zyklisch ( polling ) alle 5 Sekunden in meine Funktion float WindSpeed(), dort warte ich eine gewisse Zeit ( max 1-2Sekunden) bis ich einen Zustandswechsel am Signal feststellen kann ( pos oder neg Flanke ) , dann warte ich wieder bis der nächste Zustandswechsel kommt ( natürlich mit timeOut abgesichert ).
Nachdem der Zustandswechsel abgeschlossen ist, vergleiche ich den Start und End Timerwert und errechne mir daraus die Persiodendauer.
Ich weiß dass man sowas auch mit der Function micros() machen kann, nur meine Frage: ist diese auch genau genug für meine Signalmessung oder wäre ein laufenden Hardwaretimer besser?
Ich will aber keinen interupt haben, da ich meine Programmabläufe einhalten muss. Die Messwerterfassung darf nur via Funktionsaufruf ( durch polling ) erfolgen.
danke
Bitte in Prio 1 auf das PulseIn Problem antworten!
lg
Dieter