www.mikrocontroller.net

Forum: Compiler & IDEs Analog Tacho GLCD wie im Auto bewegen lassen


Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

hohle per GPS über CAN die Geschwindigkeit in das Anzeige Board.
es wird eine tabelle aufgerufen wo drin steht an postion 40 zeiger Xgrad 
(40KMH auf der skala)

tabelle ghet von 0 -110 mit den entsprechenden werten in 1km/h 
schritten.

Das funktioniert auch wenn ich eine schleife mit ca 300ms pause lasse 
sieht es gut aus.

Per GPS kommen aber manchmal bei straken beschleunigungen sprünge rein.

d.h 1. wert=33km/h  2. wert 45 usw.

die Tachonadel geht natürlich sprunghaft beim auto geht sie schön mit 
von 33-45 km/h in 1km/h schritten.

Wie kann man sowas effektiv machen ohne den cpu zu belasten und die 
Schleifenablauf zu gefärden???

habe mir überlegt in der Hauptschleife folgendes zu machen



if(kmhaktuell>kmhalt)zeiger++;
if(kmhaktuell<kmhalt)zeiger--;


vieleicht noch über ein timerinterrupt der alle 400ms einen tick gibt.

if(tick==1)
{
if(kmhaktuell>kmhalt)zeiger++;
if(kmhaktuell<kmhalt)zeiger--;
zeichne_zeiger(zeiger);
tick=0;
}


Danke

Gruß

Andy

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Herrmann schrieb:

> habe mir überlegt in der Hauptschleife folgendes zu machen
>
>
>
> if(kmhaktuell>kmhalt)zeiger++;
> if(kmhaktuell<kmhalt)zeiger--;
>
>
> vieleicht noch über ein timerinterrupt der alle 400ms einen tick gibt.
>
> if(tick==1)
> {
> if(kmhaktuell>kmhalt)zeiger++;
> if(kmhaktuell<kmhalt)zeiger--;
> zeichne_zeiger(zeiger);
> tick=0;
> }

sind alles Ideen, die es wert sind verfolgt zu werden.
(Ja, so macht man eine nachlaufende Anzeige)

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> sind alles Ideen, die es wert sind verfolgt zu werden.
> (Ja, so macht man eine nachlaufende Anzeige)

Ist allerdings in diesem Fall arg langsam. 1 km/h in 400 ms entspricht 
einer Beschleunigung von ca 0,07g. Oder anders: Von 0 auf 100 in 40 
Sekunden (und von 100 auf 0 auch).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Karl heinz Buchegger schrieb:
>> sind alles Ideen, die es wert sind verfolgt zu werden.
>> (Ja, so macht man eine nachlaufende Anzeige)
>
> Ist allerdings in diesem Fall arg langsam. 1 km/h in 400 ms entspricht
> einer Beschleunigung von ca 0,07g. Oder anders: Von 0 auf 100 in 40
> Sekunden (und von 100 auf 0 auch).

Ist doch nicht schlecht,  für eine Seifenkiste.

Die 400ms sind natürlich schon arg lang.

Und anstelle von

> if(kmhaktuell>kmhalt)zeiger++;
> if(kmhaktuell<kmhalt)zeiger--;

kann man das Ganze dann ja auch noch so machen, dass bei größeren 
Abweichungen die Sprünge größer werden.

Ein wenig experimentieren ist angesagt.

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>> if(kmhaktuell>kmhalt)zeiger++;
>> if(kmhaktuell<kmhalt)zeiger--;
>
> kann man das Ganze dann ja auch noch so machen, dass bei größeren
> Abweichungen die Sprünge größer werden.

Zum einen das, außerdem würde ich die Zeitbasis verkleinern. 400 ms 
bedeuten ja auch nur 2,5 Änderungen pro Sekunde, was recht ruckelig 
wirken wird.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Karl heinz Buchegger schrieb:
>>> if(kmhaktuell>kmhalt)zeiger++;
>>> if(kmhaktuell<kmhalt)zeiger--;
>>
>> kann man das Ganze dann ja auch noch so machen, dass bei größeren
>> Abweichungen die Sprünge größer werden.
>
> Zum einen das, außerdem würde ich die Zeitbasis verkleinern. 400 ms
> bedeuten ja auch nur 2,5 Änderungen pro Sekunde, was recht ruckelig
> wirken wird.

Yep.
So 10 bis 20 dürftens schon sein.
Mehr wird nichts bringen, weil dann das GLCD wahrscheinlich nicht mehr 
mitkommt und nur noch flackert. Und ausserdem kann eh keiner so schnell 
schauen.

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Habe es ohne zeitbasis gemacht


         if(vstart==0)
  {
    zeiger=struct_v_rpm.v;
    vstart=1;
  }
  if(struct_v_rpm.v>struct_v_rpm.vold)
  {
    if((struct_v_rpm.v-struct_v_rpm.vold)<10)
    {
      draw_tach_zeiger(zeiger++);
    }
    else
    {
            draw_tach_zeiger(zeiger+=3);
            if(zeiger>=110)zeiger=110;
    }
  }

  if(struct_v_rpm.v<struct_v_rpm.vold)draw_tach_zeiger(zeiger--);
  {

    if((struct_v_rpm.vold-struct_v_rpm.v)<10)
           {
                   draw_tach_zeiger(zeiger--);
           }
           else
           {
            draw_tach_zeiger(zeiger-=3);
            if(zeiger<=0)zeiger=0;
          }
}


mit den 3++ schritten geht er jetzt bei großen differenzen schön mit 
kann aber noch auf 4 gehen muß ich in fahrt testen

aber so ist es gut.

Danke

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die allgemeine Lösung ist ein Regler. Das was Karl- Heinz da gebaut hat 
ist ein Regler mit I-Verhalten.

Der Stellwert (Sollwert) ist dann der Wert vom GPS, die Regelstrecke 
deine Variable, die du aufs Display ausgibst. Je nach Auslegung des 
Reglers und seiner Zeitkonstante(n) kannst du nun die Geschwindigkeit 
einstellen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Herrmann schrieb:

> aber so ist es gut.

Ich rate dir ganz dringend dazu, deine Codeformatierung zu überdenken 
und etwas gegen deinen Saustall zu tun!

Das hier
  if(struct_v_rpm.v<struct_v_rpm.vold)draw_tach_zeiger(zeiger--);
  {

    if((struct_v_rpm.vold-struct_v_rpm.v)<10)
           {
                   draw_tach_zeiger(zeiger--);
           }
           else
           {
            draw_tach_zeiger(zeiger-=3);
            if(zeiger<=0)zeiger=0;
          }
}

war mit an Sicherheit grenzender Wahrscheinlichkeit nicht so gedacht!

Oder hast du bemerkt, dass der ganze Block der in der 2.ten Zeile 
beginnt in keinster Weise vom if abhängt?

Eine saubere Code-Formatierung ist keineswegs nur Selbstzwecke! Sie ist 
ein Werkzeug um Fehler im Code schneller zu sehen bzw. gar nicht erst zu 
machen!
Mit solchen Saustallcodeformatierungen stellst du dir regelmässig selbst 
ein Bein. Und nein. Das Argument "Das mach ich alles hinten nach" das 
gilt nix! Durch schlechte Formatierung machst du Fehler, deren Suche 
mehr Zeit kostet als wie wenn man gleich von vorne herein sauber 
formatiert!


(Formatierung: In erster Linie sauber Einrücken; Code-Style konsequent 
anwenden; immer gleich und konsequent arbeiten; nicht alles in einer 
Wurscht und ohne Punkt und Komma oder Leerzeichen)


Hab ich das noch richtig im Kopf, dass deine Zeichenroutine auf Tabellen 
basiert?
Was passiert da drinnen wenn hier
            draw_tach_zeiger(zeiger-=3);
etwas negatives übergeben wird? zeiger kann an dieser Stelle theoretisch 
die Werte -1, -2, -3 annehmen. Du korrigierst zwar den Wert für zeiger 
hinten nach, aber da ist das Kind dann schon in den Brunnen gefallen!
Die restlichen ++ und -- sind zb überhaupt nicht auf Überlauf 
abgesichert.

Ausserdem stimmt die Nachführung nicht.
Der Zeiger wird solange nachgeführt, bis die Anzeige identisch ist mit 
dem Messwert und nicht solange, solange sich der Messwert verändert! 
Dein Zeiger muss eine Chance haben, dem tatsächlichen Messwert 
nachzulaufen, selbst wenn sich der Messwert nicht mehr verändert. Warum? 
Weil er eben diesen Messwert noch nicht anzeigt.

  if( vstart == 0 )
  {
    zeiger = struct_v_rpm.v;
    vstart = 1;
  }

  //
  // Ist die Anzeige schon korrekt auf dem Messwert?
  //
  if( struct_v_rpm.v != zeiger )
  {
    // Nein, muss noch korrigiert werden!
    //
    // In welche Richtung muss korrigiert werden und um wieviel?
    //
    if( struct_v_rpm.v > zeiger )         // Zeiger zeigt noch zu wenig an?
    {
      if( struct_v_rpm.v - zeiger < 10 )
        zeiger++;
      else
        zeiger += 3;
    } 
    else                                  // Nö. Er zeigt zuviel an!
    {
      if( zeiger - struct_v_rpm.v < 10 )
        zeiger--;
      else
        zeiger -= 3;
    }

    //
    // Sicherstellen, dass der Zeiger seinen zulässigen Bereich nicht
    // verlässt
    //
    if( zeiger > 110 )
      zeiger = 110;

    if( zeiger < 0 )
      zeiger = 0;

    //
    // das wars, GLCD updaten
    //
    draw_tach_zeiger( zeiger );
  }


(Und ich denke, die Sonderbahndlung mit dem vstart brauchst du jetzt gar 
nicht mehr. Aber da kenn ich jetzt den Rest des Programms nicht um das 
entscheiden zu können)

Autor: Andreas Herrmann (andy78)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Danke

Habe ich dann auch bemerkt das der zeiger macht was er will habe es aber 
dann korrigiert.

Vielen Dank

Gruß

Andy

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.