Hallo zusammen, bin ein Anfänger und habe eine Frage. Habe einen Atmega 644 und habe das Problem das ich mit dem ADC (Spannung messsen) LEDs ansteuern will. An den Ports habe ich aber immer Spannungen zwischen 0,6 V - 2,9 V als high Signal. Habe einen ULN2804 dazwischen gesetzt inkl. Vorwiderstand für die LED. Woran kann das liegen das die Spannung an den Ports so niedrig ist? Bekomme keine vernünftige Leistung an die LEDs. Laut Datenblatt müsste ein high Siganl mindestens 4,2 V haben.
emit5 schrieb: > Habe einen Atmega 644 und habe das Problem das ich mit dem ADC (Spannung > messsen) LEDs ansteuern will. Benutzt du den Port (Pin) zum Einlesen einer Spannung oder möchtest du ein Signalpegel ausgeben, oder misst du mit einem Pin die Spannung und möchtest eine entsprechende Ausgabe über einen anderen Pin machen?? emit5 schrieb: > Habe einen ULN2804 dazwischen gesetzt inkl. Vorwiderstand für die LED. Wenn du "normale" LEDs nutzt kannst du sie mit Vorwiderstand direkt an den Pin schalten - entweder gegen Masse oder gegen Vcc. Teile mal mit, welchen Pin / Port du nutzt und wie du ihn ansteuerst -> wahrscheinlich schreibst du die Register falsch. Hast du denn den Ausgangsport mal als einfache Blinkschaltung betreiben können??
Du willst mit dem ADC eine LED ansteuern? Sicher dass du den ATmega mit 5V betreibst und nich tnur mit 3,3V? Beschaltung?
ADC ist doch ein "AVR to Diode Converter"? Im Ernst: das was dir fehlt, steht vermutlich auch großteils im Tutorial.
Simon D. schrieb: > Benutzt du den Port (Pin) zum Einlesen einer Spannung oder möchtest du > > ein Signalpegel ausgeben, oder misst du mit einem Pin die Spannung und > > möchtest eine entsprechende Ausgabe über einen anderen Pin machen?? Benutze PIN PA0 zum Einlesen der Spannung. Zur Ausgabe des Ergebnisses benutze ich PD0- PD5. Simon D. schrieb: > Wenn du "normale" LEDs nutzt kannst du sie mit Vorwiderstand direkt an > > den Pin schalten - entweder gegen Masse oder gegen Vcc. Habe ich probiert. Gab auch nur ein paar gedimmte LEDs. Simon D. schrieb: > Teile mal mit, welchen Pin / Port du nutzt und wie du ihn ansteuerst -> > > wahrscheinlich schreibst du die Register falsch. Hast du denn den > > Ausgangsport mal als einfache Blinkschaltung betreiben können?? Blinkschaltung hat geklappt (2 Leds). Die hatte ich auch direkt an die Ports angeschlossen. Aber sobald ich 4 oder 5 LEDs ansteuere dimmen die nur noch vor sich hin oder gehen gar nicht mehr an. Register schreibe ich immer zuerst auf null mit : PORTD: 0x00; Dann setze ich Port D als Ausgang: DDRD: 0xff; Danach im Programm setze ich die Signale mit den üblichen Befehlen: PORTD = (1<<PD0); PORTD &=~(1<<PD1);
>Aber sobald ich 4 oder 5 LEDs ansteuere dimmen die nur noch vor sich hin oder gehen gar nicht mehr an. Der AVR ist nur begrenzt belastbar, sthet im Datenblatt (ich meine 20mA oder so ähnlich). Bau Transistoren ein und gut ist.
Tobi schrieb: > Du willst mit dem ADC eine LED ansteuern? > > Sicher dass du den ATmega mit 5V betreibst und nich tnur mit 3,3V? > > Beschaltung? Möchte mit dem ADC nur zu Versuchszwecken die LED ansteuern. Habe den ATmega ganz sicher auf 5V. Die Beschaltung? Ich habe mir ein Pollin ATMEL Evaluations Board gekauft.
>Möchte mit dem ADC nur zu Versuchszwecken die LED ansteuern. Herje... Mit einem ADC steuert man keine LEDs an, sondern misst eine analoge Größe. Wenn du nicht richtig beschreiben kannst wie deine Schaltung aussieht, dann zeig wenigstens einen Schaltplan her...
emit5 schrieb: > Danach im Programm setze ich die Signale mit den üblichen Befehlen: > > PORTD = (1<<PD0); > PORTD &=~(1<<PD1); Naja, das ist ja schonmal nicht ganz korrekt! Das Löschen stimmt soweit, nur beim Setzen von Bits in einem Register muss das schon REG |= (1<<BIT_NUM); heißen. In deinem Fall überschreibst du ja das gesamte Register mit deinem neu zu setzenden Bit. Also egal was da vorher gesetzt war, hinterher ist es genau das eine Bit von der Zuweisung. Mit dem |= verhinderst du das Problem. Du gibst ja damit die Anweisung, den momentanen Wert des Registers einzulesen, ihn mit dem zu setztenden Bit zu ver-odern und in das Register zurückzuschreiben. Das falsche Setzen könnte auch deinen Fehler erklären. Bei einer Blinkschaltung kann es sein, dass das garnicht auffällt. Aber jetzt, wo es mehr Leds sind, schalten die Setz-Anweisungen sich gegenseitig aus. Genauer kann man dir das sagen wenn du deinen Code mal hochladen würdest...
Kann es sein, das du wild an den LED-Pins umschaltest und es dadurch aussieht, daß die LED gedimmt wird. Zeig mal dein Programm. Gruß Joachim
ich schrieb: > Herje... Mit einem ADC steuert man keine LEDs an, sondern misst eine > > analoge Größe. > > Wenn du nicht richtig beschreiben kannst wie deine Schaltung aussieht, > > dann zeig wenigstens einen Schaltplan her... Ich steuere mit dem ADC keine LEDs an sondern benutzte den ADC nur um die Ports zu steuern! Die auf den ULN2804 gehen, der dann LEDs ansteuert! Entschuldigung das ich ein Anfänger bin und etwas lernen möchte!! Ausserdem geht es mir mehr darum: Warum ist die Spannung an den Ausgangsports so niedrig?
Hallo emit5: >>Möchte mit dem ADC nur zu Versuchszwecken die LED ansteuern. > > Herje... Mit einem ADC steuert man keine LEDs an, sondern misst eine > analoge Größe. > Wenn du nicht richtig beschreiben kannst wie deine Schaltung aussieht, > dann zeig wenigstens einen Schaltplan her... Da siehst Du mal wohin das fuehrt...... Du hast es zwar schon oben erklaert, aber wenn man eine Frage KLAR stellt, kommt schneller eine sinnvolle Antwort heraus. Gruss Michael
>Ausserdem geht es mir mehr darum: Warum ist die Spannung an den >Ausgangsports so niedrig? Weil du vermutlich mehr Strom aus dem AVR ziehst als du darfst. Oder du im Programm schnell ein- und ausschaltest. Hast du eine Möglichkeit mit einem Oszilloskop an deinen Ausgangspins zu messen? Wie groß sind denn deine Vorwiderstände der LEDs?
Hallo Felix, Felix schrieb: > Naja, das ist ja schonmal nicht ganz korrekt! > > Das Löschen stimmt soweit, nur beim Setzen von Bits in einem Register > > muss das schon REG |= (1<<BIT_NUM); heißen. In deinem Fall überschreibst > > du ja das gesamte Register mit deinem neu zu setzenden Bit. Also egal > > was da vorher gesetzt war, hinterher ist es genau das eine Bit von der > > Zuweisung. > > > > Mit dem |= verhinderst du das Problem. Du gibst ja damit die Anweisung, > > den momentanen Wert des Registers einzulesen, ihn mit dem zu setztenden > > Bit zu ver-odern und in das Register zurückzuschreiben. > > Das falsche Setzen könnte auch deinen Fehler erklären. Bei einer > > Blinkschaltung kann es sein, dass das garnicht auffällt. Aber jetzt, wo > > es mehr Leds sind, schalten die Setz-Anweisungen sich gegenseitig aus. > Genauer kann man dir das sagen wenn du deinen Code mal hochladen > > würdest... Danke!! Das ist schonmal ne super Erklärung! Werde mein Programm hochladen wenn ich zu Hause bin. Bin im Moment noch auf der Arbeit!!
ich schrieb: > Weil du vermutlich mehr Strom aus dem AVR ziehst als du darfst. > > Oder du im Programm schnell ein- und ausschaltest. > > Hast du eine Möglichkeit mit einem Oszilloskop an deinen Ausgangspins zu > > messen? > > Wie groß sind denn deine Vorwiderstände der LEDs? Benutze 220 Ohm Widerstände. Oszilloskop habe ich leider nicht!
emit5 schrieb: > Ausserdem geht es mir mehr darum: Warum ist die Spannung an den > Ausgangsports so niedrig? Ich habe dir ein klein wenig weiter oben schon einen Hinweis gegeben. Gehe dem bitte mal nach und kontrolliere deinen Quellcode und/oder poste ihn auch gleich mal hier im Forum, vielleicht finden sich ja noch mehr Fehler. Das mit der Spannung würde sich auch über durch den oben beschriebenen Fehler beim Bits setzen erklären. Ich nehme mal an du misst die Spannung mit einem normalen Multimeter. Dein Controller läuft aber nun wesentlich schneller als das Multimeter messen kann. Der Controller schaltet nun die Leds immer mal kurz an und wieder aus, weil du das wahrscheinlich so programmiert hast. Daher ist die mittlere Spannung eben wesentlich geringer als die 5V, die Multimeter messen ja nur rund drei bis fünf mal pro Sekunde und haben eine gewisse Integrationszeit. Auf einem hinreichend schnellen Ozilloskop würdest du dann sicher auch die kleinen Pulse sehen die dein Controller ausgibt. -> Also: Schau nach dem Bit-Setz-Problem
220 Ohm... Das entspricht dann etwa 15mA pro LED. Das sollte vom Strom her noch kein Problem sein. Pro Pin musst du unter 40mA, im gesammten unter 200mA bleiben!
Felix schrieb: > -> Also: Schau nach dem Bit-Setz-Problem Hallo nochmal, das mit dem Bit-Setz-Problem stimmte. Aber da ich euch noch den Quellcode schuldig bin: #include <inttypes.h> #include <avr/io.h> #include <avr/interrupt.h> int main (void) { unsigned int low=0, high=0, ad=0, x=0, admax=0; DDRD = 0xFF; PORTD = 0x00; ADMUX = 0b01000000; ADCSRA = 0xE0; while(1) { low = ADCL; high = ADCH; ad = high * 256; x = ad + low; if (x > admax) { x = admax; } if (x >= 206 || admax >=206) { (PORTD |= (1<<PD0)); } else { (PORTD &=~ (1<<PD0)); } if (x >= 412 || admax >=412) { (PORTD |= (1<<PD1)); } else { (PORTD &=~ (1<<PD1)); } if (x >= 618 || admax >=618) { (PORTD |= (1<<PD2)); } else { (PORTD &=~ (1<<PD2)); } if (x >= 824 || admax >=824) { (PORTD |= (1<<PD3)); } else { (PORTD &=~ (1<<PD3)); } if (x >= 950 || admax >=950) { (PORTD |= (1<<PD4)); } else { (PORTD &=~ (1<<PD4)); } } } Vielleicht findet ja noch einer einen Fehler?!? Danke im voraus!!
> Vielleicht findet ja noch einer einen Fehler?!?
Ist da noch einer versteckt, oder ist das nur einfach so pauschal
dahingefragt?
Na gut. Du mußt du den AD-Wert nicht selber zusammenbasteln, das macht
der Compiler für dich:
1 | x = ADCW; |
Ist hier bei der Zuweisung x und admax vertauscht?
1 | if (x > admax) x = admax; |
Was wäre, wenn admax=0 wäre und x=10? Dann wären anschliessend beide 0... :-o Drehen wir das mal um:
1 | if (x > admax) admax = x; |
2 | |
3 | if (x >= 206 || admax >=206) PORTD |= (1<<PD0); |
4 | else PORTD &=~ (1<<PD0); |
Überleg mal die Funktion deines Programms nochmal genau. (Lass dich mal nicht davon verwirren, dass ich das etwas lesbarer formatiert habe) Ich würde sagen, du kannst die Abrage auf x ganz einfach ohne Funktionseinschränkung weglassen...
Lothar Miller schrieb: > Was wäre, wenn admax=0 wäre und x=10? > > Dann wären anschliessend beide 0... :-o Super Danke!!! Habe die ganze Zeit versucht meinen Fehler zu finden! Bin aber irgendwie nicht drauf gekommen! Lothar Miller schrieb: > Ich würde sagen, du kannst die Abrage auf x ganz einfach ohne > > Funktionseinschränkung weglassen... Was meinst du damit?
emit5 schrieb: >> Ich würde sagen, du kannst die Abrage auf x ganz einfach ohne >> >> Funktionseinschränkung weglassen... > > Was meinst du damit? Denk logisch nach (korrigiert)
1 | if (x > admax) |
2 | admax = x; |
kann admax nicht mehr kleiner als x sein. Wenn es das wäre, wäre es durch diese Abfrage auf x angehoben worden. Damit ist es hier zb
1 | if (x >= 950 || admax >=950) |
nicht notwendig beide abzufragen. Wenn x größer/gleich 950 ist, dann muss es auch admax sein. admax kann niemals kleiner als x sein. Deine vorhergehende Abfrage x > admax mit Nachsetzen von admax hat das sichergestellt. Allerdings kann x kleiner als admax sein. Das spielt hier aber keine Rolle mehr, denn in dem Fall greift dann immer (auch bei den anderen Fällen) die Abfrage ob admax größer/gleich als irgendein Wert ist. -> Die Abfrage ob x irgendetwas ist, ist sinnlos und ohne Auswirkungen. Probiers mit ein paar Zahlen in mehreren Schleifendurchgängen auf dem Papier durch. Das ist überhaupt empfehlenswert, denn dann hättest du deinen letzten Fehler auch ganz einfach selbst erkannt.
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.