PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Software für LED Cube



oZe
08.01.2008, 17:46
Hallo liebe Roboter Gemeinde!

Ich hab mir jetzt einen 3x3x3 LED Cube gebaut und die einzelnen LED`s per Matrix verschaltet. Es sind also alle Kathoden in der wagerechten und alle Anoden in der Senkrechten miteinerander verbunden. Durch diese anordnung brauche ich für 9 LED`s nur 6 Ports am µC und kann jede LED einzeln ansteuertn.

Mein eigentliches Problem ist aber die Programmierung. Ich habe mir jetzt 2 Subroutinen geschrieben jeweils für LED_AN und LED_AUS. Die Subroutinen werden mit 3 Parametetn aufgerufen in Form von der X, Y und Z Koordinate. Durch dieses vorgehen wird das Programm aber riesig werden, da ich ja jeden Fall respektieren muss. Ich poste mal kurz meinen Ansatz des Codes für die Sub LED_AN den ich noch im Kopf habe (Bin leider grade auf der Arbeit):


Sub LED_AN(X as INTEGER, Y as INTEGER, Z as INTEGER)
IF X=1 THEN
IF Y= 1 THEN

IF Z=1 THEN
PORTA.0 = 1
PORTB.0 = 1
END IF

IF Z=2 THEN
PORTA.1 = 1
PORTB.1 = 1
END IF

IF Z=3 THEN
PORTA.2 = 1
PORTB.2 = 1
END IF

END IF

IF Y= 2 THEN

IF Z=1 THEN
PORTC.0 = 1
PORTD.0 = 1
END IF

IF Z=2 THEN
PORTC.1 = 1
PORTD.1 = 1
END IF

IF Z=3 THEN
PORTC.2 = 1
PORTD.2 = 1
END IF

END IF

END IF
END SUB

Die Portnamen und Nummern sind rein willkürlich gewählt da ich die "echten" nicht im Kopf habe.

Es muss doch eine einfacherer Möglichkeit geben als die ganzen möglichen Kombinationen mit If abfragen ineinander zu verschachteln oder? Hat da eventuell jemand einen Tipp für mich?


Edit: Mir kommt grade noch eine Idee: Gibt es sowas wie 3 Dimensionale Arrays in Bascom? Das wäre mit Sicherheit eine der einfacheren Lösungen!

StevieL
08.01.2008, 19:28
Hallo oZe,

die Variablen als Integer zu definieren ist wohl etwas übertrieben, als Byte reicht völlig aus.

Du könntest x,y und z auch als Zahl übergeben (z. B. 321 oder 001) wobei die erste Stelle den X-Wert und die letzte den y-Wert darstellt. Dann kannst du mit select-case arbeiten. Wird zwar auch viel Code, ist aber übersichtlicher.

Bascom kann nur eindimensionale Arrays.

oZe
08.01.2008, 19:40
Hey das ist natürlich noch ne Idee. Damit komm ich auf jedenfall besser durch.
Jetzt ist noch die Frage ob das Codemäßig die Bascom-Demo "überfordert" aber das wird sich dann ja rausstellen.
Mit dem Array wär das ganze natürlich noch schöner zu lösen aber wenns das nicht gibt dann kann man nix machen :-)


Danke für den Tipp!

PicNick
08.01.2008, 19:42
mehrdimenional is mit Bascom nicht. :-(
schau aber mal da:
https://www.roboternetz.de/wissen/index.php/Bascom_Tabellen#mehrdimensionale_Tabellen

btw: Schau dir mal den Befehl "SELECT" an.

Michael
08.01.2008, 19:44
Hallo oZe,


Ich hab mir jetzt einen 3x3x3 LED Cube gebaut und die einzelnen LED`s per Matrix verschaltet. Es sind also alle Kathoden in der wagerechten und alle Anoden in der Senkrechten miteinerander verbunden. Durch diese anordnung brauche ich für 9 LED`s nur 6 Ports am µC und kann jede LED einzeln ansteuertn.
3x3x3 sind doch 27 und nicht nur 9?
Afaik könntest du mit 6 Ports nur eine Ebene mit 3x3x1 = 9 oder einen Würfel mit 2x2x2 = 8 LEDs ansteuern.

Kannst du deine Elektrik nochmal erklären?

Gruß, Michael

PicNick
08.01.2008, 19:57
Wenn ich das richtig verstanden habe, braucht er:
x --> 3 Pin
y --> 3 Pin
z --> 3 Pin
---------------
9 Pins

oZe
08.01.2008, 20:24
Ok zugegeben ich bin nicht der Meister sowas in Worte zu fassen aber ich versuch es noch mal:

Der Cube besteht aus 3x3x3 = 27 LED`s

Die X und die Y Achse sind jeweils per Matrix verschaltet (Auf X sind die Kathoden zusammengelötet und auf Y die Anoden). Somit habe ich immer 9 LED`s zusammen die über 6 Pins angesteuert werden können. Diesen Aufbau habe ich 3 mal gebaut für die Z Achse. Insgesamt brauche ich also 18 Pins vom µC um auf alle LED`s zugriff zu haben.

Noch mal in anderen Worten: Es gibt 3 Schichten aus jeweils 9 LED`s, die per Matrix verschaltet sind.

Ich hoffe das ist jetzt verständlicher gewesen als meine erste Beschreibung ;-)

oZe
09.01.2008, 12:51
So jetzt bin ich grade mal zuhause und habe die Software zur Hand von daher poste ich die jetzt schon mal.

Leider funktioniert das nicht so wie ich will. Normalerweise sollte jetzt LED 111 angehen (also x=1 y=1 z=1). Es gehen aber LED 111 und LED 112 an...

An der Hardware liegt es nicht (also keine lötbrücken o.ä.). Es liegt irgendwie an der Sub. Wenn ich den befehl LED_an(111) auskommentiere liegen alle Ports auf den gewünschten Zuständen (PA und PC auf 0 und PB und PD auf 1). Wo liegt mein Fehler?


$regfile = "m16def.dat" 'Mega 16 Def
$framesize = 32
$swstack = 32
$hwstack = 32
$baud = 9600


Config Porta = Output
Config Portb = Output
Config Portc = Output
Config Portd = Output

Porta = 0
Portc = 0

Portd = 1
Portb = 1

Declare Sub Led_an(byval Led As Integer)
Declare Sub Led_aus(byval Led As Integer)


Do

Call Led_an(111)

Loop


End


Sub Led_an(led As Integer)

Select Case Led

Case 111 :
Porta.0 = 1
Portd.0 = 0
Case 112 :
Porta.0 = 1
Portb.7 = 0
Case 113 :
Porta.0 = 1
Portb.6 = 0
Case 121 :
Porta.1 = 1
Portd.0 = 0
Case 122 :
Porta.1 = 1
Portb.7 = 0
Case 123 :
Porta.1 = 1
Portb.6 = 0
Case 131 :
Porta.2 = 1
Portd.0 = 0
Case 132 :
Porta.2 = 1
Portb.7 = 0
Case 133 :
Porta.2 = 1
Portb.6 = 0




Case 211 :
Porta.3 = 1
Portd.3 = 0
Case 212 :
Porta.3 = 1
Portd.2 = 0
Case 213 :
Porta.3 = 1
Portd.1 = 0
Case 221 :
Porta.4 = 1
Portd.3 = 0
Case 222 :
Porta.4 = 1
Portd.2 = 0
Case 223 :
Porta.4 = 1
Portd.1 = 0
Case 231 :
Porta.5 = 1
Portd.3 = 0
Case 232 :
Porta.5 = 1
Portd.2 = 0
Case 233 :
Porta.5 = 1
Portd.1 = 0





Case 311 :
Porta.6 = 1
Portd.6 = 0
Case 312 :
Porta.6 = 1
Portb.5 = 0
Case 313 :
Porta.6 = 1
Portb.4 = 0
Case 321 :
Porta.7 = 1
Portd.6 = 0
Case 322 :
Porta.7 = 1
Portb.5 = 0
Case 323 :
Porta.7 = 1
Portb.4 = 0
Case 331 :
Portc.7 = 1
Portd.6 = 0
Case 332 :
Portc.7 = 1
Portb.5 = 0
Case 333 :
Portc.7 = 1
Portb.4 = 0

End Select

End Sub




Sub Led_aus(led As Integer)

Select Case Led

Case 111 :
Porta.0 = 0
Portd.0 = 1
Case 112 :
Porta.0 = 0
Portb.7 = 1
Case 113 :
Porta.0 = 0
Portb.6 = 1
Case 121 :
Porta.1 = 0
Portd.0 = 1
Case 122 :
Porta.1 = 0
Portb.7 = 1
Case 123 :
Porta.1 = 0
Portb.6 = 1
Case 131 :
Porta.2 = 0
Portd.0 = 1
Case 132 :
Porta.2 = 0
Portb.7 = 1
Case 133 :
Porta.2 = 0
Portb.6 = 1




Case 211 :
Porta.3 = 0
Portd.3 = 1
Case 212 :
Porta.3 = 0
Portd.2 = 1
Case 213 :
Porta.3 = 0
Portd.1 = 1
Case 221 :
Porta.4 = 0
Portd.3 = 1
Case 222 :
Porta.4 = 0
Portd.2 = 1
Case 223 :
Porta.4 = 0
Portd.1 = 1
Case 231 :
Porta.5 = 0
Portd.3 = 1
Case 232 :
Porta.5 = 0
Portd.2 = 1
Case 233 :
Porta.5 = 0
Portd.1 = 1





Case 311 :
Porta.6 = 0
Portd.6 = 1
Case 312 :
Porta.6 = 0
Portb.5 = 1
Case 313 :
Porta.6 = 0
Portb.4 = 1
Case 321 :
Porta.7 = 0
Portd.6 = 1
Case 322 :
Porta.7 = 0
Portb.5 = 1
Case 323 :
Porta.7 = 0
Portb.4 = 1
Case 331 :
Portc.7 = 0
Portd.6 = 1
Case 332 :
Portc.7 = 0
Portb.5 = 1
Case 333 :
Portc.7 = 0
Portb.4 = 1

End Select

End Sub

StevieL
09.01.2008, 21:09
Hallo,

ich hab es nur mal überflogen, aber so werden, wenn ich es richtig gesehen habe, Port A und B auf 1 gesetzt, C und D auf 0. Ist das so gewollt?

oZe
09.01.2008, 23:24
Ja das ist so gewollt, da ich als Treiber einmal ein NPN Transistor Array benutze und einmal ein PNP Transistor Array. Wenn ich jetzt LED 111 einschalten will bekommt diese über PA1 Masse und über PB7 +5V. An PortA hängt das NPN Array daher muss ich dort auf 1 Schalten. An PortB hängt das PNP Array. Daher muss ich dort dann auf 0 Schalten.

Zum besseren Verständnis anbei der (zugegeben ziemlich unaufgeräumte) Schaltplan. K5 und K4 sind blos dummies für einen eventuellen taster für eine spätere erweiterung (Muster umschalten).

stefan_Z
10.01.2008, 02:03
Man kann das bestimmt VIEL trickreicher lösen...
Alle möglichen Zustände aller 27 LEDs kann man z.B. in ner LONG-Variablen erfassen ;-) Die musst du dann nur noch mit ner trickreichen Routine in die Matrix einspielen.
Ich würde mir da mal die Logikoperationen NOT AND usw. ansehen.
Geht bestimmt ganz einfach, ich bin jetzt aber auch zu faul, dir das zu machen ;-)

oZe
10.01.2008, 13:33
Das will ich ja gar nicht. Ich möchte erst mal wissen warum mein Programm nicht das tut was es soll. Irgendwas muss da noch falsch dran sein. Nur was? Ich steh echt langsam aufm Schlauch. Ich hab gestern noch bis 2 Uhr morgens dran rum geschraubt und es geht einfach nicht.

stefan_Z
10.01.2008, 15:41
Versuch mal die Stacks zu erweitern... das hilft bei Subs oft weiter... Ansonsten verstehe ich nicht, wieso es nicht gehen sollte... die Routine ist umständlich, aber klar zu vrstehen.

oZe
10.01.2008, 17:47
Ich hab den Fehler gefunden aber nicht ganz verstanden:



Porta = 0
Portc = 0

Portd = 1
Portb = 1



Mit diesen Befehlen wollte ich vor dem Start des Programmes erreichen, dass alle Pins um Port A und C auf Low gezogen werden und alle Pins im PortD und PortB auf high gesetzt werden, damit das NPN Array und das PNP Array komplett sperrt und somit keine LED durch den undefinierten Zustand der Ports zufällig an ist.

Scheinbar tut der Befehl aber nicht das was ich dachte. Wenn ich das PortA = 0 durch PortA.0 = 0 , PortA.1 = 0 usw. ersetze geht es.

Naja jetzt hab ich schon wieder das nächste Problem, das das PNP Array nicht sauber läuft... An den Eingängen des PNP Arrays habe ich genau das was ich per Software einstelle. Komischerweise schalten aber nahezu alle Ausgänge des Arrays auf high obwohl ich nur einen Eingang ansteuer... Woran das liegt kann ich mir mal wieder nicht erklären aber ich tüftel weiter dran.

StevieL
10.01.2008, 18:06
Hallo oZe,

das schreibst du am Besten so:



PortA = &B00000000
PortC = &B00000000

PortB = &B11111111 '255
PortD = &B11111111 '255

oZe
10.01.2008, 19:13
Alles klar! Werde ich einfügen damit es übersichtlicher bleibt ;-)

Danke erst mal für die wirklich nette Hilfe!

stefan_Z
11.01.2008, 00:47
die 0 ist natürlich &B0000000
die 255 (alle auf 1) ist &B1111111
Binär eben
PortB = 1 wäre nur &B00000001

PhoenixTS82
12.07.2008, 18:10
@oze

ich wollte auch mit ner funktion arbeiten,
aber ich will kein case benutzen.

das led aus kannst du dir doch sparen oder ?

ich habe immer biäres format, wenn ich jetzt eine ebene einschalte
setzich ich damit ja immer die andere automatisch wieder auf "0":

porta = &B00000001 'led reihe 1 ein, alle anderen aus

porta = &B00010000 'led reihe5 ein, alle anderen aus

stefan_Z
12.07.2008, 18:49
@Phoenix:
Nein, man MUSS einen Schwarz-Zyklus reinbauen und dann erst die Spalte wechseln! Ansonsten entstehen Geisterbilder, weil man ja nie Reihen und Spalten gleichzeitig schalten kann!

PhoenixTS82
12.07.2008, 20:07
mach ich doch damit

porta = &B00000001 'led reihe 1 ein, alle anderen aus

porta = &B00010000 'led reihe5 ein, alle anderen aus

mit der 2. anweisung schalte ich doch die anderen 7 pins auf gezielt "0", zumindest äuft das so bei mir...

stefan_Z
12.07.2008, 20:18
ja, aber PortA ist ja nur ein Teil - du hast immer 2 Ports bei einer Matrix - und einer der beiden muss beim Umschalten des Anderen auf 0 gesetzt werden.

PhoenixTS82
13.07.2008, 15:41
ja natürlich, ich habe ja nur an einem beispiel dagestellt