Nochmals bitte um Hilfe bei ADC

OP #1735510
Lesenswert?

Hallo guten Morgen an alle,
ich hatte ja vor ein paar Tage im Beitrag "ADC-Mega8, Hilfe bitte ich 
komme nicht weiter", schon mal um Hilfe gebeten und konnte das Problem 
danach auch beheben. War eigentlich keine große Sache ich hatte es nur 
nicht gesehen. Jetzt gibt es wieder ein Problem (sicherlich ähnlich 
banal) und mir ist einfach nicht klar wo der Fehler liegt. Vielleicht 
erkennt Ihr den "Kasus Knacksus". :-)

U.a. soll  folgender Code ausgeführt werden:

ISR (TIMER1_OVF_vect){
…
result = Read_Channel(0);     // ACD – Wert wird zugewiesen

…

lcd_out(result);

return;
}

void lcd_out(uint16_t wert){

  set_cursor(0,2);

  if(wert>963){
    lcd_string("wird geladen");
  }else if(wert>928 && wert<963){
    lcd_string("Batterie voll");
  }else if(wert>785){
    lcd_string("Ladung gring!");
  }else if(wert<=737 && wert>717){
    lcd_string("Ladung kritisch!");
  }else if(wert==917){
    lcd_string("abgeschaltet!!");
  }else if(wert==0){
    lcd_string("Schalter aus!");
  }
}

Es wird offenbar keine der If-Anweisungen ausgeführt, den ich erhalte 
auf dem Display keine Anzeige.
Lieg es an der Notation der Vergleiche, ist es ein Typ-Konflikt … ???



Gruß Wilfried
#1735516
Lesenswert?

Prinzipiell ist es schlecht, Code in einer ISR aufzurufen, der längere 
Zeit für die Abarbeitung braucht.

Ohne deine Beschreibung, wie sich der Controller verhält, wird es 
schwierig genaues zu sagen.

Als erstes würde ich aber den ADC-Wert direkt auf dem Display ausgeben, 
um zu sehen, dass die Ausgabe-Funktion überhaupt abgearbeitet wird.
#1735528
Lesenswert?

Um aus der ISR die LCD-Ausgabe zu "triggern", verwendet man eigentlich 
z.B. folgenden Mechanismus (Pseudo-Code):
1
#define IDLE    0
2
#define LCD_OUT 1
3

4
volatile uint8_t command;
5

6
ISR(TIMER1_OVF_vect)
7
{
8
    //...
9
    command = LCD_OUT;
10
}
11

12
int main()
13
{
14
    //...
15

16
    for(;;)
17
    {
18
        if(command == LCD_OUT)
19
        {
20
            lcd_out(...);
21
            command = IDLE;
22
        }
23
    }
24
    return 0;
25
}
OP #1735544
Lesenswert?

Ich glaube ich habe meinen Fehler gefunden. Wenn ich dem ADC-Wert über 
die Funktion "itoa" wandele und direkt anzeigen lasse erhalte ich z.B. 
bei 2,5V Eingangsspannung die Anzeige "0000000511". Ich schließe daraus, 
das ich die führenden Nullen beim Vergleich berücksichtigen muß, 
richtig?
#1735545
Lesenswert?

Diese Schreibweise
1
  if(wert>963){
2
    lcd_string("wird geladen");
3
  }else if(wert>928 && wert<963){
4
    lcd_string("Batterie voll");
5
  }else if(wert>785){
6
    lcd_string("Ladung gring!");
7
  }else if(wert<=737 && wert>717){
8
    lcd_string("Ladung kritisch!");
9
  }else if(wert==917){
10
    lcd_string("abgeschaltet!!");
11
  }else if(wert==0){
12
    lcd_string("Schalter aus!");
13
  }

ist sehr unübersichtlich. Ist dir zb aufgefallen, dass der Fall 
(wert==917) nie ausgeführt werden kann?

Beobachtung:
Wenn der Wert zb 980 ist, dann wird dieser if Teil
1
    if( wert > 963 )
genommen. Da alle andere Abfragen mittels else if an dieses if gekoppelt 
sind, werden sie gar nicht mehr ausgewertet. Du musst daher hier
1
    else if( wert > 928 && wert < 963 )
gar nicht mehr abfragen, ob der Wert kleiner als 963 ist.  Er kann nicht 
mehr größer als 963 sein, ansonsten würde das Programm gar nicht bei 
dieser Abfrage sein!

was soll eigentlich passieren, wenn der Wert exakt 963 ist. Das ist ein 
Tippfehler, da muss es <= heißen :-).

Aber besser ist es, das ganze zu vereinfachen und immer nur auf die 
Untergrenze zu prüfen und die in absteigender Reihenfolge anzuordnen:
1
  //
2
  // zuerst die fixen Werte
3
  //
4
  if( wert == 917 )
5
    lcd_string( "abgeschaltet!!" );
6

7
  else if( wert == 0 )
8
    lcd_string( "Schalter aus!" );
9

10
  else {    // dann Wertebereiche
11
    if( wert > 963 )
12
      lcd_string( "wird geladen" );
13

14
    else if( wert > 928 )
15
      lcd_string( "Batterie voll" );
16

17
    else if( wert > 785 )
18
      lcd_string( "Ladung gring!" );
19

20
    else if( wert > 717 )
21
      lcd_string( "Ladung kritisch!" );
22

23
    else
24
      lcd_string( "massive Unterspannung !" );
25
  }

auf die Art kann es dir nie passieren, dass Bereichsgrenzen nicht 
aneinanderpassen und du unbeabsichtigt Lücken in deinen Bereichen hast. 
Auch solltest du dir angewöhnen einen 'default'-else Zweig einzufügen, 
der alles andere auffängt.
#1735548
Lesenswert?

Wilfried H. schrieb:
> Ich glaube ich habe meinen Fehler gefunden. Wenn ich dem ADC-Wert über
> die Funktion "itoa" wandele und direkt anzeigen lasse erhalte ich z.B.
> bei 2,5V Eingangsspannung die Anzeige "0000000511". Ich schließe daraus,
> das ich die führenden Nullen beim Vergleich berücksichtigen muß,
> richtig?

Falsch.
Dein Code arbeitet schon richtig.
Für den Fall, dass der wert 511 beträgt, hast du ganz einfach keine 
Ausgabe vorgesehen.

(Siehe auch meinen vorhergehenden Beitrag, wie du das besser machen 
kannst)
#1735563
Lesenswert?

Wilfried H. schrieb:
> Soory, die 917 im Code ist falsch muß heißen 717!

Und wahrscheinlich hätte es im Original auch nicht == sondern < heissen 
sollen :-)

-> was lernen wir daraus:
optische Formatierung und Aufbereitung des Codes ist kein Selbstzweck 
sondern hilft auch mit Fehler zu sehen!

Wer die Einzelteile einer Anweisung auf Knirsch ohne Leerzeichen 
aneinanderpappt, hat es nicht besser verdient. Seit du klein bist, hast 
du dein Gehirn darauf trainiert, dass zwischen Wörtern Leerraum steht. 
Warum man diese Konditionierung bei der C Programmierung über Bord 
werfen muss nur weil es erlaubt ist, entzieht sich meinem Verständnis. 
Wäre ja auch zu einfach, wenn man eine Anweisung lesen kann ohne erst 3 
mal vorwärts/rückwärts mit den Augen durch die Anweisung laufen zu 
müssen um die Einzelteile optisch zu identifizieren.
OP #1735588
Lesenswert?

Hallo Karl Heinz,
danke Dir ein weiteres mal. Du hast natürlich völlig recht.
Aber so ist das wenn man lange nicht programmiert hat, dann verlernt man 
doch vieles. Vor allen Dingen bei den eigentlich so logischen Basics, da 
denkt man garnicht mehr richtig nach, denn "das muß ja stimmen".

Also danke noch mal Wilfried

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren