Forum: Mikrocontroller und Digitale Elektronik String an LCD ausgeben


von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich möchte gerne eine Variable an ein Display (EA W204-BNLED via Channaa 
I2C- LCD Adapter) ausgeben. Dazu muss ich aber erst einen String an das 
LCD senden können.

Ich habe nun einfach den Code des String-Unterprogrammes aus dem 
Tutorial übernommen und angepasst.
Hier der betroffene Ausschnitt aus dem ganzen Programm (siehe Anhang):
1
void i2c_writes(char *data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);         // I2C Adresse und "Schreib Modus" setzen
4
  i2c_write(0x76);                       // Schreib Adresse 0x76 (String)
5
    while(*data) 
6
  {
7
      i2c_write('*data');
8
      data++;
9
    }
10
  i2c_stop();                            // I2C Stop
11
}

Nun erhalte ich beim Kompilieren die Warnung "warning character constant 
too long for its type"

Das Display zeigt dann bloss Spannung A an wobei das A blinkt. TEST 
erscheint nicht.

Was läuft hier schief?

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:

>       i2c_write('*data');

Ohne '
Du willst ja das Zeichen senden, welches an der Position data
gespeichert ist

        i2c_wwrite( *data );

> Nun erhalte ich beim Kompilieren die Warnung "warning character constant
> too long for its type"

Logisch. ' steht in C für dies_ist_ein_Character, so wie
beispielsweise 'A', 'B' oder auch '9'
'*data' ist aber kein einzelnes Zeichen.

Aber das willst du ja auch gar nicht, du willst das Zeichen
senden, welches an der Speicheradresse die in data steht.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Marcel wrote:

>   while(*data)
>   {
>       i2c_write('*data');
                  ^     ^

Lass das weg. Das käme nur hin, wenn ein Buchstabenkonstante oder eine 
Zifferkonstante direkt als Funktionsargument übergeben würde.

von Marcel (Gast)


Lesenswert?

Hallo,

habe ich geändert der Fehler ist weg aber TEST erscheint weiterhin 
nicht.

Marcel

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Lass mal display() weg. Möglicherweise überschreibt/löscht das dir das 
TEST.

von Marcel (Gast)


Lesenswert?

So jetzt klappts, hat aber noch nen kleinen Fehler. Poste nach dem 
Mittag den neuen Code und das Problem.

Mahlzeit :)

von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

Also hier die neueste Version, habe noch einen Uart Test eingebaut 
welcher auch funktioniert. Die Ausgabe des Strings funktioniert nun 
jedoch erhalte ich wieder 2 Warnungen:

../ipa_2902_v01.c:37: warning: passing argument 1 of 'i2c_write' makes 
integer from pointer without a cast
../ipa_2902_v01.c: In function 'i2c_writes':
../ipa_2902_v01.c:45: warning: passing argument 1 of 'i2c_writec' makes 
pointer from integer without a cast

Betroffen sind die Unterprogramme:
1
void i2c_writec(char *data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);         // I2C Adresse und "Schreib Modus" setzen
4
  i2c_write(0x76);            // Schreib Adresse 0x76 (String)
5
  i2c_write(data);
6
  i2c_stop();
7
}
8
9
void i2c_writes(char *data)
10
{
11
    while(*data) 
12
  {
13
      i2c_writec(*data);
14
      data++;
15
    }
16
}

Die ausgabe des Strings funktioniert zwar, jedoch erscheint jeweils das 
2te Zeichen des Strings nicht, in diesem Fall ACDEFE....

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:

>
> void i2c_writec(char *data)

Hier willst du keinen Pointer haben.
In data steht bereits der auszugebende Character.

void i2c_writec(char data)

von Marcel (Gast)


Lesenswert?

Wenn ich "void i2c_writec(char data)" schreibe kriege ich einen Fehler, 
wenn ich einfach nur den Pointer weglass kriege ich nur noch eine 
Warnung aber `bcde... anstelle ABCDE.

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:
> Wenn ich "void i2c_writec(char data)" schreibe kriege ich einen Fehler,

Welchen?
Wo?

von Marcel (Gast)


Lesenswert?

../ipa_2902_v01.c:50: error: expected expression before 'char'

in der Zeile die ich geändert habe also "void i2c_writec(char data)"

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:
> ../ipa_2902_v01.c:50: error: expected expression before 'char'
>
> in der Zeile die ich geändert habe also "void i2c_writec(char data)"

Das ergibt so noch keinen Sinn.
Zeig mal mehr von der Umgebung an dieser Stelle.
Oder einfach den kompletten Code.

von Marcel (Gast)


Lesenswert?

Hier die aktuellste Version, Display() habe ich erstmal auskommentiert, 
nun ist neben Uart noch ein ADC hinzugekommen.

Die Umgebung:
1
void i2c_writec(char *data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);             // I2C Adresse und "Schreib Modus" setzen
4
  i2c_write(0x76);                // Schreib Adresse 0x76 (String)
5
  i2c_write(data);                
6
  i2c_stop();
7
}
8
9
void i2c_writes(char *data)
10
{
11
    while(*data) 
12
  {
13
      i2c_writec(data);
14
      data++;
15
    }
16
}
17
18
void display_init(void)
19
{
20
  i2c_start_wait(LCD+I2C_WRITE);             // I2C Adresse und "Schreib Modus" setzen
21
  i2c_write(0x6C);                // Display Konfiguration
22
  i2c_write(0x0C);                // Display ein, Cursor aus
23
  i2c_stop();                    // I2C Stop
24
  
25
  i2c_start_wait(LCD+I2C_WRITE);             // I2C Adresse und "Schreib Modus" setzen
26
  i2c_write(0x61);                // Display komplett löschen
27
  i2c_stop();                    // I2C Stop
28
29
  i2c_writes("ABCDEFG");              // String an LCD  
30
}

von Stefan B. (stefan) Benutzerseite


Lesenswert?

void i2c_writec(char data)
{
  i2c_start_wait(LCD+I2C_WRITE);  // I2C Adresse und "Schreib Modus" 
setzen
  i2c_write(0x76);                // Schreib Adresse 0x76 (String)
  i2c_write(data);
  i2c_stop();
}

void i2c_writes(char *data)
{
  while(*data)
  {
    i2c_writec(*data);
    data++;
  }
}

von Marcel (Gast)


Lesenswert?

Wenn ichs so schreibe wie Stefan erhalte ich keine Fehler und auch keine 
Warnung. Der Text ist auch grossgeschrieben wie gewünscht jedoch fehlt 
wie immer das zweite Zeichen des Strings also ACDEF statt ABCDEF. Sehr 
merkwürdig.

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:
> Wenn ichs so schreibe wie Stefan erhalte ich keine Fehler und auch keine
> Warnung.

Liegt, daran, dass zumindest die String-Behandlung damit korrekt
ist.

> Der Text ist auch grossgeschrieben wie gewünscht jedoch fehlt
> wie immer das zweite Zeichen des Strings also ACDEF statt ABCDEF. Sehr
> merkwürdig.

Könnte das irgend ein I2C-Problem sein?

Was ist mit dem Code 0x76, der in deinem Code immer wieder
auftaucht. Könnte der damit etwas zu tun haben?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dein anderer Code im Programm schreibt vielleicht auf die Stelle 
'ABCDEF' ein ' A' und dann sieht es aus wie ' ACDEF'.

von Marcel (Gast)


Lesenswert?

Erst kurz zu Stefans Beitrag:
Habe ich derzeit auskommentiert, schreibt aber auch erst an 10ter Stelle 
das blinkende A wie ich es auch möchte.

Jetzt zu Karl Heinz:
Das LCD Display ist über den Adapter des Ingenieurbüros Channaa 
angeschlossen. Ich muss möglichst viele Port Pins freihalten daher habe 
ich mich überhaupt für I2C entschieden.

Mit dem Code 0x76 gebe ich nun den Befehl WriteString siehe Datenblatt 
Seite 17: http://www.channaa.com/files/I2C_LCD_Adapter_V10_Rev5.PDF

In der Ursprungsversion sah das ganze so aus:
1
  i2c_start_wait(LCD+I2C_WRITE);         // I2C Adresse und "Schreib Modus" setzen
2
  i2c_write(0x76);            // Schreib Adresse 0x76 (String)
3
  i2c_write('A');             // A
4
  i2c_write('B');             // B
5
  i2c_write('C');             // C
6
  i2c_write('D');             // D
7
  i2c_stop();                 // I2C Stop

So funktioniert es, auch jetzt noch.

von Gast (Gast)


Lesenswert?

Was sagt dein Debugger?



Mann könnte es aber auch so machen:
1
void i2c_writec(char *data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);
4
  i2c_write(0x76);              
5
  i2c_write(*data);                
6
  i2c_stop();
7
}
8
9
void i2c_writes(char *data)
10
{
11
    while(*data) 
12
  {
13
      i2c_writec(data);
14
      data++;
15
    }
16
}

von Karl H. (kbuchegg)


Lesenswert?

Gast wrote:

> Mann könnte es aber auch so machen:

Könnte man, ist aber nicht so praktikabel.
1
int main()
2
{
3
  ...
4
  i2c_writec( 'a' );
5
}

geht dann erst mal in die Hose.
1
int main()
2
{
3
  ...
4
  i2c_writec( &'a' );
5
}

geht auch nicht

und
1
int main()
2
{
3
  char MyA = 'a';
4
  ...
5
  i2c_writec( &MyA );
6
}

ist ja wohl der Albtraum schlechthin :-)

So wie es ist, also einem char Argument bei i2c_writec
ist das schon in Ordnung.

von Karl H. (kbuchegg)


Lesenswert?

@Marcel

Was passiert, wenn du nicht die WriteString sondern die
CharToLCD Funktion benutzt
1
void i2c_writec(char data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);
4
  i2c_write(0x64);              
5
  i2c_write(data);                
6
  i2c_stop();
7
}
8
9
void i2c_writes(char *data)
10
{
11
  while(*data) 
12
  {
13
      i2c_writec(*data);
14
      data++;
15
  }
16
}

Im übrigen würde ich da sowieso 2 getrennte Funktionen dafür
einsetzen, wenn dir der I2C Adapter das schon so anbietet
1
void i2c_writec(char data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);
4
  i2c_write(0x64);              
5
  i2c_write(data);                
6
  i2c_stop();
7
}
8
9
void i2c_writes(char *data)
10
{
11
  i2c_start_wait(LCD+I2C_WRITE);
12
  i2c_write(0x76);              
13
14
  while(*data) 
15
  {
16
      i2c_write(*data);
17
      data++;
18
  }
19
20
  i2c_stop();
21
}

Probier mal beide Varianten aus.

(Ich finde es nicht sehr schlau, wenn du in ein Testprogramm
für die LCD gleich UART und ADC mit einbaust. Je mehr Subsysteme
aktiv sind, desto mehr Fehler kann man sich einhandeln. Test-
programme sollten eigentlich immer so einfach wie nur irgendwie
möglich sein)

von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

so habe heute morgen mal beide Varianten ausprobiert, die erste 
Funktionierte nicht, "frass" erneut das 2te Zeichen.

Die zweite musste ich noch etwas anpassen und nun läuft es:
1
void i2c_writec(char *data)
2
{
3
  i2c_start_wait(LCD+I2C_WRITE);             // I2C Adresse und "Schreib Modus" setzen
4
  i2c_write(0x64);                // Schreib Adresse 0x76 (String)
5
  i2c_write(*data);                
6
  i2c_stop();
7
}
8
9
void i2c_writes(char *data)
10
{
11
  i2c_start_wait(LCD+I2C_WRITE);
12
  i2c_write(0x76);
13
14
    while(*data) 
15
  {
16
      i2c_write(*data);
17
      data++;
18
    }
19
  i2c_stop();
20
}

Besten Dank für die Hilfe :)

Marcel

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:
> Hallo,
>
> so habe heute morgen mal beide Varianten ausprobiert, die erste
> Funktionierte nicht, "frass" erneut das 2te Zeichen.
>
> Die zweite musste ich noch etwas anpassen und nun läuft es:
>
1
> void i2c_writec(char *data)
2
3
4
Wie oft denn noch:
5
Das hier ist Unsinn.
6
Diese Funktion soll einen einzigen Character aufs Display
7
ausgeben. Dazu ist ein Pointer kontraproduktiv, weil du
8
die Funktion dann nicht vernünftig (beim Aufruf) benutzen kannst.
9
10
[C]
11
void i2c_writec(char data)
12
{
13
  i2c_start_wait(LCD+I2C_WRITE);             // I2C Adresse und "Schreib Modus" setzen
14
  i2c_write(0x64);                // Schreib Adresse 0x76 (String)
15
  i2c_write(data);                
16
  i2c_stop();
17
}

Das hier kannst du zb so verwenden
1
int main()
2
{
3
  ...
4
  i2c_writec( 'A' );
5
  ...
6
}

Deine Version muss so benutzt werden und kann auch nicht
anders benutzt werden:
1
int main()
2
{
3
  char a_char = 'a';
4
5
  ...
6
  i2c_writec( &a_char );
7
  ...
8
}

von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hattest recht habe ich noch angepasst.

Nun versuche ich den ADC Wert auf dem Display anzuzeigen. Die Ausgabe 
einer Variable hat auf Anhieb geklappt, doch der AD Wandler mach noch 
macken.

Die ADC Subroutine habe ich aus dem Tutorial übernommen und für meine 
Zwecke angepasst (8MHz, AVREF als Referenz). Nun gibt er mir auf dem 
Display aber immer 1023 also quasi 5V aus. Egal ob ich auf den Kanal0 
via Poti zwischen 0-5V habe.

Sieht jemand den Fehler? Dürfe in der Sensor Subroutine liegen:
1
// Analog-Digital Wandler einlesen
2
uint16_t Sensor(uint8_t mux)
3
{
4
    uint8_t i;                    // Varaible i
5
   uint16_t result;                // Variable result
6
 
7
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);   // ADC aktivieren und Frequenzvorteiler auf 64 
8
9
   ADMUX = mux;                              // Kanal waehlen
10
  ADCSRA |= (1<<ADSC);                      // "Aufwärm" Wandlung
11
   while ( ADCSRA & (1<<ADSC) ){}            // auf Abschluss der Wandlung warten
12
   result = ADCW;                    // ADCW muss einmal gelesen werden,
13
                                    // sonst wird Ergebnis der nächsten Wandlung
14
                                    // nicht übernommen.
15
   
16
   /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
17
   result = 0; 
18
   for( i=0; i<4; i++ )
19
   {
20
     ADCSRA |= (1<<ADSC);                  // eine Wandlung "single conversion"
21
      while ( ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
22
      result += ADCW;                  // Wandlungsergebnisse aufaddieren
23
   }
24
 
25
   ADCSRA &= ~(1<<ADEN);                    // ADC deaktivieren
26
27
   result /= 4;                             // Summe durch vier teilen = arithm. Mittelwert
28
   return result;
29
}

Marcel

von Karl H. (kbuchegg)


Lesenswert?

Wie ist AVRef beschaltet?

von Marcel (Gast)


Lesenswert?

Mit 5V über L/C Netzwerk wie es das Datenblatt vorschlägt.

von Marcel (Gast)


Lesenswert?

Ne sorry AVCC ist so beschaltet, AVRev ist über einen 1uF auf GND.

von Marcel (Gast)


Lesenswert?

Argh, danke geht natülich nicht wenn ich 0V als Referenz nehme -.-

ADMUX |= (1<<REFS0);

Und es klappte.

von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

Ich bins nochmal. Nun möchte ich ja die Spannung die ich einlese auch 
noch auf dem Display ausgeben. Mit dem jetztigen Code geht das schonmal 
jedoch nur ganzzahlig. Das heisst mit dem Code so wie er angehängt ist 
wird mir 0-5 angezeigt, kommentiere ich die Umrechnung aus wird mir 
0-1023 angezeigt.

Gehe ich richtig in der Annahme das ich für Nachkommastellen mit 
Festkommaarithmetik arbeiten muss wie es im Tutorial steht? Leider wird 
im Tutorial nur Assembler Code verwendet und ich kann die als Bild 
eingefügten Formeln im Tutorial nicht lesen da sie flasch dargestellt 
werden.

von Marcel (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:

> Gehe ich richtig in der Annahme das ich für Nachkommastellen mit
> Festkommaarithmetik arbeiten muss wie es im Tutorial steht? Leider wird
> im Tutorial nur Assembler Code verwendet und ich kann die als Bild
> eingefügten Formeln im Tutorial nicht lesen da sie flasch dargestellt
> werden.

Das Prinzip ist sehr einfach:
Wenn du anstelle von 5 mit 50 multiplizierst, dann erhältst du
nicht Zahlen von 0 bis 5 sondern von 0 bis 50. Im Prinzip
hast du dann schon eine Kommastelle, du musst nur bei der
Ausgabe dafür sorgen, daß zwischen erster und zweiter
Ausgabestelle ein Komma eingefügt wird. So wird dann aus 49
auf der Anzeige ein 4,9 und aus 12 wird 1,2. Vorsicht bei
Werten kleiner 10, musst du noch eine künstliche 0 davorstellen.
Denn aus 8 muss ja 0,8 werden.

Eine sehr simple, wenn auch rechenintensive Methode ist
zb. folgendes
1
    ....
2
    adcval *= 50;       // eine Nachkommastelle, daher 50
3
    adcval /= 1023;
4
5
    sprintf( buffer, "%d,%01d", adcval / 10, adcval % 10 );


PS: an deinen Kommentaren musst du noch arbeiten. Ein Kommentar ala

    adcval *= 5;       // mit 5 multiplizieren

ist ein sinnloser Kommentar. Da ist es besser du lässt ihn weg.
Das verwirrt dann wenigstens keinen, wenn du im Code die 5 mal
gegen etwas anderes austauschst und im Kommentar den Update vergisst.
Kommentare sollen nicht das erzählen, was ohnehin im Code bereits
steht. Jeder halbwegs C-mächtige Anfänger kann aus

   adcval *= 5;

in weniger als 2 Zehntelsekunden ablesen, dass hier adcval mit
5 multiplizert wird. Das brauchst du nicht kommentieren. Viel
interesanter ist warum adcval ausgerechnet mit 5 multipliziert
wird! Aber das steht, leider, leider, nicht im Kommentar.

von Marcel (Gast)


Lesenswert?

Hallo,

habe es mit deinem Vorschlag versucht klappt ganz gut ich erhalte aber 2 
Warnungen:

../ipa_2902_v01.c:118: warning: implicit declaration of function 
'sprintf'
../ipa_2902_v01.c:118: warning: incompatible implicit declaration of 
built-in function 'sprintf'

Wie kriege ich die noch weg?

Ausserdem möchte ich gerne noch eine zweite Nachkommastelle, dies habe 
ich versucht es klappt aber nicht:
1
adcval *= 500;                // adcval mit 500 multiplizieren
2
adcval /= 1023;                // adcval durch 1023 dividieren
3
sprintf(adc,"%d,%01d%001d",adcval/10,adcval%10,adcval%1); // Festkommaarithmetik

Bezüglich Komentar gebe ich dir Recht, dies werde ich in einer 
endgültigen Version noch anpassen.

Marcel

von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch die aktuelle Version

von FBI (Gast)


Lesenswert?

Hi,

da fehlt noch ein Headerfile:
1
#include <stdio.h>
Dann sollten auch die Warnungen weg sein.

CU

von Marcel (Gast)


Lesenswert?

Hast Recht FBI, Danke.

von Marcel (Gast)


Lesenswert?

Kennt jemand einen Link bezüglich der sprintf Syntax? Schaffe die 2te 
Nachkommastelle nicht :(

von FBI (Gast)


Lesenswert?

Wie wärs denn mit der avr-libc Doku?
http://www.nongnu.org/avr-libc

Die sollte sich aber eigentlich auch auf Deinem Rechner befinden!

von Marcel (Gast)


Angehängte Dateien:

Lesenswert?

So nun läuft es, jedoch sind noch zwei Fehler zu beheben:

1. Bei 9mV ist die Anzeige noch 0.9V, erst wenn 10 mV erreicht sind wird 
die Stelle geschoben und die Anzeige wechselt auf 0.10V.
Wie kann ich nun noch die zusätzliche 0 erzeugen um 0.09V bei 9mV 
anzuzeigen.
1
uint32_t adcval;               // Variable adcval
2
char adc[20];                  // Variable adc
3
adcval = Sensor(0);            // adcval entspricht Kanal 0
4
adcval *= 500;                 // adcval mit 500 multiplizieren
5
adcval /= 1023;                // adcval durch 1023 dividieren
6
sprintf(adc,"%ld,%0ld",adcval/100,adcval%100); // Festkommaarithmetik

2. Die Angezeigte Spannung stimmt nicht mit der realen Spannung überein 
bei 4.3V werden bereits 5V angezeigt also 0.7V Offset je niedriger die 
Spannung desto kleiner der Offset. Die Rechnung (ADC*500)/1023 stimmt 
doch?

von Marcel (Gast)


Lesenswert?

Wenn ich:
1
adcval *= 500;                 // adcval mit 500 multiplizieren
2
adcval /= 1023;                // adcval durch 1023 dividieren
in
1
adcval *= 432;                 // adcval mit 500 multiplizieren
2
adcval /= 1023;                // adcval durch 1023 dividieren

ändere so stimmen die Messwerte zwar duchs Band weg jedoch ist dann der 
Maximale Messwert natürlich bei 4.32V.

Gibt es noch einen Anderen Weg das anzugleichen?

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:
> So nun läuft es, jedoch sind noch zwei Fehler zu beheben:
>
> 1. Bei 9mV ist die Anzeige noch 0.9V, erst wenn 10 mV erreicht sind wird
> die Stelle geschoben und die Anzeige wechselt auf 0.10V.
> Wie kann ich nun noch die zusätzliche 0 erzeugen um 0.09V bei 9mV
> anzuzeigen.

Du hast die Doku zu sprintf (und Konsorten) immer noch nicht
gelesen. Sonst wüsstest du, dass du das mit dem Format String
hinbügeln kannst.

  sprintf( adc, "%ld,%02ld", ....
                      ^^
                      ||
                      |+--  Diese 2 bedeutet, dass die Ausgabe in
                      |     einem Feld der Breite 2 Zeichen gemacht
                      |     werden soll. 10 würde als als "10"
                      |     ausgegeben, wohingegen 9 als " 9" ausgegeben
                      |     wird
                      |
                      +---  Diese 0 bedeutet, dass führende Leerzeichen
                            in der Ausgabe, wie sie zb. bei " 9"
                            auftreten würden, durch 0 ersetzt werden.
                            eine Ausgabe von 9 würde also als "09"
                            ausgegeben.

Summa, summarum wird also dein 'Nachkommaanteil' in einem Feld
der Breite 2 ausgegeben, wobei führende Leerzeichen als '0'
ausgegeben werden.

wenn dein Wert also 209 ist, dann liefert 209/100 -> 2
und 209%100 -> 9

Zuerst werden die 2 ausgegeben, dann das ',' und dann die 9, wobei
die 9 als "09" ausgegeben werden. In Summe steht also dort "2,09"

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:

> 2. Die Angezeigte Spannung stimmt nicht mit der realen Spannung überein
> bei 4.3V werden bereits 5V angezeigt also 0.7V Offset je niedriger die
> Spannung desto kleiner der Offset. Die Rechnung (ADC*500)/1023 stimmt
> doch?

Miss mal deine Referenzspannung am Pin ARef nach.

von Shin (Gast)


Lesenswert?

Habe jetzt noch eine dritte Nachkommastelle hinzugefügt und zusätzlich 
die Breite festgelegt.
1
adcval *= 4320;                 // adcval mit 4320 multiplizieren
2
adcval /= 1023;                // adcval durch 1023 dividieren
3
sprintf(adc,"%ld,%3ld",adcval/1000,adcval%1000); // Festkommaarithmetik

Jetzt erhalte ich als Anzeige z.B 1.  2V oder 1. 23V. Das ist schonmal 
besser da alle Stellen fixiert sind jedoch wäre es schön wenn man nun 
noch die Leerschläge duch Nullen ersetzen kann.

Das zweite Problem mit den 4.32V konnte ich bisher auch noch nicht 
lösen.

von Marcel (Gast)


Lesenswert?

Ah, die eine Null hat noch gefehlt, danke.

An ARef habe ich derzeit 0V da ich noch mit AVCC als Referenz arbeite. 
Diese Spannung hat etwas Brumm aber nicht so stark das es einen solchen 
Offset gibt. Am Montag erhalte ich noch eine Referenzspannung welche ich 
dann an ARev anschliesse.

Mein Kollege das Problem liege ev. beim Datenbereich, also das die Zahl 
zu gross wird. Was meinst du?

von Karl H. (kbuchegg)


Lesenswert?

Marcel wrote:
> Ah, die eine Null hat noch gefehlt, danke.
>
> An ARef habe ich derzeit 0V da ich noch mit AVCC als Referenz arbeite.

Das macht nichts.
Wenn du AVcc als Referenz gewählt hast, wird diese Spannung an ARef
ausgegeben. Als Minimalbeschaltung sollte dann ein Kondensator
von ARef nach Masse geschaltet werden. So um die 100nF

> Mein Kollege das Problem liege ev. beim Datenbereich, also das die Zahl
> zu gross wird. Was meinst du?

Hab ich nicht kontrolliert. Aber rechne doch einfach mal nach.
Nimm einen Taschenrechner und vollzieh die Berechnung nach. Wenn
irgendwann auf deinem Taschenrechner eine Zahl größer als 32767
auftaucht, dann hast du ein Problem.

Sehe gerade beim Zurückscrollen:
Dein adcval ist ein uint32_t. Daher: Vergiss das mit den 32767.
Die Grenze liegt wesentlich höher und ist so sicher nicht zu
erreichen.
Ich bleibe dabei: Halte mal ein Voltmeter an den Pin ARef.
(Oszi wäre besser)

von Marcel (Gast)


Lesenswert?

Hallo, ja Kondensator ist drin. Nachgerechnet haben wir vorhin auch, 
kein Problem.

Hast Recht, sowohl an ARev wie auch an AVCC messe ich mit Scope bloss 
4.4-4.5V, merkwürdig. Als Speisung habe ich einen AC/DC Wandler von 
Traco mit 5V/3A also daran dürfte es nicht liegen.

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.