Sie sind nicht angemeldet.

Lieber Besucher, herzlich willkommen bei: Das Wettringer Modellbauforum. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

271

Montag, 12. Juni 2017, 16:40

Oh, tatsächlich!
Bin aber unschuldig hab es so aus der Anleitung abgeschrieben, gerade noch mal nachgeguckt und da steht wirklich MSPA56!
Schlau wie ich aber bin hab ich jetzt mal auf den Transistor geguckt und da steht MPSA56 :P
Danke dir





Gruß, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

272

Montag, 12. Juni 2017, 18:38

Hallo Mario,

auch von uns ein herzliches Wilkommen im Thread. :hand:

Zu Deinen Fragen:
Wir benutzen auch den ATMega8(A), weil der im Gegensatz zum ATTiny4313 AD-Wandler hat.
Die brauchen wir, um z. B. Potentiometer auszuwerten. Der Speicher der Mikrocontroller muss nicht vollständig beschrieben werden.
Bascom-Demo & Mega8 sind für unsere Zwecke eine sinnvolle Kombination.

12V-Warnung: Es ist zwar unwahrscheinlich aber mit 12V könnte man sich den USB-Port im Computer zerschießen.
Deshalb raten wir, den Mikrocontroller stets ohne anliegende Fremdspannung zu programmieren.
Der USBASP bringt 5 (oder 3,3)V selbst mit - aus dem USB-Anschluss.
Nach dem Programmieren vom Computer trennen und erst dann 5 und 12V an die Schaltung anschließen.
Sicher ist sicher.

Elektronik-Kauderwelsch: Wir haben uns bemüht, die Erklärungen verständlich zu schreiben.
Sei bloß nicht still und frage, wenn etwas unklar sein sollte! :schrei:

Viel Spaß & viele Grüße

Mathias und Micha

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


273

Sonntag, 18. Juni 2017, 19:52

Moin!

Hab da mal wieder eine Frage, passt zwar nicht 100%ig zu eurem Thread wollte dafür aber keinen neuen aufmachen!


Und zwar bin ich gerade dabei mir einige Bauteile für meine Blinkermodul Lötorgie zu bestellen.
U.a. brauche ich auch einige Elkos 47µF/25v/85°c. Ich finde aber nur welche mit 105°c und die Größe bzw. die Höhe ist auch anders.
Kann ich die trotzdem verbauen oder gibt's dann Probleme?

Ja ich weiß, Amateur Frage aber mit so Dingern werde ich wohl noch öfter um die Ecke geschossen kommen :D


Danke, Gruß Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

274

Sonntag, 18. Juni 2017, 20:25

Hallo Mario,
jeder hat mal angefangen.
Wenn Fragen aufkommen, dann nur her damit.
Hier werden sie geholfen. ^^

Elkos gibt es in den unterschiedlichsten Abmessungen.
Wichtig bei der Auswahl sind der Kapazitätswert und die Spannungsfestigkeit, also 47µF/25v.
Auf die Temperaturangabe habe ich persönlich noch nie geachtet. :nixweis:

Darüber hinaus ist noch stehende oder liegende Montage zu beachten, je nachdem, wie du den Elko verbauen willst.
Stehend = Anschlußdrähte auf einer Seite (kann man, wenn die Anschlußdrähte gebogen werden, natürlich auch liegend einbauen. siehe HIER )
Liegend = Anschlußdrähte auf den gegenüberliegenden Seiten.

Auf die Größe musst du eigentlich nur achten, wenn du mal einen Elko in einer bestehenden Schaltung austauschen musst, damit er auch hineinpasst.
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

275

Sonntag, 18. Juni 2017, 20:28

Schon wieder was gelernt :D

Danke dir
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

276

Sonntag, 2. Juli 2017, 15:58

Hallo Bastelfreunde,

heute möchte ich Euch sozusagen als Exkurs und bevor Willie seine Projekte vorstellt, zwei Dinge erklären, die unsere Mikrocontroller
können bzw. beinhalten: Interrupts und EEPROM


Interrupts

Unsere Mikrocontroller besitzen eine Eigenschaft, die das laufende Programm unterbricht: Interrupts (engl. to interrupt = unterbrechen).
Das bedeutet, wenn ein definierter Interrupt kommt, wird dessen Aufgabe sofort ausgeführt und danach im bisher laufenden Programm weitergemacht.
Ein Interrupt kann sogar innerhalb eines Wait-Befehls, der den µC einfach nur stoisch warten lässt, erkannt und behandelt werden.
Äußerst praktisch!

Bascom kennt folgende Interrupts:


Quelle: Bascom Hilfe

Diese Fülle scheint erst mal heftig zu erschlagen – ist aber gar nicht so wild!

Schauen wir uns einmal den ATTiny4313 und den ATMega8(A) an:


Quelle: Datenblatt

Neben anderen Aufgaben hat der ATTiny4313 auf
Pin 6 die Funktion INT0 und auf
Pin 7 die Funktion INT1


Quelle: Datenblatt

Der ATMega8(A) hat entsprechend auf
Pin 4 die Funktion INT0 und auf
Pin 5 die Funktion INT1

Was bedeutet das für uns?


Wir können im Hintergrund die externen Interrupts INT0 und INT1 bzw. die entsprechenden Pins am µC überwachen.
Passiert dort etwas, das wir festgelegt haben, wird der entsprechende Interrupt ausgelöst.

Wir programmieren jetzt als Beispiel INT0:

Wenn INT0 ausgelöst wird, soll aus dem laufenden Programm in ein Unterprogramm gesprungen, dieses ausgeführt und wieder zurück gesprungen werden:

On Int0 Int0_isr

Das Unterprogramm heißt Int0_isr, wobei „isr“ für „Interrupt Service Routine“ steht. Die ISR endet wie alle Unterprogramme mit einem Return-Befehl und
wird auch nach dem „End“ des Hauptprogramms platziert; etwa so:

End
'
' Interrupt Service Routine(s)
Int0_isr:
' mach' hier irgendwas...
Return


Doppelpunkt nach Int0_isr: nicht vergessen! Es handelt sich ja um eine Sprungmarke.

Wir müssen definieren, wann INT0 aktiviert wird, z. B.:

Config Int0 = Rising

Es gibt hier mehrere Möglichkeiten: Int0 =
LOW LEVEL : Sobald am INT0-Pin eine Spannung (Pegel) von ca. 0V anliegt, wird der Interrupt ausgelöst – dauernd, bis der Pegel wieder die 0V-Zone nach ca. 5V verlässt.
FALLING : Sobald am INT0-Pin eine Pegeländerung von ca. 5V auf ca. 0V stattfindet, wird der Interrupt ausgelöst. „Fallende Flanke“.
RISING : Sobald am INT0-Pin eine Pegeländerung von ca. 0V auf ca. 5V stattfindet, wird der Interrupt ausgelöst. „Steigende Flanke“.
CHANGE : Sobald am INT0-Pin eine Pegeländerung von ca. 0V auf ca. 5V oder von ca. 5V auf ca. 0V stattfindet – also ein Pegelwechsel - wird der Interrupt ausgelöst.
Nicht alle µC unterstützen das CHANGE-Attribut.

Jetzt müssen wir mit dem „Interrupt-Hauptschalter“

Enable Interrupts

alle Interrupts aktivieren. Damit sind alle programmierten Interrupts aktiviert.
Mit:

Disable Interrupts

können wir den „Interrupt-Hauptschalter“ auch zum Deaktivieren aller Interrupts nutzen.
Dann kommt kein Interrupt mehr durch.
Wollen wir im Programm einzelne Interrupts aus- oder einschalten geht das z. B. mit:

Disable Int0
oder
Enable Int0

Aber immer auf den „Hauptschalter“ achten!

Disable Interrupts
Enable Int0


funktioniert nicht! INT0 bleibt deaktiviert.

Interrupts haben verschiedene Prioritäten.
Wir definieren in einem Programm zwei Interrupts, z. B. INT0 und INT1.
Kommen beide Interrupts gleichzeitig an, so wird zuerst die Int0_isr ausgeführt.
Der µC hat sich aber den INT1 gemerkt, daher wird danach die Int1_isr ausgeführt. Die Prioritäten entsprechen der Folge in obiger Tabelle.

Wir werden in zukünftigen Programmen auch weitere Interrupts benutzen; sie werden dann dort genauer erklärt werden.



EEPROM

Unsere Mikrocontroller besitzen ein mehr oder weniger großes EEPROM (= nichtflüchtiger Speicher), in dem man alle möglichen Variablen abspeichern kann.
Einmal im EEPROM, ist so die Variable nach Reset oder Stromausfall immer abrufbar.


Wie nutzen wir das EEPROM?

Bascom macht uns das sehr einfach:

Wir kennen die Definition von Variablen:

Dim Meinbyte as Byte
Dim Meinword as Word
Dim Meinbytearray(5) As Byte

Et cetera.

Bascom bezeichnet das EEPROM als ERAM.
Wir können Variable, die im EEPROM angesiedelt werden sollen, einfach wie folgt definieren:

Dim Ee_meinbyte as Eram Byte
Dim Ee_meinword as Eram Word
Dim Ee_meinbytearray(5) as Eram Byte


Variable, die normal im Programm genutzt werden, aber deren Wert ins EEPROM geschrieben oder aus diesem geladen werden sollen,
müssen unterschiedliche Bezeichnungen zu ihren EEPROM-Äquivalenten haben.
Hier bietet sich an, die Bezeichnungen der EEPROM-Äquivalente einfach durch das Voranstellen von „Ee_“ kenntlich zu machen. Das ist äußerst praktisch – aber kein Muss!

Wir können jetzt ganz einfach aus dem EEPROM lesen oder auch dahin schreiben:

Meinbyte = Ee_meinbyte


holt sich den Wert aus dem EEPROM und

Ee_meinbyte = Meinbyte


schreibt den Wert ins EEPROM. Einfacher geht‘s nicht!

VORSICHT!

EEPROM-Variable können nur etwa 10.000 mal ins EEPROM geschrieben werden. Danach legt es abnutzungsbedingt die Ohren an…

Deshalb: Nur EEPROM-Variable nutzen, wenn es wirklich sinnvoll ist. Das kann z. B. Auslagerung fester Werte oder Strings zur Entlastung
des Flash-Speichers sein. Oder dann, wenn gezielt Einstellungen langzeitig gespeichert werden sollen.

NIE (bedeutet NIE! = never ever etc.) in einer häufig durchlaufenen Schleife das EEPROM beschreiben!
Lesen ist OK - schreiben nur dann, wenn es nötig und sinnvoll ist.
Wird das nicht beachtet, so kann schon nach einem längeren Testlauf das EEPROM das Zeitliche gesegnet haben. :bang:

Test:
µC aus der Fassung oder vom Steckbrett nehmen, etwa 1 m hoch werfen. Landet der „Käfer“ auf dem Rücken, mit den Beinchen nach oben, ist er hin…

OK, Spaß muss sein… :lol:


In diesem Sinne:

Viele Grüße
Mathias & Micha

Inhaltsverzeichnis aller Projekt-Posts in Post 1

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


277

Mittwoch, 5. Juli 2017, 12:35

Wäre schön wenn ich schon soweit wäre, bin mal gerade auf Seite 3 angekommen! Aber ok hab's ja nicht eilig

Ich habe allerdings auch mal wieder eine Frage:

Und zwar wollte ich ja meine Löttechnik etwas auffrischen und hab mir dazu ein Blinkermodul ausgesucht das ich jetzt 100fach dupliziere
Fast alle Bauteile habe ich auch zusammen aber u.a. braucht man auch einen 5k Trimmpoti!
Aus mir unerklärlichen Gründen habe ich hier noch 20x 4,7K Trimmpotis liegen!
Für mich sind das 0,3K von irgendwas weniger :lol: kann ja nicht so ausschlaggebend sein


Kann ich die trotzdem benutzen?




Und wehe hier lacht einer über meine Unwissenheit :D




Gruß, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

278

Mittwoch, 5. Juli 2017, 13:26

Hallo Mario,
warum sollte jemand lachen (siehe meine Signatur)?

Widerstandswerte werden in Ohm oder Ω (nicht irgendwas ;) ) angegeben.
Zur Vereinfachung der Werteangaben wird allerdings meistens nur der Wert an sich angegeben.
Also anstelle von 5000 Ohm dann 5k.
Deine Trimmpotis kannst du ruhig benutzen.
Trimmpotis haben recht große Fertigungstoleranzen.
Bei NUR 5% Toleranz dürfte ein 5k Poti Werte zwischen 4,75k und 5,25k haben.
Meist sind die Toleranzen aber noch deutlich größer.

Hier sind die Eigenschaften von Potis sehr gut beschrieben.
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

279

Mittwoch, 5. Juli 2017, 14:03

Danke für den Link und die Erklärung.
Dann werd ich mal loslegen und schauen wann ich auf die ersten ernsthaften Probleme stoße

Gruß, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

280

Donnerstag, 20. Juli 2017, 19:02

Hallo an alle Bit und Byte-Geschädigten,
endlich ist es soweit, daß ich mein Lichtsteuerprogramm für die Autobühne vorstellen kann.

Doch vorab muss ich unbedingt noch einige Hinweise loswerden.
Ich habe mich lange mit Mathias unterhalten, ob ich es hier überhaupt vorstellen soll.
Meine Befürchtung war einfach, die Anfänger hier im Thread völlig zu frustrieren oder zu verschrecken.
Er hat mich dann aber doch überredet, da es nun fast ein Jahr her ist, dass ich mit der Mikrocontrollerprogrammierung überhaupt erst angefangen habe.
Gewissenmaßen zum Jahrestag.

Dabei soll aber nicht unerwähnt bleiben, dass ich im Vorruhestand bin und daher Zeit aufwenden kann, die Jemand, der noch voll im Berufsleben steht, einfach nicht hat.
Auch habe ich schon Vorkenntnisse im Programmieren mit Basic und VBA-Makros.
Ein nicht unerheblicher Vorsprung gegenüber einem völligen Neuling auf dem Gebiet.
Also bitte nicht die Flinte ins Korn werfen, wenn ihr mit Euren Programmierkenntnissen noch nicht ganz so weit seid. Das kommt zwangsläufig dann etwas später.

Da ich bestimmte Vorstellungen vom Programmablauf und der Steuerung hatte, konnte ich zum Einen auf Prozeduren zurückgreifen, die hier schon behandelt worden sind.
Ich musste mich aber anderseits auch schon mit Sachen beschäftigen, die Mathias hier noch nicht vorstellt hatte.
So z.B. die Benutzung eines Incrementalgebers, einer Steuerung mit Arrays, die Speicherung ins Eeprom des µC und die Zuhilfenahme der Interrupts.
Einiges davon habe ich über Google recherchiert.
Beim Rest hat mir Mathias telefonisch schon einmal vorab mit Ratschlägen und Erklärungen geholfen.

Zuerst war geplant, für die Vielzahl an Ausgängen, die ich benötigte, Portexpander zu verwenden. Da ich aber mit der Bascom-Vollversion arbeite, habe ich mich einfach für einen größeren µC entschieden.
Wie Portexpander genutzt werden, wird Mathias dann bei passender Gelegenheit vorstellen.

Zum Einsatz sollte der ATMega16 kommen, der Alles an Anschlüssen aufweist, die für mein Projekt notwendig waren und ausreichend Speicher hatte.
Leider kam es dann doch anders.
Selbst der Speicher vom 16er reichte für mein Programm nicht.
Ich musste auf den ATMega32 ausweichen.
Er hat eine zum 16er identische Pinbelegung, was mir das Umschreiben des Programms ersparte, aber doppelt so viel Speicher.
Dies war auch ein Grund für die Verzögerungen der letzten Zeit.
Es dauerte, bis die benötigten Teile eintrafen.

Die Tests der noch unbekannten Routinen und Bauteile habe ich aber noch am ATMega8 vorgenommen, so dass ihr die Testroutinen auch mit der Demo-Version nachvollziehen könnt.
Das Hauptprogramm könnt ihr mit der Demoversion von Bascom zwar laden und bei Bedarf selbstverständlich auch Teile daraus kopieren.
Allerdings könnt ihr es nicht testen oder in einen µC brennen, da die Demoversion eine Größenbeschränkung hat und ihr nur bis zu einer Größe von 4 KB Code diesen auch kompilieren könnt.

Für diejenigen unter Euch, die schon weiter sind als ich, sei noch erwähnt, dass ich mich bei Weitem noch nicht als Profi im Programmieren sehe, eher als leicht Fortgeschrittener.
Deshalb könnten einige Punkte des Programms von Profis sicherlich noch eleganter programmiert werden.
Für mich jedoch ist schon ein funktionierendes Programm ein gutes Programm!
Und jetzt genug der Vorrede und erst einmal los jetzt.

Die Interrupts und das Eeprom hat Mathias zwischenzeitig schon behandelt.
Bleibt mir nur noch die Erklärung des Inkrementalgebers und der Arrayfunktion.
Nach der grundsätzlichen Funktionsbeschreibung gibt es noch ein Demoprogramm, welches die neuen Funktionen zum Nachtesten enthält.

Beginnen wir mit dem Incrementalgeber (INC).

Aufgabenstellung:
Wir haben eine umfangreiche Liste, in der wir uns aufwärts oder abbewegen bewegen möchten.
Wenn wir eine uns genehme Stelle in der Liste erreicht haben, möchten wir diesen Punkt auswählen.

Zunächst die einfache Lösung:
Wir könnten dafür 3 Taster benutzen.
Bei jeden Tastendruck geht es einen Schritt weiter.
Taster 1 = wenn gedrückt, dann in der Liste bewegen (in Abhängigkeit von Taster 2)
Taster 2 = wenn gedrückt, dann aufwärts bewegen – wenn nicht, dann abwärts bewegen
Taster 3 = wenn gedrückt, dann Listenpunkt ausgewählen.

Kann man machen, muss man aber nicht! :(

Die elegantere Lösung ist die Benutzung eines Incrementalgebers (INC), der diese 3 Funktionen in einem Bauteil vereint.

Im täglichen Leben hat jeder schon einmal mit solch einem Regler gesteuert.
Sie sind z.B. im Autoradio als Lautstärkeregler mit gleichzeitiger Ein/Aus Drückfunktion eingesetzt.



Der INC hat 3 Ausgänge A(CLK), B(DT) und T(SW).
Am Ausgang A wird bei Drehung auf eine andere Stufe ein Impuls abgegeben.
Am Ausgang B wird auch ein Impuls, allerdings etwas zeitverschoben, abgegeben.
Da die Zeitverschiebung richtungsstabil ist, kann, ob der Impuls etwas vor A oder etwas nach A am Ausgang B anliegt, unterschieden werden, ob man den Regler links oder rechts herum gedreht hat.
Ausgang A wird am INT0 abgefragt.
Der Ausgang B wird mit einem beliebigen Eingang des µC verbunden.
Hier kann der µC auswerten, ob zum Zeitpunkt der positiven Flanke des A-Signals am INT0 das B-Signal 1 oder 0 war, für rechts oder links.

Der Taster des INC legt beim Drücken ein Potential auf den Ausgang T.
Dieses wird mit dem 2. Interrupt INT1 abgefragt, da sich die Befehlsabfolge für das Drehen des Reglers und das Drücken des Tasters unterscheidet und in 2 verschiedenen Service-Routinen abgearbeitet wird.



Zur Störsignalunterdrückung sollten die 3 Ausgänge des INC mit jeweils 100nF gegen GND bestückt werden.

Probiert es ruhig mal ohne Kondensatoren.
Ich könnt nichts kaputtmachen, aber der Unterschied ist eklatant.
Die Ausgänge werden weiterhin standardmäßig mit einem Pullupwiderstand von 36kOhm gegen Vcc bestückt.
Es reichen aber auch einkauflistenkompatibel 10kOhm Widerstände.

Da ich für meine Schaltung eine Platine angefertigt habe, habe ich auf dem nicht benötigten Bereich des Rohlings gleich kleine Platinen für den INC untergebracht.
Hier die Bilder von Platine und Regler.





Die Platine auf den Fotos ist allerdings meine Version für das Steckbrett.
In der Bühnensteuerung werden die Kabel direkt angelötet.

Fortsetzung im nächsten Post.
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

281

Donnerstag, 20. Juli 2017, 19:02

Und hier ein kleines Testprogramm, welches wir schon in Teilen für PWM benutzt hatten.

MySQL-Abfrage(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
'*****************************
'
' Test Incrementalgeber mit PWM
'
' Willie 17.07.2017
'
'*****************************
'
' Incrementalgeber A an INT0 (Pin 4)
' Incrementalgeber T an INT1 (Pin 5)
' Incrementalgeber B an PD1  (Pin 3)
'
' Alive-LED an PC0  (Pin 23) = Programmdummy
' PWM-LED an PB1    (Pin 15) = LED dimmbar durch INC-Drehregler
' Toggle-LED an PC1 (Pin 24) = LED umschaltbar durch INC-Taster
'
'*****************************
'
' ***** Genutzter Microcontroller, Takt in Hz, Stacks & Framesize
$regfile = "m8adef.dat"                                     ' ATMegaA8; Stacks etc.automatisch aus Bascom übernommen
$crystal = 8000000                                          ' ATMegaA8 intern auf 8 MHz eingestellt (Fuse-Bits!)
$hwstack = 40
$swstack = 16
$framesize = 32

'***** Variable

Dim Incwert As Word                                         ' Wert vom Incrementalgeber
Dim C As Word                                               ' Zählvariable

'***** Configs & Interrupts

Config Int0 = Rising                                        ' Positive Flanke auswerten
On Int0 Inc_geber_isr0                                      ' Interrupt Service Routine0
Config Int1 = Rising                                        ' Positive Flanke auswerten
On Int1 Inc_geber_isr1                                      ' Interrupt Service Routine1
Enable Interrupts                                           ' Master Interrupts einschalten
Enable Int0                                                 ' Interrupt 0 einschalten
Enable Int1                                                 ' Interrupt 1 einschalten

A Alias Pind.2                                              ' Int0 Incrementalgeber -A-  (Pin 4)
T Alias Pind.3                                              ' Int1 Incrementalgeber -T-  (Pin 5)
B Alias Pind.1                                              ' PD1  Incrementalgeber -B-  (Pin 3)

Config Portb.1 = Output                                     ' PWM-LED    (Pin 15)
Config Portc.0 = Output                                     ' Alive-LED  (Pin 23)
Config Portc.1 = Output                                     ' Toggle-LED (Pin 24)

Led1 Alias Pwm1a                                            ' PWM-LED    (Pin 15)
Led2 Alias Portc.0                                          ' Alive-LED  (Pin 23)
Led3 Alias Portc.1                                          ' Toggle-LED (Pin 24)


' 16-Bit Timer Config
Config Timer1 = Pwm , Pwm = 10 , Prescale = 8 , Compare_a_pwm = Clear_up , Compare_b_pwm = Clear_up       '8.000.000/8/1023/2 ~ 489Hz

Incwert = 500                                               ' zu Beginn mittlerer Wert für PWM-LED
Led3 = 0

'***** Hauptprogramm
Do
    Led1 = Incwert                                          ' PWM-LED den eingestellten Wert des INC zuweisen

    C = C + 1                                               ' Zähler für Programmdummy
    If C = 30000 Then
       Toggle Led2
       C = 0
    End If

Loop

End



'******  Interrupt Service Routine 0

Inc_geber_isr0:

If B = 1 Then                                               'B-Wert LOW während der steigenden A-Flanke = Rechtsdrehung

   If Incwert < 1023 Then                                   'Inc-Wert kleiner als Maximalwert = +100
       Incwert = Incwert + 100
          If Incwert > 1023 Then                            'Inc-Wert größer als Maximalwert = 1023
             Incwert = 1023
          End If

   End If

Else                                                        'B-Wert High während der steigenden A-Flanke = Linksdrehung

    If Incwert > 100 Then                                   'Inc-Wert größer als 100 = -100
        Incwert = Incwert - 100
           If Incwert < 100 Then                            'Inc-Wert kleiner als Minimalwert = 0
              Incwert = 0
           End If

    End If

End If

Return


'******  Interrupt Service Routine 1

Inc_geber_isr1:

   Toggle Led3                                              'Toggle-LED umschalten

Return


Es werden für den Test 3 LEDs benutzt.
LED 1 ist durch den Drehregler des INC dimmbar.
LED 2 blinkt als Dummy für ein beliebiges Programm in der Hauptschleife.
LED 3 ist durch den Taster des INC umschaltbar.


Zur Codeerklärung:
Die Standardeinstellungen wurden schon mehrfach behandelt, deshalb an dieser Stelle nur die Besonderheiten, wenn die Kommentierungen nicht reichen.

Zeilen 33-43
Hier werden die Interrupts konfiguriert, eingeschaltet und haben ihren jeweiligen Alias erhalten.

Zeilen 45-51
Hier werden die LED-Ausgänge konfiguriert und haben ihren jeweiligen Alias erhalten.

Zeilen 54-57
Konfiguration für PWM des Timers 1.
Einstellung Incwert auf mittleren Wert.

Zeilen 60-72
Im Hauptprogramm wird bei jeden Durchlauf der LED 1 der aktuelle INC-Wert zugewiesen.
Die Schleife mit C und LED 2 dient lediglich als Programmdummy für ein beliebiges Programm. Die Schleife mit C ist als Verzögerung erforderlich, damit die LED 2 ruhig vor sich hin blinkt.

Zeilen 76-102
Dies ist die Interrupt-Service-Routine für den INT0.
Im 1. Teil wird durch B=1 die Rechtsdrehung des INC ausgewertet.
Im 2. Teil wird durch B=0 die Linksdrehung des INC ausgewertet.

Damit man sich nicht den Wolf dreht wurde die Schrittweite 100 benutzt.
Deshalb muss im 2. Teile als unterer Wert die 100 abgefragt werden.
Bei einem Wert unter 100 darf nicht nochmal 100 abgezogen werden, da sonst die Variable durch den Überlauf die LED wieder voll anschalten würde.

Zeilen 105-111
Dies ist die Interrupt-Service-Routine für den INT1.
Hier wird nach einem Druck auf den Taster lediglich die LED 3 umgeschaltet.

Zum Ausprobieren:
Wer den INC "fliegend" verkabelt, kann ruhig mal die Kondensatoren weglassen.
Ändert mal die Schrittweite in der ISR0.
Bindet anstelle des Ablaufdummys ein beliebiges eigenes Programm ein.

Und immer wieder der Hinweis.
Keine Scheu vor Fragen.
Sollten Fragen dazu aufkommen, dann immer nur her damit.

Weiter geht’s dann im nächsten Post.
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

282

Donnerstag, 20. Juli 2017, 19:02

Nun kommen wir zu der von mir benutzten Arrayfunktion.
Ein Array hat Mathias ja schon für die Bitmuster zur Ansteuerung von LED-Gruppen beschrieben.

Ich habe ein etwas anderes Array für die Anzeige der Schritte des Inhaltsverzeichnisses auf dem LCD benutzt.

Dafür stellt Bascom die Befehle Data und LookUp bzw. LookUpStr zur Verfügung.
Mit Data können Datentabellen/Arrays verschiedenster Variablentypen erstellt werden.
Der Befehl LookUp holt dann einen bestimmten Variablenwert aus der Tabelle.
Sind in der Datentabelle jedoch String-Variable hinterlegt, so muss der Befehl LookUpStr benutzt werden.
Mit dieser Funktion kann ich also mit einem Zahlenwert einen bestimmten String aus einer Datentabelle ganz gezielt auslesen und weiterverarbeiten.

Syntax des Befehls:
Var = LookUpStr(index, Label)
oder übersetzt
Arbeitsvariable = LookUpStr(Zahlenwert, Name des Datentabelle)
Var bzw. Arbeitsvariable sind dann natürlich String-Variable, also vom gleichen Typ wie die hinterlegten Daten und müssen ausreichend groß dimensioniert sein, um den längsten Tabellenwert aufnehmen zu können.

Hierbei ist nur zu beachten, dass der Index nullbasierend ist, d.h. dass die Datentabelle grundsätzlich mit Datenfeld Null beginnt.
Der Name der Tabelle ist eine Sprungmarke und muss daher mit einem Doppelpunkt enden.
Innerhalb der Tabelle muss jede Zeile mit Data beginnen.
Wie viele Einträge in der Zeile stehen, ist unerheblich.
Es wird einfach von Beginn bis Ende der Tabelle durchgezählt.

Von Vorteil ist, dass man dieses Array bzw. die Datentabelle nicht vorab dimensionieren muss.
Jedoch muss der Programmierer sicherstellen, dass er sich mit seinen Abfragen innerhalb des gültigen Bereiches der Datentabelle bewegt, da der Index nicht auf Überschreiten der Tabellengrenze geprüft wird.

Für die Anzeige auf dem LCD kann der Inhalt des Datenfeldes als Index aufgerufen und angezeigt werden.

LCD LookUpStr(Zahlenwert, Name des Datentabelle)

Eine Tabelle kann z. B. so aussehen:

name_der_tabelle:
Data "", "Eintrag 1", "Eintrag 2", "Eintrag 3", "Eintrag 4"

Die gleiche Funktion hat die Tabelle mit folgendem Aufbau:

name_der_tabelle:
Data ""
Data "Eintrag 1"
Data "Eintrag 2"
Data "Eintrag 3"
Data "Eintrag 4"

Variable=LookUpStr(3, name_der_tabelle) bringt das Ergebnis Variable = "Eintrag 3"

Variable=LookUpStr(0, name_der_tabelle) bringt das Ergebnis Variable = ""

Das Schöne an diesem Array ist, dass man mit den Indexwerten rechnen kann.
Die Berechnung kann allerdings NICHT innerhalb des Befehls erfolgen.
Dafür muss eine Hilfsvariable zu Hilfe genommen werden.

Mathias hat ja schon beschrieben, dass eine Rechnung Ergebnis=Variable1/ Variable 2 nur ein ganzzahliges Ergebnis liefert, wenn die Variablen selbst ganzzahlige Variablentypen sind.
Dieses Verhalten habe ich bei der Anzeige auf dem Display benutzt.

Im Data-Bereich 1-9 habe befinden sich die Zeichenketten für die Überschriften.
In den 10er-Bereichen die einzelnen Punkte der Menüs.

Als Beispiel das Menü mit Zeilennummern:
1 Menue 1
11 Menuepunkt 1.1
12 Menuepunkt 1.2
13 Menuepunkt 1.3
2 Menue 2
21 Menuepunkt 2.1
22 Menuepunkt 2.2
23 Menuepunkt 2.3
3 Menue 3
31 Menuepunkt 3.1
32 Menuepunkt 3.2
33 Menuepunkt 3.3

Die Datentabelle dazu:

data_menue:
Data "", "Menue 1", "Menue 2", Menue 3", "", "", "", "", "", "", ""
Data "Menuepunkt1.1", "Menuepunkt1.2","Menuepunkt1.3", "", "", "", "", "", "", ""
Data "Menuepunkt2.1", "Menuepunkt2.2","Menuepunkt2.3", "", "", "", "", "", "", ""
Data "Menuepunkt3.1", "Menuepunkt3.2","Menuepunkt3.3", "", "", "", "", "", "", ""

Zu beachten ist hier, dass die nicht benötigten Werte mit Leerstrings aufgefüllt werden, damit der Befehl beim Abzählen die richtigen Einträge findet!
AUCH NICHT GEFÜLLTE DATENFELDER WERDEN GEZÄHLT!

Für die Anzeige im Display liefert
LCD LookUpStr(Zeilennummer, data_menue)
für die Zeilennummer 22 das Ergebnis "Menuepunkt2.2"

Um in der gleichen Anzeige auch die Menüüberschrift anzuzeigen, nehme ich eine Hilfsvariable zu Hilfe.

Titel = Zeilennummer / 10
LCD LookUpStr(Titel, data_menue)
liefert für die Zeilennummer 22 das Ergebnis "Menue 2"

Im Display erscheint mit entsprechender Positionierung folgende Anzeige:

Menue 2
Menuepunkt2.2

Soweit zur Grundfunktion, wie ich sie eingesetzt habe.

Hier nun ein kleines Demoprogramm:

MySQL-Abfrage(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
'###############################################################
'*
'* Arraytest mit I2C-LCD 20x4 by Willie
'*
'* Schaltung:
'* LCD 20x4, mit I2C-Adapter
'*
'* Vcc auf +5V (Pin 7)
'* GND auf GND (Pin 8)
'* 100nF Kerko zwischen Vcc und GND
'* 3,6kOhm zwischen PC5 (Pin 28) und Vcc  -  Pullup für I2C-SCL
'* 3,6kOhm zwischen PC1 (Pin 27) und Vcc  -  Pullup für I2C-SDA
'*
'* Namen für Menü werden mit lookupstr aus Data-Bereich ausgelesen
'* Der Index für lookupstr. ist Null-basierend !!!!
'*
'*
'###############################################################

'***** Genutzter Microcontroller, Takt in Hz, Stacks & Framesize

$regfile = "m8adef.dat"                                     ' ATMegaA8; Stacks etc.automatisch aus Bascom übernommen
$crystal = 8000000                                          ' ATMegaA8 auf 8 MHz eingestellt (Fuse-Bits!)
$hwstack = 40
$swstack = 16
$framesize = 32

'***** I2C & LCD konfigurieren

Config Scl = Portc.5                                        ' I2C Scl (Pin 28)
Config Sda = Portc.4                                        ' I2C Sda (Pin 27)
Config Lcd = 20x4
$lib "YwRobot_Lcd_i2c.lib"                                  'YwRobot Treiber für LCD
Const Pcf8574_lcd = 78                                      'Slave-Adresse des I2C-LCDs
 'Pcf8574_lcd = 78
 'Pcf8574A_lcd = 126
Dim Lcd_backlight As Byte                                   '1 = an; 0 = aus. Wird erst durch einen LCD-Befehl umgesetzt!
Config I2cdelay = 1                                         '1=1Mhz,5=200Khz,10=100Khz,15=66,66Khz
 'Wenn in Lcd keine Anzeige muß der Delaywert erhöht werden.Mit Wert 15 beginnen und dann langsam verringern.
Waitms 300                                                  'warte bis Kondensator bei Ta0 geladen, auch für LCD-Init!

'***** Variablen

Dim Zeile As Byte                                           ' aktueller Menüzeilenwert
Dim Titel As Byte                                           ' Arbeitsvariable für Menuetitel


Lcd_backlight = 1                                           ' LCD Backlight einschalten


Cls                                                         ' LCD leeren/initialisieren und Programmnamen ausgeben
Cursor Off Noblink

Locate 1 , 1
Lcd "Arraytest"
Wait 2

'***** Menü im LCD anzeigen

Cls
Locate 1 , 1
Lcd "Daten nur anzeigen,"
Locate 2 , 1
Lcd "wenn vorhanden!"
Wait 2

Cls

For Zeile = 0 To 30

        Locate 1 , 1
        Lcd "                   "
        Locate 2 , 1
        Lcd "                   "
        Locate 4 , 1
        Lcd "Zeilenzaehler = "
        Lcd Zeile
        Lcd " "

        If Zeile > 10 Then
                If Zeile < 14 Then Gosub Lcd_anzeige
        End If

        If Zeile > 20 Then
                If Zeile < 24 Then Gosub Lcd_anzeige
        End If

        If Zeile > 30 Then
                If Zeile < 35 Then Gosub Lcd_anzeige
        End If

        Wait 1

Next

Cls
Locate 1 , 1
Lcd "Fertig"
Wait 2



End


Lcd_anzeige:

    Titel = Zeile / 10                                      ' Titel berechnen
    Locate 1 , 1
    Lcd Lookupstr(titel , Data_menue)


    Locate 2 , 1
    Lcd Lookupstr(zeile , Data_menue)


Return


data_menue:
Data "" , "Menue 1" , "Menue 2" , "Menue 3" , "" , "" , "" , "" , "" , "" , ""
Data "Menuepunkt1.1", "Menuepunkt1.2","Menuepunkt1.3", "", "", "", "", "", "", ""
Data "Menuepunkt2.1", "Menuepunkt2.2","Menuepunkt2.3", "", "", "", "", "", "", ""
Data "Menuepunkt3.1" , "Menuepunkt3.2" , "Menuepunkt3.3" , "" , "" , "" , "" , "" , "" , ""


Zu Beginn des Codes die üblichen bekannten Einstellungen.

Zeilen 54-67
Programmvorstellung auf dem LCD

Zeilen 69-103
Es wird eine For-Next-Schleife in der Größenordnung des Arrays durchlaufen.
Bei jedem Durchlauf werden die LCD-Zeilen 1 und 2 gelöscht, damit nur Daten von gefüllten Datenfeldern angezeigt werden.
In der Zeile 4 des LCDs wird der Wert des Durchlaufzählers angezeigt.
Dies ist bei Programmtests äußerst sinnvoll, damit man sieht, was mit dem Zähler passiert.
In den If-Then-Abfragen werden die Datenfelder mit Inhalten eingegrenzt.

Zeilen 96-99
Schlussanzeige

Zeilen 106-117
Untermenü LCD-Anzeige
Es wird nur bei gültigen Zeilenwerten angesprungen.
In Zeile 108 wird der Titel berechnet.
Für den Bereich 1-9 kann kein Titel angezeigt werden da z.B. 9/10=0,9 also 0 ist und das Datenfeld mit dem Index 0 leer ist.

Zeilen 120-124
Datenarray


Zum Ausprobieren:
Füllt weitere Felder des Arrays
Ändert mal die Größenordnung des Arrays.
Testet die Abhängigkeit der Einschränkung in den If-Then-Abfragen zu den Einträgen in der Datentabelle

Und immer wieder der Hinweis.
Keine Scheu vor Fragen.
Sollten Fragen dazu aufkommen, dann immer nur her damit.

Bevor es mit dem Hauptprogramm weitergeht, habe ich noch ein kleines Scharmützel mit der Videokamera. :!!
Zum Abschluß soll ja auch was zu sehen sein.
Also bis dann. :wink:
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

283

Donnerstag, 20. Juli 2017, 22:05

Post reserviert :D

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


284

Freitag, 21. Juli 2017, 12:49

Moinsen!

Gibt es eigentlich irgendeine Möglichkeit zu überprüfen ob IC's funktionsfähig sind ohne sie gleich zu programmieren?
Habe gerade meine Ladung ATTINY2313 aus China bekommen und da die spottbillig waren suche ich immer noch nach einem Haken.
China ist ja nicht gerade für seine Qualitätsprodukte bekannt und wenn die so billig sind (7,29€ für 10 Stück) MUSS da ein Haken sein :)
Danke

Gruß und schönes WE, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

285

Freitag, 21. Juli 2017, 13:20

Hallo Mario,
also ich habe bisher noch bei keinen Elektronikbauteilen aus China Probleme gehabt.

Überleg doch mal:
Was denkst du, wo die deutschen Händler ihre ICs beziehen?
Und bei denen setzt sich garantiert niemand hin, und prüft jeden einzelnen Chip nach.
Beim deutschen Händler bezahlst du nur etliche Posten mit.
Einfuhrumsatzsteuer, Zoll, Lagerhaltung, Versand, Personal, Einkommensteuer, MWSt etc.

Aber wenn du schon ein Steckbrett dein Eigen nennst, den Programmieradapter fertig hast und die Programmierkabel an die richtigen Anschlüsse des Tiny angesteckt hast, brauchst du nur auf das Programmiersymbol zu klicken und im folgenden Menü auf die im Bild markierte Schaltfläche klicken.
Wenn Bascom den Tiny erkennt und im Chipfenster anstelle der ??? anzeigt, sollte er auch funktionieren.



Meine persönliche Meinung dazu:
Selbst wenn bei 10 Stk. ein defektes IC dabei sein sollte, interessiert mich das bei dem Preis garantiert nicht.
Ist aber bei mir noch nicht vorgekommen.
Also kein Haken, sondern nur nicht die Kosten, die ein Händler in Deutschland hat.
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

286

Freitag, 21. Juli 2017, 15:31

Schon richtig aber die Händler hier in Deutschland bestellen ihren Kram mit Sicherheit auch nicht bei einem Ebay Händler der (vielleicht) irgendwo in Shanghai, auf einem Hinterhof, eine 90jährige Oma IC's verpacken lässt :D

Aber hast schon recht wenn da ein oder zwei defekt wären spielt es keine große Rolle. Und nach deinem Tipp funktionieren sie auch alle, also alles gut
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

287

Freitag, 21. Juli 2017, 21:31

Hallo Modellbaufreunde,
nun ist die Zeit gekommen, mein Lichtsteuerungsprogramm vorzustellen.

Die Bühne wurde mit 8 weißen LEDs und 4 RGB-LEDs in den Scheinwerfern bestückt.
Für alle LEDs lassen sich verschiedene Lichtmuster und Funktionen manuell über das Menü einstellen.
Dazu sind die weißen LEDs 1-4 für den linken Bühnenteil, die weißen LEDs 5-8 für den rechten Bühnenteil und die RGB-LEDS für die rückwärtige Bühnenausleuchtung jeweils als Gruppe zusammengefasst.
Es lassen sich alle LEDS gemeinsam abdimmen.
Die Geschwindigkeit des Lauflichtes ist ebenfalls für alle LEDs gemeinsam regelbar.
Als Zusatzoption ist ein fest programmierter Showablauf integriert, der verschiedene Einstellungen der Steuerung automatisch abarbeitet.

Hier noch einmal der Beleuchtungsplan der Bühne:



Für eine direkte Anzeige des Programms wären 6 Posts notwendig.

Deshalb stehen zum Verständnis, was dort programmiert ist, 2 Dateien zum Download zur Verfügung.
Zunächst die Textdatei für die Leser mit einer Bascom-Installation.
Die Textdatei in Eurer Programmbibliothek abspeichern, die Endung in .bas ändern und dann mit Bascom öffnen.
Für diejenigen Leser, die noch keine Bascom-Installation haben, ist die pdf-Datei, damit man die Erklärungen anhand der integrierten Zeilennummern im Code auch nachvollziehen kann.

Hier die Dateien zum Herunterladen

Steuerprogramm Bühne Vers12-32 - FERTIG.txt

Steuerprogramm Bühne Vers12-32 - FERTIG.pdf

Die Funktionen werden mit einer externen Kontrolleinheit gesteuert.
Dafür wurde in der Einheit ein I2C-LCD-Display verbaut.
Um zu sehen, was man steuert, wurde dafür ein Menü erstellt, welches im Laufe des Projektes immer umfangreicher geworden ist. Neue Ideen wurden implementiert.
Die Struktur sieht mit Durchnummerierung wie folgt aus:
In Klammern sind die grundlegenden Funktionen erwähnt.
Dort, wo nichts beschrieben ist, wird die ausgewählte Funktion immer parallel im Eeprom gespeichert.
Das betrifft natürlich nicht die Menüaufrufe und den Showstart.

1 Startmenue
11 Neue Szenerie (ALLE LEDs aus und direkter Sprung ins Hauptmenü)
12 letzte Szenerie (aus Eeprom gespeichertes zuletzt verwendetes Lichtmuster laden)
13 Alles an (ALLE LEDs einschalten ohne Eeprom-Speicherung)
14 Showstart (Start des fest programmierten Showablaufs)

2 Hauptmenue
21 Stand By An/Aus (Anzeige blinkt während aktiviertem Stand By)
22 Alles Voll An (ALLE LEDs einschalten)
23 Alles Lauflicht (ALLE LEDs einschalten)
24 Alles Aus (ALLE LEDs ausschalten ohne Eeprom-Speicherung)
25 Buehne Links ( zu Menü 3)
26 Buehne Rechts ( zu Menü 4)
27 RGB ( zu Menü 5)
28 Showstart (Start des fest programmierten Showablaufs)
29 INV-DIMM-SPEED ( zu Menü 6)

3 Menue Links
31 Alles An (LEDs 1-4 einschalten)
32 Lauflicht (LEDs 1-4 einschalten)
33 Links Aus (LEDs 1-4 ausschalten)
34 Hauptmenue ( zu Menü 2)

4 Menue Rechts
41 Alles An (LEDs 5-8 einschalten)
42 Lauflicht (LEDs 5-8 einschalten)
43 Rechts Aus (LEDs 5-8 ausschalten)
44 Hauptmenue ( zu Menü 2)

5 Menue RGB
51 Gemischt An ( LEDs 9-12 einschalten – 3 Muster)
52 Nur Rot An ( LEDs 9-12 einschalten)
53 Nur Gruen An ( LEDs 9-12 einschalten)
54 Nur Blau An ( LEDs 9-12 einschalten)
55 Lauflicht ( LEDs 9-12 einschalten)
56 RGB Aus ( LEDs 9-12 ausschalten)
57 Hauptmenue ( zu Menü 2)

6 Menue INV-DIMM-SPEED
61 RGB INV ( LEDs 9-12 Farbwerte invertieren)
62 Rot INV ( LEDs 9-12 Farbwerte invertieren)
63 Gruen INV ( LEDs 9-12 Farbwerte invertieren)
64 Blau INV ( LEDs 9-12 Farbwerte invertieren)
65 Buehne Links INV ( LEDs 1-4 Lichtmuster invertieren)
66 Buehne Rechts INV ( LEDs 5-8 Lichtmuster invertieren)
67 LEDs dimmen (Anzeige mit Einstellungswerten)
68 Geschwindigkeit (Anzeige mit Einstellungswerten)
69 Hauptmenue ( zu Menü 2)

Das Startmenü wird nach dem Einschalten der Steuerung nur einmal beim Programmstart angezeigt und bietet nur die Auswahl "manuelle Einstellung", sowie 3 Schnellstartoptionen.
Danach bildet das Hauptmenü die oberste Auswahlebene.

Das Programm enthält im groben Überblick folgende Teile mit Zeilennummern:

1-53 Angaben zu Name, Beschaltung, Hardwareeinstellungen und Hinweise

56-226 Dimensionierungen, Konfigurationen, Variablenzuweisungen und Starteinstellungen

227-295 Hauptprogramm

298-359 Unterprogramm für Menüsteuerung

362-752 Ausführungsroutinen für Caseabfrage Hauptprogramm

755-852 Unterprogramm für Showsteuerung

855-1216 Ausführungsroutinen für Caseabfrage Showsteuerung

1220-1321 Interrupt Service Routine für INT0

1325-1378 Interrupt Service Routine für INT1

1382-1416 Unterprogramm LCD-Anzeige ändern


Fortsetzung im nächsten Post.
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

288

Freitag, 21. Juli 2017, 21:31

Die Einstellungen, die bisher schon mehrfach in Codes verwendet wurden, werde ich nicht mehr explizit erläutern.
Für jeden Schritt ist das Programm, so weit es möglich ist, ausführlich auskommentiert.
Um weitere Erklärungen nicht unnötig ausufern zu lassen, beschränke ich mich auf die Besonderheiten.
Wer jedoch Fragen dazu hat, sollte sich nicht scheuen, sie zu stellen.

Zeilen 40-41
Hier wird die Hardware des ATMega32 angepasst.
In den Fusebits den internen Arbeitstakt auf 1MHz einstellen.
In den Fusebits die Option JTAG ausschalten , da sonst die Ports PC2-PC5 nicht als Ausgänge nutzbar sind.

Zeilen 45-51
Diese Prozedur ist nur einmal nach dem Brennen des µC und ersten Starten des Programms auszuführen, damit die Eeprom-Variablen einen definierten Arbeitszustand erhalten.

Zeilen 120-121
Hier werden die eigenen Zeichen definiert für die Pfeilanzeige im LCD.

Zeilen 232-291
Dies ist die Hauptschleife des Programms, die nur dann in Unterroutinen verlassen wird, wenn durch ISR A und ISR B Änderungen erfolgt sind.

Zeilen 300-359
Dies ist das Unterprogramm für die Menüsteuerung.
Hier wird nach der Änderung des Zeilenzählers durch ISR A und Auswahl durch ISR B in dem entsprechenden Case die dazugehörige Änderungsroutine aufgerufen bzw. auf das dazugehörige Menü umgeschaltet.

Zeilen 364-752
Hier stehen die Ausführungsroutinen für die einzelnen Cases.
Die Aufgaben sind in den Kommentaren eigentlich ausführlich genug beschrieben.
Bis auf wenige Ausnahmen werden alle Einstellungen der Lichtmuster, des Dimmwertes und der Ablaufgeschwindigkeit parallel im Eeprom gespeichert und lassen sich nach dem Aus- und wieder Einschalten durch die Schnellstartoption im Startmenü wieder abrufen, ohne sie nochmalig manuell einstellen zu müssen.

Eine Besonderheit stellen auch die Dimmereinstellung im UP67 und die Geschwindigkeitseinstellung im UP68 dar.
Hier wird jeweils nach Auswahl die Menüanzeige geändert, um die Änderungswerte im Display anzuzeigen.
Nach dem Bestätigen der neuen Einstellung durch ISR B wird wieder auf die normale Menüanzeige zurückgeschaltet.

Zeilen 759-850
Hier ist das Unterprogramm für den Showablauf.
Es arbeitet nach Aufruf in einer eigenen Programmschleife mit eigenen Caseroutinen.
Dies war für den automatischen Ablauf einfacher zu programmieren, als die ganzen "Sonderlocken" für den automatischen Ablauf in der Hauptprogrammschleife unterzubringen.
Auch hierfür gibt es wieder eine gesonderte LCD-Anzeige, die nach dem Stoppen der Automatik wieder auf die normale Menüanzeige zurückgeschaltet wird.
Das Stoppen erfolgt wieder durch ISR B (Tasterdruck).

Zeilen 855-1216
Hier befinden sich die Ausführungsroutinen für die Cases der Showsteuerung.
Die Einschaltdauer der einzelnen Sequenzen wird durch den Globalzähler Gs gesteuert.
Mit der Variablen "Showablauf" wird auf das jeweils nächste Case weitergeschaltet.

Zeilen1220-1321
Dieser Bereich bildet die Interrupt-Service-Routine A für den Drehregler.
Sie wird durch eine Drehung des INC (Inkrementalgebers) über den INT0 angesprungen.
Das Hauptprogramm wird dafür solange unterbrochen, unabhängig davon, an welcher Stelle es sich gerade befindet.
Hier sind die Einstellungscodes für die Geschwindigkeitsregelung, den Dimmwert und die Zeilenweiterschaltung ineinander verschachtelt und werden, je nachdem, welches Statusflag (Speedmodus, Dimmermodus) auf 1 gesetzt ist, abgearbeitet.
Ohne Statusflag wird die Zeilenweiterschaltung im Menü behandelt.
Die Änderungen werden nach dem Rücksprung in die Hauptschleife beim nächsten Schleifendurchlauf sofort umgesetzt.

Zeilen 1329-1378
Hier ist die Interrupt-Service-Routine B für den Taster.
Ist eines der Flags für Stand By, Dimmen, Showmodus oder Geschwindigkeit gesetzt, werden die jeweiligen Änderungen gespeichert bzw. die Showroutine beendet, das Menü aufgerufen und der Unterpunkt angezeigt, von wo aus das jeweilige Unterprogramm aufgerufen wurde.
Dies erfolgt über die Einstellung des Zeilenzählers vor der LCD-Aktualisierung.
Ohne Flag wird zum Unterprogramm für die Menüsteuerung verzweigt und dort die jeweilige Caseeinstellung zur Ausführung gebracht.

Zeilen 1386-1416
Am Ende des Codes befindet sich das Unterprogramm zur Änderung der LCD-Anzeige mit dem dazugehörigen Datamenü für die Menüeinträge.

Hier wird, wie in der Arrayerklärung beschrieben, mit den Zeilenwerten gerechnet.
Allerdings werden hier 4 Zeilen angezeigt.

In der 1. Zeile des LCD befindet sich immer der Menüname.
Er wird mit dem Zeilenzähler errechnet.
Titel = Zeile / 10 ergibt als ganzzahligen Wert den Index für das anzuzeigende Überschriftenfeld.

Die aktuell gültige Zeile befindet sich in der Zeile 3 des LCD und ist mit einem Pfeil aus den selbstdefinierten Zeichen markiert.
Der Zeilenwert bildet den Index.

In der Zeile 2 wird mit der Hilfsvariablen R durch Zeilenwert - 1 der Index für den vorhergehenden Datensatz errechnet und angezeigt.

In der Zeile 4 wird mit der Hilfsvariablen R durch Zeilenwert + 1 der Index für den nachfolgenden Datensatz errechnet und angezeigt.

Befindet sich das jeweilige Menü am Anfang oder Ende, wird entsprechend in Zeile 2 oder 4 ein Leerfeld angezeigt.
Beim nicht vollständig gefüllten 10er Bereich sind die nicht benötigten Einträge Leerfelder, so dass auf den letzten Eintrag immer ein Leerfeld folgt.
Um auch in der Zeile 2 ggf. ein Leerfeld anzeigen zu können, ist es notwendig, das im Datenarray das jeweils vorhergehende 10er-Feld immer ein Leerfeld sein muss.


Das waren die Erklärungen zu meinem Programmcode.
Ich hoffe, es ist Euch beim Lesen nicht schwindelig geworden.
Mir jedenfalls hat beim Fehlersuchen im Code manchmal ganz schön der Kopf geraucht. :cracy:

Nach all der "trockenen Kost" sollt ihr aber auch sehen, wie Steuerung optisch wirkt.
Dazu habe ich wieder ein kurzes Video angefertigt, das den Showablauf und einige Fotoaufnahmen zeigt.

Und zum Abschluss wieder der Hinweis:
Scheut Euch nicht zu fragen!
Nur durch Fragen wird Unverständnis beseitigt.


Der Bau der Traversen kann HIER nachgelesen werden.

Nun aber viel Spaß beim Anschauen des Videos und bis bald. :wink:

Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

289

Dienstag, 5. September 2017, 22:34

'Nabend!

Ich habe gestern in einem anderen Thread gefragt wie man LEDs dimmen kann und Willie hat mir netterweise eine einfache Möglichkeit erklärt. Die habe ich auch gleich mal in die Tat umgesetzt und es funktioniert einwandfrei.
Ich hatte dieselbe Frage auch in einem Elektronikforum gestellt und da habe ich die Antwort bekommen das man das auch mit PMS, 'ne Moment, PWM machen könnte :lol:
Jetzt hat mir das erstmal natürlich nix gesagt also Onkel Google gefragt und was ich da so gefunden (und verstanden) habe bedeutet das ja wohl das man dazu ein IC programmieren müsste.
Da ich hier erst auf Seite 4 oder 5 angekommen bin und bis dahin nix gefunden habe (oder hab ich es schon wieder vergessen?) dachte ich mir das könnte doch hier netterweise mal jemand erklären :pfeif:

Was ich vor habe:

Ich will demnächst die Voyager von Revell bauen, natürlich mit Beleuchtung. Auf allen Bildern bzw. Bauberichten finde ich die Lichter, vor allem die der Fenster, extrem hell. Die armen Leutchen da drinn sehen ja gar nix weil sie komplett geblendet ständig gegen Wände rennen :)
Fazit: LEDs dauerhaft dimmen


Und jetzt die Profis bitte :)




Danke euch, Gruß Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

290

Dienstag, 5. September 2017, 23:21

Hi Mario, fauler Kerl! :abhau:

Natürlich haben wir PWM ausführlich erklärt (s. Inhaltsverzeichnis in Post 1).

Kurze Antwort - morgen oder übermorgen mehr: Du hast je nach µC 3 oder 4 PWM-Kanäle, die Du unabhängig voneinander regeln kannst.
Zusätzlich könntest Du noch 2 verschiedene Dimmstufen pro Pin realisieren.
LED dauerhaft dimmen = größerer Vorwiderstand.

Die Voyager habe ich hier auch liegen...

Gute Nacht
Mathias (gäääääähn)

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


291

Dienstag, 5. September 2017, 23:30

Das ist ja auch auch Seite 7, soweit bin ich doch noch nicht
Aber gut, ich muss zugeben das Inhaltsverzeichnis habe mir nicht durchgelesen :cracy:


Nacht zusammen
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Beiträge: 845

Realname: Wilfried Hoffmann

Wohnort: Braunschweig

  • Nachricht senden

292

Mittwoch, 6. September 2017, 08:48

Hallo Mario,
klar kann man die LEDs per PWM dimmen.
Das kann man unter Verwendung eines µC manuell über ein Poti steuern oder per Programmierung automatisch ablaufen lassen.

Wie das aussehen kann, ist im Video in Post 288 auf Seite 10 (aufdimmen zu Anfang - abdimmen am Ende) zu sehen.

Das wäre den Aufwand wert, wenn sich in deinem Modell später verschiedene Fenster lichttechnisch verändern sollen.
Ist allerdings mit einer Menge Programmieraufwand und Versuchen verbunden.

Wenn ich dich aber recht verstanden habe, willst du die LEDs dauerhaft dimmen, d.h. im fertigen Modell nicht mehr nachregeln können. ?(

Und hier ist meine Devise:
Geringstmöglicher Aufwand für höchstmöglichen Effekt!

Und da wäre meiner Ansicht nach die Option mit den festen Widerständen sicher die bessere Wahl. :)
Viele Grüße
Willie

Man ist niemals zu alt, um Neues zu lernen.
Es gibt keine dummen Fragen, nur dumme Antworten.

Fertig:

Scratchbau beleuchtete Bühne mit Euro-Truss Traversen in 1:25

In Bearbeitung:
VW Bus T3 – Mein erster Tourbus

Fertige Projekte im Portfolio!

293

Mittwoch, 6. September 2017, 08:49

Hi Mario,

ich habe mir auch so meine Überlegungen gemacht.
Leichte Grundbeleuchtung mit LED-Strips.
Alle Fenster gleich hell geht gar nicht!
Ich würde sie in Gruppen aufteilen und jede Gruppe mit einer LED und Lichtleitern beleuchten, evtl. mit SW-PWM.
PWM braucht's eigentlich nur zwingend für den Warp-Effekt, den Impulsantrieb und die Photonen-Torpedos.
Gondeln beweglich?

Schreib' doch mal, was Deine Voyager so können soll und welche Lichteffekte Du haben willst.

Viele Grüße
Mathias

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


294

Mittwoch, 6. September 2017, 12:16

Na jetzt gehts aber los, du bringst mich auf Ideen :) Aber ok, der Reihe nach:

@Willie: Ja richtig, der Plan war kaltweiße und warmweiße LEDs dauerhaft zu dimmen damit die Fensterbeleuchtung nicht aussieht wie eine Supernova Explosion :) bis Matthias, mit seinen Ideen, um die Ecke geschossen kam, jetzt will ich mehr :D


@Mathias: Tja, was soll meine Voyager können?! Du bringst mich auf Ideen an die ich noch nicht mal ansatzweise gedacht habe. Also gut:

- Bewegliche Warpgondeln, wären schon klasse. Aber wie? Manuell? Automatisch? Mit Motor? Oder wie oder was? Und das Licht nur an wenn die Gondeln oben sind?
- Die Warpgondeln wollte ich ja mit einer Kaltlichtkathode beleuchten, die läuft aber leider nicht mit 9v. Ich schätze mal dazu müsste ein neuer Inverter her, weil der der dabei ist wohl auf 12v gepolt ist. Also kommen blaue LEDs in die Gondeln.
- Die Fensterbeleuchtung möchte ich mit kaltweißen und warmweißen LEDs ausleuchten, jetzt aber auch in verschiedenen Helligkeitsstufen :)
- Was ich sonst noch beleuchten will ist das blaue Teil unten in der mitte (Deflektor glaub ich), die Phaserbank in rot und am besten als Lauflicht von hinten nach vorne. Beide Seiten logischerweise simultan
- Ein paar einfache Positonsleuchten, ich glaub die waren rot
- Impulsantrieb und Torpedos auch beleuchtet. Gab's da auch Effekte? Oder waren die einfach nur "an" oder "aus"? Alles schon sooooo lange her, ich glaub ich muss mir auf TELE5 mal wieder ein paar Folgen anschauen
- Die Direktbeleuchtung der Kennung wäre auch schön aber wie ich in ein paar anderen Bauberichten gelesen habe scheint das nicht so einfach zu sein weil der Winkel wohl nicht 100%ig stimmt. Aber gut das ist nicht wirklich wichtig.

Über mehr hab ich mir im Moment noch keine Gedanken gemacht. Was aber nicht heißen soll das meinem kranken Hirn nicht noch mehr geniale Ideen entspringen :D

So und jetzt wieder Ihr


Gruß, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

295

Mittwoch, 6. September 2017, 16:48

Hallo Mario,

es gibt hier im Forum einen exzellenten Baubericht der Voyager.
Da wurden die Gondeln elektrisch bewegt! Auch sonst allererste Sahne.
Reinschauen!

Bei den gefühlt 5782 Fenstern wird es Entscheidungen geben müssen.
Ich tendiere zu einer schwachen, warmweißen Grundbeleuchtung via Stripes.
Heißt: Vorwiderstände. Auf die Wattzahl achten!
Die Voyager besteht ja nicht aus Einzelzellen... Meint: Ein Acrylglasstück anpassen für z. B 3 nebeneinanderliegende Fenster.
Kleine Bohrung ins Acryl und einen angeschliffenen Lichtleiter einkleben, dann das Stück hinter die Fenster kleben - beides mit Weißleim.
Im Normalfall lässt das Acryl die Grundbeleuchtung fast komplett durch. Dunkler: Edding.
Kommt nun kaltweißes Licht durch den Lichtleiter, so wird der "Raum" mit den drei Fenstern heller = wird "betreten".
Eine 5 mm LED kann ca. 24 dünne Lichtleiter bedienen (ja, das habe ich ausprobiert). Also lieber 3er oder 1,8er nehmen.
Dann die Acrylstückchen "zufällig" verteilen und im Takt von mehreren Sekunden (auch die Dauer sollte zufällig sein) toggeln.
Nicht zu schnell! Sonst hast Du an Stelle der Supernova einen amerikanischen Weihnachtsbaum.
Soweit dazu.

Wie kommst Du auf 9 V?
Stripes sind auf 12 V ausgelegt und ein guter Warpblitz wird die wohl auch brauchen... 12 V blau + kaltweiß in der Gondel.

Viele Grüße
Mathias

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


296

Mittwoch, 6. September 2017, 17:06

Zitat

Wie kommst Du auf 9 V?
Stripes sind auf 12 V ausgelegt und ein guter Warpblitz wird die wohl auch brauchen... 12 V blau + kaltweiß in der Gondel.
Weil bei mir jegliche Beleuchtung bis jetzt auf 9v läuft. Dafür habe ich Unmengen an Widerständen für einzelne LEDs. Klar ist jetzt nicht das Problem andere passende Widerstände zu kaufen, muss aber nicht unbedingt sein.
Und die Kaltlichtkathode, die ich benutzen wollte, ist aus einem alten PC und hat einen 4 poligen Molex Anschluss und das sind doch 12v, oder nicht?
An 9v hab ich sie ausprobiert, da bleibt sie schlicht und einfach dunkel. Einen passenden 9v Inverter neu bauen übersteigt dann doch meine bescheidenen Elektronik Fähigkeiten.
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

297

Mittwoch, 6. September 2017, 17:27

OK.
Normalerweise reichen Dir 5 V dicke aus.
µC + LEDs
Wenn aber Stripes ins Spiel kommen, dann sind die bei 9 V wesentlich dunkler als bei 12 V.

Kaltlichtkathode finde ich nicht so toll - Stripes lassen sich per PWM für Effekte klasse dimmen.

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


298

Mittwoch, 6. September 2017, 18:02

Dann werden es eben 12v und blaue Stripes, ein paar neue Widerstände werden mich schon nicht ruinieren :)

Übrigens welchen Baubericht meinst du? Ich finde nur einen und da ist seit Anfang April nix mehr passiert


Gruß, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

299

Mittwoch, 6. September 2017, 18:23

Die Suchfunktion Du nutzen musst, junger Padawan.

Ich habe mindestens vier verschiedene Threads gefunden - dann aber aufgehört.
Der mit deb Gondeln isses - die anderen sind aber auch OK.
Aaaaah - such' mal nach Angelschnur.

Bin kurz weg.

Zu Hülf' - meine Kugel ist umgefallen!

Heisenberg bei einer Radarkontrolle:
Polizist: "Wissen Sie, wie schnell Sie waren?"
Heisenberg: "Nein. Aber ich weiß genau, wo ich jetzt bin!"


300

Sonntag, 8. Oktober 2017, 19:36

'Nabend!

Meinem kranken Hirn ist schon wieder eine grandiose Idee entsprungen :D


Gibt es eine (simple) Möglichkeit alle verbauten Platinen einzeln per programmierbarer Fernbedienung zu anzusteuern?
IR LED mit auf die Platine und dann?


Dachte mir sowas wie z.B. Knopf 1 drücken und dann geht die Beleuchtung, meinetwegen, an der Voyager an, Knopf 2 und das Licht am Auto springt an, Knopf 3 das Licht am Schiff usw.


Ist bestimmt nur mit einem abgeschlossenen Elektronik und Informatik Studium möglich aber fragen musste ich trotzdem :)


Gruß, Mario
Zwei Dinge sind unendlich,
das Universum und die menschliche Dummheit,
aber bei dem Universum bin ich mir noch nicht ganz sicher
(Albert Einstein)

Werbung