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?
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
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_tad_wandeln(void)//AD wandeln#
5
{
6
uint16_tsample;
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
intmain(void)
26
{
27
uint8_ta,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
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.
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.