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


von Andreas H. (andy78)


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

von Karl H. (kbuchegg)


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)

von Rolf M. (rmagnus)


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).

von Karl H. (kbuchegg)


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.

von Rolf M. (rmagnus)


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.

von Karl H. (kbuchegg)


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.

von Andreas H. (andy78)


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

von Simon K. (simon) Benutzerseite


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.

von Karl H. (kbuchegg)


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
1
  if(struct_v_rpm.v<struct_v_rpm.vold)draw_tach_zeiger(zeiger--);
2
  {
3
4
    if((struct_v_rpm.vold-struct_v_rpm.v)<10)
5
           {
6
                   draw_tach_zeiger(zeiger--);
7
           }
8
           else
9
           {
10
            draw_tach_zeiger(zeiger-=3);
11
            if(zeiger<=0)zeiger=0;
12
          }
13
}

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
1
            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.

1
  if( vstart == 0 )
2
  {
3
    zeiger = struct_v_rpm.v;
4
    vstart = 1;
5
  }
6
7
  //
8
  // Ist die Anzeige schon korrekt auf dem Messwert?
9
  //
10
  if( struct_v_rpm.v != zeiger )
11
  {
12
    // Nein, muss noch korrigiert werden!
13
    //
14
    // In welche Richtung muss korrigiert werden und um wieviel?
15
    //
16
    if( struct_v_rpm.v > zeiger )         // Zeiger zeigt noch zu wenig an?
17
    {
18
      if( struct_v_rpm.v - zeiger < 10 )
19
        zeiger++;
20
      else
21
        zeiger += 3;
22
    } 
23
    else                                  // Nö. Er zeigt zuviel an!
24
    {
25
      if( zeiger - struct_v_rpm.v < 10 )
26
        zeiger--;
27
      else
28
        zeiger -= 3;
29
    }
30
31
    //
32
    // Sicherstellen, dass der Zeiger seinen zulässigen Bereich nicht
33
    // verlässt
34
    //
35
    if( zeiger > 110 )
36
      zeiger = 110;
37
38
    if( zeiger < 0 )
39
      zeiger = 0;
40
41
    //
42
    // das wars, GLCD updaten
43
    //
44
    draw_tach_zeiger( zeiger );
45
  }


(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)

von Andreas H. (andy78)


Lesenswert?

Hallo

Danke

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

Vielen Dank

Gruß

Andy

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.