Einen Wunderschönen, liebes µC-Forum!
#######
ANMERKUNG: Bevor ihr dem Verlauf dieses Themas folgt, wenn ihr das selbe
Problem habt wie ich es hier beschreibe, sei gesagt, dass die Lösung ein
defekter Microcontroller war. Auch wenn ihr das bereits ausgeschlossen
habt, findet ihr in diesem Verlauf fast schon eine Schritt für Schritt
Anleitung zum Ausmachen eures vielleicht anderen Fehlers.
#######
Gleich zum Problem:
Wenn ich an meinem LED-Würfel (3x3x3) die unterste, vordere LED
ansteuere, leuchtet die dahinter liegende ebenfalls auf. Umgekehrt aber,
wenn ich die dahinter liegende ansteuere, leuchtet die vorne liegende
NICHT auf. Ähnliches Verhalten beobachte ich bei weiteren LED-"Paaren"
(die ja eigentlich keine sein sollten!).
Als Controller benutze ich einen ATtiny2313A-PU auf einer
Lochrasterplatine, dazu 3 NPN-Transistoren (C945), 330R's hinter den
LED's aber vor dem collector der NPN's, 10k's zwischen ATtiny Output und
NPN-base und blaue Leuchtdioden.
Guckt man von vorne auf den Würfel, teilen jeweils die in die tiefe
verlaufenden Bahnen die Anode -also die obere Linke mit den beiden
dahinter, die Mittlere mit den beiden dahinter und so weiter- und alle 9
Vorderen die Kathode (und so weiter).
Im Quellcode (C) für den Attiny definiere ich die Outputs wie folgt:
DDRB = 0b11111111;
DDRD = 0b01111000;
Vorher habe ich sie á la Bitwise-Manipulation gesetzt, mit dem selben
Ergebnis (ich bevorzuge bei einmaligen Definitionen das Setzen des
gesamten Bytes).
Um es als Pins auszudrücken: PB0 bis PB7 sind outputs (8 LED's), PD3 bis
PD6 sind outputs (PD6 ist die LED, der Rest schaltet die NPN's).
Wie oben erwähnt, leuchtet, wenn ich die LED an PB7 und PD4 ansteuere
auch die LED an PB7 und PD3 (zur Erinnerung: PB3 und PD4 sind
Transistoren).
Meine zweite Vermutung, nachdem ich die Deklaration scheinbar
ausschließen konnte, war ein fehlender Widerstand zwischen Base und GND
um den input low zu pullen, aber den habe ich auch sonst in keiner
Schaltung gesehen (auf die Idee kam ich, weil man bei µC-Inputs auch
einen Pulldown braucht).
Meine Frage ist (Trommelwirbel, denn das kommt überraschend!): Warum
leuchten beide LED's?
Da ich mich leider immer etwas lang auszudrücken vermag, entschuldige
ich mich für den langen Text zu dem kurzen Problem und bedanke mich für
Antworten und Reaktionen.
*Felix grüßt freundlich.
Felix Merz schrieb:> Meine Frage ist (Trommelwirbel, denn das kommt überraschend!): Warum> leuchten beide LED's?
Erst mal sollte man klären, ob du dich verlötet hast, oder ob du einen
Fehler im Programm hast.
Ich würde mal damit anfangen, die Hardware zu prüfen. Dazu braucht es
keinen µC mit einem möglicherweise fehlerhaften Programm. Einfach den µc
aus seinem Sockel nehmen und mit Drahstücken die entsprechenden
Verbindungen zu Vcc bzw GND herstellen um jede LED so wie geplant zum
leuchten zu bringen.
Wenn sich dabei schon zeigt, dass 2 LED gemeinsam leuchten, obwohl sie
das nicht sollten, dann hast du irgendwo in der Verdrahtung einen Bock
geschossen.
> Meine zweite Vermutung, nachdem ich die Deklaration scheinbar> ausschließen konnte, war ein fehlender Widerstand zwischen Base> und GND um den input low zu pullen
Braucht es nicht. Wenn du einen auf Ausgang geschalteten Portpin auf 0
schaltest, dann stellt der eine Verbindung zu GND her. Und vice versa:
schaltest du den Pin auf 1, dann stellt der eine Verbindung zu Vcc her.
Sprich: der ausgangspin wird immer aktiv entweder nach GND oder nach Vcc
getrieben.
back to jungle schrieb:> Kann es sein daß eine LED einfach in die andere reinleuchtet?
Das habe ich durch wegbiegen der entsprechenden LED's überprüft, leider
nein.
back to jungle schrieb:> Schlimmer gehts immer..
Scheinbar ist die Idee mit dem pulldown ja lächerlich abwegig. :) Ich
kam darauf, weil ich zuvor gelesen hatte ein Pin auf low würde noch
0v2-0v4 Sourcen, scheinbar ein Irrtum, wie Karl Heinz bestätigt.
Karl Heinz schrieb:> Ich würde mal damit anfangen, die Hardware zu prüfen.
Ich habe die Hardware geprüft, mit meinen Breadboard-Litzen kann ich
jede LED einzeln ansteuern (auch indirekt, also quasi indem ich tue, was
der µC machen sollte, den ich vorher vom Sockel zog).
Damit wäre die Verdrahtung wohl korrekt.
Felix Merz schrieb:> Damit wäre die Verdrahtung wohl korrekt.
Damit bleibt dann nur noch dein unbekanntes Programm als Ursache.
Dein Programm emuliert nicht das, was du mit deiner Hardware-Prüfung
gemacht hast.
Felix Merz schrieb:> back to jungle schrieb:>> Schlimmer gehts immer..> Scheinbar ist die Idee mit dem pulldown ja lächerlich abwegig. :) I
Nein, es geht darum "den input low zu pullen". Das kann man ohne jeden
Sinnverlust und ohne vergewaltigtes englisches Vokabular auch auf
Deutsch sagen: "den Eingang herunterzuziehen"...
> würde noch 0v2-0v4 Sourcen, scheinbar ein Irrtum
Richtig, denn es wird niemals eine Spannung "gesourced", sondern
bestenfalls ein Strom. Mag sein, dass dann noch eine Restspannung oder
eine Sättigungsspannung von 0,2..0,4V übrigbleibt. Aber nur, wenn
tatsächlich einer einen Strom in den Pin hinein treibt. Wie hoch die
verbleibende Spannung bei einem bestimmten Strom maximal ist, das steht
im Datenblatt.
> Breadboard
Steckbrett
Lothar schrieb.
>...und ohne vergewaltigte englisches Vokabular auch auf>Deutsch sagen: "den Eingang herunterzuziehen"...>> Breadboard>Steckbrett
Ja, das HAT Sinn.
MfG Paul
Karl Heinz schrieb:> Dein Programm emuliert nicht das, was du mit deiner Hardware-Prüfung> gemacht hast.
Ich habe eine Litze mit Vcc in die Sockel-Slots geschoben, die der µC
high gesetzt hätte (also eine LED-Anode und eine Transistor base) und
eine Litze mit GND in den Sockel-Slot, wo der µC (und da geteiltes GND
auch jede andere Komponente) GND anliegen hat. Es trifft das, was der µC
von außen betrachtet anstellt verhältnismäßig gut.
1
/*
2
* GccApplication2.c
3
*
4
* Created: 02.02.2014 22:58:12
5
* Author: wexa
6
*/
7
8
#include<avr/io.h>
9
10
#define F_CPU 20000000UL
11
12
intmain(void)
13
{
14
// 0b76543210
15
DDRB=0b11111111;
16
DDRD=0b01111000;
17
while(1)
18
{
19
//volatile unsigned int i;
20
PORTB|=(1<<PB7);
21
PORTD|=(1<<PD4);
22
}
23
}
Damit wäre das Programm bekannt. Natürlich ist es nicht das vollständige
Programm, aber ich habe exakt diesen Ausschnitt auf den Controller
geladen und es verursacht den "gewünschten" Fehler.
@Lothar Miller: Du hast recht, meine Ausdrucksweise ist bestenfalls
störend. Ich führe das darauf zurück, dass ich alles was ich weiß aus
größtenteils Englischen Anleitungen, Foren-Einträgen und Datenblättern
gelernt habe und mir manchmal einfach das Deutsche Vokabular fehlt; Ich
muss aber sagen, dass ich auch gerne in ein furchtbares Denglisch
verfalle, gerade wenn ich im Internet unterwegs bin.
Felix Merz schrieb:> und es verursacht den "gewünschten" Fehler.
Das ist ein statisches Programm, da ist es jetzt einfach, den Fehler
herauszumessen...
BTW: wäre es nicht besser, den Port-Wert einmal definiert zu setzen,
statt was zu einem unbekannten Wert dazu zu verodern:
Max schrieb:> Läuft Dein Programm nicht viel zu schnell durch?> Da muss doch noch ein timing loop rein...Lothar Miller schrieb:> den Port-Wert einmal definiert zu setzen
In etwa so?
1
intmain(void)
2
{
3
// 0b76543210
4
DDRB=0b11111111;
5
DDRD=0b01111000;
6
7
PORTB=(1<<PB7);//Lothar M.
8
PORTD=(1<<PD4);
9
volatileunsignedinti;
10
11
while(1)
12
{
13
PORTB|=(1<<PB7);
14
PORTD|=(1<<PD4);
15
i=5000;//Max
16
while(i--);//Max
17
}
18
}
So habe ich es jedenfalls im Steuerprogramm für den ganzen Würfel
gemacht. Hab den hier abgebildeten Code auch kurz auf den Attiny
geladen, aber mit dem selben Ergebnis.
Verstehe ich etwas grundlegendes nicht, wenn es um Pins als Output geht?
:(
(Editiert)
Hi, kannst Du die Schaltung in Schema- antelle in Textform posten? Wäre
verständlicher.
Bei den Data Direction Registers ist:
1 = I wie Input
0 = O wie Output
Ist das bei den AT Tiny anderst?
Du brauchst eigentlich nur Outputs zur Ansteuerung der LED's, oder sehe
ich da was falsch?
Ich hab zwar von C keine Ahnung, aber ich würde vor der while
Schleife die Ports z.B. so initialisieren:
PORTB = 0b00000001;
In der while Schleife kannst Du dann die Bits jeweils um 1 nach links
schieben:
PORTB = PORTB << 1;
Hallo,
wenn du die externe Beschaltung wie beim Pollin Cube hast,
kannst du mein Programm direkt verwenden.
Beitrag "Pollin LED Cube"
Alternativ kannst du das Programm an deine Würfel anpassen.
Ernst
Max schrieb:> Du brauchst eigentlich nur Outputs zur Ansteuerung der LED's, oder sehe> ich da was falsch?
Stimmt genau, ich brauche keinen Input von außen, das Programm läuft los
sowie der Tiny anläuft und alle Visualisierungen liegen im Speicher und
warten darauf abgearbeitet zu werden.
Max schrieb:> Ist das bei den AT Tiny anderst?
Ich denke nicht.
1
DDRD&=~(1<<PD5);//PD5 wird zum Input
2
PORTD|=(1<<PD5);//aktiviert den internen pull-up Widerstand
Max schrieb:> In der while Schleife kannst Du dann die Bits jeweils um 1 nach links> schieben:
Dann müsste ich aber mehrfach nach links verschieben, wenn ich zum
Beispiel von 0b00000001 zu 0b00100000 kommen möchte, oder? Manche
Abbildungen sind allerdings auch vollständig leer, bisher gehe ich so
vor, dass ich in der selben while-Schleife immer eine LED an und dann
gleich wieder aus schalte, dann die nächste, immer per direkter
zuweisung auf den PORT, mir erscheint das einfacher als ein Verschieben,
aber ich habe damit auch erst wenig gearbeitet. Jedenfalls ist mein
Problem nach wie vor, dass ich es nicht schaffe bestimmte LED's einzeln
leuchten zu lassen, manche (nicht alle) leuchten immernoch paarweise.
Wenn Dein Würfel ähnlich wie der Pollin aufgebaut ist, solltest Du einen
Transistor ansteuern (log. 1 am zugehörigen Portausgang) und zusätzlich
nur einen Portausgang (für eine LED) auf log. 1 setzen, alle anderen
Portausgänge log.0.
Jetzt sollte nur eine LED leuchten.
Das Testprogramm musst Du so schreiben, dass es die Portausgänge nur
einmal beschreibt und dann stoppt (in eine Endlosschleife laufen
lassen).
Deine Anweisungen scheinen mir etwas kompliziert, nach dem Motto: wieso
einfach, wenn es auch kompliziert geht.
" DDRD &= ~(1 << PD5);//PD5 wird zum Input
PORTD |= (1 << PD5);//aktiviert den internen pull-up Widerstand "
Wieso setzt Du nicht einfach DDRD mit einer Zuweisung von einem hex
Wert?
Zum Anteuern der LED und Transistoren brauchst Du keine Inputs und auch
keine internen pull up Widerstände.
max schrieb:> Zum Anteuern der LED und Transistoren brauchst Du keine Inputs und auch> keine internen pull up Widerstände.
Ich weiß, du sagtest nur du wärst nicht vertraut mit C, bzw. den Tiny's,
da dachte ich mir, ich erwähne kurz, wie ich es gewohnt bin dort Inputs
zu setzen.
max schrieb:> Wieso setzt Du nicht einfach DDRD mit einer Zuweisung von einem hex> Wert?
Ich habe oben schon kurz gesagt, direkte Zuweisungen ganzer PORTs mache
ich bevorzugt über Hex- oder Binärzuweisungen, nur wenn ich nur ein Bit
manipulieren will, dann wiederum mache ich das gerne über OR und AND auf
das entsprechende Bit, dann sehe ich auf einen Blick was da los ist (und
veränder im Zweifelsfall nichts an den sonstigen Bits).
max schrieb:> Wenn Dein Würfel ähnlich wie der Pollin aufgebaut ist, solltest Du einen> Transistor ansteuern (log. 1 am zugehörigen Portausgang) und zusätzlich> nur einen Portausgang (für eine LED) auf log. 1 setzen, alle anderen> Portausgänge log.0.
Genau das mache ich ja auch. Da liegt ja der Hund begraben, dass OBWOHL
ich nur zwei Pins aktiv setze, sprich einen Transistor und eine LED
ansteuere, trotzdem zwei LED's (Selber Pin am Tiny, aber verschiedene
Transistoren) zu leuchten beginnen.
Vereinfacht sieht das so aus:
1
+--LED1--WIDERSTAND--TRANSISTOR--GND
2
| |
3
VCC | +------------+
4
_|_ | |
5
| |a-+--LED2--WIDERSTAND--TRANSISTOR--GND |
6
|ATT| | |
7
|INY|b--------------------------+ |
8
| | |
9
| |c---------------------------------------+
10
|___|--GND
Wenn a nun log.1 ist, passiert nichts.
Wenn a und c log.1 sind, leuchtet LED1.
Wenn a und b log.1 sind, leuchtet LED2.
Bei mir sieht das aber so aus:
Wenn a nun log.1 ist, passiert nichts.
Wenn a und c log.1 sind, leuchten beide LED's.
Wenn a und b log.1 sind, leuchtet LED2.
Teo Derix schrieb:> Moin,> Transistor für LED2, Basis mit Collector vertauscht!
Moin. Die Transistoren sind alle gleich verdrahtet. Sie sind auch in
einer Reihe, deshalb kann ich gut nachvollziehen, ob sie auf die selbe
Weise angesteuert werden. Außerdem kann ich ohne µC mit Litzen über die
Transistoren die LED's einzeln korrekt ansteuern. Jeder Transistor hat:
- den Emitter an GND
- den Collector an der Kathode der LED's (mit Widerstand für die LED's
dazwischen, da 5v0 geschaltet werden)
- die Base an jé einem Pin vom µC
>> ...> Bei mir sieht das aber so aus:> Wenn a nun log.1 ist, passiert nichts.> Wenn a und c log.1 sind, leuchten beide LED's.
Hast du das mit dem Voltmeter direkt an den Ausgängen gemessen, oder
erschliesst du aus deinem Programm, dass diese Portbelegung vorliegen
müsste?
Felix Merz schrieb:> Außerdem kann ich ohne µC mit Litzen über die Transistoren die LED's> einzeln korrekt ansteuern.
Und wie war das nochmal mit dem "Messen"? Du steuerst den uC einfach
statisch so an, wie du das mit der Brücke machen würdest und misst nach,
an welchem Pin und Transistor welcher Pegel ist. Das dauert im echten
Leben keine Viertelstunde und der Fehler ist herausgemessen...
Felix Merz schrieb:> In etwa so?
Ja. Nur noch ein wenig härter:
1
intmain(void)
2
{
3
// 0b76543210
4
DDRB=0b11111111;
5
DDRD=0b01111000;
6
7
PORTB=(1<<PB7);// Portpins statisch setzen
8
PORTD=(1<<PD4);
9
10
while(1)
11
;
12
}
Und dann muss am Pin B7 und am Pin D4 5V anliegen und an den anderen 0V.
Okey ihr lieben Menschen.
Ich muss mit einer recht peinlichen, wenngleich für mich sehr
erfreulichen Neuigkeit bei euch angekrochen kommen:
Der Tiny ist hinüber. Ich hab etwa in der Mitte dieses Themas auf einen
anderen Tiny gewechselt um mögliche Defekte auzuschließen, aber auch der
Austausch-Tiny ist defekt. Mit dem dritten und meinem Originalen Code
funktioniert alles wie gewünscht.
Vielen Dank für eure immense Mühe, ich hoffe ihr seid mir nicht allzu
böse!
*Felix grüßt freundlich.
PS.: Ich habe einige einleuchtende Vorschläge übernommen, wie zB. alles
einmal hart zu setzen, anstatt es mit x zu odern.
Felix Merz schrieb:> Der Tiny ist hinüber.
Hallo!
Ich kann mir keinen technischen Defekt innerhalb eines Tiny vorstellen,
der den von Dir beschriebenen Fehler hervorrufen könnte. Insbesondere,
wenn Du das bei zwei Exemplaren festgestellt haben willst. Suche doch
bitte noch mal genauer und wirf die zwei Verdächtigen nicht gleich weg.
Ich werd das Gefühl immer noch nicht los, dass es sich hier um einen
Wackelkontakt bzw. eine schlechte Lötung mit Kurzschlussgefahr handelt.
Mir gehts wie Route_66
Auch wenn hier im Forum immer wieder gepredigt wird, dass man die
Ausgänge eines Tiny/Mega nicht überlastet: Was ich meinem Mega16 auf dem
Experimentierbrett schon alles (unabsichtlich) zugemutet habe, geht auf
keine Kuhhaut. Nur eines hab ich bisher nicht geschafft: Einen Ausgang
tatsächlich soweit zu beschädigen, dass er nicht mehr brauchbar ist. Die
funktionieren alle ausnahmslos noch immer perfekt (soweit ich das mit
meinen Messmitteln feststellen kann). Fazit: auch wenn man
selbstverständlich die technischen Vorgaben des Herstellers beachtet, so
schnell kriegt man die Ausgänge selbst bei gnadenloser (kurzfristigen)
Überlastung der Ausgänge nicht kaputt.
Karl Heinz schrieb:> Nur eines hab ich bisher nicht geschafft: Einen Ausgang tatsächlich> soweit zu beschädigen, dass er nicht mehr brauchbar ist.
Ich schon. Allerdings war das auch nicht nur ein Kurzschluss... ;-)
Aber dass ein andere Ausgang das selbe mitmacht, das habe ich auch noch
nie gehabt.
Route_66 schrieb:> Ich kann mir keinen technischen Defekt innerhalb eines Tiny vorstellen,> der den von Dir beschriebenen Fehler hervorrufen könnte.
Ich mir auch nicht, vor allem zwei mal.
Karl Heinz schrieb:> Ich werd das Gefühl immer noch nicht los, dass es sich hier um einen> Wackelkontakt bzw. eine schlechte Lötung mit Kurzschlussgefahr handelt.
Auf der einen Seite kommt mir das auch als die naheliegendste Erklärung
vor. Der Quellcode ist ja so einfach wie er nur sein kann: Output
deklarieren, Pin setzen, Endlosschleife. Auf der anderen Seite
funktioniert der Würfel mit dem dritten Tiny nach wie vor Problemlos und
das nach mehreren Transporten in einer Brotdose in meinem Rucksack
inklusive Autofahrten.
Karl Heinz schrieb:> Nur eines hab ich bisher nicht geschafft: Einen Ausgang> tatsächlich soweit zu beschädigen, dass er nicht mehr brauchbar ist.
Mir ist mal ein µC auf den Boden gefallen und beim reflexartigen
zurückrollen mit meinem Stuhl, habe ich ihn gleich überfahren. Dabei ist
ein Pin bündig mit dem Gehäuse abgebrochen. Zählt das auch? Immerhin,
abgesehen von diesem Pin funktioniert er wunderbar in einem anderen
Projekt :)
Lothar Miller schrieb:> Aber dass ein andere Ausgang das selbe mitmacht, das habe ich auch noch> nie gehabt.
Es lagen tatsächlich an allen drei Pins (LED1, LED2, Transistor)
Spannungen an.
Felix Merz schrieb:> Lothar Miller schrieb:>> Aber dass ein andere Ausgang das selbe mitmacht, das habe ich auch noch>> nie gehabt.> Es lagen tatsächlich an allen drei Pins (LED1, LED2, Transistor)> Spannungen an.
Das Symptom ist klar. Die Ursache nicht.
Überleg doch mal: auf welche Art müsste ein IC kaputt gehen, dass zwei
nebeneinanderliegende Pins noch funktionieren, aber der eine wie über
eine diode den zweiten noch mitschaltet?
> Es lagen tatsächlich an allen drei Pins (LED1, LED2, Transistor)> Spannungen an.
Mich würde ein brauchbares Foto vom Aufbau (und der zugehörige
Schaltplan) interessieren...
Felix Merz schrieb:> Mir ist mal ein µC auf den Boden gefallen und beim reflexartigen> zurückrollen mit meinem Stuhl, habe ich ihn gleich überfahren. Dabei ist> ein Pin bündig mit dem Gehäuse abgebrochen.> Zählt das auch?
No, zählt nicht.
Ist mir auch schon passiert. Allerdings noch mit den ollen 74... in
meiner Studentenzeit.
Mit einer kleinen Schlüsselfeile vom Gehäuse rund um dem Pin gerade
soviel wegnehmen, dass Lötzinn wieder eine einigermassen gute Haftung
kriegt, einen Ersatzpin (aus Resten von Widerständen, wenn das Original
nicht mehr zu gebrauchen ist) anlöten, und weiter gehts.
> Es lagen tatsächlich an allen drei Pins (LED1, LED2, Transistor)> Spannungen an.
Hast du mal probiert, die 3 Pins aus dem Sockel zu nehmen, sind sie dann
auch alle gleich?
Das will mir nicht in den Kopf, wie du da die Ausgangstreiber ruininert
haben könntest. Ich mein: Ja, gut. Wenn du da an den Pins 230V
Netzspannung reinjagst, dann ist es klar. Aber das hast du ja sicher
nicht gemacht. Nur was könnte die Ursache dafür sein, dass du den Pins
das Licht ausgeblasen hast? Hast du das überhaupt?
Karl Heinz schrieb:> Hast du mal probiert, die 3 Pins aus dem Sockel zu nehmen, sind sie dann> auch alle gleich?
Die 3 Pins aus dem Sockel nehmen? Also unter der Lochrasterplatine an
den Lötpunkten, oder meinst du den µC aus dem Sockel nehmen und mit
Kroko-Klemmen "versorgen" um dann dort zu messen?
Karl Heinz schrieb:> Nur was könnte die Ursache dafür sein, dass du den Pins> das Licht ausgeblasen hast?
Das ist die Frage. Außer ab und an den Tiny verkehrt herum auf mein
ZIF-Sockel gesteckt und eingeschaltet zu haben, kann ich mich an keine
größeren Vorkommnisse erinnern (der Tiny wird beim verpolen
"gerade-noch-anfassbar"-warm, aber ob das ausreicht?).
Karl Heinz schrieb:> Hast du das überhaupt?
Es macht zumindest den anschein. Wenn ich noch die Zeit finde, teste ich
die "defekten" Tiny's auf meinem Steckbrett. Da ich aber heute und
morgen ausgeplant habe, komme ich vor Sonntag höchstens mit einer
spontanen Bastelnachtschicht dazu.
Lothar Miller schrieb:> Mich würde ein brauchbares Foto vom Aufbau (und der zugehörige> Schaltplan) interessieren...
Den genauen Schaltplan fertige ich dir an. Ob das mit dem Bild so hin
haut ist die Frage, aber ich tue mein Bestes.
Karl Heinz schrieb:> Wenn du da an den Pins 230V> Netzspannung reinjagst, dann ist es klar.
Kann doch jeden mal passieren ;-)