Forum: Mikrocontroller und Digitale Elektronik m328 adc-Verständnisproblem


von Karl K. (leluno)


Lesenswert?

hallo,

ich verstehe es mal wieder nicht.

an dieser Stelle -
lcd_int4(adc_read()); // <== hier mehrere ADC-Auslesungen angezeigt
- werden mehrere Messungen angezeigt und überschrieben. D.h. die 
Funktion 'lcd_int4' wird nur einmal ausgeführt da sonst hintereinander 
geschrieben würde - aber der Wert wird mehrfach angezeigt.




Wie kann das sein? Was mache ich falsch?

1
void main(void)
2
//
3
{
4
5
clock_prescale_set(clock_div_2);//8mhz
6
7
init_timer_smh();
8
led1_init;
9
10
//usart_init;
11
//USART0_init(9600);
12
//relais_init;
13
i2c_init();
14
lcd_init();
15
adc_init();
16
17
lcd_clear(RED);
18
lcd_int4(adc_read());  // <== hier eine ADC-Auslesung
19
20
//while(1);
21
22
23
24
25
timer_smh=0;
26
27
while(1)
28
{
29
30
//------------------- smh timer ------------------
31
  if (timer_smh>99)
32
  {
33
    sec=sec++;
34
    timer_smh=0;
35
      if(sec>59){
36
        sec=sec-60;  min=min+1;
37
        lcd_goto(1,4);//              
38
        lcd_int2(min);//
39
        lcd_write(":");
40
      if(min==60){
41
        min=0; hou++;
42
        if(hou==24)
43
        {
44
        hou=0;
45
        sub_day_start();
46
        
47
        }
48
        lcd_goto(1,1);//              
49
        lcd_int2(hou);//
50
        lcd_write(":");              
51
        }
52
      }
53
    lcd_goto(1,7);//              
54
    lcd_int2(sec);//
55
//    led1_tog;              
56
  }
57
//------------------------------------------------
58
59
if(sec==3 && min%6==0/**/  )//alle sechs Minuten auslesen
60
{
61
62
  if(min==0/**/)//jede Stunde -------
63
  {
64
  }
65
66
67
//wr_read_reg();
68
//sub_regelung();
69
}
70
71
72
if(sec%5==1)
73
{
74
  u8 i=0;
75
  lcd_goto(10+i++,1);
76
lcd_int4(i);// <== hier 1mal angezeigt
77
  
78
lcd_int4(adc_read()); // <== hier mehrere ADC-Auslesungen angezeigt
79
80
}
81
82
83
84
85
 }//while
86
}//main

von Nemopuk (nemopuk)


Lesenswert?

Deine Anfrage ist unklar formuliert. Gebe mal Beispiele der fehlerhaften 
Ausgabe und was du srattdessen erreichen willst.

Korrektes Einrücken hilft ungemein, den Quelltext zu verstehen.

Wo sind die Quelltexte von lcd_int4() und adc_read()? Ich will sie 
sehen, nicht nur anhand des Namens erraten, was sie tun sollten.

: Bearbeitet durch User
von Karl K. (leluno)


Angehängte Dateien:

Lesenswert?

Nemopuk schrieb:
> Wo sind die Quelltexte von lcd_int4() und adc_read()? Ich will sie
> sehen, nicht nur anhand des Namens erraten, was sie tun sollten.

pardon gehören natürlich dazu:
1
void adc_init()
2
{
3
   // Set the ADC reference to AVcc
4
    ADMUX = (1 << REFS0);
5
    
6
    // Enable ADC and set prescaler to 128 (16 MHz / 128 = 125 kHz)
7
    ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
8
}
9
10
11
#define ADCchannel 2
12
13
int16_t adc_read()
14
{
15
    // Select ADC channel (0-7) by setting the lower bits of ADMUX
16
    ADMUX = (ADMUX & 0xF8) | (ADCchannel & 0x07);
17
    
18
    // Start the conversion
19
    ADCSRA |= (1 << ADSC);
20
    
21
    // Wait for the conversion to complete
22
    while (ADCSRA & (1 << ADSC));
23
    
24
    // Return the ADC result
25
    return ADC;
26
}
27
28
 lcd_int4(i16 x){
29
  uint8_t dum[5]={' ',' ',' ','0','\0'};
30
  u8 neg=0;
31
if (x!=0)  
32
{
33
  
34
if (x<0){x=x*-1;neg=1;}
35
36
    if (x>999){
37
        dum[0]=(x/1000+48);
38
        x=x%1000;
39
    dum[1]='0';
40
    dum[2]='0';
41
    
42
        }
43
  
44
    if (x>99){
45
        dum[1]=(x/100+48);
46
        x=x%100;
47
    if(neg){neg=0;dum[0]='-';}
48
     dum[2]='0';
49
       }
50
    if (x>9){
51
        dum[2]=(x/10+48);
52
        x=x%10;
53
    if(neg){neg=0;dum[1]='-';}
54
        }
55
         dum[3]=(x+48);
56
     if(neg){dum[2]='-';}
57
58
59
}
60
    lcd_write(dum);
61
}
Die ADC-Wandlung wird auf dem Bild unten mehrfach ausgeführt und 
angezeigt - sollte aber nur ein mal ausgeführt und angezeigt werden.

von Wastl (hartundweichware)


Angehängte Dateien:

Lesenswert?

Karl K. schrieb:
> pardon gehören natürlich dazu:

.... und vielleicht mal an die Hinweise zum Posten von
Quellcode denken.

von Nemopuk (nemopuk)


Lesenswert?

Es ist zwar nicht dein Hauptproblem, ich wollte es aber trotzdem zeigen:

Deine Funktion lcd_int4() gibt positive Zahlen mit bis zu 4 Stellen aus. 
Negative Zahlen mit mehr als 3 Stellen führen zu einer fehlerhaften 
Ausgabe:

Der Test
1
int main(void) {
2
    lcd_int4(5);
3
    lcd_int4(50);
4
    lcd_int4(500);
5
    lcd_int4(5000);
6
    lcd_int4(-5);
7
    lcd_int4(-50);
8
    lcd_int4(-500);
9
    lcd_int4(-5000);
10
    return 0;
11
}

erzeugt folgende Ausgabe:
1
   5
2
  50
3
 500
4
5000
5
  -5
6
 -50
7
-500
8
50-0

von Nemopuk (nemopuk)


Lesenswert?

So sieht main() einigermaßen ordentlich formatiert aus:
1
void main(void) {
2
    
3
    clock_prescale_set(clock_div_2);  //8mhz  
4
    init_timer_smh();
5
    led1_init;
6
    //usart_init;
7
    //USART0_init(9600);
8
    //relais_init;
9
    i2c_init();
10
    lcd_init();
11
    adc_init();
12
    lcd_clear(RED);
13
    lcd_int4(adc_read());  // <== hier eine ADC-Auslesung
14
       
15
    timer_smh = 0;
16
    while (1) {
17
        
18
        //------------------- smh timer ------------------        
19
        if (timer_smh > 99) {
20
            
21
            sec = sec++;
22
            timer_smh = 0;
23
            
24
            if (sec > 59) {
25
                sec = sec - 60;
26
                min = min + 1;
27
                
28
                lcd_goto(1, 4); 
29
                lcd_int2(min);  
30
                lcd_write(":");
31
                
32
                if (min == 60) {
33
                    
34
                    min = 0;
35
                    hou++;
36
                    
37
                    if (hou == 24) {                        
38
                        hou = 0;                        
39
                        sub_day_start();
40
                    }
41
                    
42
                    lcd_goto(1, 1);                     
43
                    lcd_int2(hou);                     
44
                    lcd_write(":");
45
                }
46
            }
47
            
48
            lcd_goto(1, 7);             
49
            lcd_int2(sec);             
50
        }
51
        
52
        //------------------------------------------------       
53
        if (sec == 3 && min % 6 == 0) { //alle sechs Minuten auslesen
54
            
55
            if (min == 0)  //jede Stunde -------
56
            {
57
                // nichts?
58
            }
59
            
60
            //wr_read_reg();            
61
            //sub_regelung();
62
        }
63
        
64
        if (sec % 5 == 1)   {
65
            
66
            u8 i = 0;            
67
            lcd_goto(10 + i++, 1);
68
            
69
            lcd_int4(i);  // <== hier 1mal angezeigt
70
            lcd_int4(adc_read());  // <== hier mehrere ADC-Auslesungen angezeigt
71
        }
72
        
73
    }  //while
74
    
75
}  //main

Und auf den problematischen Teil reduziert:
1
void main(void) {
2
    
3
    while (1) {
4
        
5
        if (timer_smh > 99) {            
6
            sec = sec++;
7
            timer_smh = 0;
8
        }
9
                   
10
        if (sec % 5 == 1)   {
11
            
12
            u8 i = 0;            
13
            lcd_goto(10 + i++, 1);
14
            
15
            lcd_int4(i);  // <== hier 1mal angezeigt
16
            lcd_int4(adc_read());  // <== hier mehrere ADC-Auslesungen angezeigt
17
        }
18
        
19
    }  //while
20
    
21
}  //main

Hier fallen mir folgende Dinge auf:

Ist timer_smh als "volatile" und 8 Bit Integer deklariert? Wenn nicht, 
können Lesezugriffe im Hauptprogramm durch Schreibzugriffe in der 
Timer-ISR gestört werden und zu unerwartetem Verhalten führen. 
Allerdings nicht zu dem konkreten Verhalten, dass wir hier sehen. Dafür 
muss es noch einen anderen Grund geben.

> lcd_goto(10 + i++
ergibt immer 10, weil i immer 0 ist.

> lcd_int4(i);
gibt immer 1 aus, weil i immer 1 ist.

> lcd_int4(adc_read());
Gibt mit Sicherheit nur eine ADC Messung aus. Denn etwas anderes kann 
diese Funtkion nicht tun.

Offenbar kommt die Ausgabe "   1 813" von diesen beiden Aufrufen.

Die unerwarte Ausgabe in der dritten Display-Zeile stimmt nicht mit dem 
Quellcode überein. Denn er enthält kein "lcd_goto(3,1)". Sie kann auch 
nicht von "lcd_int4()" kommen, weil diese Funktion immer 4 Ziffern 
rehtsbündig ausgibt.

Vermutlich ist der Fehler ganz woanders, in einem Stück Code, den du 
nicht gezeigt hast. Ich würde mal alle andere Display-Ausgaben 
auskommentieren um auszuschließen, dass sie stören.

: Bearbeitet durch User
von Karl K. (leluno)


Lesenswert?

Nemopuk schrieb:
> Die unerwarte Ausgabe in der dritten Display-Zeile stimmt nicht mit dem
> Quellcode überein.

stimmt - "lcd_goto(3,1)" hab ich nachträglich eingefügt weil es in der 
ersten Zeile sonst blöd aussieht.


lcd_goto(10 + i++
ergibt immer 10, weil i immer 0 ist.

stimmt auch, habe die Deklaration nach oben gezogen. Ergebnis bleibt. 
Stelle wird nur einmal aufgerufen.

Nemopuk schrieb:
> Negative Zahlen mit mehr als 3 Stellen führen zu einer fehlerhaften
> Ausgabe:

Das ist bewusst in kauf genommen. Die Funktion dient zur Positionierung 
auf dem Display. Wenn größere negative Werte zu erwarten sind muss man 
das anders machen.


Nemopuk schrieb:
> Allerdings nicht zu dem konkreten Verhalten, dass wir hier sehen. Dafür
> muss es noch einen anderen Grund geben.

Jedenfalls Dank für dein Bemühen. Es hilft schon weiter zu wissen, dass 
mein Unverständnis nicht ganz unberechtigt ist.

: Bearbeitet durch User
von Nemopuk (nemopuk)


Lesenswert?

Karl K. schrieb:
> stimmt - "lcd_goto(3,1)" hab ich nachträglich eingefügt
> stimmt auch, habe die Deklaration nach oben gezogen

Wenn du hilfreiche Hilfe bekommen willst, solltest du deine Probleme 
ordentlich beschreiben. Wenn man sich Mühe gibt, erkennt man die Ursache 
beim verfassen der Problembeschreibung sogar oft selbst.

> Ergebnis bleibt. Stelle wird nur einmal aufgerufen.

Damit kann ich nichts anfangen. Ist das jetzt eine gute oder eine 
schlechte Nachricht?

Nochmal von vorne: Zeige den kompletten Quelltext (ordentlich 
formatiert!), die dazugehörige Ausgabe, und was du stattdessen 
erwartest.

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Nemopuk schrieb:
> So sieht main() einigermaßen ordentlich formatiert aus:

Stefan Frings darf sich auch an die Regeln zum Posten von
Sourcecode halten.

von Karl K. (leluno)


Lesenswert?

Nemopuk schrieb:
> Nochmal von vorne: Zeige den kompletten Quelltext (ordentlich
> formatiert!), die dazugehörige Ausgabe, und was du stattdessen
> erwartest.

ich werde den code noch mal komplett neu aufsetzen und dann hier 
einstellen.

Das Merkwürdige ist, dass die Messwerte überschrieben werden obwohl die 
Cursorposition bei lcd_write eigentlich mit jedem Wert fortgeschrieben 
wird:
1
void lcd_write_(uint8_t* str)
2
{
3
while(*str>31)
4
    {
5
        lcd_char_(*str++);
6
        curposx =curposx+ f_width;
7
        if(frame)curposx++;
8
    }
9
}

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Karl K. schrieb:
> ich werde den code noch mal komplett neu aufsetzen und dann hier
> einstellen.

Aber dann bitte als Dateianhang, nicht im Posting selbst.

Beitrag #7930953 wurde von einem Moderator gelöscht.
Beitrag #7930961 wurde von einem Moderator gelöscht.
Beitrag #7930968 wurde von einem Moderator gelöscht.
Beitrag #7930985 wurde von einem Moderator gelöscht.
Beitrag #7931018 wurde von einem Moderator gelöscht.
Beitrag #7931021 wurde von einem Moderator gelöscht.
von Karl K. (leluno)


Lesenswert?

Problem gelöst:

    lcd_goto(1,7);//
    lcd_int2(sec);//
//    led1_tog;
  } <===
//------------------------------------------------

Die Klammer gehört nach unten damit die Schleife nur einmal je Sekunde 
durchlaufen wird. Eigentlich ganz einfach.

von Nemopuk (nemopuk)


Lesenswert?

Karl K. schrieb:
> Die Klammer gehört nach unten

Wie meinst du das?

Ich meine, dass diese beiden Zeilen bereits in 
Beitrag "Re: m328 adc-Verständnisproblem" nur 
einmal pro Sekunde ausgeführt werden.
1
        if (timer_smh > 99) {
2
3
            sec = sec++;
4
            timer_smh = 0;
5
6
            if (sec > 59) {
7
               ...
8
            }
9
10
            lcd_goto(1, 7);             
11
            lcd_int2(sec);             
12
        }
Außerdem erklärt das nicht, wieso Ausgaben fälschlicherweise in Zeile 3 
landen. lcd_goto(1, 7) geht ja nach Zeile 1.

Zeige mal den vorher/nachher Vergleich mit etwas mehr Kontext. Gerne 
auch als zwei komplette Dateien (vorher.c, nachher.c) im Anhang.

: Bearbeitet durch User
von Karl K. (leluno)


Lesenswert?

Nemopuk schrieb:
> Zeige mal den vorher/nachher Vergleich mit etwas mehr Kontext.
1
void main(void)
2
//
3
{
4
u8 i=0;
5
clock_prescale_set(clock_div_2);//8mhz
6
7
init_timer_smh();
8
led1_init;
9
i2c_init();
10
lcd_init();
11
adc_init();
12
lcd_clear(RED);
13
14
while(1)
15
{
16
17
//------------------- smh timer ------------------
18
  if (timer_smh>99)
19
    {
20
      sec=sec+timer_smh/100;
21
      timer_smh=timer_smh%100;
22
      if(sec>59){
23
        sec=sec-60;  min=min+1;
24
        lcd_goto(1,4);//              
25
        lcd_int2(min);//
26
        lcd_write(":");
27
      if(min==60){
28
        min=0; hou++;
29
        if(hou==24)
30
        {
31
        hou=0;
32
        sub_day_start();
33
        
34
        }
35
        lcd_goto(1,1);//              
36
        lcd_int2(hou);//
37
        lcd_write(":");              
38
        }
39
      }
40
    lcd_goto(1,7);//              
41
    lcd_int2(sec);//
42
//    led1_tog;              
43
//} <== Klammer vorher  
44
//------------------------------------------------
45
46
  if(sec==3 && min%6==0/**/  )//alle sechs Minuten auslesen
47
  {
48
  }
49
50
  if(min==0/**/)//jede Stunde -------
51
  {
52
  }
53
54
55
56
  if(sec%5==1)
57
  {
58
    volt=measure_adc();
59
    lcd_goto(10,1);
60
    lcd_int_10(volt);
61
    lcd_write(" V");
62
  }
63
64
  }//sec <== Klammer richtig
65
  }//while
66
}//main

Die while-Schleife soll nur einmal je Sekunde durchlaufen werden. 
Deswegen war die Klammer falsch.

von Nemopuk (nemopuk)


Lesenswert?

Ah, jetzt habe ich begriffen.

Warum eine falsche Ausgabe in Zeile 3 landet, ist mir allerdings immer 
noch nicht klar. Egal, du kriegst das hin.

von Karl K. (leluno)


Lesenswert?

Nemopuk schrieb:
> falsche Ausgabe in Zeile 3

oben:
Nemopuk schrieb:
> Die unerwarte Ausgabe in der dritten Display-Zeile stimmt nicht mit dem
> Quellcode überein.

stimmt - "lcd_goto(3,1)" hab ich nachträglich eingefügt weil es in der
ersten Zeile sonst blöd aussieht.

Nochmals Dank für deine kritischen Nachfragen. Man denkt darüber nach 
und das hilft weiter. So z.B. neue Anzeige-Funktion mit Komma:
1
void lcd_int_10(i16 x){
2
  uint8_t dum[5]={' ','0',',','0','\0'};
3
  uint8_t keinkomma=0;
4
  u8 neg=0;
5
if (x!=0)  
6
{
7
  
8
if (x<0){x=x*-1;neg=1;}
9
10
    if (x>999){
11
        dum[0]=(x/1000+48);
12
        x=x%1000;
13
    dum[1]='0';
14
    dum[2]='0';
15
    keinkomma=1;
16
    
17
        }
18
  
19
    if (x>99){
20
    if(keinkomma==1)
21
      {
22
        dum[1]=(x/100+48);
23
        dum[2]='0';
24
      }
25
      else
26
      {
27
        dum[0]=(x/100+48);
28
        dum[1]='0';
29
      }
30
      
31
        x=x%100;
32
    if(neg){neg=0;dum[0]='-';}
33
       }
34
35
    if (x>9){
36
  
37
    if(keinkomma==1)
38
      {
39
        dum[2]=(x/10+48);
40
      }
41
    else
42
      {
43
        dum[1]=(x/10+48);
44
      }
45
      
46
        x=x%10;
47
    if(neg){neg=0;dum[1]='-';}
48
        }
49
    
50
         dum[3]=(x+48);
51
     if(neg){dum[2]='-';}
52
53
54
}
55
    lcd_write(dum);
56
}

von Harald K. (kirnbichler)


Lesenswert?

Findest Du diese Quelltextformatierung in irgendeiner Weise lesbar?

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ich hätte noch mehr zu sagen....
Was heißt dum, und warum dum?

Wieso ist dum kein C String, obwohl es doch ganz offenbar einer sein 
soll?

Karl K. schrieb:
> x=x*-1
OK, nicht wichtig, aber warum nicht so: x=-x;
oder:
x=x%100; zu x%=100;

Karl K. schrieb:
> i16
Was ist das, und vor allen Dingen, warum ist das?

Für mich wäre an der Stelle der Punkt gekommen, wo ich über sprintf oder 
seine Brüder nachgedacht hätte, auch wenn es 2k Flash kostet.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Harald K. schrieb:
> Findest Du diese Quelltextformatierung in irgendeiner Weise lesbar?

Er wartet noch darauf, dass endlich ein Werkzeug wie ›astyle‹ erfunden 
wird. Und ein Editor welcher automagisch tabs in spaces umwandelt. 
;-)

von Peter D. (peda)


Lesenswert?

Arduino F. schrieb:
> Für mich wäre an der Stelle der Punkt gekommen, wo ich über sprintf oder
> seine Brüder nachgedacht hätte, auch wenn es 2k Flash kostet.

Sehe ich auch so, bei 32kB ist doch reichlich Platz.
Zu Zeiten des AT90S2313 oder AT90S4433 hatte ich das auch noch zu Fuß 
gemacht.

von Wastl (hartundweichware)


Lesenswert?

Peter D. schrieb:
> Sehe ich auch so, bei 32kB ist doch reichlich Platz.

Warum einfach wenn's umständlich auch geht. Ich schätze mal dass
der TO von der Existenz von sprintf noch nichts gehört hatte.

von Falk B. (falk)


Lesenswert?

Selbst wenn man diese Anzeige selber programmiert, geht das deutlich 
besser. Angefangen bei der Formatierung des Quelltextes.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Ein kurzer Test sagt:
lcd_int_10(-42); //  -,2
lcd_int_10(-5555);  // -555

Die Funktion ist kaputt!

von Wastl (hartundweichware)


Lesenswert?

Arduino F. schrieb:
> Die Funktion ist kaputt!

Wenn man es schon nicht schafft vernünftige, aussagekräftige
Namen für Funktionen und Variablen zu finden dann kann's auch
mit deren Inhalten schwierig werden, um es mal vorsichtig
auszudrücken ....  ja, und die Formatierung, ein Graus ....

von Falk B. (falk)


Lesenswert?

So ist die Formatierung und ein paar Grundlagen OK. Die Funktion ist 
aber immer noch fehlerhaft. Und wozu soll ein Komma bei Integerzahlen 
gut sein?
1
void lcd_int_10(i16 x) {
2
    uint8_t dum[5]= " 0,0";
3
    uint8_t keinkomma=0;
4
    u8 neg=0;
5
  
6
    if (x<0) {
7
        x = -x;
8
        neg = 1;
9
    }
10
    if (x>999) {
11
        dum[0] = x/1000+'0';
12
        x=x%1000;
13
        dum[1] = '0';
14
        dum[2] = '0';
15
        keinkomma = 1;
16
    }
17
    if (x>99) {
18
        if(keinkomma) {
19
            dum[1] = x/100 + '0';
20
            dum[2] = '0';
21
        } else {
22
            dum[0] = x/100 + '0';
23
            dum[1] = '0';
24
        }
25
        x=x%100;
26
        if(neg){neg=0;dum[0]='-';}
27
    }
28
    if (x>9) {
29
        if(keinkomma) {
30
            dum[2] = x/10 + '0';
31
        } else {
32
            dum[1] = x/10 + '0';
33
        }      
34
        x=x%10;
35
        if(neg) { neg=0; dum[1]='-';}
36
    }
37
    dum[3]=(x+'0');
38
    if(neg) { dum[2]='-';}
39
    lcd_write(dum);
40
}

von Karl K. (leluno)


Lesenswert?

Wastl schrieb:
> TO von der Existenz von sprintf

gehört schon - gebraucht noch nicht.

Das schöne an diesem Forum - man wird zwar moralisch niedergemacht  - 
aber man lernt noch was.

von Falk B. (falk)


Lesenswert?

Karl K. schrieb:
> Das schöne an diesem Forum - man wird zwar moralisch niedergemacht

Sarkasmus ist halt nicht jedermanns Sache.

von Wastl (hartundweichware)


Lesenswert?

Karl K. schrieb:
> man wird zwar moralisch niedergemacht

Immerhin wirst du hier nicht beschimpft, sondern es werden
sachlich die "Probleme" (und es sind mehrere) angesprochen.

Karl K. schrieb:
> aber man lernt noch was

Das bleibt zu hoffen. Wir haben hier aber auch schon jede Menge
beratungsresistente Leute gesehen.

von Wastl (hartundweichware)


Lesenswert?

Karl K. schrieb:
> gehört schon - gebraucht noch nicht.

Wenn du mal im Detail beschreibst was deine Funktion am LCD
machen soll (ich kann es nicht, will es auch nicht verstehen)
dann könnte man (jemand hier im Forum) dir mit ein paar
"Pinselstrichen" eine vernünftige Funktion mit der Anwendung
von sprintf(...) schreiben.

Ich nehme an dass du das nicht alleine schaffst, denn schon
der Titel deines Threads hat nichts mit dem zu tun was du
wirklich an Problemen hast. Jedenfalls hat das alles (zuerst
mal) nichts mit dem ADC zu tun.

von Peter D. (peda)


Lesenswert?

1
#include <stdio.h>
2
#include <stdint.h>
3
4
void lcd_int4(int16_t val)
5
{
6
  char s[] = "Err ";
7
  if ( val >= -999 && val <= 9999 )
8
    sprintf(s, "%4d", val); 
9
  lcd_write(s);
10
}

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Peter D. schrieb:
> #include <stdio.h>
> #include <stdint.h>
> void lcd_int4(int16_t val)
> {
>   char s[] = "Err ";
>   if ( val >= -999 && val <= 9999 )
>     sprintf(s, "%4d", val);
>   lcd_write(s);
> }

Schlechter Stil. Bei sowas kann man sich bei C immer wieder leicht in 
den Fuß schießen. Entweder die Einzelanweisung hinter if() in der 
gleichen Zeile oder IMMER mit Klammern!
1
    if ( val >= -999 && val <= 9999 ) sprintf(s, "%4d", val);

1
    if ( val >= -999 && val <= 9999 ) {
2
        sprintf(s, "%4d", val);
3
    }

von Wastl (hartundweichware)


Lesenswert?

Falk B. schrieb:
> Schlechter Stil.

Ja schon gut, du hast ja Recht. Aber es passiert ja im Fall
der Fälle nix Schlimmes. Höchstens etwas was man nicht erwartet.

von Karl K. (leluno)


Lesenswert?

Falk B. schrieb:
> Und wozu soll ein Komma bei Integerzahlen
> gut sein?

Sorry ich hab noch nie mit Fließkomma gearbeitet und habe das auch im 
Prinzip nie gebraucht. Der ADC liefert bei 10bit 0-1023. 
Spannungsmessung Genauigkeit ist 0,1 Volt.

Die Darstellung auf dem lcd muss formatiert sein - sonst sieht es blöd 
aus. Also immer 4Stellen für eine Zahl.

Die Funktion lcd_int_10() kann auf 4Stellen also Werte von
+9999 bis -999 darstellen davon den Zahlenbereich 99,9 bis -9,9 als 
Dezimalwert mit Komma. Im Prinzip ist das der Sinn meiner Funktion wobei 
ihr ganz richtig bemerkt habt, dass die Funktion noch nicht ganz fertig 
ist weil die Anzeige von negativen Zahlen nicht funktioniert und die 
Ausgaben von Zahlen >99,9 auch noch nicht implementiert ist. (ich muss 
nur Spannungen von 0 - 60V auswerten - brauch ich also noch nicht)

Ich fand die Idee gut für Dezimalzahlen aus der ADC-Spannungsmessung 
eine eigene Funktion zu schreiben statt bisher
lcd_int2(x/10);
lcd_write(",");
lcd_int(x%10);

Aber irgendwie versteht mich mal wieder keiner.

von Falk B. (falk)


Lesenswert?

Karl K. schrieb:
> Sorry ich hab noch nie mit Fließkomma gearbeitet und habe das auch im
> Prinzip nie gebraucht. Der ADC liefert bei 10bit 0-1023.
> Spannungsmessung Genauigkeit ist 0,1 Volt.

Aha, also Festkommaarithmetik. Die ist aus deiner Funktion aber 
nicht so recht ablesbar.

> Aber irgendwie versteht mich mal wieder keiner.

Das könnte an deinen Informationen liegen, welche du nicht lieferst.

von Wastl (hartundweichware)


Lesenswert?

Karl K. schrieb:
> Aber irgendwie versteht mich mal wieder keiner.

Wirres Zeug kann man eben nicht verstehen.

von Joachim B. (jar)


Lesenswert?

Karl K. schrieb:
> Aber irgendwie versteht mich mal wieder keiner.

denn mache es doch richtig, uint16 reicht doch bis 6000centiVolt

Spannungsteiler
0-60V Kennlinie aufnehmen und Steigung m und Konstante b ermitteln mit 
der Geradengleichung y = m * x + b

hinterher Komma an der richtigen Stelle einsetzen per 
Stringmanipulation, ganz ohne float.

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Joachim B. schrieb:
> hinterher Komma an der richtigen Stelle einsetzen per
> Stringmanipulation, ganz ohne float.

Man kann auch float Zahlen darstellen ganz ohne float zu
benutzen. Karl hat es im Ansatz schon gezeigt.

Karl K. schrieb:
> lcd_int2(x/10);
> lcd_write(",");
> lcd_int(x%10);

Nur den letzten Schritt, dies vernünftig in einer Funktion zu
vereinen, das scheint für ihn zu schwierig zu sein.

von Joachim B. (jar)


Lesenswert?

Wastl schrieb:
> Man kann auch float Zahlen darstellen ganz ohne float zu
> benutzen.

ach und was schrieb ich?

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.