Hallo,
ich brauche dringend Hilfe, um für mein erstes echtes Projekt den
Widerstand auszulesen.
(Ich weiß, dass es dazu auch schon viele Beiträge im Forum gibt, aber
weitergeholfen haben sie mir bisher nicht.)
In meinem Spannungsteiler ist ein Widerstand mit 10kOhm und ich
simulieren meinen Widerstand den ich auslesen will einem 1kOhm
Wiederstand und einem 20kOhm Widerstand. Das Ergebnis soll über 4 Leds
am PortB ausgegeben werden.
Mit meinem aktuellen Programm und Beschaltung hätte ich gedacht, dass
für die zwei Testwiderstände die Spannung am ADC0 zwischen nahezu
maximal (5V)und 0V wechselt. Aber irgendwie will mir das Programm das
nicht ausgeben.
Ich verwende von embedded-projects das AVR-Starterkit, in dem schon
einge Kondensatoren eingebaut sind, sodass ich erstmal auf weitere
verzichtet habe.
Hat jemand eine Idee, was ich falsch mache?
Gruß
Luggi
Luggi schrieb:> dass für die zwei Testwiderstände die Spannung am ADC0 zwischen nahezu> maximal (5V)und 0V wechselt.
Dann rechne zuerst mal die Spannungsteiler aus:
+5V - 1k - PC0 - 10 k 0V
+5V - 20k - PC0 - 10 k 0V
Nahezu +5V könnte man ja gelten lassen, aber nahezu 0V wohl nicht.
Gruß Dietrich
Hi
>Mit meinem aktuellen Programm und Beschaltung hätte ich gedacht, dass>für die zwei Testwiderstände die Spannung am ADC0 zwischen nahezu>maximal (5V)und 0V wechselt.
Wie kommst du darauf? Bei festen 10k kann die Spannung an PC1 zwischen
ca. 1,7V (20K) und ca. 4,5V (1k) variieren.
MfG Spess
Luggi schrieb:> Aber irgendwie will mir das Programm das nicht ausgeben.
Dann sag mal, wie Du Dir die Ausgabe vorgestellt hast.
Das verstehe ich jedenfalls nicht:
1
if(c<=512){
2
led_blink(0x03);
3
led_blink(0x01);
4
c=600;}
5
if(c>512){
6
led_blink(0x0C);
7
c=0;
8
led_blink(0x01);}
Und wenn der Kommentar stimmt (ich habe die Initialisierung nicht
kontrolliert):
1
c=ADCH;/* Nur ADCH lesen, weil 8-Bit Modus */
ist der Wert von c max. 255. Was soll dann oben ein Vergleich mit 512?
Gruß Dietrich
Auf jeden Fall ist meine Spannung dann unter 2,5 V. :-D
Das mit dem 8 Bit-Modus hab ich dann wohl falsch verstanden. Ich dachte
die Werte bleiben zwischen 0 und 1023 bloß dass sie in nur in min 3
Schritten wechseln.
-Das werde ich dann gleich mal ändern.
Auf jeden Fall schonmal vielen Dank soweit!
> Also ich brauch trotzdem die ganzen Kondensatoren zwischen den Pins und> GND ?
Falls die auf dem Board schon vorhanden sind, mußt du die natürlich
nicht doppelt einfügen, logisch. Aber die einzelnen Pins müssen auf
jeden Fall beschaltet sein. Im ADC-Tutorial, das ich verlinkt habe, ist
eine Beispielschaltung.
Mindestens:
zweites GND-Pin anschließen
AVCC über eine Drossel an VCC anschließen, dazu 100n gegen GND
ARef muß einen 100n gegen Masse bekommen
Reset sollte über 10k gegen VCC liegen
Wie die Kondensatoren auf deinem Board geschaltet sind, weiß ich nicht,
aber vergleiche mal die gesamte Schaltung mit der Beispielschaltung im
Tutorial.
Luggi schrieb:> Das mit dem 8 Bit-Modus hab ich dann wohl falsch verstanden.
... und nicht nachgedacht. Du liest nur ein Teil der Daten des ADC aus,
und zwar ADCH. Und das ist ein Byte (8 Bit-Register).
> Ich dachte> die Werte bleiben zwischen 0 und 1023 bloß dass sie in nur in min 3> Schritten wechseln.
In ein Byte "passen" keine 1023 hinein ;-(
Gruß Dietrich
Luggi schrieb:> Auf jeden Fall ist meine Spannung dann unter 2,5 V. :-D>> Das mit dem 8 Bit-Modus hab ich dann wohl falsch verstanden. Ich dachte> die Werte bleiben zwischen 0 und 1023 bloß dass sie in nur in min 3> Schritten wechseln.
ABer spätestens bei
1
unsignedcharc;
hätte dir aber klar sein müssen, das der Wert niemals größer als 255
sein kann. Denn ein unsigned char hat 8 Bit und mit 8 Bit sind nun mal
nur Werte zwischen 0 und 255 möglich.
AUs dem und ähnlichen Gründen schreibt man auch lieber
1
uint8_tc;
anstelle von
1
unsignedcharc;
Denn dann ist es recht offensichtlich, dass das eine 8 Bit Variable ist.
Hier in diesem Teil
1
if(c<=512){
2
led_blink(0x03);
3
led_blink(0x01);
4
c=600;}
5
if(c>512){
6
....
verstehe ich die Zuweisung von 600 an c nicht. Was war da die Idee
dahinter? Effektiv führt das dazu, dass das 2.te if ausgehebelt wird.
Denn entweder c war von Anfang an schon größer als dein Grenzwert, dann
wird das 2.te if genommen, oder es war kleiner/gleich, dann wird am Ende
des 1.ten if dafür gesorgt, dass auch das 2.te if genommen werden muss.
Ich nehme mal an, dass diese Zuweisung den Grund hatte, dass du etwas
siehst.
Denn worauf ich eigentlich raus will:
So etwas
1
if(a<=Grenzwert)
2
{
3
....
4
}
5
if(a>Grenzwert)
6
{
7
....
8
}
ist nicht sinnvoll, wenn sich a zwischendurch sowieso nicht verändern
kann (wie es in deinem Fall eigentlich sein sollte).
Denn: Wenn a NICHT kleiner/gleich als der Grenzwert ist, dann MUSS es
größer als der Grenzwert sein. Es gibt keine andere Möglichkeit mehr.
D.h. obiges ist gleichwertig zu
1
if(a<=Grenzwert)
2
{
3
....
4
}
5
else
6
{
7
....
8
}
Verwende dieses 'else', wenn es möglich ist! Denn im Originalcode taucht
der Grenzwert 2 mal auf. D.h. bei Änderungen musst du darauf achten,
dass du immer beide Stellen an der der Grenzwert auftaucht anpasst,
sonst kommt es zu Inkonsistenzen. Das kann dir durch die Verwendung
eines 'else' nicht passieren. Der Grenzwert taucht nur einmalig auf und
damit gibt es keine 2.te Stelle die man anpassen müsste, wenn sich der
Grenzwert verändert.
PS: Dein Schreibweisen Schema für { - } Klammern solltest du nochmal
überdenken. Es ist recht sinnfrei, die schliessende } ans Ende der Zeile
nach der letzten Anweisung im Block zu setzen.
Du hast zwar sauber eingerückt (was gut ist!), trotzdem muss man zur
Kontrolle, ob die Einrückung richtig ist und ob alle { - } Blöcke
korrekt sind, mit den Augen dauernd den Code absuchen
1
if(c<=512){
2
led_blink(0x03);
3
led_blink(0x01);
4
c=600;}
5
if(c>512){
6
led_blink(0x0C);
7
c=0;
8
led_blink(0x01);}
So geschrieben
1
if(c<=512){
2
led_blink(0x03);
3
led_blink(0x01);
4
c=600;
5
}
6
if(c>512){
7
led_blink(0x0C);
8
c=0;
9
led_blink(0x01);
10
}
brauch ich das nicht. Die schliessende { steht IMMER exakt in der
Spalte, in der auch die Anweisung darüber beginnt, in der auch die
öffnende { steht.
Wie du es ja zb bei
1
SIGNAL(ADC_vect){
2
....
3
}
auch gemacht hast.
Das ist auch gut so, denn diese { } Klammer Einrückungen, und zwar so,
dass man sie wiederfindet, sind ein Hilfsmittel um bei größerem Code
nicht den Überblick zu verlieren.
So geschrieben
1
if(c<=512)
2
{
3
led_blink(0x03);
4
led_blink(0x01);
5
c=600;
6
}
7
if(c>512)
8
{
9
led_blink(0x0C);
10
c=0;
11
led_blink(0x01);
12
}
ist dann dieser Zusammenhang noch viel offensichtlicher!
Die schliessende { steht immer exakt in derselben Spalte, wie du
zugehörige öffnende {. Will ich wissen, zu welchem { eine vorhandene }
gehört, dann brauch ich nur in derselben Spalte nach oben suchen und die
erste { auf die ich stosse, ist die richtige (wenn alles andere stimmt).
Ok,
Ich hab jetzt:
1.) Die fehlenden Kondensatoren und die Spule mit den entsprechenden
Pins zusammengeschossen (bis auf AGND, der wohl in dem einen GND schon
drin ist)
2.) Die zwei GND miteinander kurzgeschossen
3.) das Programm bzgl. Schreibweise und dem ADCH-Wert verbessert.
..und .. es FUNKTIONIERT! :-D
Vielen Dank an alle für eure Kritik!!
Ich hätte jetzt aber noch zwei Fragen:
a.) Und zwar leuchten die LEDs nicht so hell, wie in einem einfachen
"led_blink"-Programm mit der selben Schaltung. Woran kann das liegen?
b.) Welchen Effekt hat die Schaltung am RESET-Pin? Ich hatte jetzt ein
par Probleme den µController direkt neu zu flashen. Liegt das an dieser
Schaltung?
Gruß Luggi
>a.) Und zwar leuchten die LEDs nicht so hell, wie in einem einfachen>"led_blink"-Programm mit der selben Schaltung. Woran kann das liegen?
Gib jeder LED einen eigenen Vorwiderstand. Das ist ja grottig so
wie du es machst.
Luggi schrieb:> a.) Und zwar leuchten die LEDs nicht so hell, wie in einem einfachen> "led_blink"-Programm mit der selben Schaltung. Woran kann das liegen?
Genau genommen werden sie unterschiedlich hell leuchten - je nach dem,
wie viele gerade an sind.
Ok, jede LED hat jetzt ihren eigenen Widerstand und sie leuchten jetzt
tatsächlich heller.
Vielen Dank dafür!
Das sie dunkler leuchten, wenn alle gleichzeitig aufblinken kann ich
nicht beobachten.
Gruß Luggi
Luggi schrieb:> Das sie dunkler leuchten, wenn alle gleichzeitig aufblinken kann ich> nicht beobachten.
Zusammen sind sie dann auch wieder gleichhell und wenn das Auge nicht
den direkten Vergleich hat, fällt das nicht so sehr auf.
> Ich hab jetzt:> 1.) Die fehlenden Kondensatoren und die Spule mit den entsprechenden> Pins zusammengeschossen (bis auf AGND, der wohl in dem einen GND schon> drin ist)
Schließ mal bitte das AGND mit an GND an. Sonst wird innerhalb des
Controllers der Strom fließen und dir bestenfalls das Meßergebnis
verfälschen. Grundsätzlich hat jeder VCC-Pin seinen GND-Pin und
dazwischen gehören immer Abblockkondensatoren (100n), und zwar so kurz
und dicht wie möglich an den Anschlußbeinen. Genauso ist es bei AVCC und
AGND, das ist die Stromversorgung für den Analogteil. Auch dort ein 100n
dazwischen. Und in die Zuführung von VCC nach AVCC eine Drossel. Diese
Maßnahme filtert dir die Versorgung des ADC.
Der Rest wie in der Beispielschaltung.
> 2.) Die zwei GND miteinander kurzgeschossen
Soweit ich weiß hat der Atmega8 gar keinen AGND-Pin (hab ich jedenfalls
so hier im Forum gelesen und im Datenblatt finde ich keine entsprechende
Belegung). Da kann ich ja AGND nicht mit GND verbinden.
Ansonsten entspricht doch deine Beschreibung der Schaltung aus dem
Tutorial..
Du hast Recht, der Pin 22 (beim DIL-Gehäuse) ist nur in der
Beispielzeichnung als AGND bezeichnet. Ich denke, wegen der
Verdeutlichung, daß dies der GND-Anschluß für den Analogteil ist und der
auch zu AVCC gehört. Im Datenblatt ist er nur als GND bezeichnet. Das
hat zur Verwirrung geführt.
Aber wenn du zwischen 20 und 22 einen 100n hast und zwischen 7 und 8
auch, dann ist das in Ordnung.