Beschleunigungsmessung

Hallo,

du nervst mich noch nicht. ;) Habe die Code Kommentare nochmal angepasst. Wenn du noch Verständnisprobleme hast, vielleicht nochmal die Grundlagen durchgehen. Wünsche maximale Erfolge.

Dankeschön

Hallo, so langsam dämmerts wie der enum eingesetzt wird, der code läuft perfekt, um die ganze geschichte abzurunden versuch ich jetzt die bestzeit im eeprom abzulegen, dafür nutz ich die eeprom.put und eeprom.get oder doch die read und write,

eeprom.put und eeprom.get oder doch die read und write

Wenn du mehr als 1 Byte brauchst, nimmt dir put/get die Mehr-Arbeit ab.

Ich würde mir das mit demZeit= Zeit/1000;aber nochmal ansehen.
Bei long Zeit; ist das eine Ganzzahl-Division und du kriegst nur ganze Sekunden-Werte (abgerundet).
Ausserdem ist es immer Mist wenn man nicht weiss, was eine Variable bedeutet (Sekunden oder Millisekunden)

Warum du die Zustände CALC und ENDE nicht zusammenfasst, weiss ich übrigens nicht.
STOP und READY sind auch ziemlich gleich ( das eine ist bei VSS == 0, das andere bei VSS < 1 )

Aber prinzipiell ist so eine Zustands-enum schon hübsch :wink:

na klar könnte man den code noch etwas verkürzen, aber es dient der veraunschaulichung und jemmand wie mich der noch nicht so begabt ist in arduino programmiern, die einzelnen schritte besser zu verstehen, und ohne die Hilfe von Doc_Arduino hät ich das nie hinbekommen

Medolino73:
na klar könnte man den code noch etwas verkürzen, aber es dient der veraunschaulichung und jemmand wie mich der noch nicht so begabt ist in arduino programmiern, die einzelnen schritte besser zu verstehen, und ohne die Hilfe von Doc_Arduino hät ich das nie hinbekommen

Wenn du das auf meine Bemerkung “statt 5 Zustände reichen auch 3” beziehst, gebe ich dir Recht.
Wenn es für dich anschaulicher ist, ist es gut !

Ich wollte auch nicht an Docs Hilfe herumkritisieren…
… na ja, das mit dem   Zeit = Zeit / 1000;   würde ich wirklich überarbeiten. :wink:
( Um was für Größenordungen geht es eigentlich ? )

   if (Zustand == CALC) {                     // Zeit berechnen, evtl. neue BestZeit speichern und ausgeben
      unsigned int aktZehntel = (endMillis - startMillis) / 100;
      Zustand = ENDE;
      if ( aktZehntel < BestZeit ) {
         BestZeit = aktZehntel;
         eeprom.put(0, BestZeit);
         Serial.print( "Neue Bestzeit : ");
         Serial.print( BestZeit / 10 ); Serial.write('.'); Serial.println(BestZeit%10);
      }
   }

long Zeit wird nicht gebraucht.
Eine globale[b] unsigned int Bestzeit; [/b]würde ich in setup() aus dem eeprom lesen.

ja also am anfang wußte ich nichts mit dem enum anzufangen, aber jetzt begreif ich einiges, hab auch den code entsprechend verkürzt, geht um 1/100sec also 0.00 ausgabe, was mir aber noch nicht ganz klar ist, wie speicher ich die bestzeit im eeprom ab tu das ganze auch gleich per serialprint anzeigen
hier mal der jetzige verkürze code

#include <FlexCAN.h>
#include <EEPROM.h>

static CAN_message_t rxmsg;
typedef enum {
  STOP, RUN, ENDE
} state;
state Zustand = STOP;
int VSS = 0;

unsigned long startMillis = 0;
unsigned long endMillis = 0;
float Zeit = 0.00;

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200);
  Can0.begin(500000);
}

void loop() {
  display();
  Verarbeitung();
}

void Verarbeitung () {
  if (VSS >= 0 && Zustand == STOP) {
    startMillis = millis();
    Zustand = RUN;
  }

  if (VSS > 100 && Zustand == RUN) {
    endMillis = millis();
    Zeit = endMillis - startMillis;
    Zeit = Zeit / 1000;
    Zustand = ENDE;
  }

  if (VSS < 1 && Zustand == ENDE) {
    Zustand = STOP;
  }
}

die serialprint hab ich vorerstmal auf ein tab gelegt damits übersichtlicher wird

void display() {
  if (Can0.read(rxmsg)) {
    switch (rxmsg.id) {
      case 1562:
        VSS = (int)(word(rxmsg.buf[0], rxmsg.buf[1]) / 2.76);
        break;
    }
    Serial1.print("t401.txt=");
    Serial1.write(0x22);
    Serial1.print(VSS);
    Serial1.write(0x22);
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);

    Serial1.print("t403.txt=");
    Serial1.write(0x22);
    Serial1.print(Zeit);
    Serial1.write(0x22);
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);

    Serial1.print("t404.txt=");
    Serial1.write(0x22);
  //  Serial1.print(   );
    Serial1.write(0x22);
    Serial1.write(0xff);
    Serial1.write(0xff);
    Serial1.write(0xff);
  }
}

Entweder so wie ich es mit Zehntel gezeigt habe (das kannst du leicht auf Hundertstel ändern)
oder mit

 float zeit =(endemillis - startmillis) /1000.0 ; // Dies ist eine float - Division ! 
  if (zeit < bestzeit) {
     eeprom.put(0, zeit);

bestzeit ist dann natürlich auch ein float…

Nachtrag: Nachteil ist, dass ein jungfräulicher eeprom als float nicht so eine schöne Zahl ist wie als unsigned int ( 655.35 hundertstel )

um den vergleich zu machen was im eeprom steht, muß er das ganze erstmal auslesen oder, und da müßte eigentlich auch vorher was drinstehen ??

Nachtrag, so jetzt funktioniert auch die Bestzeit im eeprom ablegen

if (VSS > 100 && Zustand == RUN) {
    endMillis = millis() - startMillis;
    Zeit = endMillis / 1000.00;
    if (Zeit < EEPROM.get( 0, eep )) {
      EEPROM.put( 0, Zeit );
    }

jetzt gibts da aber ein kleines problemchen hab ich wärend dem Testen gemerkt,
angenommen man steht an der startlinie und würgt den Motor ab, die Zeit läuft aber schon, jetzt müßte man über 100 erstmal fahren damit er wieder resetet, dafür gibts bestimmt auch eine lösung hoffe ich mal, dann wäre die geschichte absolut perfekt

damit er wieder resetet, dafür gibts bestimmt auch eine lösung hoffe ich mal

Nennt sich Reset :wink: Warum sollte man diesen Arduino-Taster nicht entsprechend verwenden?

Kann man natürlich auch mit einem anderen Taster realisieren, der dann in der Programm-Logik den Zustand entsprechend setzt.

(Was passiert, wenn du bei fahrendem Auto den Arduino resettest ?)

Ansonsten: Das wichtigste fehlt in deinem Sketch: die Variablen-Definition ( Zeit , eep )
Schön zu lesen, dass

float eep;
float zeit = 999.99;
if (zeit < EEPROM.get(0,eep) { 
  Serial.println("EEPROM initialisert");
  EEPROM. put(0,zeit);
}

auch funktioniert, wenn das get bei jungfräulichem eeprom erstmal NaN liefert … (?) …


Na gut, das zweitwichtigste (die eindeutige Definition der verwendeten Libraries) fehlt auch bei mir :wink:

Hallo,

ich würde einen Taster nehmen und damit die ganze Sache wieder "Nullen" wie bei einer Stoppuhr. Da das Zustandsgesteuert ist, sollte das kein Problem sein. Ein Programm mit dem echten Resettaster zubeenden geht zwar auch, ist aber unschön programmiert.

Was du auch noch erweitern kannst ist, eine laufende Anzeige sobald es losgeht. Auch wie bei einer Stoppuhr. Der Beifahrer will ja was zum gucken haben. :)

Wegen dem Wert speichern usw., dass würde ich etwas anders machen. Ich würde innerhalb vom Programm keine float verwenden. Überall mit der Ganzzahl millis arbeiten. Und erst wenn es zur Anzeige kommt, Display oder sonstwas, erst dann würde ich die Ausgabe auf Menschen freundlicherer Einheiten formatieren. Damit haste intern "keinerlei" Rundungsfehler zubefürchten.

ja also taster würd ich schon gerne weglassen, wenn das irgendwie ginge das sobald 0 ansteht auch da der reset ist und erst bei 1 die zeit rennt, wenn nicht geht bleibt mir nix anderes übrig, die lauffende zeit anzuzeigen wäre natürlich die krönung, mal schaun ob man das so hinbekommt

Hallo,

die Automatikerkennung und dessen Nullen ist natürlich auch möglich.

Hi,

wird das genauso mit enum gemacht oder doch anders, und wie das Zeitresetten geht weis ich erlichgesagt im moment nicht

Hallo,

Thema Nullen wenn “Start versaut”.
Mit Taster wäre es leichter. Aber nun guckt.
Die Frage ist, kann dein CAN Bus so schnell reagieren, dass es beim anrucken schon einen VSS größer 0 rausgibt?
Danach richtet sich alles weitere, laut meiner Meinung.
Wenn VSS auf Null bleibt, muss man ein zeitliches Timeout einbauen. Das heißt das Auto muss diese Zeit still stehen.
Wenn VSS schon zuckt beim Ruckler, dann sollte die Zustandsabfrage neu kombiniert ausreichend sein.

Also die ausgabe vom canbus ist schon ziehmlich nahe an echtzeit, müßte so sein das, wenn sich innerhalb einer sekunde sich nix tut, also immer noch bei 0 steht, der reset erfolgt, sobald aber über 1kmh die geschichte ganz normal läuft und die zeit hochzählt

Zeit-Anzeige ohne Null-Taster: reine Überlegung erstmal Die Verarbeitungsfunktion errechnet die Zeitdifferenz. Diesen Wert lässt du dir in einer Funktion "Anzeige" ausgeben. Die Trennung in Funktionen erleichtert das programmieren und ändern, auch wenn es vielleicht auf den ersten Blick nicht danach aussieht.

Nullen: gut, dann überlege dir eine Erkennung aus den Zuständen heraus. Also du hast verschiedene Werte, alle etwas verschieden, die müssen jetzt logisch verknüpft werden. Meinetwegen kannste die enum Variable beliebig erweitern.

also irgendwie schnall ich das nicht, wie man die Zeit jetzt ausgibt damit man es sieht wie es hochläuft, gibts dafür eine spezielle funktion oder einfach nur logic

Hallo,

aktuell ist das "nur" ein kombinieren der vorhandenen Daten. :) In welchen Zustand läuft denn die aktuelle Zeit derzeit im Hintergrund? Richtig, im RUN Zustand. Laut meinem aktuellen Sketch. Wenn der Zustand da ist, errechnest du permanent die aktuelle Differenz zur Startzeit und gibts diese aus. Dabei kannst du auch die Variable Zeit verwenden. Für dieses Zwischenspiel. Diese wird am Ende, wenn 100 erreicht eh mit dem dann aktuellen Wert überschrieben. Reicht das um den Code zu schreiben?

ja so hab ich das versucht mit dem berechnen, aber habs nicht hinbekommen mit permanent berechnen