Forum: Mikrocontroller und Digitale Elektronik AD- Wandler ATMEGA32 in C


von Matthias (DC2RLM) (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

erstmal danke fürs lesen.
Ich bin gerade dabei, mir die ersten Dinge in Sachen AVRs anzueignen, 
und experimentiere hier mit einem STK 500, einem ATMEGA 32, dem AVR- 
Studio 4.13 inkl. GCC und euren Tutorials rum.

Im großen und ganzen komm ich glaub ich ganz gut zurecht- der C- Gott 
bin ich nicht, hab halt ein Praktikum in C an der FH hinter mir, aber 
bisher hab ich das was ich wollte auch zum Laufen gekriegt (gut, ohne 
die Hilfe dieser Seite hätts nicht so schnell und reibungslos geklappt 
;)).

Aktuell steck ich aber fest, und weiss nicht recht weiter:
Meine Idee ist, mit dem ADC des M32, einem "Messwandler" (den ich mir 
hier geklaut habe: 
http://www.umnicom.de/Elektronik/Sonstiges/Messtechnik/tmKap2/tmKap223/tmKap223.html) 
und einem PT- 100 eine Temperatur zu messen und auf dem LCD auszugeben.
Anstelle des PT-100 habe ich einen "PT- 100- Simulator" an den 
Messwandler angeschlossen, dessen Widerstandswerte für die Temperaturen 
1°, 20°, 55°, 72°, 103°... usw. den Werten eines "echten" PT100 
entsprechen, ich bekomme also für einen Bereich von 0- 400°C 
Spannungswerte zwischen 0 und 5 Volt an den ADC0- Eingang des µC (AREF = 
VCC = 5V).
Diese wandle ich mit itoa in einen Char um, und gebe sie auf dem LCD 
aus.
Und da stimmt irgendwas nicht, wie man der folgenden "Tabelle" entnehmen 
kann:

Temp.:     U an ADC0:     Wert im LCD:
1°         0.95 V         1903
20°        0.14 V         2643
55°        0.61 V         1263
72°        0.84 V         1743
103°       1.25 V         2603
125°       1.54 V         3213
.             .            .
.             .            .
.             .            .
409°       5.39           1023

Seltsam finde ich hier zwei Dinge:
1. die "3" am Ende JEDES Wertes (auch bei den nicht angeg. Temperaturen)
2. Die Werte an sich, die ja zwischen 0...255 liegen sollten...

Den Code aus dem GCC Tutorial habe ich weitestgehend übernommen, 
lediglich den ADC- Vorteiler auf 128 angepasst (Freq. am M32: 16 MHz -> 
Freq. für ADC 125kHz), sowie die LCD- Sachen hinzugefügt, siehe Anhang.

Ich habe die Vermutung, dass ich beim ADC noch irgendeinen Bock drin 
habe, seh ihn aber nicht- vielleicht kann mir jemand von euch nen Tipp 
geben, wo ich ansetzen könnte, bzw. ob ich irgendwas anderes 
grundsätzliches falsch habe...

Grüße aus Regensburg,
Matthias

von gast (Gast)


Lesenswert?

naja, du überscreibst auf dem lcd anshceinend immer wieder die alten 
werte
also wenn als erstes 1003 kommt und danach 900, steht bei dir 9003, da 
nur die ersten 3 zeichen überschrieben werden, also erst einmal ein 
clear vor jedem schreiben

deine zahlen sollten aber trotzdem zwischen 0 und 1023 liegen

von Johannes M. (johnny-m)


Lesenswert?

Naja, Du gibst offensichtlich die Werte linksbündig aus und löschst die 
Display-Stellen nicht vor dem nächsten Schreibvorgang. Die 3 hinten 
stammt schätzungsweise von der 1023.

von gast (Gast)


Lesenswert?

schneller^^

von Johannes M. (johnny-m)


Lesenswert?

gast wrote:
> deine zahlen sollten aber trotzdem zwischen 0 und 1023 liegen
Nö, wenn er den Wert in einen char konvertiert (wie er schreibt), 
werden nur die letzten 8 Bit übernommen, und der ausgegebene Wert liegt 
tatsächlich zwischen 0 und 255.

von Johannes M. (johnny-m)


Lesenswert?

Matthias (DC2RLM) wrote:
> Temp.:     U an ADC0:     Wert im LCD:
> 1°         0.95 V         1903
Das war mal ne 190...

> 20°        0.14 V         2643
...ne 26...

> 55°        0.61 V         1263
...ne 126... usw.

von Johannes M. (johnny-m)


Lesenswert?

gast wrote:
> schneller^^
Dafür hab ich den OP aber auch richtig gelesen, im Gegensatz zu Dir... 
Ich glaube, Du hast den Sinn eines Forums nicht ganz verstanden: es geht 
nicht darum, möglichst schnell möglichst viel geistigen Dünnschiss, der 
idealerweise auch noch möglichst weit am Thema vorbeizielt, von sich zu 
geben (was allerdings offensichtlich weit verbreitet ist...), sondern 
auf eine bestimmte Frage zu antworten...

von Jochen (Gast)


Lesenswert?

Hallo,

du wandelst 0 - 4  = 5 mal
und teilst dann durch 4,
sehe ich das richtig.

Gruß
Jochen

von Johannes M. (johnny-m)


Lesenswert?

Jochen wrote:
> du wandelst 0 - 4  = 5 mal
> und teilst dann durch 4,
> sehe ich das richtig.
Nein, das siehst Du falsch! Da steht
1
for(i = 0; i < 4; i++)
2
{           ^^^^
3
    //...
4
}
also wird i höchstens 3.

von gast (Gast)


Lesenswert?

>> Dafür hab ich den OP aber auch richtig gelesen, im Gegensatz zu Dir...

mal nicht gleich patzig werden

"Die Funktion der avr-libc zur Umwandlung von vorzeichenbehafteten 
16bit-Ganzzahlen (int16_t) in Zeichenketten heißt itoa (Integer to 
ASCII)"
   char s[7];
   int16_t i = -12345;
   uart_init();
   itoa( i, s, 10 ); // 10 fuer radix -> Dezimalsystem
   uart_puts( s );
---> "-12345" , warum sollte das nicht von 0 bis 1023 gehen
aber so wie ich das sehe, kommt bestimmt wieder gleich eine patzige 
antwort ,also wars das von meiner seite

so weit vom thema kann ich ja nicht weg gewesen sein, immerhin hast das 
gleiche geschrieben

von Johannes M. (johnny-m)


Lesenswert?

gast wrote:
> so weit vom thema kann ich ja nicht weg gewesen sein, immerhin hast das
> gleiche geschrieben
Das war eine allgemeine Feststellung, die sich auf Dein "schneller" 
bezog, das in diesem Zusammenhang einfach nur schwachsinnig ist. Das ist 
hier kein Wettrennen!

Du hast Recht, der Code (in Sachen Verarbeitung des ADC-Wertes) ist auch 
soweit korrekt, nur die Ausgabe stimmt nicht. Entweder generell 
4-stellig rechtsbündig ausgeben oder die Display-Stellen vor der Ausgabe 
löschen.

von Johannes M. (johnny-m)


Lesenswert?

@Matthias:
Nur so nebenbei: Die Werte, die der ADC ausspuckt, liegen tatsächlich 
zwischen 0 und 1023, es handelt sich schließlich um einen 10-Bit-ADC. 
Dementsprechend ist auch die Ausgabe für den Höchstwert korrekt.

von Matthias (DC2RLM) (Gast)


Lesenswert?

Hallo Leute!

Erstmal recht herzlichen Dank für die zahlreichen hilfreichen Anregungen 
zum Thema- ich bin tatsächlich weitergekommen ;).

Der ADC gibt jetzt Werte zwischen 0 und 1023 aus. Die 1023 bei 409° sind 
ja soweit korrekt, da die anliegende Spannung in diesem Fall über der 
Vref von 5 Volt liegt (~5.4 Volt).

Jetzt werd ich mal sehen, dass ich die ADC- Werte in °C umrechnen kann.
Die 1024 Stufen sind natürlich korrekt, da wir nen 10bit- Wandler haben- 
hab mich da verrannt.
Jetzt werd ich mir mal nochwas einfallen lassen, was das Display- 
Löschen betrifft (denke da an einen Timer Impuls alle Sekunde, mit dem 
dann der Display gelöscht wird, weil ich eigentlich nicht mit nem Delay 
arbeiten will).

Wenns ok geht, poste ich nächste Woche mal, was draus geworden ist, und 
ihr könnt euren Senf dazu abgeben- gibt mit Sicherheit bei meinen C- 
Fähigkeiten noch Optimierungspotential ;)

Schönes WE und merci nochmal!

Grüße,
Matthias

von Johannes M. (johnny-m)


Lesenswert?

Matthias (DC2RLM) wrote:
> Jetzt werd ich mir mal nochwas einfallen lassen, was das Display-
> Löschen betrifft (denke da an einen Timer Impuls alle Sekunde, mit dem
> dann der Display gelöscht wird, weil ich eigentlich nicht mit nem Delay
> arbeiten will).
Warum so kompliziert? Es muss ja lediglich bei jedem Schreibzugriff 
gewährleistet sein, dass alles, was vorher da stand, gelöscht wird. Wenn 
Du die Zahl mit itoa in einen String umgewandelt hast, musst Du doch nur 
dafür sorgen, dass der String im Ausgabe-Array so verschoben wird, dass 
die Zahl selbst immer rechtsbündig erscheint und eben vier Stellen lang. 
Davor wird mit Leerzeichen (0x20) aufgefüllt.

itoa legt den String immer linksbündig in Dein Zielarray und schließt 
ihn mit einem Nullterminator ab. Du kannst dann einfach den String von 
vorne an nach der ersten Null absuchen. Wenn der Nullterminator bereits 
korrekt an der fünften Stelle steht, dann so lassen. Andernfalls eben um 
eine, zwei oder drei Stellen nach hinten schieben und vorne entsprechen 
Blanks einfügen.

von Johannes M. (johnny-m)


Lesenswert?

Beispiel:
Ausgangswert 158.
itoa macht daraus den String {'1', '5', '8', '\0'}. Du musst daraus 
jetzt den String {' ', '1', '5', '8', '\0'} machen, damit Du für die 
Ausgabe auf vier Stellen kommst. Das sollte in C recht simpel machbar 
sein.

von Matthias (DC2RLM) (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

da bin ich wieder!

@Johannes: Ich hab die Formatierung jetzt komplett anders gemacht- damit 
hat sich das Array- Manipulieren durch "sprintf" auch erledigt. Die 
Werte werden jetzt schön aktualisiert und machen auch Sinn, kaum macht 
mans richtig, schon funktionierts.

Von den Timer- gesteuerten LCD- Löschungen bin ich wieder weg- hat zwar 
funktioniert, aber ist wie hier auch schon gesagt wurde eigentlich nicht 
notwendig und damit zu umständlich.

Auf jeden Fall läuft die Sache jetzt zufriedenstellend, lediglich die 
1°- Anzeige hab ich "manipulieren" müssen, weil ich vermute, dass der 
von mir im Messwandler verwendete LM324 die Spannung nicht so weit 
runterzieht, wie er sollte- ich messe fast 0.1 Volt (0.095 Volt), 
sollten aber wohl weniger sein, da bei 0° ja 0V anliegen sollten.

So weit, so gut- wenn jemand noch Anregungen/ Ergänzungen hat, immer 
raus damit ;)

Grüße aus Regensburg,
Matthias

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.