Hi Comunity, Ich hab ein kleines Problem mit dem AD Wandler des Atmega8. Zum Aufbau: vier 100k Potis zwischen VCC und GND, Mittelabgriff direkt auf ADC0 bis ADC3, an jeden Mittelabgriff zusätzlich noch einen 1uF C gegen GND. An TX einen Transistor + Futter + SUBD 9 Buchse. Die Schaltung soll lediglich die Werte der Potis auslesen und an den PC senden. Allen voran ein "Startbyte": 0x00 Allerdings bekomme ich nun im hterm bei der Einstellung aller Potis auf 0V folgende (HEX) werte: 00, 96, 94, 96, 95, 00, 96,... etc. drehe ich nun ein Poti nach oben, wird dessen richtiger Wert bei überschreiten von ca. 95 richtig übertragen. Interessant an der sache ist, dass wenn ein oder mehrere Potis komplett auf 5V gestellt sind, werden auch die restlichen Werte richtig übertragen. also beispielsweise Poti 1 und 3 auf 5V und 2 und 4 auf 0V gibt folgende Werte: 00, 255, 03, 255, 03. Das kommt mir wesentlich plausibler vor. Hat jemand eine Idee woran es liegen könnte, dass die Werte nur dann richtig übertragen werden? Hardware? Software? Der relevante Codeteil ist angehängt. Danke schonmal
die 100k sind eventuell zu groß. das gibt dann n paar µA an Stromfluss, kann sein das der entweder zu klein ist um richtig gesampled zu werden oder Störeinstreuungen mit in den Messwert ein gehen. Probiers mal mit 10k oder kleiner.
Fhutdhb Ufzjjuz schrieb: > Probiers mal mit 10k oder kleiner. Ok, danke. Hab leider gerade keine zur Hand. Aber werds die nächsten Tage mal versuchen. Allerdings glaube ich nicht, dass wenn ich alle Potis direkt auf Masse einstelle, der Stromfluss so gering ist. werd sie mal schnell direkt mit Masse verbinden und sehen was passiert. Für sonstige Tipps bin ich natürlich weiterhin dankbar.
Thomas B. schrieb: > werd sie mal schnell direkt mit > Masse verbinden und sehen was passiert. gesagt, getan. Ich erhalte die Werte 00, 89, 91, 92, 90, 00, 89,.... daher tippe ich eher auf einen Fehler in der Software Thomas B. schrieb: > folgende (HEX) werte sorry ich meinte natürlich DEC Werte.
Thomas B. schrieb: > Hi Comunity, > > Ich hab ein kleines Problem mit dem AD Wandler des Atmega8. > > Zum Aufbau: vier 100k Potis zwischen VCC und GND, Mittelabgriff direkt > auf ADC0 bis ADC3, an jeden Mittelabgriff zusätzlich noch einen 1uF C > gegen GND. An TX einen Transistor + Futter + SUBD 9 Buchse. Was hast du mit dem AREF Pin gemacht?
Mit welcher Taktfrequenz arbeitest Du? Wie ist "sample" definiert? Wie ist "value" definiert?
Karl heinz Buchegger schrieb: > Was hast du mit dem AREF Pin gemacht? Der liegt auf VCC Edi R. schrieb: > Mit welcher Taktfrequenz arbeitest Du? > > Wie ist "sample" definiert? > > Wie ist "value" definiert? 16Mhz mit ext. Quarz
1 | int sample = 0; |
2 | char value = 0; |
Nebenbaustelle: Gewöhn dir schleunigst an, dass du selber die Kontrolle über das Vorzeichen übernimmst und das nicht dem Compiler überlässt. char benutzt du nur dann, wenn du Textverarbeitung machst. In allen anderen Fällen benutzt du entweder signed char oder unsigned char, oder noch besser uint8_t bzw. int8_t
Ich seh aber auch nix, was das Problem so wie geschildert, erklären könnte. Meine einzige Hoffnung war, dass ARef in der Luft hängt. Versuch mal auf das Mittelwertbilden zu verzichten und den Wert aus ADCH direkt auszugeben. 1 Messung -> 1 Übertragung mit der UART (und mach alles unsigned) Und bau deine globalen Variablen ab. Mit dem 100-maligem Umkopieren wird es nicht leichter zu durchschauen, welcher Wert jetzt wohin kopiert wird.
1 | #define NR_SAMPLES 1
|
2 | #define ADC_MUX_BASE ((1<<ADLAR))
|
3 | |
4 | uint8_t ad_wandeln (void) //AD wandeln# |
5 | {
|
6 | uint16_t sample; |
7 | |
8 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
9 | while (ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten |
10 | ;
|
11 | sample = ADCH; //einmal AD wandeln, ergebnis verwerfen |
12 | |
13 | sample=0; |
14 | for(i = 0; i < NR_SAMPLES; i++) //32 mal wiederholen |
15 | {
|
16 | ADCSRA |= (1<<ADSC); //single conversion mode ein |
17 | while ( ADCSRA & (1<<ADSC) ) //warten bis Konvertierung abgeschlosen |
18 | ;
|
19 | sample += ADCH; //aufsummierung der samplewerte |
20 | }
|
21 | |
22 | return (uint8_t)( sample/NR_SAMPLES); |
23 | }
|
24 | |
25 | int main(void) |
26 | {
|
27 | uint8_t a, b, c, d; |
28 | |
29 | DDRD = 0b00100010; |
30 | DDRC = 0b00000000; |
31 | PORTC= 0b11101111; |
32 | |
33 | init_uart(UBRR_VAL); |
34 | sei(); |
35 | |
36 | ADMUX=0b00100000; //ADC Referenz auf Ext |
37 | ADCSRA=0x80; //ADC einschalten |
38 | |
39 | while (1) |
40 | {
|
41 | send_char(0x00); |
42 | |
43 | ADMUX = ADC_MUX_BASE + 0; //ADC MUX auf Kanal 0 einstellen |
44 | a = ad_wandeln(); |
45 | send_char( a ); |
46 | |
47 | ADMUX = ADC_MUX_BASE + 1; //ADC MUX auf Kanal 1 einstellen |
48 | b = ad_wandeln(); |
49 | send_char( b ); |
50 | |
51 | ADMUX = ADC_MUX_BASE + 2; //ADC MUX auf Kanal 2 einstellen |
52 | c = ad_wandeln(); |
53 | send_char( c ); |
54 | |
55 | ADMUX = ADC_MUX_BASE + 3; //ADC MUX auf Kanal 3 einstellen |
56 | d = ad_wandeln(); |
57 | send_char( d ); |
58 | }
|
59 | |
60 | return 1; |
61 | }
|
Liegt nicht beim Mega8 der ADC am Port C? DDRC = 0b00000000; PORTC= 0b11101111; Warum schaltest du dann die Pullup Widerstände ein? Da darfst du dich nicht wirklich wundern, wenn dein ADC alles mögliche misst, wenn du ständig parallel zum Eingang einen Widerstand unbekannter Höhe nach Vcc geschaltet hast.
und da in ADCSRA die ADPS-Bits alle 0 sind soll er auch noch mit 8MHz wandeln! Sascha
Hi 16MHz und Prescaler 2. Sehr portlich. Die ADC-Frequenz sollte zwischen 50 und 200kHz liegen. Du hast 8 MHz. MfG Spess
Karl heinz Buchegger schrieb: > Warum schaltest du dann die Pullup Widerstände ein? hatte die mal ein und mal aus. Geändert hat sich dadurch nicht sonderlich viel. Dachte zuerst auch das könnte das problem sein. Werd Sie wieder abschalten. Und selbst wenn ich die Eingänge hart auf Masse lege werden seltsame Werte gemessen. Da dürfte ein Pullup nicht sonderlich viel ausmachen. Karl heinz Buchegger schrieb: > Ich seh aber auch nix, was das Problem so wie geschildert, erklären > könnte. Meine einzige Hoffnung war, dass ARef in der Luft hängt. > > Versuch mal auf das Mittelwertbilden zu verzichten und den Wert aus ADCH > direkt auszugeben. > 1 Messung -> 1 Übertragung mit der UART > > (und mach alles unsigned) > > Und bau deine globalen Variablen ab. Mit dem 100-maligem Umkopieren wird > es nicht leichter zu durchschauen, welcher Wert jetzt wohin kopiert Deinen Code habe ich probiert, Problem ist erhalten geblieben. Sascha Weber schrieb: > und da in ADCSRA die ADPS-Bits alle 0 sind soll er auch noch mit 8MHz > wandeln! Spess53 schrieb: > Die ADC-Frequenz sollte zwischen 50 und 200kHz liegen. Du hast 8 MHz. Danke Ihr beiden, an so etwas hatte ich noch garnicht gedacht. Werd den Prescaler mal höher stellen. Melde mich wieder wenn ichs versucht hab.
Nochmal danke an alle. Nach dem Einstellen des Prescalers hat es funktioniert.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.