mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Nochmals bitte um Hilfe bei ADC


Autor: Wilfried H. (willi_2)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lord Ziu (lordziu)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lord Ziu (lordziu)
Datum:

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

volatile uint8_t command;

ISR(TIMER1_OVF_vect)
{
    //...
    command = LCD_OUT;
}

int main()
{
    //...

    for(;;)
    {
        if(command == LCD_OUT)
        {
            lcd_out(...);
            command = IDLE;
        }
    }
    return 0;
}

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

Bewertung
0 lesenswert
nicht lesenswert
Wilfried H. schrieb:

> Lieg es an der Notation der Vergleiche, ist es ein Typ-Konflikt … ???

Wie wäre es mit:
Der Wert ist nicht der, den du erwartest?

Du hast zb keine Ausgabe für Werte
* die kleiner als 717 sind
* die sich im Bereich  738 bis 785 bewegen.

Welche Werte hast du denn?

Autor: Wilfried H. (willi_2)
Datum:

Bewertung
0 lesenswert
nicht 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?

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

Bewertung
0 lesenswert
nicht lesenswert
Diese Schreibweise
  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!");
  }

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
    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
    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:
  //
  // zuerst die fixen Werte
  //
  if( wert == 917 )
    lcd_string( "abgeschaltet!!" );

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

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

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

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

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

    else
      lcd_string( "massive Unterspannung !" );
  }

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.

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

Bewertung
0 lesenswert
nicht 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)

Autor: Wilfried H. (willi_2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soory, die 917 im Code ist falsch muß heißen 717!

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

Bewertung
0 lesenswert
nicht 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.

Autor: Wilfried H. (willi_2)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

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.