Hi,
ich muss für die Schule ein Fahrradtacho mithilfe eines Funduino Uno(Chip: ATMEGA328P U), eines Hall Magnet Sensors, Magneten und eines LCD`s bauen. Hierbei stießen ich und mein Lehrer auf das Problem, dass der Code die Zeit immer wenn der Sensor 1 war ausgespuckt hat also einmal alle paar ms. Wir wollen für unsere Programmierung aber nur einmal den Zeitwert und zwar wenn der Code auf 1 schaltet. Der Sensor ist latching(leider).
Habt ihr Tipps wie ich dies durchsetzen kann?
Hier mein aktueller Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C Lcd(0x27,16,2);
int MAGNETSENSOR = 4;
int Sensorstatus;
int Zeit;
int letztes_Millis=0;
int Geschw;
int Zeitr;
int umf = 0.00113097;
void setup() {
pinMode(MAGNETSENSOR, INPUT);
Serial.begin(9600);
Lcd.init();
Geschw = 0;
}
void loop() {
Sensorstatus = digitalRead(MAGNETSENSOR);
while(Sensorstatus==1){
Sensorstatus=digitalRead(MAGNETSENSOR);
}
if (Sensorstatus==1){
Rechnung();
Serial.println(millis());
}
Ueberprufung();
Lcd.clear();
Lcd.backlight();
Lcd.setCursor(3,0);
Lcd.print(Geschw);
Lcd.print("kmh");
}
void Rechnung(){
Zeit = millis() - letztes_Millis;
Zeitr = Zeit*0.000000278;
Geschw = umf/Zeitr;
letztes_Millis = millis();
}
void Ueberprufung(){
if (Sensorstatus == 1){
Sensorstatus = digitalRead(MAGNETSENSOR);
Serial.println("Nord");
}
else{
Sensorstatus = digitalRead(MAGNETSENSOR);
Serial.println("Süd");
}
}
Du brauchst eine Flankenerkennung. D.h. deine Rechnung wird nur ausgeführt, wenn der Status des Magnetsensors von 0 auf 1 wechselt.
Etwa so ( ungetestet ):
void loop() {
Sensorstatus = digitalRead(MAGNETSENSOR);
if (Sensorstatus==1 && lastSensorStatus == 0 ){
Rechnung();
//Serial.println(millis());
}
lastSensorStatus = SensorStatus;
delay(20); // optional, falls das Signal prellt
}
Du hast einen latching Sensor --> platziere 2 Magneten mit entgegengesetzter Orientierung gegenüber an der Felge --> 1/2 Umdrehung 1, 1/2 Umdrehung 0. Dann nimmst du pulselen(MAGNETSENSOR,1000) für Messung von 2*ω. Deine untere Grenzfrequenzz ist bei 1000ms timeout 0.5Hz.
Der nette Teil bei latching: du kannst die Auflösung belibig steigern ω*(2,4,6, ...) ... solange du nur aeine gerade Anzahl Magneten nimmst
Danke für den Ansatz aber wärst du so lieb und würdest mir das mal noch als Code schreiben, weil ich leider grad mit ω nichts anfangen kann. Ansonsten erklär mir bitte das nochmal.
Danke
Ich hab dabei halt das Problem das ich ihn erst am Freitag wieder habe und bis dahin die Programmierung im Idelfall fertug sein sollte und ich hab das halt schon gehabt im Zusammenhang Kreisbewegung und Zentripetalkraft usw. aber einfach eine kleine Erklärung würde reichen.
Umdrehung (bzw. halbe Umdrehung, das hängt vom Verhalten deines Sensors ab, ob er einen oder zwei Magneten braucht, um zwischen High und Low umzuschalten) erfassen.
jedes Umschalten (Flankenwechsel. Bei non latching Sensor natürlich nur rising oder falling) zeitlich messen. Entweder mit (wie von @zwieblum vorgeschlagen) mit pulseln() oder (wie von @pucki007) neu_millis = millis(); laufzeit = neu_millis - alt_millis; alt_millis = neu_millis;
Zauber der Mathematik: aus der Zeit für eine (halbe, viertel, 8el..) Umdrehung und dem Umfang/Radius/Durchmesser des Rads die Geschwindigkeit:
geschwindigkeit = 2 * π * r(Radius des Rads) / t(Laufzeit für eine ganze Umdrehung)
Nur noch die Einheiten für Maße (mm/cm/m/km) und Zeit (ms/s/min/h) anpassen, dann hat man doch schon was.
Wir verbauen Luxustechnik. Die verbauen Technik die erprobt ist, und funktioniert.
DAS ist der Unterschied.
Und wenn mir ein Professor das als Aufgabe gibt, würde ich ihn fragen wieso so teure Technik.
Das wäre Praxisfremd, unökologisch, und nicht wirtschaftlich. Und da bekomme ich eine 1, weil ich über die Aufgabe nachdenke anstatt sie von eine Community lösen zu lassen.
Antwort : NIX . Denn kein Lehrer gibt ein eine Aufgabe wenn man nicht vorher die Lösungsansätze gelernt hat. Wozu braucht man sonst Lehrer. ??!
Einziges Problem damals war übrigens : Die LCD-Anzeige mochte keine Sonnenstrahlen. Zu lang in der Sonne und das Display war WEG.