10 Bit ADC Wert als Zahl formatieren und auf Display ausgeben
Montag, 21. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  CCS Compiler  |  AD-Wandler (CCS)  |  10 Bit ADC Wert als Zahl formatieren und auf Display ausgeben « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: 10 Bit ADC Wert als Zahl formatieren und auf Display ausgeben  (Gelesen 4481 mal)
 
SHOOTER
Full Member
***
Offline Offline

Beiträge: 103



Profil anzeigen WWW
« am: März 05, 2006, 17:27:34 »

Hallo

Ich möchte gerne mit einem PIC Spannungsmessungen vornehmen und sie anschließend auf dem LCD ausgeben.
Bei folgendem Code kommen immo nur Hyroglyphen  8-)

Code: (c)
int16 wert;

void main()
{

   port_b_pullups(TRUE);
   setup_adc_ports(sAN0|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   setup_timer_2(T2_DIV_BY_16,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_8MHZ|OSC_INTRC);

   delay_ms(500);
   output_high(PIN_B1);
   delay_ms(250);
   output_low(PIN_B1);
   delay_ms(500);

   lcd_init();
   output_high(PIN_B1);
   delay_ms(100);

   lcd_putc("-> Display ready");

   delay_ms(1000);
   lcd_putc('\f');



while (1) {
   set_adc_channel(0);
   delay_ms(500);
   wert=read_adc();

   printf("Spannung: %u" ,wert);

}
}

Der Befehl (printf("Volt: %u" ,wert)Zwinkernd ganz unten bringt bei mri einen Fehler.

Wie kann ich das Ergebniss des ADC auf dem LCD ausgeben und zwar als Zahlenwert, z.B. 2,789 V?

mfg
Benny
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: März 05, 2006, 17:49:19 »

1)
Funktioniert das LCD denn mittlerweile korrekt?

2)
"wert" ist eine 16-Bit Variable, das dafür nötige Formatzeichen ist "lu":

Code:
printf("Spannung: %lu", wert);

Wenn Du die Ausgabe auf das LCD umleiten willst, mußt Du die nötige Funktion dafür in printf angeben:

Code:
printf(lcd_putc, "Spannung: %lu", wert);

3)
read_adc() liefert nur dann einen 10-Bit Wert, wenn Du

Code:
#device ADC=10

verwendest.

4)
Bei 10-Bit Auflösung und 5V Versorgungsspannung gilt der Zusammenhang:

Code:
U = (AD_wert / 1024) * 5V


Viele Grüße

Bernd
Gespeichert

SHOOTER
Full Member
***
Offline Offline

Beiträge: 103



Profil anzeigen WWW
« Antworten #2 am: März 05, 2006, 22:25:18 »

Hi Bernd

1. Ja es funktioniert mein Fehler war das ich vergessen hatte den Internen OSC in CCS einzuschalten.  Augen rollen

2. Vielen Dank das war die Lösung!

3. Hatte ich schon gemacht

4. OK das ist dann mein nächster Schritt in der Entwicklung den AD-Wert in eine Spannung umzurechnen!

EDIT: Welche Variablentyp muss ich bei 4. für U nehmen? Integer geht ja nun nichtmehr ist ja nicht immer eine Ganzzahl!
EDIT2: Müsste die Formel nicht U = ( (AD-Wert+1) / 1024) * 5 ) heißen, da AD-Wert zwischen 0 und 1023 liegt?

mfg
Benny
« Letzte Änderung: März 06, 2006, 17:10:16 von SHOOTER » Gespeichert
SHOOTER
Full Member
***
Offline Offline

Beiträge: 103



Profil anzeigen WWW
« Antworten #3 am: März 06, 2006, 20:00:13 »

Mal ein Update wies grad bei mir steht.

Im Moment sieht mein Code folgendermaßen aus:
Code: (c)
int16 wert;
float Spannung, Spannung2;
Code: (c)
while (1) {
   lcd_putc('\f');
   set_adc_channel(0);
   delay_ms(5);
   wert=read_adc();

   Spannung = (wert + 1) / 1024;
   Spannung2 = wert * 5.06;

   lcd_gotoxy(1,1);
   printf(lcd_putc, "Wert: %lu", wert);       // AD-Wert 0-1023
   
   lcd_gotoxy(1,2);
   printf(lcd_putc, "Spg: %f", Spannung);      // (AD-Wert+1) / 1024
   
   lcd_gotoxy(1,3);
   printf(lcd_putc, "Spg2: %f", Spannung2)      // Spannung in Volt;
   delay_ms(1000);

}
Mein Problem: Ab der zweiten Zeile (ab Spg: ... auf dem LCD) bekomme ich nur Schrott.
Es wird dauern 0.0000... Ausgegeben es sei denn mein AD-Wert ist 1023 dann kommt 1.0000...
Unten bei Spg2: kommt lauter Müll raus also z.B. -72... oder dann wenn ich den AD-Wert um eins ändere ist es auf eineml +.... .

Ich tipp ja ma stark drauf das ich den falschen Datentyp benutzt habe. Aber welcher kann es sonst noch sein außer float?

Ich bitte um Hilfe.  :smile:

mfg
Benny
Gespeichert
Sandynister
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 557



Profil anzeigen WWW
« Antworten #4 am: März 06, 2006, 20:23:49 »

Das Problem wird diese Zeile sein:
Code: (c)
Spannung = (wert + 1) / 1024;
Du musst casten
Code: (c)
Spannung = ((float)wert + 1.) / 1024.0;

Ein Wert würde auch schon genügen.

In diesem Sinne
Gespeichert

Das beste und lauteste Hobby der Welt unter http://normu.net ;-)
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #5 am: März 06, 2006, 20:33:08 »

@Shooter

Der CCS hat je nach Version enorme Probleme im Zusammenhang mit float und printf:

http://www.ccsinfo.com/forum/viewtopic.php?t=24052
http://www.ccsinfo.com/forum/viewtopic.php?t=24522
http://www.ccsinfo.com/forum/viewtopic.php?t=24469

Das könnte für den falschen Wert von "Spannung2" verantwortlich sein.


Viele Grüße

Bernd
Gespeichert

Sandynister
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 557



Profil anzeigen WWW
« Antworten #6 am: März 06, 2006, 21:00:39 »

@Bernd

Das ändert doch aber nichts an der Cast-Problematik - oder verhält sich der CCS da auch unerwartet?
Gespeichert

Das beste und lauteste Hobby der Welt unter http://normu.net ;-)
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #7 am: März 06, 2006, 21:12:25 »

@Sandynister

Zitat
Das ändert doch aber nichts an der Cast-Problematik

Nein, überhaupt nicht. Da Du bereits auf diesen Fehler im Code hingewiesen hast, habe ich ihn nicht mehr erwähnt. Ich wollte nur noch mal auf ein generelles Problem des CCS hinweisen.

Code: (c)
Spannung2 = wert * 5.06;

muß eigentlich funktionieren (gemäß ANSI C). Es kann aber sein, daß der CCS auch hier eine Cast von "wert" nach float benötigt. Die Vermischung von negativen und positiven Werten deutete für mich aber eher auf die in den verlinkten Threads beschriebenen Probleme hin.


Viele Grüße

Bernd
Gespeichert

SHOOTER
Full Member
***
Offline Offline

Beiträge: 103



Profil anzeigen WWW
« Antworten #8 am: März 06, 2006, 21:13:56 »

Hallo

Erstmal danke!

Noch ne Frage was bedeutet casten bzw. die Cast-Problematik?

Dann hat ich noch nen Fehler in meinem Code den ich aber nun behoben hab und auch das von Sandynister noch eingefügt habe. Jetzt gehts!
Aber was mir aufgefallen ist nachdem ich den Code vom Sandynister benutzt habe ist mein ROM Speicherplatz von 30% auf 44% angestiegen. Ganz schön heftig, wovon kommt denn dieser Anstieg?

Code: (c)
while (1) {
   lcd_putc('\f');
   set_adc_channel(0);
   delay_ms(5);
   wert=read_adc();

   //Spannung = (wert + 1) / 1024;
   Spannung = ((float)wert + 1.) / 1024.0;     // Danach steigt der PLatzbedarf auf 44%
   Spannung2 = Spannung * 5.06;    // Hier war noch ein Fehler!

   lcd_gotoxy(1,1);
   printf(lcd_putc, "Wert: %lu", wert);
   
   lcd_gotoxy(1,2);
   printf(lcd_putc, "Spg: %f", Spannung);
   
   lcd_gotoxy(1,3);
   printf(lcd_putc, "Spg2: %f", Spannung2);
   delay_ms(1000);
//   lcd_putc(" V");

}

Danke nochmal!

mfg
Benny
« Letzte Änderung: März 06, 2006, 21:19:38 von SHOOTER » Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #9 am: März 06, 2006, 21:46:04 »

Zitat
Noch ne Frage was bedeutet casten bzw. die Cast-Problematik?

In dem Ausdruck

Code: (c)
Spannung = (wert + 1) / 1024;

sind alle Werte rechts von Gleichheitszeichen vom Typ Integer (also ganzzahlig). Damit wird die Berechnung des Ergebnisses auch in Integer (ohne Nachkommastellen) durchgeführt. Für wert < 1023 ist das Ergebnis immer "0" , für wert = 1023 ist das Ergebnis "1". Dieses Integer-Ergebnis wird durch die Zuweisung an die float-Variable "Spannung" in einen float-Wert umgewandelt, was aber am Ergebnis nichts mehr ändert.

Um die Berechnung in float zu "erzwingen", muß (nach ANSI-C) mindestens ein Wert auf der rechten Seite des Gleichheitszeichens vom Typ float sein. Das kann durch einen Cast erreicht werden,

Code:
(float)wert

der die Integer-Variable "wert" in eine float-Variable "umwandelt". Bei Konstanten ergibt sich der Typ "float" aus der Tatsache, daß sie über einen Dezimalpunkt verfügen (z.B. 1.0).

Zitat
nachdem ich den code vom Sandynister benutzt habe ist mein ROM Speicherplatz von 30% auf 44% angestiegen. ganz schön heftig, wovon kommt denn dieser Anstieg?

Die PICs sind für Rechenoperationen mit float-Variablen nicht sonderlich geeignet. Daher wird für die Berechnung solcher Werte viel Zeit und Programmspeicher benötigt. Man kann das umgehen, indem man "geschicktere" Berechnungsmöglichkeiten wählt, welche die Verwendung von float vermeiden.

Du könntest z.B. schreiben:

Code: (c)
int32 spannung;
wert+=1;
spannung = ( ((int32)wert * 5000) / 1024 );

Für wert = 1023 wäre das Ergebnis dann 5000, was als Spannung von 5.000V interpretiert werden kann. Die letzten drei Dezimalziffern repräsentieren also die Nachkommastellen.

Nur aus Neugier:

Funktioniert

Code: (c)
Spannung2 = wert * 5.06;
// bzw.
Spannung2 = (float)wert * 5.06;

bei Dir? Natürlich ist das Ergebnis um den Faktor 1024 zu groß, aber negative Werte dürfen trotzdem nicht auftreten.


Viele Grüße

Bernd
Gespeichert

SHOOTER
Full Member
***
Offline Offline

Beiträge: 103



Profil anzeigen WWW
« Antworten #10 am: März 07, 2006, 16:38:14 »

Hi

Also der Code
Code:
Spannung2 = wert * 5,06
ist falsch gewesen von mir. Richtig ist
Code:
Spannung2 = Spannung * 5.06

Danke für die super Erklärung!

Ich hab jetzt folgenden Code verwendet:
Code: (c)
Spannung = ((float)wert + 1.) / 1024.0;
Spannung2 = wert * 5.06;

lcd_gotoxy(1,1);
printf(lcd_putc, "Wert: %lu", wert);

cd_gotoxy(1,2);
printf(lcd_putc, "Spg: %f", Spannung);

lcd_gotoxy(1,3);
printf(lcd_putc, "Spg2: %f", Spannung2);
Hier bekomm ich ab den AD-Wert 849 ein positives Ergebnis alles drunter ist negativ.

mfg
Benny
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #11 am: März 07, 2006, 18:34:08 »

Zitat
Hier bekomm ich ab den AD-Wert 849 ein positives Ergebnis alles drunter ist negativ.

Das könnte dann der von mir verlinkte Bug sein. Um ganz sicher zu gehen: Kannst Du es noch mal mit dem Cast ausprobieren:

Code:
Spannung2 = (float)wert * 5.06;



Viele Grüße

Bernd
Gespeichert

Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.047 Sekunden mit 19 Zugriffen.
 
Top! Top!