1

3

home

res_1

res_2

linux_mint

software

hardware

projekte

download

5

Kontakt:

mail@sedna-robotics.ch

-


-

Projekt LED Cube

-




LED CUBE 4 x 4 x 4



Bascom Basic Code

---------------------------

Die Initialisierung und der Effektcode :


Das erste, was der ATmega (Mikroprozessor) beim Booten macht, ist die Initialisierung.

$regfile = "m32def.dat"
$crystal = 14745600
$hwstack = 128
$framesize = 128
$swstack = 128

$prog &HFF , &HCE , &HD9 , &H00 ' generated. Take care that the chip supports all fuse bytes.

Config Serialin = Buffered , Size = 30 , Bytematch = 13

Config Timer0 = Timer , Prescale = 8 'Konfiguriere Timer0
Enable Timer0 'schalte den Timer0 Overflow-interrupt ein
On Timer0 Isr_von_timer0 'verzweige bei Timer0 überlauf zu Isr_von_Timer0
Enable Interrupts


Dieser Abschnitt definiert den verwendeten Prozessortyp,

und definiert die Geschwindigkeit mit der wir den Prozessor laufen lassen (14.7 Mhz).

Im weiteren wird das vorhandene RAM eingeteilt.

Es folgt die Einstellung der Fuse Bits.

Darauf folgt noch die Einstellung für die serielle Kommunikation, und der Timer mit seinem Interrupt.

'***********************************************************************
'* Subroutinen Definition
'***********************************************************************
Declare Sub Machmallangsam(ByVal Wieviel_mS as Word)
Declare Sub Seq_ZL_Rain(ByVal StartSpeed as word , Byval Endspeed as word)
Declare Sub Seq_ZL_Slowed_Down_Rnd_Fill(ByVal StartSpeed as word , Byval Endspeed as word)
Declare Sub Seq_ZLayer_Random_Fill(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Seq_XLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Seq_YLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Seq_ZLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Serial0charmatch()

In diesem Schritt werden die Subroutinen definiert.

Der Aufruf einer Subroutine erfolgt mit dem Befehl 'call' und macht in etwa dasselbe wie ein 'gosub'

einfach mit dem Unterschied das wir einer Subroutine noch ein paar Parameter mitgeben können wenn wir sie aufrufen.

Und eben, sie müssen wie hier vor dem Gebrauch erst mal definiert worden sein.

'***********************************************************************
'* Variables Definition
'***********************************************************************

Dim L_serout As Bit 'Serielle Debug Ausgabe

Dim L_function_key_pressed As Bit 'Function Key is pressed
Dim L_f1_key_pressed As Bit 'F1 Key is pressed
Dim L_f2_key_pressed As Bit 'F2 Key is pressed
Dim L_f3_key_pressed As Bit 'F3 Key is pressed
Dim L_f4_key_pressed As Bit

Dim W_counter_1 As Word
Dim W_counter_2 As Word

Dim B_layer As Byte
Dim W_delaytime As Word
Dim W_delaycount As Word


Dim Led_Columns(4 , 4 ) As Byte '16 Anode Columns, only bit 0..3 are used
Dim Xpos As Byte '0..4
Dim Ypos As Byte '0..4
Dim Zpos As Byte '0..4

Dim Locxcount As Byte
Dim Locycount As Byte
Dim Allonalloff As Boolean

Dim Datalatch0 As Byte
Dim Datalatch1 As Byte
Dim Datalatch2 As Byte
Dim Datalatch3 As Byte
Dim Datalatch4 As Byte
Dim Datalatch5 As Byte
Dim Datalatch6 As Byte
Dim Datalatch7 As Byte

Als nächstes werden hier die Variablen definiert.

Variablen sind Platzhalter für variable Werte.

Die Variablennamen können fast beliebig gewählt werden.

Die Werte die die Variablen annehmen können werden mit 'bit', 'byte','word' .. usw. definiert.

Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output

Config Pinb.3 = Input 'F1
Config Pinb.4 = Input 'F2

Config Portd.3 = Output 'Status

Config Pind.4 = Input 'F3
Config Pind.5 = Input 'F4

Config Portd.6 = Output 'Output Enable
Config Portd.7 = Output 'Error

Config Portc.0 = Output 'Layer0
Config Portc.1 = Output 'Layer1
Config Portc.2 = Output 'Layer2
Config Portc.3 = Output 'Layer3
Config Portc.4 = Output 'Layer4
Config Portc.5 = Output 'Layer5
Config Portc.6 = Output 'Layer6
Config Portc.7 = Output 'Layer7

Config Porta.0 = Output 'AVRPin_Data0
Config Porta.1 = Output 'AVRPin_Data1
Config Porta.2 = Output 'AVRPin_Data2
Config Porta.3 = Output 'AVRPin_Data3
Config Porta.4 = Output 'AVRPin_Data4
Config Porta.5 = Output 'AVRPin_Data5
Config Porta.6 = Output 'AVRPin_Data6
Config Porta.7 = Output 'AVRPin_Data7

Config Com1 = 38400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com1:" For Binary As #1 ' Sitzt auf PE0 und PE

Alle IO-Ports des ATmega sind bidirektional. Das heiss sie können Ein oder auch Ausgänge sein.

In diesem Schritt wird genau dieses festgelegt.

In unserem Programm sind alles Ausgänge mit Ausnahme von Input F1 .. F4.

Hier könnten wir eventuell noch ein paar Taster oder Schalter anschliessen.

'***********************************************************************
'* Aliases Definition
'***********************************************************************

Addr0 Alias Portb.0
Addr1 Alias Portb.1
Addr2 Alias Portb.2

Oe Alias Portd.6
Status Alias Portd.3

Layer0 Alias Portc.0
Layer1 Alias Portc.1
Layer2 Alias Portc.2
Layer3 Alias Portc.3
Layer4 Alias Portc.4
Layer5 Alias Portc.5
Layer6 Alias Portc.6
Layer7 Alias Portc.7

AVRPin_Data0 Alias Porta.0
AVRPin_Data1 Alias Porta.1
AVRPin_Data2 Alias Porta.2
AVRPin_Data3 Alias Porta.3
AVRPin_Data4 Alias Porta.4
AVRPin_Data5 Alias Porta.5
AVRPin_Data6 Alias Porta.6
AVRPin_Data7 Alias Porta.7

In diesem Schrit definieren weitere Variablen.

Diese Variablen sind jedoch direkt mit einem Anschluss am Microprozessor Chip verbunden.

Also z.B. geben wir im Program der Variable Addr0 den Wert '1' so wird unmittelbar der Pin 1 (PortB.0) des Prozessors eine '1' haben.

Oder elektrisch gesehen 5.0 VDC haben.

Wir können die Pins (Anschlüsse) also direkt über einen von uns gewählten Variablennamen ansprechen.

'***********************************************************************
'* Variables Preset
'***********************************************************************
Addr0 = 0 'Adresse voreinstellen -> Chip Select
Addr1 = 0
Addr2 = 0

Addr0 = 1
Addr1 = 1
Addr2 = 1

Layer0 = 0
Layer1 = 0
Layer2 = 0
Layer3 = 0
Layer4 = 0
Layer5 = 0
Layer6 = 0
Layer7 = 0
B_layer = 3
W_delaytime = 100
Oe = 0

Ganz wichtig ist nun das wir jeder Variablen einen Anfangswert zuweisen.

Das verhindert 'schlechte' Ueberraschungen in der folgenden programmierung.

'***********************************************************************
'* Program
'***********************************************************************
Gosub Dataalloff

Do 'Mainloop
'Porta = Rnd(255)

Call Seq_XLayer_Upwards(3 , 50)
Call Seq_YLayer_Upwards(3 , 50)
Call Seq_ZLayer_Upwards(3 , 50)
Call Seq_ZLayer_Random_Fill(100 , 10)
Call Seq_ZL_Slowed_Down_Rnd_Fill(1 , 50)
Gosub LED_Random_Fill
Call Machmallangsam(500)

Call Seq_ZL_Rain(1 , 100)
Led_Columns(0 , 0 ) .0 = 1
Call Machmallangsam(100)
'Led_Columns(0 , 0 ) .0 = 0 'index LED just for orientation
Gosub Dataalloff
Gosub Dataoutlineon
Call Machmallangsam(1000)
Loop

Dieser Abschnitt ist das eigentliche Programm.

Es fängt an mit 'gosub Dataalloff'. Hier wird eine Prozedur aufgerufen die einfach alle LED's löscht (ausschaltet).

Dann folgt der Befehl 'do' gefolgt von 'loop' (zuunterst).

Dieses ist eine sogenannte Endlosschleife.

Der Prozessor ist darin 'gefangen'. Er führt nur noch alle Kommandos aus die zwischen 'do' und 'loop' stehen.

Wir können also nach belieben Unterroutinen (Prozeduren) schreiben die wir dann von hier aus aufrufen.

Diesen Teil der Software nennen wir den Effekt Code.

Hier starten wir alle Animationen oder sonstige Effekte.


Software: Interrupt Routine


Das Herz des LED-Würfelcodes ist die Interruptroutine (ISR).

Durch die Einstellung am Timer0 Wird die ISR ca 1000 mal pro Sekunde aufgerufen.

Dieses geschieht gänzlich unabhängig vom Effekt Code der auch ausgeführt wird.

Die Prozessor kann aber nur einen Code zur selben Zeit ausführen!

Wird die ISR ausgeführt wird der Effekt Code also für einen kurzen Moment angehalten.

Im folgenden Bild (Timing Diagram) sieht man wie die ISR arbeitet.

Die oberen vier Linien zeigen die Ausgänge vom Kathoden Ebenen Treiber ULN 2803.

Ist die Linie unten ist die Ebene ausgeschaltet.

Ist die Linie oben ist die Ebene eingeschaltet.

Er ist also ersichtlich das immer eine Ebene eingeschaltet ist. Aber eben immer nur eine gleichzeitig!

Der Code hierzu sieht folgendermassen aus:

'***********************************************************************
'* ISR : Interrupt Service Routine
'***********************************************************************
Isr_von_timer0:
Oe = 1 'Output ausschalten

Incr B_layer
If B_layer = 4 Then
B_layer = 0
End If

If B_layer = 0 Then
Gosub Loaddata
Layer0 = 1
Layer1 = 0
Layer2 = 0
Layer3 = 0
End If

If B_layer = 1 Then
Gosub Loaddata
Layer0 = 0
Layer1 = 1
Layer2 = 0
Layer3 = 0
End If

If B_layer = 2 Then
Gosub Loaddata
Layer0 = 0
Layer1 = 0
Layer2 = 1
Layer3 = 0
End If

If B_layer = 3 Then
Gosub Loaddata
Layer0 = 0
Layer1 = 0
Layer2 = 0
Layer3 = 1
End If

OE = 0 'Output Einschalten
Return

Jedes mal wenn Die ISR ausgeführt wird wird Oe (der Output Enable) auf '1' gesetzt. Dieses schaltet die Latches aus.

Der LED Würfel wird somit ausgeschaltet.

Die Zählvariable 'B_layer' wird um eins erhöht (Kathodenebene).

Wir benötigen aber nur Ebene (Layer) 0-3, deshalb wird 'B_Layer' beim erreichen des Wertes 4 auf 0 gesetzt.

Mit 'gosub Loaddata' werden die jeweiligen Daten der aktuellen Kathodenebene geladen.

Vor dem verlassen des ISR wird der LED Würfel wieder eingeschaltet 'OE = 0'.

Dieses Signal (OE) ist die achte Linie von oben (07) im Timing Diagramm.

Mann kann auch schön sehen das das Signal OE fast die hälfte der Zeit ausgeschaltet ist.

Das heisst der Würfel leuchtet eigentlich nur die halbe Zeit.

Das ist nicht schlimm, der Würfel sowieso eher zu hell, aber mann sieht das da noch Verbesserungspotential vorhanden ist. ;-)



Speicherbedarf :



Der einfachste Weg, jedes Voxel zu adressieren, wäre eine dreidimensionale Pufferanordnung.

So was wie :

Array Würfel [x] [y] [z] in Bascom (Basic) : Led (4 , 4 , 4) As Boolean

Das heisst wir benötigen (4x4x4 Bit) 64 Bit um ein Bild zu speichern.


Dieses lässt sich in Bascom aber nicht realisieren.

Die kleinste Einheit die wie als Array programmieren können ist ein Byte.

Ein Byte besteht aus 8 Bits.


Das Array würde so aussehen Led (4 , 4 , 4) As Byte.

Das heisst wir benötigen (4x4x4 Bit x 8Bit) 512 Bit um ein Bild zu speichern.


Wir würden also 7/8 des Speicherplatzes verschwenden.


Die Addressierung der einzelnen LED‘s wirft aber noch ein ganz anderes Problem auf.

Wir wollen auch die Komponenten auf

der Platine voll ausnutzen. Wir haben zwei Latchspeicher die (jeweils 8) 16 Anodenreihen ansteuern können. Um diese Zwei Speicher (Latches) zu füllen brauchen wir zwei Bytes.


Wir benötigen also etwas Magie.


Die Speicheranordnung ist nun so organisiert:


Dim Led_Columns(4 , 4 ) As Byte

Wir verwenden also 16 Bytes (128bit) um ein Bild zu speichern, und verschleudern somit nur noch den halben Platz, da wir nur jeweils Bit 0 bis Bit 3 verwenden ? jeweils die halben Bytes (nennt sich Nibbles).


Hinzu kommt, falls wir einen Würfel mit 8x8x8 LED‘s bauen wollen. Wäre die Organisation :


Dim Led_Columns(8 , 8 ) As Byte


Was vom Speicherbedarf perfekt wäre und das Programm nicht grossartig geändert werden müsste.

Das Erklärt auch gleich warum die meisten LED Würfel eine 8 x 8 x 8 Struktur haben.


Die Datenstruktur ist also :

Led_Columns(4 , 4 ) As Byte

Die erste 4 steht für die X Achse, die zweite für die Y Achse.

Das ‚low nibble‘ also Bit 0 bis Bit 3 des Bytes stehen für die Z Achse.



Das Setzen eines Voxels (LED einschalten) mit den Koordinaten x = 4, y = 3, z = 2 erfordert den folgenden Code:

Led_Columns(5 , 3 ) .2 = 1


Achsen und Ebenen :



Im Bild sieht man die LED hinten unten leuchten, das ist die Koordinate (Voxel) 0,0,0

Nach rechts erhöht sich der Zähler der Y Achse bis 0,3,0.

Nach Vorne erhöht sich der Zähler für die X Achse bis 3,0,0.

Nach oben erhöht sich der Zahler für die Z Achse bis 0,0,3.


Wiederverwendbarer Code und Codegröße :

Im Mikrocontroller haben wir nur 32KB Speicher.

Das Programm muss also so klein wie möglich sein.


Deshalb verwenden (recyclen wir den Code so oft es geht. Es ist auch langweilig

immer dasselbe wieder zu schreiben, und die Lesbarkeit des Codes ist auch schlecht.


Will man zum Beispiel den ganzen Würfel leuchten lassen, und jedes LED einzeln anzusteuern, würde es alleine dafür 64 Instruktionen benötigen.


Die kleinste Einheit sind die LED‘s. Sie leuchten oder nicht.

Das ergibt dann ein Bit (1 oder 0).

Die nächst grössere Einheit wäre dann ev. eine Linie aus LED‘s, gefolgt von der nächsten Grösse einer Fläche. Die dann aus verschiedenen (4 in unserem 4x4x4 Würfel) Linien bestehen.

Der ganze Würfel wiederum besteht aus vier Flächen.


Das Ein- oder Ausschalten von LED‘s nennen wir Bilder.


Mehrere solcher Bilder hintereinander nennen wir eine Sequenz. Zu den Bildern kommt noch die Information wie oft die Sequenz gezeigt wird und wie langsam sie laufen soll.


Der Microprozessor lauft immer mit der gleichen Geschwindigkeit. Soll eine Sequenz langsam erscheinen, müssen wir den Prozessor ausbremsen

und ihn sozusagen mit hoher Geschwindigkeit nichts tun lassen.


Dies haben wir gelöst indem wir den Prozessor eine feste Zeit warten lassen.

In unserem Fall eine Milisekunde (also eine tausendstel Sekunde).

Um längere Zeit zu warten wiederholen wir einfach die Wartezeit. Um eine halbe Sekunde zu warten wiederholen wir also die feste Wartezeit 500 mal.












In dieser Ausrichtung verläuft die Y-Achse von links nach rechts. Die X-Achse geht von vorne nach hinten. Die Z-Achse geht von unten nach oben.

Koordinaten werden immer als x, y, z dargestellt.

Die Position 0,0,0 ist die untere linke hintere Ecke. Position 7,7,7 ist die obere rechte vorderste Ecke.


Wenn die Anzeige eine höhere Auflösung und mehr Farben hätte, hätten wir sin () und cos () Funktionen und all das verwenden können, um einen Blickfang zu machen. Mit zwei Farben (an und aus) und niedriger Auflösung müssen wir viele For – Next Schlaufen verwenden, um etwas sinnvolles zu machen.

In den nächsten Schritten führen wir Sie durch einige der Animationen, die wir gemacht haben und wie sie funktionieren. Unser Ziel ist es, Ihnen zu zeigen, wie Sie Animationen erstellen und Sie dazu inspirieren können, Ihre eigenen zu erstellen.



Programmierung des Microcontrollers :


Um den Microcontroller zu programmieren wird er mit einem Kabel (Adapter) mit einem PC verbunden. Der Adapter nennt sich ISP Programmer.


Da wir vorderhand mit Bascom Basic programmieren, verwenden wir auch den Adapter dieser Firma.



USB ISP Programmer


Zurzeit ist dieser wohl nicht mehr erhältlich. Er ist mit 39€ auch ein bisschen teuer.

Leider läuft Bascom Basic auch nur auf Windows.


Es gibt einige Alternativen z.B. :

https://learn.adafruit.com/usbtinyisp


Nebst dem eigentlichen Programmcode benötigt der Microcontroller auch eine Einstellung (Sicherungsbytes).


Der ATmega32 hat zwei Sicherungsbytes. Diese enthalten Einstellungen, die geladen werden müssen, bevor die CPU gestartet werden kann, wie Clock-Quelle und andere Sachen. Sie müssen Ihren ATmega so programmieren, dass er einen externen Hochgeschwindigkeits-Quarzoszillator verwendet und JTAG deaktiviert.

Wir setzen das untere Sicherungsbyte (lfuse) auf 0b11101111 und das High-Sicherungsbyte auf 0b11001001. (0b bedeutet, dass alles nach dem b binär ist).

Warnung: Wenn Sie dies falsch machen, können Sie Ihren ATmega leicht blockieren! Wenn Sie beispielsweise die Reset-Taste deaktivieren, können Sie sie nicht neu programmieren. Wenn Sie die falsche Taktquelle auswählen, wird möglicherweise überhaupt nicht gebootet oder die Software läuft nicht mit der richtigen Geschwindigkeit.





Bascom Programm Code Komplett :

'***********************************************************************
'* Programm : LED Cube 4x4x4 (LED Wuerfel 4x4x4)
'*
'* Compiler : BASCOM-AVR IDE 2.0.7.8
'* Hardware : Homebrew
'* Language : Basic
'* Chip type : ATMega32
'* Compiler : Bascom 2.0.7.8
'* From : Sedna Robotics Switzerland
'* Contact : mail@sedna-robotics.ch
'*
'***********************************************************************
'* Date : 17.11.2017
'***********************************************************************
'* Version : 0.09
'***********************************************************************
'It is partially prepared to run an 8x8x8 cube.
'Also there are preparations to have a rs232 connection to a pc.
'But we did not implement that really for the 4x4x4 cube.
'Makes more sense on a 8x8x8 cube.

$regfile = "m32def.dat"
$crystal = 14745600
$hwstack = 128
$framesize = 128
$swstack = 128

$prog &HFF , &HCE , &HD9 , &H00 ' generated. Take care that the chip supports all fuse bytes.

Config Serialin = Buffered , Size = 30 , Bytematch = 13

Config Timer0 = Timer , Prescale = 8 'Konfiguriere Timer0
Enable Timer0 'schalte den Timer0 Overflow-interrupt ein
On Timer0 Isr_von_timer0 'verzweige bei Timer0 überlauf zu Isr_von_Timer0
Enable Interrupts

'***********************************************************************
'* Subroutinen Definition
'***********************************************************************
Declare Sub Machmallangsam(ByVal Wieviel_mS as Word)
Declare Sub Seq_ZL_Rain(ByVal StartSpeed as word , Byval Endspeed as word)
Declare Sub Seq_ZL_Slowed_Down_Rnd_Fill(ByVal StartSpeed as word , Byval Endspeed as word)
Declare Sub Seq_ZLayer_Random_Fill(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Seq_XLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Seq_YLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Seq_ZLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Declare Sub Serial0charmatch()


'***********************************************************************
'* Variables Definition
'***********************************************************************

Dim L_serout As Bit 'Serielle Debug Ausgabe

Dim L_function_key_pressed As Bit 'Function Key is pressed
Dim L_f1_key_pressed As Bit 'F1 Key is pressed
Dim L_f2_key_pressed As Bit 'F2 Key is pressed
Dim L_f3_key_pressed As Bit 'F3 Key is pressed
Dim L_f4_key_pressed As Bit

Dim W_counter_1 As Word
Dim W_counter_2 As Word

Dim B_layer As Byte
Dim W_delaytime As Word
Dim W_delaycount As Word


Dim Led_Columns(4 , 4 ) As Byte '16 Anode Columns, only bit 0..3 are used
Dim Xpos As Byte '0..4
Dim Ypos As Byte '0..4
Dim Zpos As Byte '0..4

Dim Locxcount As Byte
Dim Locycount As Byte
Dim Allonalloff As Boolean

Dim Datalatch0 As Byte
Dim Datalatch1 As Byte
Dim Datalatch2 As Byte
Dim Datalatch3 As Byte
Dim Datalatch4 As Byte
Dim Datalatch5 As Byte
Dim Datalatch6 As Byte
Dim Datalatch7 As Byte

'***********************************************************************
'* Configurations 1
'***********************************************************************
Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output

Config Pinb.3 = Input 'F1
Config Pinb.4 = Input 'F2

Config Portd.3 = Output 'Status

Config Pind.4 = Input 'F3
Config Pind.5 = Input 'F4

Config Portd.6 = Output 'Output Enable
Config Portd.7 = Output 'Error

Config Portc.0 = Output 'Layer0
Config Portc.1 = Output 'Layer1
Config Portc.2 = Output 'Layer2
Config Portc.3 = Output 'Layer3
Config Portc.4 = Output 'Layer4
Config Portc.5 = Output 'Layer5
Config Portc.6 = Output 'Layer6
Config Portc.7 = Output 'Layer7

Config Porta.0 = Output 'AVRPin_Data0
Config Porta.1 = Output 'AVRPin_Data1
Config Porta.2 = Output 'AVRPin_Data2
Config Porta.3 = Output 'AVRPin_Data3
Config Porta.4 = Output 'AVRPin_Data4
Config Porta.5 = Output 'AVRPin_Data5
Config Porta.6 = Output 'AVRPin_Data6
Config Porta.7 = Output 'AVRPin_Data7

Config Com1 = 38400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com1:" For Binary As #1 ' Sitzt auf PE0 und PE1

'***********************************************************************
'* Aliases Definition
'***********************************************************************

Addr0 Alias Portb.0
Addr1 Alias Portb.1
Addr2 Alias Portb.2

Oe Alias Portd.6
Status Alias Portd.3

Layer0 Alias Portc.0
Layer1 Alias Portc.1
Layer2 Alias Portc.2
Layer3 Alias Portc.3
Layer4 Alias Portc.4
Layer5 Alias Portc.5
Layer6 Alias Portc.6
Layer7 Alias Portc.7

AVRPin_Data0 Alias Porta.0
AVRPin_Data1 Alias Porta.1
AVRPin_Data2 Alias Porta.2
AVRPin_Data3 Alias Porta.3
AVRPin_Data4 Alias Porta.4
AVRPin_Data5 Alias Porta.5
AVRPin_Data6 Alias Porta.6
AVRPin_Data7 Alias Porta.7


'***********************************************************************
'* Variables Preset
'***********************************************************************
Addr0 = 0 'Adresse voreinstellen -> Chip Select
Addr1 = 0
Addr2 = 0

Addr0 = 1
Addr1 = 1
Addr2 = 1

Layer0 = 0
Layer1 = 0
Layer2 = 0
Layer3 = 0
Layer4 = 0
Layer5 = 0
Layer6 = 0
Layer7 = 0
B_layer = 3
W_delaytime = 100
Oe = 0

'***********************************************************************
'* Program
'***********************************************************************
Gosub Dataalloff

Do 'Mainloop
'Porta = Rnd(255)

Call Seq_XLayer_Upwards(3 , 50)
Call Seq_YLayer_Upwards(3 , 50)
Call Seq_ZLayer_Upwards(3 , 50)
Call Seq_ZLayer_Random_Fill(100 , 10)
Call Seq_ZL_Slowed_Down_Rnd_Fill(1 , 50)
Gosub LED_Random_Fill
Call Machmallangsam(500)

Call Seq_ZL_Rain(1 , 100)
Led_Columns(0 , 0 ) .0 = 1
Call Machmallangsam(100)
'Led_Columns(0 , 0 ) .0 = 0 'index LED just for orientation
Gosub Dataalloff
Gosub Dataoutlineon
Call Machmallangsam(1000)
Loop


Sub Machmallangsam(ByVal Wieviel_ms as word)
Local Zaehler as byte

For Zaehler = 1 to Wieviel_mS
Waitms 1
next
end Sub

Sub Seq_ZL_Rain(ByVal StartSpeed as word , Byval Endspeed as word)
Local Layer as byte
For Layer = 0 to 3
For Locxcount = 0 To 3
For Locycount = 0 To 3
Shift Led_Columns(locxcount , Locycount ) , Right
Next
Next
Gosub Led_ZLayer3_Off
Call Machmallangsam(1000)
next
End Sub

Sub Seq_ZL_Slowed_Down_Rnd_Fill(ByVal StartSpeed as word , Byval Endspeed as word)
Local Zaehler as byte
Local Stepnr as single
For Zaehler = 1 to EndSpeed - Startspeed step 1
Stepnr = Zaehler / 4
Call Seq_ZLayer_Random_Fill(1 , Zaehler)
next
End Sub

Sub Seq_ZLayer_Random_Fill(ByVal Repeats as word , Byval Wieviel_ms as word)
Local Zaehler as byte
For Zaehler = 1 to Repeats
Gosub LED_Random_Fill
Call Machmallangsam(Wieviel_ms)
next
End Sub

Sub Seq_XLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Local Zaehler as byte
For Zaehler = 1 to Repeats
Gosub Led_XLayer0_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_XLayer0_Off
Gosub Led_XLayer1_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_XLayer1_Off
Gosub Led_XLayer2_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_XLayer2_Off
Gosub Led_XLayer3_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_XLayer3_Off
next
End Sub

Sub Seq_YLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Local Zaehler as byte
For Zaehler = 1 to Repeats
Gosub Led_YLayer0_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_YLayer0_Off
Gosub Led_YLayer1_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_YLayer1_Off
Gosub Led_YLayer2_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_YLayer2_Off
Gosub Led_YLayer3_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_YLayer3_Off
next
End Sub

Sub Seq_ZLayer_Upwards(ByVal Repeats as word , Byval Wieviel_ms as word)
Local Zaehler as byte
For Zaehler = 1 to Repeats
Gosub Led_ZLayer0_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_ZLayer0_Off
Gosub Led_ZLayer1_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_ZLayer1_Off
Gosub Led_ZLayer2_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_ZLayer2_Off
Gosub Led_ZLayer3_On
Call Machmallangsam(Wieviel_ms)
Gosub Led_ZLayer3_Off
next
End Sub

LED_XLayer0_On:
Led_Columns(0 , 0 ) .0 = 1
Led_Columns(0 , 1 ) .0 = 1
Led_Columns(0 , 2 ) .0 = 1
Led_Columns(0 , 3 ) .0 = 1
Led_Columns(0 , 0 ) .1 = 1
Led_Columns(0 , 1 ) .1 = 1
Led_Columns(0 , 2 ) .1 = 1
Led_Columns(0 , 3 ) .1 = 1
Led_Columns(0 , 0 ) .2 = 1
Led_Columns(0 , 1 ) .2 = 1
Led_Columns(0 , 2 ) .2 = 1
Led_Columns(0 , 3 ) .2 = 1
Led_Columns(0 , 0 ) .3 = 1
Led_Columns(0 , 1 ) .3 = 1
Led_Columns(0 , 2 ) .3 = 1
Led_Columns(0 , 3 ) .3 = 1
Return

LED_XLayer0_Off:
Led_Columns(0 , 0 ) .0 = 0
Led_Columns(0 , 1 ) .0 = 0
Led_Columns(0 , 2 ) .0 = 0
Led_Columns(0 , 3 ) .0 = 0
Led_Columns(0 , 0 ) .1 = 0
Led_Columns(0 , 1 ) .1 = 0
Led_Columns(0 , 2 ) .1 = 0
Led_Columns(0 , 3 ) .1 = 0
Led_Columns(0 , 0 ) .2 = 0
Led_Columns(0 , 1 ) .2 = 0
Led_Columns(0 , 2 ) .2 = 0
Led_Columns(0 , 3 ) .2 = 0
Led_Columns(0 , 0 ) .3 = 0
Led_Columns(0 , 1 ) .3 = 0
Led_Columns(0 , 2 ) .3 = 0
Led_Columns(0 , 3 ) .3 = 0
Return

LED_XLayer1_On:
Led_Columns(1 , 0 ) .0 = 1
Led_Columns(1 , 1 ) .0 = 1
Led_Columns(1 , 2 ) .0 = 1
Led_Columns(1 , 3 ) .0 = 1
Led_Columns(1 , 0 ) .1 = 1
Led_Columns(1 , 1 ) .1 = 1
Led_Columns(1 , 2 ) .1 = 1
Led_Columns(1 , 3 ) .1 = 1
Led_Columns(1 , 0 ) .2 = 1
Led_Columns(1 , 1 ) .2 = 1
Led_Columns(1 , 2 ) .2 = 1
Led_Columns(1 , 3 ) .2 = 1
Led_Columns(1 , 0 ) .3 = 1
Led_Columns(1 , 1 ) .3 = 1
Led_Columns(1 , 2 ) .3 = 1
Led_Columns(1 , 3 ) .3 = 1
Return

LED_XLayer1_Off:
Led_Columns(1 , 0 ) .0 = 0
Led_Columns(1 , 1 ) .0 = 0
Led_Columns(1 , 2 ) .0 = 0
Led_Columns(1 , 3 ) .0 = 0
Led_Columns(1 , 0 ) .1 = 0
Led_Columns(1 , 1 ) .1 = 0
Led_Columns(1 , 2 ) .1 = 0
Led_Columns(1 , 3 ) .1 = 0
Led_Columns(1 , 0 ) .2 = 0
Led_Columns(1 , 1 ) .2 = 0
Led_Columns(1 , 2 ) .2 = 0
Led_Columns(1 , 3 ) .2 = 0
Led_Columns(1 , 0 ) .3 = 0
Led_Columns(1 , 1 ) .3 = 0
Led_Columns(1 , 2 ) .3 = 0
Led_Columns(1 , 3 ) .3 = 0
Return

LED_XLayer2_On:
Led_Columns(2 , 0 ) .0 = 1
Led_Columns(2 , 1 ) .0 = 1
Led_Columns(2 , 2 ) .0 = 1
Led_Columns(2 , 3 ) .0 = 1
Led_Columns(2 , 0 ) .1 = 1
Led_Columns(2 , 1 ) .1 = 1
Led_Columns(2 , 2 ) .1 = 1
Led_Columns(2 , 3 ) .1 = 1
Led_Columns(2 , 0 ) .2 = 1
Led_Columns(2 , 1 ) .2 = 1
Led_Columns(2 , 2 ) .2 = 1
Led_Columns(2 , 3 ) .2 = 1
Led_Columns(2 , 0 ) .3 = 1
Led_Columns(2 , 1 ) .3 = 1
Led_Columns(2 , 2 ) .3 = 1
Led_Columns(2 , 3 ) .3 = 1
Return

LED_XLayer2_Off:
Led_Columns(2 , 0 ) .0 = 0
Led_Columns(2 , 1 ) .0 = 0
Led_Columns(2 , 2 ) .0 = 0
Led_Columns(2 , 3 ) .0 = 0
Led_Columns(2 , 0 ) .1 = 0
Led_Columns(2 , 1 ) .1 = 0
Led_Columns(2 , 2 ) .1 = 0
Led_Columns(2 , 3 ) .1 = 0
Led_Columns(2 , 0 ) .2 = 0
Led_Columns(2 , 1 ) .2 = 0
Led_Columns(2 , 2 ) .2 = 0
Led_Columns(2 , 3 ) .2 = 0
Led_Columns(2 , 0 ) .3 = 0
Led_Columns(2 , 1 ) .3 = 0
Led_Columns(2 , 2 ) .3 = 0
Led_Columns(2 , 3 ) .3 = 0
Return

LED_XLayer3_On:
Led_Columns(3 , 0 ) .0 = 1
Led_Columns(3 , 1 ) .0 = 1
Led_Columns(3 , 2 ) .0 = 1
Led_Columns(3 , 3 ) .0 = 1
Led_Columns(3 , 0 ) .1 = 1
Led_Columns(3 , 1 ) .1 = 1
Led_Columns(3 , 2 ) .1 = 1
Led_Columns(3 , 3 ) .1 = 1
Led_Columns(3 , 0 ) .2 = 1
Led_Columns(3 , 1 ) .2 = 1
Led_Columns(3 , 2 ) .2 = 1
Led_Columns(3 , 3 ) .2 = 1
Led_Columns(3 , 0 ) .3 = 1
Led_Columns(3 , 1 ) .3 = 1
Led_Columns(3 , 2 ) .3 = 1
Led_Columns(3 , 3 ) .3 = 1
Return

LED_XLayer3_Off:
Led_Columns(3 , 0 ) .0 = 0
Led_Columns(3 , 1 ) .0 = 0
Led_Columns(3 , 2 ) .0 = 0
Led_Columns(3 , 3 ) .0 = 0
Led_Columns(3 , 0 ) .1 = 0
Led_Columns(3 , 1 ) .1 = 0
Led_Columns(3 , 2 ) .1 = 0
Led_Columns(3 , 3 ) .1 = 0
Led_Columns(3 , 0 ) .2 = 0
Led_Columns(3 , 1 ) .2 = 0
Led_Columns(3 , 2 ) .2 = 0
Led_Columns(3 , 3 ) .2 = 0
Led_Columns(3 , 0 ) .3 = 0
Led_Columns(3 , 1 ) .3 = 0
Led_Columns(3 , 2 ) .3 = 0
Led_Columns(3 , 3 ) .3 = 0
Return

LED_YLayer0_On:
Led_Columns(0 , 0 ) .0 = 1
Led_Columns(1 , 0 ) .0 = 1
Led_Columns(2 , 0 ) .0 = 1
Led_Columns(3 , 0 ) .0 = 1
Led_Columns(0 , 0 ) .1 = 1
Led_Columns(1 , 0 ) .1 = 1
Led_Columns(2 , 0 ) .1 = 1
Led_Columns(3 , 0 ) .1 = 1
Led_Columns(0 , 0 ) .2 = 1
Led_Columns(1 , 0 ) .2 = 1
Led_Columns(2 , 0 ) .2 = 1
Led_Columns(3 , 0 ) .2 = 1
Led_Columns(0 , 0 ) .3 = 1
Led_Columns(1 , 0 ) .3 = 1
Led_Columns(2 , 0 ) .3 = 1
Led_Columns(3 , 0 ) .3 = 1
Return

LED_YLayer0_Off:
Led_Columns(0 , 0 ) .0 = 0
Led_Columns(1 , 0 ) .0 = 0
Led_Columns(2 , 0 ) .0 = 0
Led_Columns(3 , 0 ) .0 = 0
Led_Columns(0 , 0 ) .1 = 0
Led_Columns(1 , 0 ) .1 = 0
Led_Columns(2 , 0 ) .1 = 0
Led_Columns(3 , 0 ) .1 = 0
Led_Columns(0 , 0 ) .2 = 0
Led_Columns(1 , 0 ) .2 = 0
Led_Columns(2 , 0 ) .2 = 0
Led_Columns(3 , 0 ) .2 = 0
Led_Columns(0 , 0 ) .3 = 0
Led_Columns(1 , 0 ) .3 = 0
Led_Columns(2 , 0 ) .3 = 0
Led_Columns(3 , 0 ) .3 = 0
Return

LED_YLayer1_On:
Led_Columns(0 , 1 ) .0 = 1
Led_Columns(1 , 1 ) .0 = 1
Led_Columns(2 , 1 ) .0 = 1
Led_Columns(3 , 1 ) .0 = 1
Led_Columns(0 , 1 ) .1 = 1
Led_Columns(1 , 1 ) .1 = 1
Led_Columns(2 , 1 ) .1 = 1
Led_Columns(3 , 1 ) .1 = 1
Led_Columns(0 , 1 ) .2 = 1
Led_Columns(1 , 1 ) .2 = 1
Led_Columns(2 , 1 ) .2 = 1
Led_Columns(3 , 1 ) .2 = 1
Led_Columns(0 , 1 ) .3 = 1
Led_Columns(1 , 1 ) .3 = 1
Led_Columns(2 , 1 ) .3 = 1
Led_Columns(3 , 1 ) .3 = 1
Return

LED_YLayer1_Off:
Led_Columns(0 , 1 ) .0 = 0
Led_Columns(1 , 1 ) .0 = 0
Led_Columns(2 , 1 ) .0 = 0
Led_Columns(3 , 1 ) .0 = 0
Led_Columns(0 , 1 ) .1 = 0
Led_Columns(1 , 1 ) .1 = 0
Led_Columns(2 , 1 ) .1 = 0
Led_Columns(3 , 1 ) .1 = 0
Led_Columns(0 , 1 ) .2 = 0
Led_Columns(1 , 1 ) .2 = 0
Led_Columns(2 , 1 ) .2 = 0
Led_Columns(3 , 1 ) .2 = 0
Led_Columns(0 , 1 ) .3 = 0
Led_Columns(1 , 1 ) .3 = 0
Led_Columns(2 , 1 ) .3 = 0
Led_Columns(3 , 1 ) .3 = 0
Return

LED_YLayer2_On:
Led_Columns(0 , 2 ) .0 = 1
Led_Columns(1 , 2 ) .0 = 1
Led_Columns(2 , 2 ) .0 = 1
Led_Columns(3 , 2 ) .0 = 1
Led_Columns(0 , 2 ) .1 = 1
Led_Columns(1 , 2 ) .1 = 1
Led_Columns(2 , 2 ) .1 = 1
Led_Columns(3 , 2 ) .1 = 1
Led_Columns(0 , 2 ) .2 = 1
Led_Columns(1 , 2 ) .2 = 1
Led_Columns(2 , 2 ) .2 = 1
Led_Columns(3 , 2 ) .2 = 1
Led_Columns(0 , 2 ) .3 = 1
Led_Columns(1 , 2 ) .3 = 1
Led_Columns(2 , 2 ) .3 = 1
Led_Columns(3 , 2 ) .3 = 1
Return

LED_YLayer2_Off:
Led_Columns(0 , 2 ) .0 = 0
Led_Columns(1 , 2 ) .0 = 0
Led_Columns(2 , 2 ) .0 = 0
Led_Columns(3 , 2 ) .0 = 0
Led_Columns(0 , 2 ) .1 = 0
Led_Columns(1 , 2 ) .1 = 0
Led_Columns(2 , 2 ) .1 = 0
Led_Columns(3 , 2 ) .1 = 0
Led_Columns(0 , 2 ) .2 = 0
Led_Columns(1 , 2 ) .2 = 0
Led_Columns(2 , 2 ) .2 = 0
Led_Columns(3 , 2 ) .2 = 0
Led_Columns(0 , 2 ) .3 = 0
Led_Columns(1 , 2 ) .3 = 0
Led_Columns(2 , 2 ) .3 = 0
Led_Columns(3 , 2 ) .3 = 0
Return

LED_YLayer3_On:
Led_Columns(0 , 3 ) .0 = 1
Led_Columns(1 , 3 ) .0 = 1
Led_Columns(2 , 3 ) .0 = 1
Led_Columns(3 , 3 ) .0 = 1
Led_Columns(0 , 3 ) .1 = 1
Led_Columns(1 , 3 ) .1 = 1
Led_Columns(2 , 3 ) .1 = 1
Led_Columns(3 , 3 ) .1 = 1
Led_Columns(0 , 3 ) .2 = 1
Led_Columns(1 , 3 ) .2 = 1
Led_Columns(2 , 3 ) .2 = 1
Led_Columns(3 , 3 ) .2 = 1
Led_Columns(0 , 3 ) .3 = 1
Led_Columns(1 , 3 ) .3 = 1
Led_Columns(2 , 3 ) .3 = 1
Led_Columns(3 , 3 ) .3 = 1
Return

LED_YLayer3_Off:
Led_Columns(0 , 3 ) .0 = 0
Led_Columns(1 , 3 ) .0 = 0
Led_Columns(2 , 3 ) .0 = 0
Led_Columns(3 , 3 ) .0 = 0
Led_Columns(0 , 3 ) .1 = 0
Led_Columns(1 , 3 ) .1 = 0
Led_Columns(2 , 3 ) .1 = 0
Led_Columns(3 , 3 ) .1 = 0
Led_Columns(0 , 3 ) .2 = 0
Led_Columns(1 , 3 ) .2 = 0
Led_Columns(2 , 3 ) .2 = 0
Led_Columns(3 , 3 ) .2 = 0
Led_Columns(0 , 3 ) .3 = 0
Led_Columns(1 , 3 ) .3 = 0
Led_Columns(2 , 3 ) .3 = 0
Led_Columns(3 , 3 ) .3 = 0
Return

LED_ZLayer0_On:
Led_Columns(0 , 0 ) .0 = 1
Led_Columns(0 , 1 ) .0 = 1
Led_Columns(0 , 2 ) .0 = 1
Led_Columns(0 , 3 ) .0 = 1
Led_Columns(1 , 0 ) .0 = 1
Led_Columns(1 , 1 ) .0 = 1
Led_Columns(1 , 2 ) .0 = 1
Led_Columns(1 , 3 ) .0 = 1
Led_Columns(2 , 0 ) .0 = 1
Led_Columns(2 , 1 ) .0 = 1
Led_Columns(2 , 2 ) .0 = 1
Led_Columns(2 , 3 ) .0 = 1
Led_Columns(3 , 0 ) .0 = 1
Led_Columns(3 , 1 ) .0 = 1
Led_Columns(3 , 2 ) .0 = 1
Led_Columns(3 , 3 ) .0 = 1
Return

LED_ZLayer0_Off:
Led_Columns(0 , 0 ) .0 = 0
Led_Columns(0 , 1 ) .0 = 0
Led_Columns(0 , 2 ) .0 = 0
Led_Columns(0 , 3 ) .0 = 0
Led_Columns(1 , 0 ) .0 = 0
Led_Columns(1 , 1 ) .0 = 0
Led_Columns(1 , 2 ) .0 = 0
Led_Columns(1 , 3 ) .0 = 0
Led_Columns(2 , 0 ) .0 = 0
Led_Columns(2 , 1 ) .0 = 0
Led_Columns(2 , 2 ) .0 = 0
Led_Columns(2 , 3 ) .0 = 0
Led_Columns(3 , 0 ) .0 = 0
Led_Columns(3 , 1 ) .0 = 0
Led_Columns(3 , 2 ) .0 = 0
Led_Columns(3 , 3 ) .0 = 0
Return

LED_ZLayer1_On:
Led_Columns(0 , 0 ) .1 = 1
Led_Columns(0 , 1 ) .1 = 1
Led_Columns(0 , 2 ) .1 = 1
Led_Columns(0 , 3 ) .1 = 1
Led_Columns(1 , 0 ) .1 = 1
Led_Columns(1 , 1 ) .1 = 1
Led_Columns(1 , 2 ) .1 = 1
Led_Columns(1 , 3 ) .1 = 1
Led_Columns(2 , 0 ) .1 = 1
Led_Columns(2 , 1 ) .1 = 1
Led_Columns(2 , 2 ) .1 = 1
Led_Columns(2 , 3 ) .1 = 1
Led_Columns(3 , 0 ) .1 = 1
Led_Columns(3 , 1 ) .1 = 1
Led_Columns(3 , 2 ) .1 = 1
Led_Columns(3 , 3 ) .1 = 1
Return

LED_ZLayer1_Off:
Led_Columns(0 , 0 ) .1 = 0
Led_Columns(0 , 1 ) .1 = 0
Led_Columns(0 , 2 ) .1 = 0
Led_Columns(0 , 3 ) .1 = 0
Led_Columns(1 , 0 ) .1 = 0
Led_Columns(1 , 1 ) .1 = 0
Led_Columns(1 , 2 ) .1 = 0
Led_Columns(1 , 3 ) .1 = 0
Led_Columns(2 , 0 ) .1 = 0
Led_Columns(2 , 1 ) .1 = 0
Led_Columns(2 , 2 ) .1 = 0
Led_Columns(2 , 3 ) .1 = 0
Led_Columns(3 , 0 ) .1 = 0
Led_Columns(3 , 1 ) .1 = 0
Led_Columns(3 , 2 ) .1 = 0
Led_Columns(3 , 3 ) .1 = 0
Return


LED_ZLayer2_On:
Led_Columns(0 , 0 ) .2 = 1
Led_Columns(0 , 1 ) .2 = 1
Led_Columns(0 , 2 ) .2 = 1
Led_Columns(0 , 3 ) .2 = 1
Led_Columns(1 , 0 ) .2 = 1
Led_Columns(1 , 1 ) .2 = 1
Led_Columns(1 , 2 ) .2 = 1
Led_Columns(1 , 3 ) .2 = 1
Led_Columns(2 , 0 ) .2 = 1
Led_Columns(2 , 1 ) .2 = 1
Led_Columns(2 , 2 ) .2 = 1
Led_Columns(2 , 3 ) .2 = 1
Led_Columns(3 , 0 ) .2 = 1
Led_Columns(3 , 1 ) .2 = 1
Led_Columns(3 , 2 ) .2 = 1
Led_Columns(3 , 3 ) .2 = 1
Return

LED_ZLayer2_Off:
Led_Columns(0 , 0 ) .2 = 0
Led_Columns(0 , 1 ) .2 = 0
Led_Columns(0 , 2 ) .2 = 0
Led_Columns(0 , 3 ) .2 = 0
Led_Columns(1 , 0 ) .2 = 0
Led_Columns(1 , 1 ) .2 = 0
Led_Columns(1 , 2 ) .2 = 0
Led_Columns(1 , 3 ) .2 = 0
Led_Columns(2 , 0 ) .2 = 0
Led_Columns(2 , 1 ) .2 = 0
Led_Columns(2 , 2 ) .2 = 0
Led_Columns(2 , 3 ) .2 = 0
Led_Columns(3 , 0 ) .2 = 0
Led_Columns(3 , 1 ) .2 = 0
Led_Columns(3 , 2 ) .2 = 0
Led_Columns(3 , 3 ) .2 = 0
Return

LED_ZLayer3_On:
Led_Columns(0 , 0 ) .3 = 1
Led_Columns(0 , 1 ) .3 = 1
Led_Columns(0 , 2 ) .3 = 1
Led_Columns(0 , 3 ) .3 = 1
Led_Columns(1 , 0 ) .3 = 1
Led_Columns(1 , 1 ) .3 = 1
Led_Columns(1 , 2 ) .3 = 1
Led_Columns(1 , 3 ) .3 = 1
Led_Columns(2 , 0 ) .3 = 1
Led_Columns(2 , 1 ) .3 = 1
Led_Columns(2 , 2 ) .3 = 1
Led_Columns(2 , 3 ) .3 = 1
Led_Columns(3 , 0 ) .3 = 1
Led_Columns(3 , 1 ) .3 = 1
Led_Columns(3 , 2 ) .3 = 1
Led_Columns(3 , 3 ) .3 = 1
Return

LED_ZLayer3_Off:
Led_Columns(0 , 0 ) .3 = 0
Led_Columns(0 , 1 ) .3 = 0
Led_Columns(0 , 2 ) .3 = 0
Led_Columns(0 , 3 ) .3 = 0
Led_Columns(1 , 0 ) .3 = 0
Led_Columns(1 , 1 ) .3 = 0
Led_Columns(1 , 2 ) .3 = 0
Led_Columns(1 , 3 ) .3 = 0
Led_Columns(2 , 0 ) .3 = 0
Led_Columns(2 , 1 ) .3 = 0
Led_Columns(2 , 2 ) .3 = 0
Led_Columns(2 , 3 ) .3 = 0
Led_Columns(3 , 0 ) .3 = 0
Led_Columns(3 , 1 ) .3 = 0
Led_Columns(3 , 2 ) .3 = 0
Led_Columns(3 , 3 ) .3 = 0
Return


'***********************************************************************
'* Sub : All On
'***********************************************************************
Dataallon:
For Locxcount = 0 To 3
For Locycount = 0 To 3
Led_Columns(locxcount , Locycount ) = 255
Next
Next
Return

'***********************************************************************
'* Sub : All Off (Clear)
'***********************************************************************
Dataalloff:
For Locxcount = 0 To 3
For Locycount = 0 To 3
Led_Columns(locxcount , Locycount ) = 0
Next
Next
Return

'***********************************************************************
'* Sub : All Random Fill
'***********************************************************************
LED_Random_Fill:
For Locxcount = 0 To 3
For Locycount = 0 To 3
Led_Columns(locxcount , Locycount ) = Rnd(255)
Next
Next
Return

'***********************************************************************
'* Sub : OutLine
'***********************************************************************
Dataoutlineon:
Led_Columns(0 , 0 ) .0 = 1
Led_Columns(0 , 1 ) .0 = 1
Led_Columns(0 , 2 ) .0 = 1
Led_Columns(0 , 3 ) .0 = 1
Led_Columns(1 , 0 ) .0 = 1
Led_Columns(1 , 1 ) .0 = 0
Led_Columns(1 , 2 ) .0 = 0
Led_Columns(1 , 3 ) .0 = 1

Led_Columns(2 , 0 ) .0 = 1
Led_Columns(2 , 1 ) .0 = 0
Led_Columns(2 , 2 ) .0 = 0
Led_Columns(2 , 3 ) .0 = 1
Led_Columns(3 , 0 ) .0 = 1
Led_Columns(3 , 1 ) .0 = 1
Led_Columns(3 , 2 ) .0 = 1
Led_Columns(3 , 3 ) .0 = 1

Led_Columns(0 , 0 ) .1 = 1
Led_Columns(0 , 1 ) .1 = 0
Led_Columns(0 , 2 ) .1 = 0
Led_Columns(0 , 3 ) .1 = 1
Led_Columns(1 , 0 ) .1 = 0
Led_Columns(1 , 1 ) .1 = 0
Led_Columns(1 , 2 ) .1 = 0
Led_Columns(1 , 3 ) .1 = 0

Led_Columns(2 , 0 ) .1 = 0
Led_Columns(2 , 1 ) .1 = 0
Led_Columns(2 , 2 ) .1 = 0
Led_Columns(2 , 3 ) .1 = 0
Led_Columns(3 , 0 ) .1 = 1
Led_Columns(3 , 1 ) .1 = 0
Led_Columns(3 , 2 ) .1 = 0
Led_Columns(3 , 3 ) .1 = 1

Led_Columns(0 , 0 ) .2 = 1
Led_Columns(0 , 1 ) .2 = 0
Led_Columns(0 , 2 ) .2 = 0
Led_Columns(0 , 3 ) .2 = 1
Led_Columns(1 , 0 ) .2 = 0
Led_Columns(1 , 1 ) .2 = 0
Led_Columns(1 , 2 ) .2 = 0
Led_Columns(1 , 3 ) .2 = 0

Led_Columns(2 , 0 ) .2 = 0
Led_Columns(2 , 1 ) .2 = 0
Led_Columns(2 , 2 ) .2 = 0
Led_Columns(2 , 3 ) .2 = 0
Led_Columns(3 , 0 ) .2 = 1
Led_Columns(3 , 1 ) .2 = 0
Led_Columns(3 , 2 ) .2 = 0
Led_Columns(3 , 3 ) .2 = 1

Led_Columns(0 , 0 ) .3 = 1
Led_Columns(0 , 1 ) .3 = 1
Led_Columns(0 , 2 ) .3 = 1
Led_Columns(0 , 3 ) .3 = 1
Led_Columns(1 , 0 ) .3 = 1
Led_Columns(1 , 1 ) .3 = 0
Led_Columns(1 , 2 ) .3 = 0
Led_Columns(1 , 3 ) .3 = 1

Led_Columns(2 , 0 ) .3 = 1
Led_Columns(2 , 1 ) .3 = 0
Led_Columns(2 , 2 ) .3 = 0
Led_Columns(2 , 3 ) .3 = 1
Led_Columns(3 , 0 ) .3 = 1
Led_Columns(3 , 1 ) .3 = 1
Led_Columns(3 , 2 ) .3 = 1
Led_Columns(3 , 3 ) .3 = 1
Return

'***********************************************************************
'* Sub :
'***********************************************************************
Dataoutlineoff_2:
Gosub Dataalloff
Led_Columns(0 , 0 ) .0 = 0
Led_Columns(0 , 1 ) .0 = 0
Led_Columns(0 , 2 ) .0 = 0
Led_Columns(0 , 3 ) .0 = 0
Led_Columns(1 , 0 ) .0 = 0
Led_Columns(1 , 1 ) .0 = 0
Led_Columns(1 , 2 ) .0 = 0
Led_Columns(1 , 3 ) .0 = 0

Led_Columns(2 , 0 ) .0 = 0
Led_Columns(2 , 1 ) .0 = 0
Led_Columns(2 , 2 ) .0 = 0
Led_Columns(2 , 3 ) .0 = 0
Led_Columns(3 , 0 ) .0 = 0
Led_Columns(3 , 1 ) .0 = 0
Led_Columns(3 , 2 ) .0 = 0
Led_Columns(3 , 3 ) .0 = 0

Led_Columns(0 , 0 ) .1 = 0
Led_Columns(0 , 1 ) .1 = 0
Led_Columns(0 , 2 ) .1 = 0
Led_Columns(0 , 3 ) .1 = 0
Led_Columns(1 , 0 ) .1 = 0
Led_Columns(1 , 1 ) .1 = 0
Led_Columns(1 , 2 ) .1 = 0
Led_Columns(1 , 3 ) .1 = 0

Led_Columns(2 , 0 ) .1 = 0
Led_Columns(2 , 1 ) .1 = 0
Led_Columns(2 , 2 ) .1 = 0
Led_Columns(2 , 3 ) .1 = 0
Led_Columns(3 , 0 ) .1 = 0
Led_Columns(3 , 1 ) .1 = 0
Led_Columns(3 , 2 ) .1 = 0
Led_Columns(3 , 3 ) .1 = 0

Led_Columns(0 , 0 ) .2 = 0
Led_Columns(0 , 1 ) .2 = 0
Led_Columns(0 , 2 ) .2 = 0
Led_Columns(0 , 3 ) .2 = 0
Led_Columns(1 , 0 ) .2 = 0
Led_Columns(1 , 1 ) .2 = 0
Led_Columns(1 , 2 ) .2 = 0
Led_Columns(1 , 3 ) .2 = 0

Led_Columns(2 , 0 ) .2 = 0
Led_Columns(2 , 1 ) .2 = 0
Led_Columns(2 , 2 ) .2 = 0
Led_Columns(2 , 3 ) .2 = 0
Led_Columns(3 , 0 ) .2 = 0
Led_Columns(3 , 1 ) .2 = 0
Led_Columns(3 , 2 ) .2 = 0
Led_Columns(3 , 3 ) .2 = 0

Led_Columns(0 , 0 ) .3 = 0
Led_Columns(0 , 1 ) .3 = 0
Led_Columns(0 , 2 ) .3 = 0
Led_Columns(0 , 3 ) .3 = 0
Led_Columns(1 , 0 ) .3 = 0
Led_Columns(1 , 1 ) .3 = 0
Led_Columns(1 , 2 ) .3 = 0
Led_Columns(1 , 3 ) .3 = 0

Led_Columns(2 , 0 ) .3 = 0
Led_Columns(2 , 1 ) .3 = 0
Led_Columns(2 , 2 ) .3 = 0
Led_Columns(2 , 3 ) .3 = 0
Led_Columns(3 , 0 ) .3 = 0
Led_Columns(3 , 1 ) .3 = 0
Led_Columns(3 , 2 ) .3 = 0
Led_Columns(3 , 3 ) .3 = 0
Return

'***********************************************************************
'*Serial0charmatch()
'***********************************************************************
Sub Serial0charmatch()
Local Incoming_data As String * 30

'Daten vom Buffer auslesen
Input Incoming_data Noecho
'Ausgelesene Daten zurück schicken
Print Incoming_data
End Sub


'***********************************************************************
'* Sub : Update Data Latch Buffer
'***********************************************************************
Updatedatalatchbuffer:
Datalatch0.0 = Led_Columns(0 , 0 ) .b_layer
Datalatch0.1 = Led_Columns(0 , 1 ) .b_layer
Datalatch0.2 = Led_Columns(0 , 2 ) .b_layer
Datalatch0.3 = Led_Columns(0 , 3 ) .b_layer
Datalatch0.4 = Led_Columns(1 , 0 ) .b_layer
Datalatch0.5 = Led_Columns(1 , 1 ) .b_layer
Datalatch0.6 = Led_Columns(1 , 2 ) .b_layer
Datalatch0.7 = Led_Columns(1 , 3 ) .b_layer

Datalatch1.0 = Led_Columns(2 , 0 ) .b_layer
Datalatch1.1 = Led_Columns(2 , 1 ) .b_layer
Datalatch1.2 = Led_Columns(2 , 2 ) .b_layer
Datalatch1.3 = Led_Columns(2 , 3 ) .b_layer
Datalatch1.4 = Led_Columns(3 , 0 ) .b_layer
Datalatch1.5 = Led_Columns(3 , 1 ) .b_layer
Datalatch1.6 = Led_Columns(3 , 2 ) .b_layer
Datalatch1.7 = Led_Columns(3 , 3 ) .b_layer
Return

'***********************************************************************
'* Sub : LoadData
'***********************************************************************
Loaddata:
Gosub Updatedatalatchbuffer
' Outenable = 1
'Output ausschalten
Addr0 = 0
Addr1 = 0
Addr2 = 0
'Datalatch0
'Datalatch1
Porta = Datalatch0

'select Chip1
'Chip0 uebernimmt daten wenn Chipselect high wird, also deselektiert wird
Addr0 = 1
Addr1 = 0
Addr2 = 0

Porta = Datalatch1

'select Chip2
'Chip1 uebernimmt daten wenn Chipselect high wird, also deselektiert wird
Addr0 = 1
Addr1 = 1
Addr2 = 1

'Outenable = 0 'Output Einschalten
Return

'***********************************************************************
'* ISR : Interrupt Service Routine
'***********************************************************************
Isr_von_timer0:
Oe = 1 'Output ausschalten

Incr B_layer
If B_layer = 4 Then
B_layer = 0
End If

If B_layer = 0 Then
Gosub Loaddata
Layer0 = 1
Layer1 = 0
Layer2 = 0
Layer3 = 0
End If

If B_layer = 1 Then
Gosub Loaddata
Layer0 = 0
Layer1 = 1
Layer2 = 0
Layer3 = 0
End If

If B_layer = 2 Then
Gosub Loaddata
Layer0 = 0
Layer1 = 0
Layer2 = 1
Layer3 = 0
End If

If B_layer = 3 Then
Gosub Loaddata
Layer0 = 0
Layer1 = 0
Layer2 = 0
Layer3 = 1
End If

OE = 0 'Output Einschalten
Return


-


M.Weber & M.Eccer 30.11.2017

*

7

Disclaimer / Sitemap