Geschwindigkeitsmessung über Reed-Sensor / Speedometer

Schönen Guten Tag,
Ich habe ein Programm aufgebaut mit einem 2,8 Zoll Display und einem Arduino Mege 2350 und über einen Reed-Sensor an der Fahrradgabel und einem Magnet kann die Drehzahl erkannt werden. Die Funktion habe ich mit Interrupts programmiert.

Jedoch gibt es nun ein kleines Problem und zwar das bei Stillstand des Fahrrades sich die Zahlen nicht ganz auf Null zurücksetzen sondern meistens bleibt die 2-3te Stelle übrig nur die erste wird Null

Gesamter Code:

#include <Elegoo_GFX.h>    
#include <Elegoo_TFTLCD.h>
#include <SPI.h>
#include <TouchScreen.h>

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

//Bildschirmpins
#define LCD_CS A3 
#define LCD_CD A2 
#define LCD_WR A1 
#define LCD_RD A0 
#define LCD_RESET A4

//Farbendefinition
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

//Touchscreen
#define YP A3  
#define XM A2  
#define YM 9   
#define XP 8 

#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940

#define MINPRESSURE 240
#define MAXPRESSURE 1000

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);



//Reed-Sensor
#define reed    A14

Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
//Berechnungen
//Rad Radius ca. 13,5 Zoll
//Umfang ca. 2*r*PI = 85 Zoll
//Maximal Geschwindigkeit von 56,327 km/h
//Rotationen per Minute 7,25

//Speichervariablen
const float radius = 13.5;
const float circumference = 2 * 3.14 * radius;



const int maxReedCounter = 100;

long int reedCounter;
long timer;
float  mph;
long int kph;
long int rpm;
long int reedVal;

boolean buttonEnabled = true;

unsigned long draw_begin()
{
  unsigned long start = micros();
  tft.setRotation(3);
  tft.fillScreen(BLACK);
  tft.setCursor(0, 0);
  tft.setTextColor(WHITE, BLACK);
  tft.setTextSize(2);
  tft.println("Willkommen");
  tft.setCursor(0, 40);
  tft.setTextSize(2);
  tft.println("Speedometer");
  tft.setCursor(0, 70);
  tft.println("made by");
  tft.setCursor(0, 100);
  tft.println("METZLER Lukas");
  return micros() - start;
  tft.fillScreen(BLACK);
}

unsigned long draw_main()
{
  int kphCopy, rpmCopy;

  cli();
  kphCopy = kph;
  rpmCopy = rpm;
  sei(); 
  
  unsigned long start = micros();
  tft.setRotation(3);
  

  tft.setCursor(8, 20);
  tft.setTextColor(WHITE, BLACK);
  tft.setTextSize(2);
  tft.println("Speed km/h");
  tft.setCursor(8, 50);
  tft.setTextSize(4);
  tft.println(kph);
  
  
  tft.setCursor(8, 120);
  tft.setTextSize(2.5);
  tft.println("Rotation per min");
  tft.setCursor(8, 120);
  tft.setTextSize(4);
  tft.setCursor(8, 150);
  tft.println(rpm);


  //Create Button
  tft.fillRect(60,180,200, 40, BLACK);
  tft.drawRect(60,180,200,40, WHITE);
  tft.setCursor(80,188);
  tft.setTextSize(2);
  tft.print("Weiter!");

  
  return micros() - start;
}
unsigned long draw_second()
{
  tft.setRotation(3);
  tft.setTextColor(WHITE, BLACK);
  tft.setTextSize(1);
  tft.println("Test1");
}
void setup(void)
{

     reedCounter=maxReedCounter;
     pinMode(reed, INPUT);
    
     tft.fillScreen(BLACK);   
    
    
    //Vom LCD-Bildschirm Hersteller vorgegebene Syntax 
    Serial.begin(9600);
    Serial.println(F("TFT LCD test"));

    #ifdef USE_Elegoo_SHIELD_PINOUT
    Serial.println(F("Using Elegoo 2.8\" TFT Arduino Shield Pinout"));
    #else
    Serial.println(F("Using Elegoo 2.8\" TFT Breakout Board Pinout"));
    #endif
  
    Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());


  uint16_t identifier = tft.readID();
  identifier=0x9341;
  if(identifier == 0x9325) {   
    Serial.println(F("Found ILI9325 LCD driver"));
    } else if(identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
    } else if(identifier == 0x7575) {
    Serial.println(F("Found HX8347G LCD driver"));
    } else if(identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
    } else if(identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
    } else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Elegoo 2.8\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_Elegoo_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Elegoo_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    return;
  }
  tft.begin(identifier);
  Serial.println(F("Done!"));

  
  Serial.println(F("Benchmark                Time (microseconds)"));

  Serial.print(F("Beginning Screen"));
  Serial.println(draw_begin());
  delay(2000);
  tft.fillScreen(BLACK);
  
  /*Serial.print(F("Text                     "));
  Serial.println(draw_main());
  delay(3000); */

  //Interrupts
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 1999;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);
  TIMSK1 |= (1 << OCIE1A);
  sei();


}
ISR(TIMER1_COMPA_vect) {
  reedVal = digitalRead(reed);
  if (reedVal){
    if (reedCounter == 0)
    {
      mph = (56.8*float(circumference))/float(timer);
      rpm = (float(60000))/(float(timer));
      timer = 0;
      reedCounter = maxReedCounter;
      kph = mph * 1.609344;
    }
    else{
      if (reedCounter > 0)
      {
        //reedCounter -= 1; */
      }
    }
  }
  else{
    if (reedCounter > 0){
      reedCounter -= 1;
    }
  }
  if (timer > 1000)
  {
    mph = 0;
    kph = 0;
    rpm = 0;
  }
  else{
    timer += 1;
  } 
}
void loop()
{
  draw_main();
  delay(50);
  
  /*TSPoint p=ts.getPoint();

  if(p.z > ts.pressureThreshhold)
  {
    p.x=map(p.x, TS_MAXX, TS_MINX, 0,320);
    p.y=map(p.y, TS_MAXY, TS_MINY, 0,240);

    if(p.x>60 && p.x<260 && p.y>180 && p.y<220 && buttonEnabled) 
    {
      buttonEnabled=false;
      //This is important, because the libraries are sharing pins
      pinMode(XM, OUTPUT);
      pinMode(YP, OUTPUT);
     
      tft.fillScreen(BLACK);
      
      draw_second();
    
    }
    delay(10);   
  }
   */
}

Betroffener Code (glaube ich):

  if (timer > 1000)
  {
    mph = 0;
    kph = 0;
    rpm = 0;
  }

Für die Ausgabe solltest Du kphCopy und rpmCopy benutzen.

Vermutlich gibt println() die Zahl linksbündig aus, dann bleiben die nachfolgenden Stellen unverändert stehen. Dann brauchst Du eine rechtsbündige Anzeige von 2-4 Stellen, die links mit Leerzeichen aufgefüllt wird.

Hi

Meinst Du, Es wird besser, wenn Du das Forum mit Deinen Fragen zumüllst?
Warum machst Du nicht Da weiter, wo Du exakt die gleiche Frage bereits gestellt hast??
Ach ja - falls Du Das nicht mehr findest (wie sollen WIR DAS denn finden, wenn Du Deinen eigenen Thread nicht mehr kennst???)
Klick

DrDiettrich:
Für die Ausgabe solltest Du kphCopy und rpmCopy benutzen.

Vermutlich gibt println() die Zahl linksbündig aus, dann bleiben die nachfolgenden Stellen unverändert stehen. Dann brauchst Du eine rechtsbündige Anzeige von 2-4 Stellen, die links mit Leerzeichen aufgefüllt wird.

Vielen Dank für den Tipp hab die Sachen jetzt geändert jedoch immer noch mit dem gleichen Resultat aber vielleicht liegt das Problem wirklich an der print()-Funktion

  int kphCopy, rpmCopy;

  cli();
  kphCopy = kph;
  rpmCopy = rpm;
  sei(); 
  
  unsigned long start = micros();
  tft.setRotation(3);
  

  tft.setCursor(8, 20);
  tft.setTextColor(WHITE, BLACK);
  tft.setTextSize(2);
  tft.println("Speed km/h");
  tft.setCursor(8, 50);
  tft.setTextSize(4);
  tft.print(kphCopy);
  
  
  tft.setCursor(8, 120);
  tft.setTextSize(2.5);
  tft.println("Rotation per min");
  tft.setCursor(8, 120);
  tft.setTextSize(4);
  tft.setCursor(8, 150);
  tft.print(rpmCopy);

Variablen habe ich jetzt auf volatile geändert wegen dem Interrupt

long int reedCounter;
volatile long timer=0;
volatile float mph=0.00;
volatile  int kph;
volatile  int rpm;
long int reedVal;

postmaster-ino:
Hi

Meinst Du, Es wird besser, wenn Du das Forum mit Deinen Fragen zumüllst?
Warum machst Du nicht Da weiter, wo Du exakt die gleiche Frage bereits gestellt hast??
Ach ja - falls Du Das nicht mehr findest (wie sollen WIR DAS denn finden, wenn Du Deinen eigenen Thread nicht mehr kennst???)
Klick

Statt sinnlosen Input zubringen (da du scheinbar selber nicht weißt was zu machen ist) würdest du vielleicht bemerken das es im anderen Thema spezifisch um den Display und die draw()-function gegangen ist und jetzt um die Funktion einer Geschwindigkeitsmessung also zwei komplett verschiedene Themen.

Den Forumbeitrag gibt es noch ist jedoch schon abgeschlossen da die Lösung gefunden wurde.
Vielleicht einem Moderator die Arbeit überlassen :slight_smile:

Hi

Sorry - aber bis auf einen Anschiss in meine Richtung hat Dein Beitrag leider für den TO auch nicht viel über, oder?
Zugegeben: Ich habe mir diesen Beitrag nicht genau angeschaut, eine gewisse Ähnlichkeit mit dem von mir Verlinktem ist aber unabstreitbar.

Und: Jupp, an Moderator gemeldet wurde natürlich auch - wenn Dem so ist, wie Du schreibst, wohl etwas vorschnell.
Selber war ich aber auch schon 'auf der anderen Seite' und durfte Thread zusammen führen, weil die Userschar unnötig für mehr Lesestoff sorgte.

Sorry für den Exkurs

MfG

postmaster-ino:
Hi

Sorry - aber bis auf einen Anschiss in meine Richtung hat Dein Beitrag leider für den TO auch nicht viel über, oder?
Zugegeben: Ich habe mir diesen Beitrag nicht genau angeschaut, eine gewisse Ähnlichkeit mit dem von mir Verlinktem ist aber unabstreitbar.

Und: Jupp, an Moderator gemeldet wurde natürlich auch - wenn Dem so ist, wie Du schreibst, wohl etwas vorschnell.
Selber war ich aber auch schon 'auf der anderen Seite' und durfte Thread zusammen führen, weil die Userschar unnötig für mehr Lesestoff sorgte.

Sorry für den Exkurs

MfG

Ja wie gesagt sollte kein "Anschiss" sein jedoch benötige ich dringend Hilfe für mein Projekt und hätte mich über eine Hilfestellung gefreut jedoch verstehe ich deine Punkt nur verfüge ich nicht die Fähigkeit eine Post als abgeschlossen zu melden :slight_smile:

Es gibt keine abgeschlossenen Threads.

Für Ausgaben mit konstanter Zeichenzahl gibt es hier im Forum viele Beispiele oder Du schaust Dir z.B. mal sprintf an.

Gruß Tommy

Wieso sollte die Funktion mit sprintf überarbeitet werden wenn es doch über eine print() Funktion wiedergegeben werden kann es geht eher um das Zurücksetzen der Werte nach dem Stillstand des Fahrrades. Es löscht nämlich nur die erste Stelle

LG

Wenn Du meinst, es besser zu wissen, ... viel Spaß noch.

Gruß Tommy

Tommy56:
Wenn Du meinst, es besser zu wissen, … viel Spaß noch.

Gruß Tommy

Nein das meine ich doch nicht jedoch würde ich gern wissen wie du das genau meinst?
LG

Hi

Man kann (wohl) mit sprintf Strings komfortabel formatieren - z.B. mit führenden Leerzeichen.
Wenn man Das nicht macht, gibt print(10); zwei Zeichen aus, print (1); ein Zeichen.
Blöd, daß die Null von der 10 als 2.tes Zeichen eben stehen bleibt.
Wenn nun der Text mit führenden Leerzeichen auf die gewünschte Lönge 'aufgepumpt' wird, werden zuerst Diese ausgegeben - eventuell vorhandener Text ist dann dort weg - und dann kommt die eigentliche Zahl, man könnte Das 'rechtsbündig' nennen.

MfG

Man kann mit sprintf oder auch printf Zahlen sehr gut formatieren.
Wie bereits gesagt, liegt Dein Problem darin, dass Deine Zahlen linksbündig ausgegeben werden.

Wenn sie rechtsbündig mit fester Breite ausgegeben werden, tritt Dein Problem nicht mehr auf. Deswegen solltest Du Dich mit der sprintf/printf-Familie beschäftigen.

Gruß Tommy

Vielen Dank für die Tipps ich werde es jetzt mal versuchen und mich im Anschluss melden :slight_smile:

postmaster-ino:
Hi

Meinst Du, Es wird besser, wenn Du das Forum mit Deinen Fragen zumüllst?
Warum machst Du nicht Da weiter, wo Du exakt die gleiche Frage bereits gestellt hast??
Ach ja - falls Du Das nicht mehr findest (wie sollen WIR DAS denn finden, wenn Du Deinen eigenen Thread nicht mehr kennst???)
Klick

Alter geh dich vergraben, es geht um völlig andere Themen in den beiden Threads. Leute wie du ziehen das Niveau und die Qualität dieses Forums ganz schön runter. Das nervt übrigens auch Mitlesende, die sich für das Thema interessieren, aber stattdessen unbegründeten Anschiss von dir lesen müssen.

@Mahismus: Du bist der einzige, der hier die Qualität herunterzieht :frowning:

Die in diesem Thread gestellte Frage wurde in dem alten bereits beantwortet, nur scheint der TO keine Lösung zu akzeptieren, weder die aus dem alten noch aus dem neuen Thread.

@Mahimus
Alleine Dein Sprachgebrauch lässt erahnen, daß Deine Eltern bei Dir wohl nicht Alles richtig gemacht haben - weiter bist Du 'etwas' spät - oder musstest Du so lange warten, bis Du mit dem 2.ten Nick hier antworten konntest?
Hättest Du dann noch ein oder zwei Posts weiter gelesen ... aber ja, geh wieder spielen, Du hast Recht und ich meine Ruhe.

OfG (das O steht für Ohne :wink: )

postmaster-ino:
@Mahimus
Alleine Dein Sprachgebrauch lässt erahnen, daß Deine Eltern bei Dir wohl nicht Alles richtig gemacht haben - weiter bist Du 'etwas' spät - oder musstest Du so lange warten, bis Du mit dem 2.ten Nick hier antworten konntest?
Hättest Du dann noch ein oder zwei Posts weiter gelesen ... aber ja, geh wieder spielen, Du hast Recht und ich meine Ruhe.

OfG (das O steht für Ohne :wink: )

Du führst dich hier auf als dürftest du entscheiden wer was fragen darf und bei Gegenwind wirst du persönlich? Daraus könnte ich nun auch einige Schlüsse auf dein Leben außerhalb dieses Forums ziehen, so wie du es bei mir getan hast, aber ich bin ja nicht dein Seelenklempner.

Ich werde mich in diesem Forum weiterhin gegen jeden wehren, der sich sinnlos destruktiv äußert, wie du es in #2 getan hast, anstatt eine fachliche Diskussion zu ermöglichen - egal ob mein Thread oder nicht.

Hi

Ok, weil Du es bist - dieses eine Mal noch.
Darfst Du nur an Feiertagen an den PC?
Dann hätte ich aber Besseres zu tun, als mich mit Leuten rumzuärgern, Die wohl auch noch Recht haben.
Davon ab - wenn ich schon nicht bestimmen darf, Wer Was Wann zu Wem sagt - warum, bitte, solltest Du Das dürfen?
Dein "Alter, geh' Dich vergraben" hatte ich nun doch schon etwas persönlich aufgefasst - wenn SO Dein 'normaler Sprachgebrauch' aussieht - ok, Fehler bei mir - so tief will und kann ich nicht.

Zu 'sinnlos' und 'destruktiv' hätte ich Da auch einen Kandidaten :slight_smile:

OfG (nur für Dich :wink: )