Forum: Mikrocontroller und Digitale Elektronik Umgerechnet 16-Bit-ADC-Wert auf dem LCD


von Max O. (maxotto1)


Lesenswert?

Hallo alle,
ch arbeite mit PSoC 5LP. Ich möchte 16-Bit-ADC-Wert auf LCD in Volt 
Format anzuzeigen. ADC-Eingangsbereich ist 0,0 bis Vref so das LCD zeigt 
(0,1, 0,2, 0,3 ... 1.024V) an. Oder in einer anderen verständlichen 
Format. Ich habe versucht, leider habe ich die umgesetzte Wert nicht 
verstanden.

Biite finden Sie den Code, den ich versucht habe.
1
int main()
2
{
3
  
4
    uint16 ADC_Ans;
5
  //uint8 ADC_Ans8;
6
  
7
  Sys_Init(); // System Initializing
8
  CY_SET_REG8(CYREG_MLOGIC_DEBUG, CY_GET_REG8(CYREG_MLOGIC_DEBUG) | 0x40);
9
  
10
  ADC_DelSig_Start();
11
  ADC_DelSig_StartConvert();
12
  
13
    // CyGlobalIntEnable; // Enable global interrupts. 
14
    while(1)
15
    {
16
         LCD_ClearDisplay() ;
17
         LCD_PrintString("ADC Value:"); 
18
         CyDelay(1500); // Delay in ms 
19
    
20
        ADC_DelSig_IsEndConversion(ADC_DelSig_WAIT_FOR_RESULT); 
21
        ADC_Ans = ADC_DelSig_GetResult16();
22
       //ADC_DelSig_StopConvert();        
23
      
24
       //ADC_Ans8 = ADC_Ans >> 8;
25
         LCD_Position(0,10);
26
        LCD_PrintString("0x"); 
27
        
28
        LCD_Position(0,12);
29
        LCD_PrintHexUint8(ADC_Ans);
30
       //LCD_PrintInt8(ADC_Ans);  
31
       CyDelay(1500); // Delay in ms 
32
    }
33
}

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Max Otto schrieb:
> Hallo alle,
> ch arbeite mit PSoC 5LP. Ich möchte 16-Bit-ADC-Wert auf LCD in Volt
> Format anzuzeigen. ADC-Eingangsbereich ist 0,0 bis Vref so das LCD zeigt
> (0,1, 0,2, 0,3 ... 1.024V) an. Oder in einer anderen verständlichen
> Format. Ich habe versucht, leider habe ich die umgesetzte Wert nicht
> verstanden.

Dann musst du noch mal zurck auf die Schulbank. Ungefähr 7. Klasse 
Mittelschule und den viel gerühmten Dreisatz wiederholen.

1024 Äpfel kosten 5 Euro.
Wieviel kosten 234 Äpfel?

Lösung:
1
    1024    .....    5
2
     234    .....    x
3
   --------------------
4
           234 * 5
5
      x = -----------  =  1.14
6
             1024

234 Äpfel kosten also 1.14 Euros.


Jetzt hast du nicht Äpfel sondern Werte vom ADC und die kosten auch 
nicht 5 Euro, sondern wenn der ADC seinen Maximalwert liefert, dann 
entspricht das einer gemessenen Spannung die mit der Referenzspannung 
übereinstimmt.
1
    1024  ............   Spannung VRef
2
   Wert vom ADC ......   Spannung x
3
  --------------------------------------
4
          Wert vom ADC * VRef
5
    x = ----------------------
6
              1024

Den 3-Satz (früher hat man Schlussrechnung dazu gesagt) sollte man 
wirklich können. Das meiste, was dir im Alltag begegnet berechnet sich 
mit diesem Muster.
Und nein. Ein 'in Mathe war ich immer schlecht' lass ich nicht gelten. 
Wie willst du denn ohne ihn ausrechnen, bei welchem Handi-Provider die 
SMS billiger ist?

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> 234 Äpfel kosten also 1.14 Euros.
Du bist nahe an der Wahrheit, aber: die Äpfel kosten mehr, nur der 
Erzeuger bekommt gerade mal in etwa diesen Preis. Der Grund: zu viele 
Äpfel, weil Russland mit einer "Obstsperre" auf unseren Boykott 
reagiert...
Jetzt höre ich auf, sonst muss ich meinen Post löschen!

Max Otto schrieb:
> Biite finden Sie den Code, den ich versucht habe.
Du hast da nichts "versucht", sondern nur "zusammenkopiert". 
"Progammieren" kommt nicht von "Kopieren", auch wenn beide Worte mit 
"ieren" aufhören...

> Biite finden Sie den Code, den ich versucht habe.
Geh doch einfach mal analytisch vor:
Was hast du da versucht?
Und was hast du damit erhalten?
Und was müsstest du jetzt noch machen?

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Max Otto schrieb:
> ADC_Ans = ADC_DelSig_GetResult16();
> LCD_PrintHexUint8(ADC_Ans);

 Und das geht nur bis 255 wenn ich das richtig entziffert habe.
 ich nehme an, dass es so etwas wie:
1
   LCD_PrintHexUint16(ADC_Ans);
 geben muss.

Karl Heinz schrieb:
> 1024 Äpfel kosten 5 Euro.
 Wo gibt's die ?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Marc Vesely schrieb:

>  ich nehme an, dass es so etwas wie:
>
1
>    LCD_PrintHexUint16(ADC_Ans);
2
>
>  geben muss.

Ich würde das Hex auch noch weglassen.
Der TO dürfte nicht deutscher Muttersprache sein, aber zwischen den 
Zeilen kann man schon erkennen, dass er sehr wahrscheinlich mit einer 
Hex-Anzeige überhaupt nichts anfangen kann. Die im kopierten Programm 
auskommentierten Zeilen erzählen da durchaus eine kleine Geschichte.

Im Original steht da
1
        LCD_PrintHexUint8(ADC_Ans);
2
       //LCD_PrintInt8(ADC_Ans);

Das auskommentierte LCD_PintInt8 wäre mein erster Aufhänger. Wenn es ein 
PintInt8 gibt, dann schätze ich mal, dass es auch ein PintInt16 gibt.
Das hilft ihm zwar jetzt noch nichts bei der Umrechnung der Werte, aber 
es wäre zumindest mal ein Ansatz um ...
>  Ich habe versucht, leider habe ich die umgesetzte Wert nicht verstanden.
... etwas zu entschärfen.

@TO
Lothar hat da völlig recht. Einfach planlos irgendwelche Dinge zu 
kopieren und auszukommentieren, reicht nicht. Zumindest muss man das 
Programm schon auch lesen und sich vielleicht auch mal Gedanken darüber 
machen, warum eine Funktion so heisst wie sie heisst.

> Karl Heinz schrieb:
>> 1024 Äpfel kosten 5 Euro.
>  Wo gibt's die ?

Du hast natürlich recht. Es hätte heissen müssen: Der 
Apfelplantagenbesitzer kriegt von der EU für 5 Äpfel eine Förderung von 
1024 Euro. Aber ich wollte dann auch nicht mit zuviel Text verwirren.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Karl Heinz schrieb:
> Du hast natürlich recht. Es hätte heissen müssen: Der

 Schade. Hab schon 40 Euro für 8192 Äpfel beisete gelegt.

von Maxotto1 (Gast)


Lesenswert?

Marc Vesely schrieb:
> Max Otto schrieb:
>> ADC_Ans = ADC_DelSig_GetResult16();
>> LCD_PrintHexUint8(ADC_Ans);
>
>  Und das geht nur bis 255 wenn ich das richtig entziffert habe.
>  ich nehme an, dass es so etwas wie:   LCD_PrintHexUint16(ADC_Ans);
>  geben muss.


Danke, habe Ich es Probiert. Die LCD zeigt CB16, CA7A, BF35, C797, 
B9D1..

Ich glaube diese ist nicht der Richtige Antwort.

von Maxotto1 (Gast)


Lesenswert?

> Max Otto schrieb:
>> Biite finden Sie den Code, den ich versucht habe.
> Du hast da nichts "versucht", sondern nur "zusammenkopiert".
> "Progammieren" kommt nicht von "Kopieren", auch wenn beide Worte mit
> "ieren" aufhören...
>
>> Biite finden Sie den Code, den ich versucht habe.
> Geh doch einfach mal analytisch vor:
> Was hast du da versucht?
> Und was hast du damit erhalten?
> Und was müsstest du jetzt noch machen?

Danke. Ich habe 8-ADC Beispiel Programm genommen & will jetzt 16-Bit ADC 
machen.(Weil die mein Aufgabe ist) In Programm für 8-ADC, 
ADC_DelSig_GetResult16() benutz. Und in ADC Dokumentar stäte für 16-ADC 
soll Man  ADC_DelSig_GetResult32() benutzen.

So ich fange von Anfang an.
Mein Problem Priorität.
1.  Für 16-ADC soll Ich ADC_DelSig_GetResult16()  oder 
ADC_DelSig_GetResult32()  benutzen ? Ich glaube ADC_DelSig_GetResult32() 
oder..

2. Soll Ich die Global Interrupt Aktivieren..? [Mit Konversion Mode- 
Multisample]

3. Ich will ein verständliche anzeige an meine LCD haben. Die 16-Bit ADC 
Antwort entweder in Vortage oder in Hex anzeigen.

Ich warte auf dein Antwort.
Grüße
Max

von Karl H. (kbuchegg)


Lesenswert?

Maxotto1 schrieb:

> Danke. Ich habe 8-ADC Beispiel Programm genommen & will jetzt 16-Bit ADC
> machen.(Weil die mein Aufgabe ist) In Programm für 8-ADC,
> ADC_DelSig_GetResult16() benutz.

Das klingt schon mal vernünftig.

> Und in ADC Dokumentar stäte für 16-ADC
> soll Man  ADC_DelSig_GetResult32() benutzen.

Wenn das dort steht, warum benutzt du dann nicht die FUnktion mit der 32 
im Namen?
Kommt mir zwar komisch vor, dass man für ein 16 Bit Ergebnis eine 
Funktion benutzen soll, die eine 32 im Namen trägt, aber wenn die Doku 
das so sagt, dann wird das schon stimmen.

> Mein Problem Priorität.
> 1.  Für 16-ADC soll Ich ADC_DelSig_GetResult16()  oder
> ADC_DelSig_GetResult32()  benutzen ? Ich glaube ADC_DelSig_GetResult32()
> oder..

Na, wenn es die Doku sagt?

> 2. Soll Ich die Global Interrupt Aktivieren..? [Mit Konversion Mode-
> Multisample]

Wozu?
Was bringt dir das?
Mit Interrupts wird nur alles komplizierter. Steht in der Doku was, das 
du das tun musst? Wenn nein, dann würde ich es auch nicht tun.
Nur weil du das 'BUzzword' Interrupt schon mal gehört hast, heisst das 
nciht, das das die Lösung für alles ist.

> 3. Ich will ein verständliche anzeige an meine LCD haben. Die 16-Bit ADC
> Antwort entweder in Vortage oder in Hex anzeigen.

Ja, dann mach das doch.
Anscheinend kannst du Hex-Zahlen nicht lesen. Gut. Dann lass dir halt 
das Ergebnis nicht als Hex-Zahl ausgeben, sondern als ganz normale 
Dezimalzahl.

Welche Funktionen hast du denn, die Dezimalzahlen ausgeben können.
Scheinbar gibt es ja eine Funktion LCD_PrintInt8(). Wenn die Library 
auch nur ein bischen was taugt, dann gibt es auch eine Funktion 
LCD_PrintInt16() und eine Funktion LCD_PrintInt32()

Die Zahl korrespondiert dann direkt mit dem Datentyp der Variablen, in 
der das Ergebnis steht und die ausgegeben werden soll.
Machs doch nicht so kompliziert. So schwer ist das nicht
1
  int32  ADC_Ans
2
3
...
4
5
6
     ADC_Ans = ADC_DelSig_GetResult32();
7
8
...
9
10
     LCD_PrintInt32( ADC_Ans );

Das sind 3 Dinge, die von den Datentypen her zusammenstimmen sollen. Die 
Variable ist 32 Bit (erkennbar an der 32 im Datentypnamen), die Funktion 
liefert ein 32 Bit Ergebnis (erkennbar an der 32 im Namen) und die 
Anzeigefunktion kann eine 32 Bit Zahl ausgeben (wieder erkennbar an der 
32 im Namen).
Wo sind da jetzt die Höhepunkte? Einfach ein bisschen mitdenken.

Edit:
Bei nochmaliger Überlegung ist das gar nicht mehr so komisch, mit der 
32. Wenn die Funktionen immer mit signed Ergebnissen arbeiten, dann muss 
das so sein.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Siehe Festkommaarithmetik, ist im Moment sogar der Artikel der Woche 
;-)

von Maxotto1 (Gast)


Lesenswert?

Karl Heinz schrieb:
> int32  ADC_Ans
>
> ...
>
>      ADC_Ans = ADC_DelSig_GetResult32();
>
> ...
>
>      LCD_PrintInt32( ADC_Ans );

Danke. Ich wollte dir gerade schreiben dass ich diese genau probiert 
habe.
Leider LCD zeigt 0000 für alle werte. Ich habe genau verstanden was Du 
mir erklärt habe. Nicht so kompliziert machen bissen mitdenken.
Tut mir leid für meine vorherige Betrage.

Sagst Du mir jetzt Warum mein Programm nicht funktioniert weil Ich die 
gleich geschrieben habe?

von Karl H. (kbuchegg)


Lesenswert?

Maxotto1 schrieb:

> Danke. Ich wollte dir gerade schreiben dass ich diese genau probiert
> habe.

Na, dann zeig das doch mal, was du probiert hast.

> Sagst Du mir jetzt Warum mein Programm nicht funktioniert weil Ich die
> gleich geschrieben habe?

Ich weiss ja nicht, was du da alles an die Stellen reingeschrieben hast, 
die ich mit lapidaren Punkte markiert habe.

von PittyJ (Gast)


Lesenswert?

Wenn ich das hier richtige verstehe, dann gibt es eine Firma 'eletrobit 
automotive'. Deren Programmierer hat Probleme mit dem Dreisatz und kennt 
auch keine Hex-Zahlen.

Für welche Automarke programmiert diese Firma? Damit ich solche Autos in 
Zukunft meiden kann.

von Maxotto1 (Gast)


Lesenswert?

Maxotto1 schrieb:
> Karl Heinz schrieb:
>> int32  ADC_Ans
>>
>> ...
>>
>>      ADC_Ans = ADC_DelSig_GetResult32();
>>
>> ...
>>
>>      LCD_PrintInt32( ADC_Ans );
>
> Danke. Ich wollte dir gerade schreiben dass ich diese genau probiert
> habe für 16-bit. So

uint16  ADC_Ans;

ADC_Ans = ADC_DelSig_GetResult16();

LCD_PrintDecUint16(ADC_Ans);

> Ich habe der genau Analog Eingang zu mein Programm gegeben. Für 0,505v das LCD 
zeigt 34056,34057,34042... Und es ist falsch. Mein Projekt Leiter hat gesagt soll 
es 50555, 49050,50515..sein [Bissen Toleranz]

Kannst Du mir bitte weiter helfen?

von Karl H. (kbuchegg)


Lesenswert?

Maxotto1 schrieb:

>> Danke. Ich wollte dir gerade schreiben dass ich diese genau probiert
>> habe für 16-bit. So
>
> uint16  ADC_Ans;
>
> ADC_Ans = ADC_DelSig_GetResult16();
>
> LCD_PrintDecUint16(ADC_Ans);

Schön.

Welchen Teil von "Zeig dein ganzes Programm" hast du nicht verstanden?

> Kannst Du mir bitte weiter helfen?

Das wird schwierig, weil dir ganz einfach eine Menge fehlt. Und zwar von 
den allereinfachsten Sachen, so wie sich das hier im Thread präsentiert.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Maxotto1 schrieb:
>
>>> Danke. Ich wollte dir gerade schreiben dass ich diese genau probiert
>>> habe für 16-bit. So
>>
>> uint16  ADC_Ans;
>>
>> ADC_Ans = ADC_DelSig_GetResult16();
>>
>> LCD_PrintDecUint16(ADC_Ans);
>
> Schön.
>
> Welchen Teil von "Zeig dein ganzes Programm" hast du nicht verstanden?

Abgesehen davon.

Welchen Teil von "32 statt 16" hast du nicht verstanden?

von foo (Gast)


Lesenswert?

Marc Vesely schrieb:
> Karl Heinz schrieb:
>> 1024 Äpfel kosten 5 Euro.
>  Wo gibt's die ?

Gar nicht, weil es nämlich nur 1023 Äpfel sind.

von Maxotto1 (Gast)


Lesenswert?

Hallo Karl danke. nur eine Frage.

Ich habe für 16-bit ADC Single Sample mit Input Range Vssa to 1.024v.

  uint16  ADC_Ans;

  ADC_Ans = ADC_DelSig_GetResult16();

  LCD_PrintDecUint16(ADC_Ans);

Ich habe von oberen Programm alles verstanden.

Ich habe Input 0,5v gegeben. Das LCD zeigt 34044 oder 34048. Ist diese 
Antwort Richtig? Weil mein Projekt Leiter sagt dass das LCD soll 48000, 
49000 oder 50000 zeigen.

Bitte hilf mir dafür.

von Falk B. (falk)


Lesenswert?

@ Maxotto1 (Gast)

>Ich habe für 16-bit ADC Single Sample mit Input Range Vssa to 1.024v.

>  uint16  ADC_Ans;

>  ADC_Ans = ADC_DelSig_GetResult16();

>  LCD_PrintDecUint16(ADC_Ans);

>Ich habe von oberen Programm alles verstanden.

Das ist eine schöne Illusion ;-)
Verstanden hast du es, wenn dein Programm solide läuft und JEDEN Schritt 
exakt erklären kannst.

>Ich habe Input 0,5v gegeben. Das LCD zeigt 34044 oder 34048. Ist diese
>Antwort Richtig? Weil mein Projekt Leiter sagt dass das LCD soll 48000,
>49000 oder 50000 zeigen.

1,024V / 0,5 V = 2^16 / X

Ob er DAS umstellen kann?

von Karl H. (kbuchegg)


Lesenswert?

Wie wärs mit ein bischen rechnen? Muss nicht genau sein, einfach nur im 
Kopf überschlagen.

Wenn ich dich richtig verstanden habe, dann ist die Referenzspannung bei 
1.024V. D.h. in diesem Bereich kann sich die zu messende Spannung 
bewegen und wenn die zu messende Spannung 1.024V beträgt, dann liefert 
der ADC den Maximalwert.

0.5V ist ein bischen weniger als die Hälfte dieser 1.024V. D.h. es ist 
zu erwarten, dass der ADC dann auch ein bischen weniger als die Hälfte 
des Maximalwertes ausgibt.
Welches ist der Maximalwert? Welches ist die größte Zahl, die man mit 16 
Bit (unsigned) darstellen kann? Das ist 65535. ((2 hoch 16) - 1)
D.h. es ist zu erwarten, dass der ADC etwas weniger als die Hälfte von 
65535 ausgibt. Das sind ca. 32000

D.h. mit deinen 34000 ziemlich gut im Rennen, wohingegen knapp 50000 
weit ab von Schuss ist.

Wenn die Referenzspannung 1.024V beträgt! Und ob die exakt 1.024V 
beträgt (vor allen Dingen die Hunderstel bzw. Tausendstel wage ich mal 
zu bezweifeln), musst du wissen.


So ein ADC ist doch kein Hexenwerk!
Der vergleicht einfach nur die zu messende Spannung mit der 
Referenzspannung. Das Ergebnis kriegst du als eine art 'Prozent'.Es ist 
einfach nur eine Verhältniszahl. Die zu messende Spannung steht zur 
Referenzspannung des ADC im gleichen Verhältnis, wie der vom ADC 
gelieferte Wert zum Maximalwert.  Mehr steckt doch da nicht dahinter. 
Das ist doch keine Raketentechnik.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:

>
> 1,024V / 0,5 V = 2^16 / X
>
> Ob er DAS umstellen kann?

Ich hab die Hoffnung aufgegeben.
Der doktert jetzt schon 5 Tage an einem simplen ADC Beispiel rum, das er 
schon fix&fertig vorliegen hatte und lediglich von 8 Bit auf 16 Bit hoch 
bringen sollte. Eine Sache auf ein paar Minuten, selbst wenn man noch 
nie mit diesem PSoC gearbeitet hat.

von Karl H. (kbuchegg)


Lesenswert?

> Weil mein Projekt Leiter sagt dass das LCD soll 48000, >49000 oder 50000 zeigen.

Das mag schon sein, dass das LCD das in letzter Konsequenz irgendwann 
mal anzeigen soll. Wenn man dann endlich mal soweit ist und den nächsten 
Schritt macht, nämlich den Wert vom ADC (der ja immer noch eine 
Verhältniszahl ist) in eine Spannungsangabe umrechnet und anstelle von 
0.5 dann eben 50000 am Display stehen hat, was ja weiter nicht schlimm 
ist, weil ja nur der Dezimalpunkt ein paar Stellen verschoben wurde.
Aber dazu müsste man eben, welch ein Graus, dann auch mal etwas rechnen 
lassen und nicht nur den ADC Wert auf die Anzeige klatschen (obwohl ja 
auch das schon eine Leistung ist - nach 4 Tagen)

: Bearbeitet durch User
von Maxotto1 (Gast)


Lesenswert?

Herzlichen Dank Karl.
Ich habe es geschafft. Mein Programm funktioniert richtig.

1000 mal Danke.

von Max O. (maxotto1)


Lesenswert?

Es ist kurz Änderung an meine Input. Jetzt habe Ich der Input range von 
Vssa To Vdda. So 0,0v bis 3,3. Für Input 3,3v mein LCD zeigt 0004. Ich 
glaube es nimmt automatisch 4,9v. Ich habe in ADC-Design Input range 
"Vssa to Vdda" ausgewählt. Aber soll Ich auch in Programm für maximal 
Input 3,3 schreiben. Aber was..??

Grüße
Max

von Joachim B. (jar)


Lesenswert?

Max Otto schrieb:
> Es ist kurz Änderung an meine Input.

gibts den Text auch in deutsch ?

von Falk B. (falk)


Lesenswert?

@ Max Otto (Firma: Eletrobit Automotive) (maxotto1)

Deine Muttersprache ist anscheinens nicht Deutsch. Der Text klingt wie 
aus einem automatischen Übersetzter. Grauenhaft und kaum verständlich. 
Schreib auf Englisch, wenn du das besser beherrschst. Vielleicht aber 
doch in deiner Muttersprach, vielleicht spricht die jemand hier. Welche 
ist das?

von Max O. (maxotto1)


Lesenswert?

Es ist funktioniert.
Das Programm läuft richtig.

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.