Problem Coding Fahrradtacho

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");
      }
  }
  1. clean up your code !
  2. Was soll das while-if-konstrukt da machen?
  3. Wer soll wann "Rechnung" aufrufen?
  4. warum so kompliziert?

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
}

Dann brauchst Du 2 Magnete am Rad, einen zum Setzen des Sensors und einer zum Löschen. Ein besser passender Sensor kostet doch nicht die Welt?

Ist aufjedenfall ein Anfang. Danke
jetzt habe ich es so eingefügt:

#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;
int lastSensorStatus;
void setup() {
 pinMode(MAGNETSENSOR, INPUT);
 Serial.begin(9600);
 Lcd.init();
 Geschw = 0;
}

void loop() {
  SensorStatus = digitalRead(MAGNETSENSOR); 
  if (SensorStatus==1 && lastSensorStatus == 0 ){
   Rechnung();
     //Serial.println(millis());
  }
  lastSensorStatus = SensorStatus;
  delay(20); // optional, falls das Signal prellt


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");
      }
  }

aber der LCD zeigt halt leider noch immer keine Geschwindigkeit an.

  1. hab ich versucht
  2. das sollte laut meinem lehrer die Ausgabe des millis() stoppen, was auch so ist, aber dadurch hält halt alles an
  3. Der Code soll Rechnung aufrufen wenn der Sensor 1 ist, also einen Zeitwert ausspuckt
  4. weil keine andere Lösung bis dahin

Ich würde das ganz anders machen.

alt_millis = millis

Endlosschleife :
Wenn Sensor = ausgelöst dann
neu_millis = millis
laufzeit = neu_millis - alt_millis
alt_millis = neu_millis

// hier Strecke berechnen wichtig !! Umfang des Reifens angeben
ende Wenn

ende endlosschleife

Das sollte reichen.

Da bekannter Weise meine Syntax in C nicht so gut ist, das ganze als Ablaufdiagramm.

Gruß

Pucki

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 :slight_smile:

..oder auch nur den Flankenwechsel messen.. Müsste das nicht auch reichen?
also LOW => HIGH .. 1 Umdrehung ... HIGH => LOW .. 2. Umdrehung etc...

Edit: ach so.. bin jetzt von unipolar latching ausgegangen.. :sweat_smile:

Das Rechnen mit float - Werten ist hier auch nicht angebracht.

Mein Ansatz wäre hier auch:

  1. Umdrehung erfassen (also Zeit zwischen den letzten 2 Flankenwechseln erfassen)
  2. daraus Drehzahl U/zeit berechnen
  3. mit Hilfe des Reifenumfangs Km/h berechnen
  4. (optional:) Geschwindigkeit nicht bei jeder Umdrehung neu anzeigen, sondern nur alle X Sekunden den Durchschnittswert.

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

Dein Prof kennt ω und wahrscheinlich auch den Rest, ich würd' ihn mal löchern :slight_smile:

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.

Dann fang' an mit dem Programmieren ... und den 2 Magneten :slight_smile:

1er reicht.

Macht jeder billiger Fahradtacho auch China auch mit einen.

Habe so ein Teil man vor > 30 Jahren an mein erstes Mofa gemacht, da normalere Tacho nur mit 60 km/h ging :wink:

Gruß

Pucki

aber nur mit einem nicht-latchenden Sensor.

1 Like

Erklärungen gab es doch schon:

  1. 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.
  2. 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;
  3. 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.

Nur das der hat ein Herkon und nicht Hallsensor, wo von denen gibt's mehrere Sorten.
Ist kein Mobbing, Lesen Denken Antworten :wink:

Da frag ich mich doch, was man heute noch in der "Schule" lernt.
Offensichtlich recherchieren gehört nicht dazu.
Einfach mal Google fragen.

Kam halt nix dabei raus
Sorry :slight_smile:

SPAREN.

Da sie uns die Chinesen um 20 Jahre voraus.

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.

Gruß

Pucki