PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Drei Led´s mit einem Taster unabhängig von einander schalten



p@ty
11.03.2013, 12:24
Hallo zusammen,

habe da mal einige Fragen zu unten stehendem Code.
Kurz vor weg:

Es geht, wie schon im Titel beschrieben, darum drei Led´s unabhängig von einander mit einem Taster zu schalten.

Wird der Taster kurz betätigt soll eine von den 3 Led´s leuchten.
Wird der Taster länger betätigt (>=2sek) soll in eine Subroutine gesprungen werden in der je
nach dem wie lange der Taster betätigt wird (>=2 , >=4 , >=6sek) eine von den 3 Led´s ausgewählt wird.
Danach soll wieder in´s Hauptprogramm gesprungen werden in dem ich die ausgewählte Led 1 oder 2 oder 3
mit dem Taster an und ausschalten kann.

Ich bin noch ein ziemlicher Anfänger im Programmieren und würde mich über jede Hilfe freuen!
weiterhin habe ich mit der Timerkonfiguration auch noch Probleme und benötige da eure Unterstützung.

Vielen Dank schon mal für eure Hilfe!
Viele Grüße,
Patrick

Hier meine Bastellei...:

$regfile = "m168def.dat"
$crystal = 16000000
$hwstack = 100
$swstack = 100
$framesize = 100

'Pin- Portkonfiguration Outputs
Config Portd.2 As Output
Led1 Alias Portd.2
Led1 = 0

Config Portd.3 As Output
Led2 Alias Portd.3
Led2 = 0

Config Portd.4 As Output
Led3 Alias Portd.4
Led3 = 0

'Pin- Portkonfiguration Inputs
Config Pind.5 As Input
Taster Alias Pind.5
Taster = 1

Config Timer0 As Timer , Prescale? , sonstige Einstellungen für einen Sekundentimer???

Enable Timer0
Enable Interrupts

Dim A As Byte 'Lichtszenario
Dim B As Byte 'Lichtszenario- Auswahl
Dim C As Byte 'Timervariable

Timer0 = C
Stop C

Declare Sub Lichtszenen (byval B As Byte)


'Hauptprogramm
Do

C = 0 'Timer0 = 0

If Taster = 0 Then 'Wenn Taster gedrückt wird dann...
Start C 'soll Timer0 starten...
A = B 'und das Szenario ausgewählt werden.
Else 'Sonst ist...
A = 0 'A = 0 und...
Stop C 'der Timer0 wird gestoppt...
C = 0 'und auf null zurück gesetzt.
End IF

If C >= 2 Then 'wenn Timer0 >= 2sek ist dann...
Call Lichtszenen 'sprung in die Subroutine.
End IF

Loop
End

'Unterprozedur
Sub Lichtszenen

If Taster = 0 Then start C 'wenn Taster gedrückt wird start Timer0.
If C >= 2 Then B = 0 'wenn Timer0 >= 2sek dann ist B = 0
If B = 0 Then 'wenn B = 0 dann...
Led1 = 1
Led2 = 0
Led3 = 0
End If

If C >= 4 Then B = 1 'wenn Timer0 >= 4sek dann ist B = 1
If B = 1 Then 'wenn B = 1 dann...
Led1 = 0
Led2 = 1
Led3 = 0
End If

If C >= 6 Then B = 2 'wenn Timer0 >= 6sek dann ist B = 2
If B = 2 Then 'wenn B = 2 dann...
Led1 = 0
Led2 = 0
Led3 = 0
End IF

End Sub

Sauerbruch
11.03.2013, 15:22
Wieviele Bildschirme voller Fehlermeldungen spuckt Bascom denn aus, wenn Du versuchst diesen Code zu kompiliern? :-)

Fangen wir mal oben an:

Config PORTD.2 AS Output dürfte Bascom nicht verstehen. Es muss heißen Config PORTD.2 = Output.

Gleiches gilt für Config Pind.5 As Input - Config PIND.5 = Input wäre korrekt. Ist aber überflüssig, weil alle I/O-Ports nach dem Einschalt-Reset ohnehin als Eingänge konfiguriert sind.

Enable Timer0
Enable Interrupts
Ist zwar von der Syntax her richtig, aber ebenfalls unnötig, da Du ja nicht mit Timer-Interrupts arbeitest.

Timer0 = C
führt nur dazu, dass Timer0 den Wert der Variablen C annimmt (hier also 0). Sowas wie die Alias-Funktion ist das aber nicht!
Stop C funktioniert daher nicht, und müsste die nächste Fehlermeldung produzieren. Hier musst Du start timer0 bzw. stop timer0 verwenden.

Die Hauptschleife versteh´ ich zwar nicht so ganz, aber eines ist klar: Auch wenn Du das "C" durch timer0 ersetzen würdest, würde der Timer immer wieder am Anfang der Hauptschleife auf 0 gesetzt werden. Das heißt, er kann gar nicht hochzählen!

Und in der Subroutine hast Du oft eine Reihe von IFs, die nur mit einem End if abgeschlossen werden. Das geht auch nicht - für jedes If muss ein End if kommen!

Wie wär´s denn, wenn Du vielleicht erstmal mit einem etwas einfacheren Projekt erste Gehversuche unternimmst? Ich weiß - ich war am Anfang auch schrecklich ungeduldig und wollte gleich alles auf einmal machen - aber so ganz ohne minimale Kenntnisse was die Syntax und den Aufbau von Bascom anbetrifft, kommt man halt meistens überhaupt zu nix...
Und Du wirst sehen - wenn Dir die "Basics" erstmal geläufig sind (z.B. wie ein Interrupt funktioniert, wie man Timer konfiguriert etc., etc) geht der Rest wie von alleine! Und: Hier wirst Du immer geholfen :-)

Searcher
11.03.2013, 16:50
weiterhin habe ich mit der Timerkonfiguration auch noch Probleme und benötige da eure Unterstützung.
Zur Timerkonfiguration in BASCOM nehme ich immer das Datenblatt und den Simulator zur Hilfe. Im Simulator kann man sehen, welche Register mit welchen Werten bei dem CONFIG TIMER Kommando belegt werden und dann mit dem Datenblatt vergleichen.

COMPARE1A = 15624
beschreibt OCR1A (OCR1AH, OCR1AL) mit 15624

CONFIG TIMER1 = TIMER , PRESCALE = 1024 , CLEAR TIMER = 1
Versetzt den Timer in den CTC Modus und startet ihn auch. Bei Erreichen von Timerstand 15624 wird der Timerstand wieder auf 0 gesetzt und zählt wieder hoch.

Wenn der Timerstand 15624 erreicht, wird das COMPARE1A Flag gesetzt.




'Pin- Portkonfiguration Inputs
Config Pind.5 As Input
Taster Alias Pind.5
Taster = 1


Damit möchtest du vermutlich den Pullup Widerstand einschalten?
Da Taster aber den PIND.5 darstellt funktioniert das nicht. Für Einschalten des Pullup muß bei einem als Input konfigurierten Pin das Bit im PORT Register mit 1 beschrieben werden. Also: Statt "Taster = 1" muß es "PORTD.5 = 1" sein.
(Daß das Config Pind.5 Kommando einen Syntaxerror hat, hat Sauerbruch schon drauf hingewiesen)

Gruß
Searcher

Spitfire
11.03.2013, 19:19
Hallo P@ty !!!

In Sachen Bascom kann ich dir leider nicht viel helfen, aber vieleicht in der grundlegenden Herangehensweise.
Zur Abfrage des Pin`s, wie lange er High, bzw. low ist würde ich eine Schleife Prgrammieren. Solange der Pin den gewünschten zustand hat, durchläft das Programm immer wieder die Schleife. Bei jedem Schleifendurchlauf wird ein Zähler um eins erhöht. Dadurch bekommst du in dem Zähler einen Wert der von der Dauer des Tastendrucks abhängig ist. Diesen Zählerstand kannst du dann Abfragen, und je nach Höhe, die jeweilige LED ein, oder ausschalten. Ich habe dieses Prinzip zur Abfrage eines PWM-Signales eines Empfängers für Modellflugzeuge angewannt. Funktioniert Tadellos. Was vieleicht noch zu beachten währe, ist, dass bei eienem Zeitraum von mehreren Sekunden ein Register als Zäler nicht ausreicht, weil mehr als 254 durchläufe stattfinden. Eventuell bei einem Überlauf des Zählers, ein zweites Register mitzählen lassen, wieviele Überläufe stattgefunden haben. Nur das mit dem Zweiten Zähler (Register) war bei der PWM Abfrage nicht notwendig, da das Signal nur ungefähr 20ms Sekunden lange ist. Es entstehen aber immer noch Werte von 8oo bis 1ooo bei einer Taktfrequenz von 4Mhz.

Gruß
Spitfire

Searcher
11.03.2013, 19:28
Mir fällt noch was ein: Zum Taster Abfragen eignet sich das DEBOUNCE Kommando gut.

p@ty
11.03.2013, 20:36
Hallo zusammen!!
Vielen Dank für eure schnellen Anworten und Infos! :)

@ Sauerbruch: Waren ne´ ganze Menge Fehlermeldungen! :rolleyes:
Aber auch der Ansatz das ich mich mit der Grundlegenden Struktur zur Konfiguration von Timern ect mehr befassen sollte war richtig!!!
Warum ich allerdings die Ports noch falsch konfigurierte ist mir ein Rätsel...
Sicher weil ich den Code oben im Win Texteditor, heute auf der Arbeit aus´m Kopp eingehackt habe...
Habe den Timer dann kurzerhand weg gelassen und es auf anderem Wege probiert.
Das aber für jedes If ein End If kommen muss ist nicht ganz richtig...
Wenn man die gesamte Befehlsfolge in eine Reihe schreibt tut´s trozdem! ;)

Habe mir auch schon etwas Lektüre angelesen und etliche Schaltungen aufgebaut und den passenden Code dazu abgetippt.
-Aber halt nur abgetippt, was nicht immer viel Aufschluss über die Herangehensweise brachte...
Denke da muss man wie so oft im Leben einfach ausdauernd am Ball bleiben und viel ausprobieren.

Unten noch ein anderer Code der zum Erfolg geführt hat...(warum auch immer)
Kann mir da manche Sachen einfach nicht erklären....zB das byval B... in der Unterprozedur nutze ich die Variable A....:confused:
Wenn ich aber Declare Sub Lichtszenen(byval A As Byte) schreibe dann funzt es nicht mehr...
Naja, muss ich noch en´ paar Versuche starten! Macht ja richtig Laune!! :)

Vielen Dank nochmal an euch alle und auch an Kampi für seine tollen Tipps!
Bin für Verbesserungen / Vereinfachungen und weitern Tipps sehr dankbar!
Viele Grüße,
P@ty


Hier der Anfängercode der wohl für ein geübtes Auge schlimmer nicht sein könnte...

$regfile = "M168def.dat"
$crystal = 16000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 9600


'Pin- Portkonfiguration Outputs
Config Portc.0 = Output
Led1 Alias Portc.0
Portc.0 = 0

Config Portc.1 = Output
Led2 Alias Portc.1
Portc.1 = 0

Config Portb.1 = Output
Led3 Alias Portb.1
Portb.1 = 0

'Pin- Portkonfiguration Inputs
Config Pind.4 = Input
Taster Alias Pind.4
Portd.4 = 1

Dim A As Byte
Dim X As Word

Declare Sub Lichtszenen(byval B As Byte)


'Hauptprogramm
Do


If Taster = 0 Then 'Wenn Taster = 0 dann...
Incr X 'X incrementieren...
Print X 'sonst X = 0
Else
X = 0
End If

If X >= 200 Then 'Wenn X >= 200ms dann...
Gosub Lichtszenen 'Sprung in Unterprozedur Lichtszene
End If

If A = 1 And Taster = 0 Then 'Wenn Variable A = 1 und Taster = 0 dann...
Led1 = 1 'Led1 an
Led2 = 0
Led3 = 0
Elseif Taster = 1 And A = 1 Then 'Led1 aus
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 2 And Taster = 0 Then 'Wenn Variable A = 2 und Taster = 0 dann...
Led1 = 0 'Led2 an
Led2 = 1
Led3 = 0
Elseif Taster = 1 And A = 2 Then 'Led2 aus
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 3 And Taster = 0 Then 'Wenn Variable A = 3 und Taster = 0 dann...
Led1 = 0 'Led3 an
Led2 = 0
Led3 = 1
Elseif Taster = 1 And A = 3 Then 'Led3 aus
Led1 = 0
Led2 = 0
Led3 = 0
End If

Loop

End

'Unterprozedur
Sub Lichtszenen

If Taster = 0 Then Incr X 'Wenn Tatser = 0 dann Incrementiere X
If X >= 200 Then A = 1 'Wenn X >= 200ms dann Variable A = 1
If A = 1 Then 'Wenn A = 1 dann...
Led1 = 1
Led2 = 0
Led3 = 0
End If


If X >= 750 Then A = 2
If A = 2 Then 'Wenn X >= 750ms dann Variable A = 2
Led1 = 0 'Wenn A = 2 dann...
Led2 = 1
Led3 = 0
End If


If X >= 1250 Then A = 3 'Wenn X >= 1250ms dann Variable A = 3
If A = 3 Then 'Wenn A = 3 dann...
Led1 = 0
Led2 = 0
Led3 = 1
End If


If Taster = 1 Then 'Wenn Taster losgelassen wird dann...
Led1 = 0
Led2 = 0
Led3 = 0

End Sub
End If

Kampi
11.03.2013, 22:58
Hey,

setzt den Code im Forum bitte zwischen

["code"]["/code"]

Tags (ohne die ""). Das macht die Sache etwas kürzer etc.

- - - Aktualisiert - - -

Hey,

so ich habe deinen Code mal etwas gekürzt und optimiert.....



$regfile = "M168def.dat"
$crystal = 16000000
$hwstack = 100
$swstack = 100
$framesize = 100


'Pin- Portkonfiguration Outputs
Config Portc.0 = Output
Led1 Alias Portc.0
Portc.0 = 0


Config Portc.1 = Output
Led2 Alias Portc.1
Portc.1 = 0


Config Portb.1 = Output
Led3 Alias Portb.1
Portb.1 = 0


'Pin- Portkonfiguration Inputs
Config Pind.4 = Input
Taster Alias Pind.4
Portd.4 = 1


Dim A As Byte
Dim X As Word


Declare Sub Lichtszenen(byval B As Byte)
Declare Sub Muster_zeigen()


'Hauptprogramm
Do


If Taster = 0 Then 'Wenn Taster = 0 dann...
Incr X 'X incrementieren...
Waitms 10 ' -> neu, da du 2s warten willst ist vlt ein Delay für 10ms ganz gut
Else
X = 0
End If


If X >= 200 Then 'Wenn X >= 2s dann...
X = 0 'X vor dem Sprung reseten, damit wieder von 0 angefangen wird zu zählen
Gosub Lichtszenen 'Sprung in Unterprozedur Lichtszene (200ms einen Taster drücken ist bischen kurz ;) )
End If


If Taster = 0 Then 'Taster gedrückt?
Select Case A: 'Auf welchen Wert steht A
Case 1 : Led1 = 1 'LED 1 an
Led2 = 0
Led3 = 0
Case 2 : Led1 = 0 'LED 2 an
Led2 = 1
Led3 = 0
Case 3 : Led1 = 0 'LED 3 an
Led2 = 0
Led3 = 1
End Select
Else 'Taster nicht gedrückt
Led1 = 0
Led2 = 0
Led3 = 0
End If


Loop
End








'Unterprozedur
Sub Lichtszenen


While Taster = 1 'Warten bis der Taster gedrückt wird
Waitms 1
Wend


If Taster = 0 Then 'Wenn Taster = 0 dann Incrementiere X
Incr X
Waitms 10
Else
Led1 = 0
Led2 = 0
Led3 = 0
Return
End If


If X >= 200 Then 'X überprüfen und A setzen
A = 1
Elseif X >= 750 Then
A = 2
Elseif X >= 1250 Then
A = 3
End If


Select Case A: 'A überprüfen
Case 1: Led1 = 1
Led2 = 0
Led3 = 0
Case 2 : Led1 = 0
Led2 = 1
Led3 = 0
Case 3 : Led1 = 0
Led2 = 0
Led3 = 1
End Select


End Sub

p@ty
12.03.2013, 07:11
Hey Kampi!
Schläfst du auch mal?? ;)

Okay, Danke! Bin gespannt wie dieser Code läuft!

Viele Grüße,
P@ty

Kampi
12.03.2013, 07:58
Konnte gestern nicht schlafen ;)
Von daher habe ich noch bisl gesurft und schon mal angefangen deinen Code bisschen zu sortieren und ein paar gefundene Fehler auszubessern.
Getestet isser noch nicht.....muss auch erst mal schauen wie ich das auf meine Hardware übertragen kann ;)

Searcher
12.03.2013, 16:15
Hallo,
ich würde in der Hauptschleife nur feststellen (mit DEBOUNCE) ob der Taster gedrückt wurde.
In der Subroutine dann feststellen wie lange er gedrückt wird und in der gleichen Routine danach die LEDs
entsprechend schalten. Etwa so:


Hauptschleife
Taste gedrückt, dann Subroutine aufrufen
Ende Haupschleife

Subroutine:
Solange die Taste gedrückt ist, wird eine WORD-Variablen in 10ms Schritten hochgezählt.
Taste nicht mehr gedrückt, dann "WORD-Variable = WORD-Variable / 100" - ergibt ganzahlige Sekunden
Mit SELECT CASE je nach Drückdauer die LEDs schalten und in einem Flag die eingeschaltete LED Nummer speichern
In dem CASE für kurze Drückdauer eine weitere SELECT CASE Anweisung in der das Flag abgefragt wird und die entsprechende LED getoggelt wird.
RETURN (Subroutine Ende, Rücksprung in Hauptschleife)
Schönheitsfehler: Solange die Taste gedrückt ist, wird übriges Programm aufgehalten. Sollte hier aber keine Rolle spielen.

Gruß
Searcher

Sauerbruch
12.03.2013, 20:06
Schönheitsfehler: Solange die Taste gedrückt ist, wird übriges Programm aufgehalten.

Das stimmt, aber auch dafür gäbe es eine Lösung (um den armen p@ty komplett zu verwirren):

Man konfiguriert den 16-Bit-Timer so, dass er deutlich länger als 6 Sekunden für einen Durchlauf braucht. Z.B. mit einer Taktfrequenz von 1 MHz (die für diese Anwendung ja locker reichen müsste) und einem Prescaler von 1024, macht knapp 1000 Counts pro Sekunde. Der Timer läuft kontinuierlich durch.

Der Taster wird an einem Change-konfigurierten Interrupt-Eingang angeschlossen. Bei fallender Flanke (Beginn Tastendruck) wird der aktuelle Timer-Wert in eine erste Word-Variable übernommen, bei steigender Flanke (Ende Tastendruck) in eine zweite Word-Variable. Zieht man den ersten Wert vom zweiten ab weiß man, wie lange der Taster gedrückt wurde (und zwar auch, wenn der Timer zwischendurch übergelaufen ist). Dann noch ein kleines Flag nach der steigenden Flanke gesetzt, das in der Hauptschleife das Ende des Tastendrucks signalisiert - fertig!

p@ty
12.03.2013, 20:41
Jepp,

habt ihr geschafft! :o
Probiere jetzt erst einmal Daniel´s Idee dann arbeite ich mich zu euren durch!
Vielen Dank!!

Viele Grüße,
P@

p@ty
13.03.2013, 19:11
Hey zusammen,

hab´ Daniel´s Code getestet aber leider kam vom µC keinerlei Reaktion?...:(
Hier noch der Vollständigkeit halber mein Code mit allen Schaltmöglichkeiten:

Led1 oder Led2 oder Led3,
Led1 und Led2,
Led1 und Led3,
Led2 und Led3,
Led1 und Led2 und Led3.

Der tut´s wenn auch sicherlich nicht sehr effektiv...:rolleyes:


$regfile = "M168def.dat"
$crystal = 16000000
$hwstack = 100
$swstack = 100
$framesize = 100
$baud = 9600


'Pin- Portkonfiguration Outputs
Config Portc.0 = Output
Led1 Alias Portc.0
Portc.0 = 0

Config Portc.1 = Output
Led2 Alias Portc.1
Portc.1 = 0

Config Portb.1 = Output
Led3 Alias Portb.1
Portb.1 = 0

'Pin- Portkonfiguration Inputs
Config Pind.4 = Input
Taster Alias Pind.4
Portd.4 = 1

Dim A As Byte
Dim X As Word

Declare Sub Lichtszenen(byval B As Byte)


'Hauptprogramm
Do


If Taster = 0 Then 'Wenn Taster = 0 dann...
Incr X 'X incrementieren...
Print X 'sonst X = 0
Else
X = 0
End If

If X >= 200 Then 'Wenn X >= 200ms dann...
Gosub Lichtszenen 'Sprung in Unterprozedur Lichtszene
End If

If A = 1 And Taster = 0 Then 'Wenn Variable A = 1 und Taster = 0 dann...
Led1 = 1 'Led1 an
Led2 = 0
Led3 = 0
Elseif Taster = 1 And A = 1 Then 'Led1 aus
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 2 And Taster = 0 Then 'Wenn Variable A = 2 und Taster = 0 dann...
Led1 = 0 'Led2 an
Led2 = 1
Led3 = 0
Elseif Taster = 1 And A = 2 Then 'Led2 aus
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 3 And Taster = 0 Then 'Wenn Variable A = 3 und Taster = 0 dann...
Led1 = 0 'Led3 an
Led2 = 0
Led3 = 1
Elseif Taster = 1 And A = 3 Then 'Led3 aus ...usw...
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 4 And Taster = 0 Then
Led1 = 1
Led2 = 0
Led3 = 1
Elseif Taster = 1 And A = 4 Then
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 5 And Taster = 0 Then
Led1 = 0
Led2 = 1
Led3 = 1
Elseif Taster = 1 And A = 5 Then
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 6 And Taster = 0 Then
Led1 = 1
Led2 = 1
Led3 = 0
Elseif Taster = 1 And A = 6 Then
Led1 = 0
Led2 = 0
Led3 = 0
End If

If A = 7 And Taster = 0 Then
Led1 = 1
Led2 = 1
Led3 = 1
Elseif Taster = 1 And A = 7 Then
Led1 = 0
Led2 = 0
Led3 = 0
End If

Loop

End

'Unterprozedur
Sub Lichtszenen

If Taster = 0 Then Incr X 'Wenn Tatser = 0 dann Incrementiere X
If X >= 200 Then A = 1 'Wenn X >= 200ms dann Variable A = 1
If A = 1 Then 'Wenn A = 1 dann...
Led1 = 1
Led2 = 0
Led3 = 0
End If

If X >= 750 Then A = 2
If A = 2 Then 'Wenn X >= 750ms dann Variable A = 2
Led1 = 0 'Wenn A = 2 dann...
Led2 = 1
Led3 = 0
End If

If X >= 1250 Then A = 3 'Wenn X >= 1250ms dann Variable A = 3
If A = 3 Then 'Wenn A = 3 dann... usw...
Led1 = 0
Led2 = 0
Led3 = 1
End If

If X >= 1750 Then A = 4
If A = 4 Then
Led1 = 1
Led2 = 0
Led3 = 1
End If

If X >= 2250 Then A = 5
If A = 5 Then
Led1 = 0
Led2 = 1
Led3 = 1
End If

If X >= 2750 Then A = 6
If A = 6 Then
Led1 = 1
Led2 = 1
Led3 = 0
End If

If X >= 3250 Then A = 7
If A = 7 Then
Led1 = 1
Led2 = 1
Led3 = 1
End If

If Taster = 1 Then 'Wenn Taster losgelassen wird dann...
Led1 = 0
Led2 = 0
Led3 = 0

End Sub
End If

Viele Grüße,
p@

Kampi
13.03.2013, 20:10
Hey,

ja bei dem Code handelt es sich auch nur um deinen Code in gekürzter Form ;)
Wirklich Fehler hatte ich da noch nicht drin gesucht :P

p@ty
13.03.2013, 20:15
Hey Daniel,

ach so! Okay, dann war da wohl noch der Wurm drin! ^^
Kannst ja bei Gelegenheit meinen letzten mal aus probieren.

Was ich da noch nicht blicke ist die Geschichte mit dem "declareSub (byval b as Byte)" ...wobei doch "A" die Variable in der Unterprozedur ist...?

Viele Grüße,
P@

Kampi
13.03.2013, 21:18
Mit dem Declare Sub definierst du ein Unterprogramm. Den Wert den du mit dem Aufruf ins Unterprogramm übergibst, nennst du "b" und er ist vom Typ "Byte".
Innerhalb des Unterprogramms heißt die Variable dann ebenfalls "b" und du kannst diese dann natürlich auch weiter verarbeiten.

p@ty
14.03.2013, 07:59
...okay, dann blicke ich aber immer noch nicht warum mein Programm läuft. Denn von der Variablen b steht nichts in der Unterprozedur...??

Viele Grüße,
p@

Kampi
14.03.2013, 08:18
Hey,

in dem Unterprogramm greifst du nur auf globale Variablen (A und X zu).
Globale Variablen sind Variablen, die du am Anfang deines Hauptprogrammes deklariert hast. Diese Variablen stehen dann sowohl im Hauptprogramm als auch in jedem Unterprogramm zur Verfügung.
Lokale Variablen sind Variablen die du innerhalb eines Unterprogramms deklariert hast. Diese stehen dem entsprechend nur im Unterprogramm zur Verfügung.
Variablen die beim Funktionsaufruf deklariert werden (dein b) sind Variablen für ein Unterprogramm, also lokale Variablen.
Du kannst z.B schreiben.


Variable1 = 1
Declare Sub MeinUnterprogramm(byval Test as Byte)

Do

MeinUnterprogramm(Variable)

Loop
End

Sub MeinUnterprogramm(byval Test as Byte)

Local NeueVariable as Byte
NeueVariable = Test
Print NeueVariable

End Sub


schreiben. Damit deklarierst du eine Variable "Variable" = 1 und ein Unterprogramm. Das Unterprogramm rufst du anschließend auf und die Variable "Variable" wird übergeben (eine KOPIE von "Variable" wird übergeben). Der Wert der Variable "Variable" steht dann innerhalb der Funktion unter dem Namen "Test" zur Verfügung (halt der Name den du in der Unterprogrammdeklaration festgelegt hast).
Innerhalb dieses Unterprogramms wird eine lokale Variable mit Namen "NeueVariable" deklariert und diese Variable bekommt den Inhalt der Variable "Test".
Da "Test" aber nun den Wert von der Variable "Variable" besitzt, besitzt die Variable "NeueVariable" dementsprechend den Wert von "Variable", also 1.
Dieser Wert wird mittels "Print" ausgegeben.
Mit diesem Programm kannst du mal ein bisschen rumspielen um dich mit der Werteübergabe vertraut zu machen. Es (sollte) funktionieren (nicht getestet sondern einfach nur aus dem Kopf aufgeschrieben). Falls nicht -> PM dann schaue ich heute Mittag drüber.
Auf dein Programm übertragen kann man also sagen, dass du den Teil "byval B As Byte" löschen kannst, da du die Variable "b" eh nicht nutzt.
Funktioniert dein Programm den jetzt richtig? Und wenn nicht was funktioniert nicht.
Wollte das heute u.U. mal auf meinem RN-Control nachstellen.

p@ty
14.03.2013, 08:24
Hi Daniel,

okay, es wird transparenter! :)
Ja, das Programm läuft! Wäre klasse wenn Du´s mal testen könntest und mir en´ feedback geben würdest!
Danke schon mal!!

Viele Grüße,
p@

Kampi
14.03.2013, 08:45
Ok :)
Ich schau es mir mal an wenn ich Zeit habe :)

p@ty
14.03.2013, 11:21
Danke für Deine / Eure Zeit!!!

Viele Grüße,
p@

Searcher
14.03.2013, 11:24
Es geht, wie schon im Titel beschrieben, darum drei Led´s unabhängig von einander mit einem Taster zu schalten.

Wird der Taster kurz betätigt soll eine von den 3 Led´s leuchten.
Wird der Taster länger betätigt (>=2sek) soll in eine Subroutine gesprungen werden in der je
nach dem wie lange der Taster betätigt wird (>=2 , >=4 , >=6sek) eine von den 3 Led´s ausgewählt wird.
Danach soll wieder in´s Hauptprogramm gesprungen werden in dem ich die ausgewählte Led 1 oder 2 oder 3
mit dem Taster an und ausschalten kann.
Könntest Du nochmal erklären, wie Dein Programm arbeiten soll. Aus Deiner Beschreibung und Deinem Code hab ich mal Folgendes interpretiert:

Wenn die Schaltung mit µC und LEDs eingeschaltet wird, leuchtet keine LED !?
Wenn Taster kürzer zwei Sekunden (nach Einschalten) gedrückt wird, wird LED1 eingeschaltet. Nochmal kurz gedrückt schaltet sie wieder aus und so fort.

Wird der Taster zwei Sekunden und kürzer als vier Sekunden gedrückt wird, wird LED2 eingeschaltet und alles andere ausgeschaltet. Wird danach immer nur kürzer als zwei Sekunden gedrückt, wird LED2 aus-, eingeschaltet, also getoggelt.

Wird Taster vier Sekunden und kürzer als sechs Sekunden lang gedrückt, wird LED3 eingeschaltet und alles andere ausgeschaltet. Mit kurzen Tastendrücken wird die LED3 nun immer aus- und eingeschaltet.

Wird Taster sechs Sekunden und länger gedrückt, wird alles ausgeschaltet. Folgende kurze Tastendrücke schalten LED1 an und aus.


In Deinem zuletzt geposteten Programm kann ich nicht erkennen, wie Du die Sekunden mißt. Die Kommentare im Code sind nichtssagend und wiederholen eigentlich nur die Kommandos. Da sollten eigenlich kurze Erläuterungen stehen, warum etwas an der Stelle so gemacht wird.

Gruß
Searcher

p@ty
14.03.2013, 13:30
Hi Searcher,

wird der µC bestromt passiert nix, richtig.
Wird der Taster kurz gedrückt auch nichts. Erst wenn er >=200ms gehalten wird , wird in die Unterprozedur gesprungen.
Da wird dann als erstes Led1 eingeschaltet und die Variable A = 1 eingestellt. Lasse ich den Taster jetzt los gehts wieder zurück in die Hauptschleife. Dort wird mit dem IF- Befehl abgefragt welchen Wert A und der Taster hat. In diesem Beispiel wäre bei A = 1 + Taster = 0 die
Led1 = 1. Sonst wenn A = 1 + Taster = 1 wird Led1 = 0
Die Led1 leuchtet also nur so lange wie der Taster gedrückt wird.

Wird nach dem Sprung in die Unterprozedur der Taster weiterhin gedrückt gehalten, werden die 3 Led´s erst einzeln und dann als Szenarien durchgeschaltet. Also erst Led1 dann Led2 dann Led3.
Wird der Taster jetzt noch weiter gehalten dann Led1 + Led2 dann Led1 + Led3 dann Led2 + Led3 dann als letztes Led1 + Led2 + Led3. Bei jeder Änderung des Schaltzustandes ändert sich auch die Variable A. Beim los lassen des Tasters wird zurück in´s Hauptprogramm gesprungen und der Wert der Variablen A mit übergeben und wieder mit IF abgefragt welcher Zustand vorliegt und entsprechend die Led´s geschaltet.

Hintergrund ist dieser:
In meinem langen Flur habe ich 18 Deckenspots verbaut. Jeweils 6 hängen zusammen an einem Trafo! Sprich 3 Trafos. (Led1, Led2, Led3)
Ich möchte mit nur einem Flurtaster alle 3 Tarfos unabhängig von einander aber auch gleichzeitig schalten können. Ich drücke also den Taster, suche mir gewünschtes Szenario aus, lasse den Taster los und kann mit erneutem kurzem betätigen des Tasters das ausgewählte Lichtszenario schalten. Die Trafos werden über Stromstoßschalter bestromt. Deshalb leuchten die Led´s auch nur wenn der Taster gedrückt ist.

Hoffe jetzt sind alle Klarheiten beseitigt! :)

Vielen dank für Dein Interesse!
Viele Grüße,
p@

Searcher
14.03.2013, 18:29
Hoffe jetzt sind alle Klarheiten beseitigt! :)
Wahrscheinlich :shock: :-) . Hab mal was versucht :Ostern. Was hältst Du davon (Anhang) oder ist das Thema schon abgeschlossen?

Gruß
Searcher

p@ty
14.03.2013, 20:28
Hey Searcher!

WOW! :shock:
Vielen Dank für Deine Mühe!!!

Genau so hatte ich mir das vorgestellet!!! =D>
Funktioniert großartig!!!
Macht eigentlich genau das was auch mein ellenlanger Code macht nur sehr viel kompakter! ;)
Echt klasse das Du das mal so hin gezaubert hast!!

Werde mir den Code morgen abend genauer anschauen und hoffe das wenn Fragen auftauchen (und das werden sie bestimmt :confused:)
ich Dich noch mal ansprechen darf?

Viele Dank nochmal und schönen Abend,
p@



Viele Grüße,
P@

Searcher
14.03.2013, 20:35
Vielen Dank für Deine Mühe!!!
Keine Ursache. Hat mir auch geholfen.


ich Dich noch mal ansprechen darf?
Klar!

Und gleich noch ein Update. Sollte das Gleiche machen - Ich übe auch noch.

Gruß
Searcher

p@ty
14.03.2013, 20:43
Klar!

Super! Danke!
Der 2. Code funzt übrigens ebenso klasse!
Dann kann ich anfangen mir ne´ Platine zu Layouten und zu fräsen das die in ein Leergehäuse zur Hutschienenmontage passt!
Da kommt freude auf!! :)

Viele Grüße,
p@

Kampi
14.03.2013, 21:07
Klasse das es nun funktioniert :)

Searcher
15.03.2013, 08:12
Dann kann ich anfangen mir ne´ Platine zu Layouten und zu fräsen das die in ein Leergehäuse zur Hutschienenmontage passt! Da kommt freude auf!! :)

Ich drück Dir die Daumen. Hört sich an, als wenn das Ding in den Sicherungskasten kommt. Hoffentlich fallen da keine Störungen ein, die den µC außer Tritt bringen. Da hab ich keine Erfahrung und würd ich ein halbes Jahr nach Inbetriebnahme noch argwöhnisch als Betarelease betrachten :-) :-) :-)

Da sollte aber auch ein viel kleinerer µC ausreichen. Hab nu nicht für den Tiny13 optimiert - der sollte aber auch gehen aber mindestens höchstens der Tiny25.

Gruß
Searcher

p@ty
15.03.2013, 09:23
Danke!
Jepp, Beta ist wohl richtig!:) Werde den µC natürlich so weit wie möglich vom Trafo und den Relais entfernt platzieren. So "weit" wie eben möglich und hoffen das der mir nachts nicht die Spots durch schaltet das meine frau denkt wir hätten Poltergeister im Haus!! ;)
Tolle Idee eigentlich für Helloween ein Programm zu schreiben!! :rolleyes:

Denke auch das ein kleinerer µC ausreichen sollte aber unsere Code´s sind etwas über 1kB groß...
Hab´ hier auch noch 2 AtMega168 rum liegen....mal schauen ob alles in´s Leergehäuse passt. Wenn nicht dann Code-abspecken...
Ich geb´ bescheid wenn´s fertig ist. Dann aber in einem Projekt-Teil des Forums...

Viele Grüße,
p@

Searcher
15.03.2013, 10:04
Also das Programm hat nur ein Unterprogramaufruf und nichts Verschachteltes, keine Interrupts. Mit Anpassung der HW-Anschlüsse für LEDs und Taster und folgendem Header hat das letzte Programm für den Tiny13 kompiliert:


$regfile = "attiny13.dat"
$hwstack = 16
$swstack = 10
$framesize = 24
$crystal = 1200000

Bei der Anwendung ist - meine Ansicht - kein Quarz erforderlich. Tiny im Lieferzustand, glaub ich , läuft mit 1,2MHz.

Zur groben Berechnung der Headerangaben:
http://halvar.at/elektronik/kleiner_bascom_avr_kurs/speicher_hwstack_swstack_frame/

EDIT: Grad nochmal ein wenig mit dem Simulator probiert und in der Hilfe für framesize gelesen. Mit framesize = 24 sollte man hier auf der sicheren Seite sein.


Also das geht auf jeden Fall mit dem Tiny13
Gruß
Searcher

peterfido
15.03.2013, 22:27
Die Schleife "while Taster = 0" setzt einen prellfreien Kontakt voraus. Auch scheint das Licht nicht anzubleiben, wenn der Taster losgelassen wird. Oder habe ich da nen Denkfehler?

Mein erster Versuch würde jetzt so aussehen:

$regfile = "attiny13.dat"
$hwstack = 16
$swstack = 16
$framesize = 24
$crystal = 1200000


Taster Alias Pinb.4
'Led1 : Portb.0
'Led2 : Portb.1
'Led3 : Portb.2


Dim Taste As Bit
Dim Tastealt As Bit
Dim Zeit As Word
Dim Ledspeicher As Byte 'Speichert Zustand der LEDs in einzelnen Bits

Ddrb = &B00000111
Portb = &B00110000

Ledspeicher = &B00110111 'damit das erste mal kurz Tasten gleich alle Ausgänge setzt, falls nocht nicht alles bestückt ist.

Do
Gosub Tastercheck
Gosub Szeit
Gosub Licht

Loop
End


Tastercheck:
Debounce Taster , 0 , Taste_zu

Debounce Taster , 1 , Taste_offen

Taste_zu:
Taste = 1
Return
Taste_offen:
Taste = 0
Return

Szeit:
If Taste = 0 Then
If Tastealt = 1 Then
If Zeit < 500 Then 'wurde nur kurz gedrückt, dann ein-/ausschalten
Gosub Schalten
End If
Reset Tastealt
End If
End If
If Taste = 1 Then
If Tastealt = 0 Then
Set Tastealt
Zeit = 0
End If
Waitms 1
Incr Zeit
End If

Return

Licht:
If Taste = 1 Then

Select Case Zeit

Case 500 : Portb = &B00110001 'bit 4 immer an, wegen Pullup am Tastereingang

Case 1000 : Portb = &B00110010 'bit 5 immer an, wegen Pullup an offenem Eingang

Case 1500 : Portb = &B00110100

Case 2000 : Portb = &B00110011

Case 2500 : Portb = &B00110101

Case 3000 : Portb = &B00110110

Case 3500 : Portb = &B00110111

Case Is >= 4000 : Zeit = 499

End Select

End If

Return

Schalten:
If Portb > &B00110000 Then 'Wert größer Pullups
Ledspeicher = Portb
Portb = &B00110000
Else
Portb = Ledspeicher
End If

Return



Zweite Idee mit zusätzlichem Eingang für ~65 Sekunden Licht:


$regfile = "attiny13.dat"
$hwstack = 16
$swstack = 16
$framesize = 24
$crystal = 1200000


Taster Alias Pinb.4
Tasterzeit Alias Pinb.5

'Led1 : Portb.0
'Led2 : Portb.1
'Led3 : Portb.2


Dim Taste As Bit
Dim Tastealt As Bit
Dim Zeit As Word
Dim Ledspeicher As Byte 'Speichert Zustand der LEDs in einzelnen Bits
Dim Wtimer As Word

Ddrb = &B00000111
Portb = &B00111000

Ledspeicher = &B00111111 'damit das erste mal kurz Tasten gleich alle Ausgänge setzt, falls nocht nicht alles bestückt ist.

Do
Gosub Tastercheck
Gosub Szeit
Gosub Licht

Loop
End


Tastercheck:
Debounce Taster , 0 , Taste_zu

Debounce Tasterzeit , 0 , Taste_zeit

Reset Taste

Return

Taste_zu:
Set Taste
Wtimer = 0
Return

Taste_zeit:
Wtimer = 65535
Return

Szeit:
If Taste = 0 Then
If Tastealt = 1 Then
If Zeit < 500 Then 'wurde nur kurz gedrückt, dann ein-/ausschalten
Gosub Schalten
End If
Reset Tastealt
End If
End If

If Taste = 1 Then
If Tastealt = 0 Then
Set Tastealt
Zeit = 0
End If
Waitms 1
Incr Zeit
End If

If Wtimer >= 1 Then
Decr Wtimer
If Wtimer = 0 Then
If Portb > &B00110000 Then
Gosub Schalten
End If
End If
End If
Return

Licht:
If Taste = 1 Then

Select Case Zeit

Case 500 : Portb = &B00111001 'bit 4 immer an, wegen Pullup am Tastereingang

Case 1000 : Portb = &B00111010 'bit 5 immer an, wegen Pullup an offenem Eingang

Case 1500 : Portb = &B00111100

Case 2000 : Portb = &B00111011

Case 2500 : Portb = &B00111101

Case 3000 : Portb = &B00111110

Case 3500 : Portb = &B00111111

Case Is >= 4000 : Zeit = 499

End Select

End If

Return

Schalten:
If Portb > &B00110000 Then 'Wert größer Pullups
Ledspeicher = Portb
Portb = &B00110000
Else
Portb = Ledspeicher
End If

Return


Beide ungetestet, da keine passende Hardware hier. Werden die ganzen Zeiten halbiert und waitms auf 2 erhöht, verdoppelt sich die Laufzeit des Lichttimers. wtimer darf natürlich nicht größer werden.

Searcher
16.03.2013, 07:20
Hallo peterfido,

Auch scheint das Licht nicht anzubleiben, wenn der Taster losgelassen wird. Oder habe ich da nen Denkfehler?

Ich habe angenommen (wie p@ty erwähnt hat), daß an den LED Pins des µCs nicht direkt LEDs sitzen, sondern Stromstoßrelais, die die LEDs schalten. Die Relais bekommen während der Bedienung mit dem Taster immer nur einen Stromstoß und sind sonst stromlos. So wie ich dann den p@ty verstanden habe, soll es folgende Funktion geben:

1. System einschalten, keine LED leuchtet

2. Als erstes kurzer Tastendruck (<200ms) -> nichts passiert.

3. Taste wird lange gedrückt gehalten (>=200ms) -> Lichtszenario wird während gedrückter Taste ausgewählt


Die drei LED Pins (Stromstoßrelais) werden bei gedrückter Taste in gewissen Zeitabständen in unterschiedlichen Kombinationen unter Strom gesetzt mit LEDx = 1 bzw. ausgeschaltet mit LEDx = 0
Wird die Taste losgelassen, wird von allen Stromstoßrelais der Strom abgeschaltet (LEDx = 0). Das hab ich aus p@tys Programm entnommen und wurde vielleicht auch irgendwo erklärt.
Die zuletzt unter Strom gesetzten Stromstoßrelais sollen bei folgenden kurzen Tastendrücken einen Stromstoß bekommen.


4. Taste wird kurz (<200ms), nachdem mindestens einmal nach Systemstart das Auswahlszenario durchgespielt und beendet wurde, gedrückt. Kurze Tastendrücke hintereinander schalten die ausgewählten LEDs aus und ein und aus und....


Während der gedrückten Taste sollen die LED Pins, die beim Auswahlszenario als letztes high waren, wieder high werden.
Wird die Taste vor Ablauf von 200ms gelöst, beginnt also nicht das Auswahlszenario, sondern die LED Pins werden direkt auf low geschaltet.

Stromstoßrelais, die an den LED Pins hängen, bekommen also einen Stromstoß, was die LEDs dann wohl toggeln läßt.

5. Nun kann wieder Punkt 3. oder 4. eintreten.

Wie das genau bei P@ty realisiert ist weis ich auch nicht, scheint aber zu laufen.



Die Schleife "while Taster = 0" setzt einen prellfreien Kontakt voraus.
Eigentlich ja. Ist meiner Ansicht in meinem Programm aber egal. Die Entprellung wird mit dem DEBOUNCE gemacht und erst danach erreicht das Programm die Schleife, wenn der Taster stabil geschlossen ist.
Falls der Taster beim Lösen prellen sollte, könnte die while Schleife nochmal unabsichtlich durchlaufen werden, was aber bei den 10ms Schritten nicht wahrgenommen werden dürfte.
Wenn der Taster gelöst wird, dadurch die Schleife verlassen wird, aber noch nachprellt, ist das Programm wieder in der Hauptschleife und das DEBOUNCE fängt das Prellen ab.

Puh, das war jetzt nicht perfekte Arbeit aber hoffentlich verständlich. ;)
Gruß
Searcher

Kampi
16.03.2013, 10:29
Wenn es Probleme mit dem Prellen geben sollte, kann ja hinter der Tasterabfrage nochmal ein waitms 10 gesetzt werden und danach wird der Taster nochmal abgefragt.
Spätestens dann sollte der Taster nicht mehr prellen ;)

Searcher
16.03.2013, 10:58
Mir ist auch nicht wirklich klar, wie die Auswahl des Beleuchtungsszenarios funktioniert. Wenn zu Testzwecken LEDs direkt an die µC Ports angeschlossen sind, funktioniert es in meinem Programm so, wie beschrieben. Wenn Stromstoßrelais angeschlossen sind, müßte man die, in einem Szenario über Relais eingeschalteten LEDs, über einen Stromstoß wieder ausschalten, bevor das nächste Szenario eingeschaltet wird. Müßte p@ty austesten und bisher ist er wohl zufrieden!? Hab bisher versucht nur stur nach Anforderung auszuführen. :)

peterfido
16.03.2013, 12:36
Ja bei Stromstoßrelais wird es nicht einfach. Da bräuchte man noch eine Rückmeldung der 3 Relais, falls mal die Steuerspannung fehlt oder jemand manuell auf dem Relais gedrückt hat. Da reicht dann ein Tiny13 nicht mehr.

Warten wir erstmal ab, ob er sich dazu nochmal äußert.

p@ty
18.03.2013, 11:16
Hey Leute!!
Immer noch tolles Interesse!! Danke!

Also das mit den Stromstoßschaltern (SSS) war eine Idee ist aber noch nicht in die Tat umgesetzt - und bei genauerem hinsehen ergeben sich dadurch eine Reihe von Problemen die gelöst oder umgangen werden müssen. Ich werde die Schaltung vorläufig mit Standart Relais betreiben was nur eine kleine Änderungen des Codes zur Folge hätte. Denke das bei Nutzen der SSS der Code ungleich umfangreicher wird. Die größe des Codes spielt aber nicht so die Rolle da, wie schon erwähnt, ein ATMega 168 in die Schaltung integriert wird. Sollte doch reichen?:confused: Nur wie ich die SSS abfgrage (elektronisch) bin ich mir noch nicht ganz sicher... Hätte halt gerne was mit dem Sleep-Modus des µC gemacht. Das er, wenn der Taster eine gewisse Zeit nicht betätigt wird, in diesen Modus wechselt und die Relais nicht die ganze Zeit bestromt werden....hoffe da hat noch jemand den richtigen Geistesblitz! :) Ich werde erstmal noch etliche I-Net-Seiten durchstöbern müssen und hoffen irgendwo was von Ratiopharm, um eine Lösung zum Betrieb der Schaltung mit SSS zu finden...

Parallel dazu bin ich grade dabei ne´ Platine zu basteln die in ein Leergehäuse (75x50x17,5mm außen) zur Hutschienenmontage passt! Erstmal für die Variante mit standart Relais / ohne Eingänge zur SSS Abfrage. Mit dem ATMega168 garnicht mal so leicht wenn auch noch die geglätteten 5V darin erzeugt werden und die Ausgänge zu den Relais Platz finden sollen. Erst danach und wenn der Code für SSS optimiert werden konnte wird die Schaltung erweitert. Schicke wenn ich fertig bin, denke Mi oder Do mal en´ Pic von der Schlatung!

Auch hier bin ich für jeden Tipp und Verbesserungsvorschläge dankbar!

Werde mir beim großen C oder R mal 3 Stromstoßschalter bestellen und dann mal ne´ Schaltung aufbauen. Da lässt sich der Code auch gleich besser anpassen wenn man sieht was passiert. Zumindest bei mir ist das so! :rolleyes:
Viele Grüße,
P@

Kampi
18.03.2013, 11:36
Du kannst den Taster an einen INT-Pin anschließen. Dann wird der Controller bei einem Tastendruck geweckt. Und wenn z.B. 10 Sekunden nichts passiert lässt du ihn wieder schlafen und den Status der IOs löscht (auf 0 setzt).
Ein Mega168 reicht dicke aus. Der hat Platz genug ;)

p@ty
18.03.2013, 12:05
Okay, hört sich gut an!
Ne, Idee wie ich die SSS abfragen kann?

Viele Grüße,
Patrick

Kampi
18.03.2013, 12:37
Du kannst den zu schaltenden Ausgang über einen Optokoppler auf einen Mikrocontrollerpin rückkoppeln. Sprich wenn das Relais geschaltet wird, schaltet es neben den LEDs auch einen Koppler und dieser legt dann einen µC Pin auf High.
Dann weißt du das das Relais geschaltet wurde :)

p@ty
18.03.2013, 13:04
Okay, auch gut! Nur das alles in ein Leergehäuse für die Hutschienenmontage unter zu bringen wird sicherlich nicht einfach!!! :eek:

Aber ich werd es auf jeden Fall versuchen!! Vielleicht auch die Platine in 2 Ebenen aufteilen in nem´ breiterem Gehäuse...mal schauen! Halte euch auf dem laufenden!

Vielen Dank,
und bis später mal!

PS: Hab´ gerade Catia V6 R2013 aufe´ Workstation installiert bekommen!! :cool:
Da ist der Montag gleich ne´ ganze Ecke erträglicher!!! :)

Kampi
18.03.2013, 14:24
Den Teil mit den Relais zum schalten und die Optos für das Feedback würde ich dann auf eine zweite Platine packen. Dadurch hast du eine Platine für die Logik und die andere mit den Schaltern etc.
Das ganze kannst du dann mit Stiftleisten + Säulen aufeinander stecken.

peterfido
18.03.2013, 15:11
ICH würde dieses Projekt wohl mit einer einfachen Siemens Logo! aufbauen. 1 Eingang Taster, 3 Eingänge Istzustand und 3 Ausgänge Eltako Spulen (Stromstoßrelais). Sind noch 2 Eingänge und 1 Ausgang in Reserve über. Man spart sich die Trennung der 2 Spannungsebenen und wenn man möchte, nimmt man die Logo mit Display und hat so noch eine Schaltuhr.

p@ty
18.03.2013, 18:45
Hi peterfido!

Danke für Dein Interesse!
Eine´ Logo! hab ich hier noch rum liegen und die passende Software Logo Soft Comfort 6.x.
Daher war der Gedanke auch nahe aber da ich, wie schon beschrieben, Anfänger im Bereich µC bin und ich mich ein arbeiten möchte hielt ich dieses kleine Projekt für angebracht.
Die Preise für ne´ Logo! sind nicht für jedermanns Geldbörse bestimmt und pro Logo! nur 4 Ausgänge ist meist nicht ausreichend. Zumindest nicht für die Dinge die mir da für die Zukunft noch im Kopf rum schwirren! ;) -und die Erweiterungsmodule nicht zu vergessen wenn´s mal größer wird... Deshalb möchte ich es lieber weiterhin mit µC versuchen...

Im Anhang mal das erste Layout der Platine. Ist aber noch nichtganz fertig und wird wohl auch wieder umgeboxt für eine Platine mit 2 Ebenen wie Kampi schon anmerkte!
Dann halt in einem breiterem Gehäuse aber dafür kann ich die SSS verwenden!

Viele Grüße,
p@

Kampi
19.03.2013, 06:08
Hey,

eventuell solltest du dir mal Gedanken dadrüber machen ob SMDs nicht besser wären (spart Platz).
Und die "Großen" SMDs, sprich 0805 und SOT, kannst du auch easy löten. Alleine der µC als SOT benötigt etwa 50% weniger Platz :)

p@ty
19.03.2013, 11:28
Hey!
joa...erstmal muss ich die Teile verbauen die ich hier noch rum liegen habe!
Meine Finanzministerin hat meine Ausgaben minimiert... :rolleyes:

Deshalb: Platzsparend arrangieren! ^^

Viele Grüße,
p@

peterfido
19.03.2013, 18:38
Wofür ist der Quarz? Der interne Takt würde mir für diese Aufgabe reichen. Die Freilaufdioden würde ich in diesem Fall direkt an die Spulen der Eltakos anbringen. Falls das Kabel zum Taster (wo wird der angeschlossen?) nicht allein verläuft, würde ich noch Vorsorge gegen Induktion treffen. Für solche Ansteuerungen nehme ich gern den ULN2803. Spart Widerstände, Transisoren, Freilaufdioden und evtl. Adern. Sollen es Stromstoßrelais sein, dann fehlt noch die Rückmeldung für den Istzustand. Plan-B wären welche mich Zentral-Aus Eingang. Dann lässt sich einfach der Aus-Zustand am Anfang der Sequenz ansteuern. Bräuchte aber einen 4. Ausgang.

p@ty
28.03.2013, 06:53
Hallo zusammen!
Danke für die Tips peterfido!

Hab´ viel zu tun gehabt und bin daher gestern erst wieder an die Sache ran gegangen. Leider hab´ ich im Schaltschrank kaum noch Platz zur verfügung darum sollte alles in ein Hutschienenleergehäuse rein passen. Also max. Platinengröße wie ich sie schon als pic gepostet habe. 76x44x17.5mm Grundmaße! Den AtMega168 mit ext. Taktung würde ich gerne drauf behalten weil der halt zur verfügung steht und ich in Zukunft die Platine erweitern will. Dann natürlich in einem größerem Gehäuse und mit allen zur Verfügung stehenden I & O. Die Freilaufdioden würde ich auch gerne auf der Platine belassen. Möchte das möglichst modular aufbauen damit die Schaltung auch schnell mal in anderen Schaltschränken vor die Relais eingebaut werden kann. Okay, die Freilaufdioden wären wohl besser direkt am Eltako bzw. Relais zu bestücken aber spricht was dagegen die zu "Versuchszwecken" auf der Platine zu belassen?? Vielen Dank für die Infos!

Nun zu einem weiterm Problem:
Hatte gestern versucht den Code so um zu stricken das man Relais an statt Eltakos verwende kann.
Sprich die Led´s gehen beim einem Tasterimpuls an und beim nächsten aus.
Irgendwelche Ideen wie ich das mit dem Code von Searcher, peterfido oder mir als Grundlage realisieren könnte?

Für Tips und Hilfestellung bin ich wie immer sehr dankbar!
Viele Grüße und schöne Ostertage (womöglich Eiersuche im Schnee..??)
p@

Searcher
28.03.2013, 07:00
Hi, ich nehme an, daß Eltakos die Stromstoßrelais sind. Jetzt möchtest Du normale Relais an die Led1, Led2, Led3 Pinports anschließen? Was genau funktioniert denn an meinem letzten Code mit den Relais nicht?

Gruß
Searcher

p@ty
28.03.2013, 07:26
Hi Searcher!

Richtig! Eltakos sind die Stromstoßschalter!

Dein Code funktioniert entsprechend meiner Beschreibung zu 100% richtig!! :) Danke dafür!
MEIN Fehler war das ich nicht bedacht hatte das ich die Eltakos abfragen muss, da beim Szenariendurchlauf ja immer nur einmal die Ausgänge auf high gesetzt werden.

Als Beispiel:

LED1 & Led2 & Led3 werden im letzten Szenario auf high gesetzt. Also alle 3 Eltakos ziehen an und halten. Das nächste Szenario wäre Led1 high, Led2&3 low. Es würde nichts passieren da Led1 einfach high bleibt und Led2&3 keinen weiteren Impuls zum lösen des Eltkaos bekommen. Da ich aus Platzgründen nicht die Möglichkeit habe die Position der Eltakos ab zu fragen und denke das eine Änderung Softwaremäßig wohl sehr Umfangreich würde, dachte ich an Standart Relais zum betreiben der Schaltung...

War halt mein Denkfehler! Sorry! Übe´noch! ](*,)

Viele Grüße,
p@ty

Searcher
28.03.2013, 07:32
Kein Problem. Aber was funktioniert mit dem letzten Code von mir nicht. Ich überlege ja schon an einer Lösung, kann aber nur vermuten, daß Du mit dem kurzen Tastendruck das vorher angewählte Szenario nicht einschalten kannst?

Ist das so :confused:

Nur sagen, was Du brauchst - hab heute ein bißchen Zeit. SONDERANGEBOT :-)

Guß
Searcher

p@ty
28.03.2013, 07:51
Sonderangebot??? Da muss ich zu greifen!!! :)

Mit Led´s funktioniert Dein Code Klasse! Aber mit selbshaltenden Eltakos klappts dann natürlich nicht.

Okay, ich versuche es nochmal in Worte zu fassen....^^

Option 1 Relais!

Hierbei sollte die Szenarienauswahl ja passen da die Relais ja abfallen wenn keine Spannung anliegt.
Da sie ja nicht über Selbsthaltung verfügen muss das der Druck auf den Taster bewerkstelligen.
Halt Taster drücken = Led1 usw High! Nochmal drücken Led´s low! usw...

Option 2 Eltakos!
Hier würde der Code soweit abgeändert werden müssen, daß die Led´s bzw Eltakos einen zusätzlichen Impuls bekommen um vorm Szenarienwechsel wieder low zu sein. Da ja sonst die Eltakos aufgrund ihrer Selbshaltung die ganze Zeit über High wären. Man müsste sie abfragen welchen Zustand sie haben und diese Information wieder zum µC führen. Leider ist Hardwareseitig absolut kein Platz zur verfügung.

Also dann doch Option 1 mit "Normalen" Relais! ^^
Danke für Deine Hilfe Searcher!

Viele Grüße,
p@

Searcher
28.03.2013, 08:13
Tasten wir uns mal ran. Ich hab immer noch nicht verstanden, was im Datail unbefriedigend ist und hab einfach mal was gemacht. Kennst das, was von Planung über Entwicklung, Fabrikation, Lieferung und Montage am Ende übrig bleibt :-) ?

Nicht getestet aber sollte so sein:
Auswahl Szenario wie gehabt.
Am Ende der Auswahl bei Taster loslassen werden die Relais(Leds) nicht abgeschaltet, aktuelles Szenario bleibt an.
Mit folgendem kurzem Tastendruck wird dann abgeschaltet.
Mit weiterem kurzen Tastendruck wird vorhergehendes Szenario wieder eingeschaltet.

Hab noch ein Case für den kuzen Tastendruck eingefügt und das Abschalten der LedX am Ende rausgenommen. - Dieses Case wieder entfallen nach Update. Kurzer Tastendruck wird am Ende abgefragt.

PS. Ohhh schon Fehler entdeckt - Update kommt später:oops:
Update gemacht :pray:


'###################################
'### BASCOM Demoversion V2.0.7.5 ###
'###################################
$regfile = "m168def.dat"
$framesize = 32
$swstack = 32
$hwstack = 34
$crystal = 16000000

Dim Hundertstelsekunden As Word 'enthält Tastendrucklänge in Hundertstel Sekunden

Dim Ledspeicher As Byte 'Speichert Zustand der LEDs in einzelnen Bits
Const Led_1 = 0 'Zum Adressieren der Bits in Ledspeicher
Const Led_2 = 1 'Zum Adressieren der Bits in Ledspeicher
Const Led_3 = 2 'Zum Adressieren der Bits in Ledspeicher

Portd.4 = 1 'Pullup an PD4 einschalten
Taster Alias Pind.4 'Taster an PD4

Led1 Alias Portc.0 'Anschluß für LED1 ?
Led2 Alias Portc.1 'Anschluß für LED2 ?
Led3 Alias Portb.3 'Anschluß für LED3 ?
Config Led1 = Output
Config Led2 = Output
Config Led3 = Output

Do 'Hauptschleife
Debounce Taster , 0 , Taste_gedrueckt , Sub 'Wenn Tasteranschluß auf 0 (low) -> Subroutine Taste_gedrueckt
'Debounce hat bei Aktivität auf dem PIN ca. 25ms Verzögerung
Loop 'Ende Hauptschleife

Taste_gedrueckt: 'Unterprogram wird angesprungen, wenn Taste gedrückt wurde
Hundertstelsekunden = 0 'initialisieren für Zeitmessung
While Taster = 0 'Solange Taster gedrückt ist...
Waitms 10 '0,01s Zeitmeßschritte
Incr Hundertstelsekunden 'alle 10ms erhöhen
Select Case Hundertstelsekunden 'Hundertstelsekunden enthält Länge des Tastendruckes in Hundertstelsekunden
Case 20 To 69 : Ledspeicher = Bits(led_1) 'Taste zwischen 200ms und <700ms gedrückt
Case 70 To 119 : Ledspeicher = Bits(led_2) 'Taste zwischen 700ms und <1200ms gedrückt
Case 120 To 169 : Ledspeicher = Bits(led_3)
Case 170 To 219 : Ledspeicher = Bits(led_1 , Led_2)
Case 220 To 269 : Ledspeicher = Bits(led_1 , Led_3)
Case 270 To 319 : Ledspeicher = Bits(led_2 , Led_3)
Case 320 To 369 : Ledspeicher = Bits(led_1 , Led_2 , Led_3)
Case 370 : Hundertstelsekunden = 19 'Taste 3,7s und länger gedrückt-> Auswahl Lichtszenario beginnt neu
End Select
if Hundertstelsekunden >= 20 then 'wenn Selektion, dann Leds entsprechend einschalten
Led1 = Ledspeicher.Led_1
Led2 = Ledspeicher.Led_2
Led3 = Ledspeicher.Led_3
end if
Wend
if Hundertstelsekunden < 20 then 'wenn Taste nur kurz gedrückt wurde ...
If Led1 = 1 or Led2 = 1 or Led3 = 1 then 'und irgendeine Led eingeschaltet ist
Led1 = 0 'dann alle ausschalten
Led2 = 0
Led3 = 0
else 'oder gespeichertes Szenario einschalten.
Led1 = Ledspeicher.Led_1
Led2 = Ledspeicher.Led_2
Led3 = Ledspeicher.Led_3
end if
end if
Return 'zurück zur Hauptschleife

End 'end program

p@ty
28.03.2013, 08:22
Jepp, das womit sich der Kunde zufrieden geben muss
aber nichts mehr mit dem eigentlich angenommenen Auftrag zu tun hat! ^^

Mein Gott bist Du schnell!!! Ja, genau so sollte es sein!
Kann Deinen Code aber erst heute Abend testen! Hab´ erst gegen 17h Feierabend! Aber dann ist langes Osterwochenende und das hast Du mir gerade um 100% verbessert!

Bin schon sehr gespannt!

Viele Grüße!
p@

Searcher
28.03.2013, 12:39
Mein Gott bist Du schnell!!! Ja, genau so sollte es sein!
Kann Deinen Code aber erst heute Abend testen!Bin schon sehr gespannt!

Na ja, schnell ist nicht gut :( Jetzt sollte es passen. Hab den Code von heute morgen ausgetauscht und bin nun auch gespannt.

Ist immer noch vermutlich eine kleine Macke drin - soll erstmal zum Testen sein und ob die grobe Funktion so richtig ist.

p@ty
28.03.2013, 13:30
Na, geht ja jetzt für mich rapide auf´n Feierabend zu! ^^ Seh´ schon die Led am USB Progger blinken!!! :)

p@ty
28.03.2013, 19:19
Heyho!

@ Searcher:
Absolute Klasse!!! :pray:
Klappt einwand frei!!!!! :)

Ich Danke Dir für diesen tollen Code und die Mühe die Du investiert hast!!

Jetzt muss ich mich erst einmal damit auseinander setzen und versuchen den zu verstehen / nach zu vollziehen!
THX!!!!

Viele Grüße,
p@

Searcher
28.03.2013, 20:15
Noch 'ne kleine Hilfe obendrauf. Nur noch Fragen hierzu oder zu Programmänderungen notwendig, Dank habe ich schon genug bekommen und sollte erstmal reichen :cheesy:.


Deklarieren und Initialisieren

In Hauptschleife nur auf Tastendruck warten
Mit DEBOUNCE Tastendruck erkennen, entprellen und Aufruf von "Taste_gedrueckt" Unterprogramm
Ende Hauptschleife

Taste_gedrueckt:
Programmzeilen zwischen WHILE und WEND wird solange durchlaufen wie die Taste gedrückt ist (wg While Taster = 0)
Die Schleife wird alle 10ms Durchlaufen (wg waitms 10)
Die Tastendruckzeit kann der Variablen "Hundertstelsekunden" in 10ms Schritten entommen werden. Wert von 10 entspricht 100ms
In der Case Anweisung wird die Tastendruckzeit während des Drucks ständig ausgewertet und je nach Länge der Ledspeicher mit dem Szenario belegt.
Für Tastendruck kürzer als 200ms ist kein Case vorgesehen, ist ja kein Szenarioauswahl
Case 370: Zu langer Druck -> kein neues Szenario verfügbar -> Zurücksetzten Hundertstelsekunden -> Vorgaukeln eines kürzeren Druckes und Szenarioauswahl beginnt von vorne.
Vor dem WEND werden dann die LEDs während des Szenarioauswahldruckes eingeschaltet, aber nur wenn kein kurzer Tastendruck vorliegt, der ja hier noch möglich sein kann, da die Zeitmessung noch nicht zu Ende ist.

Taste wurde gelöst -> Programmzeilen nach WEND werden durchlaufen
Wenn mit langem Tastendruck eine Szenarioauswahl stattgefunden hat, wurden die LEDs ja schon entsprechend geschaltet
Also wird mit der ersten If Abfrage nur bei kurzem Tastendruck eine Aktion ausgeführt.
Die gleich folgende If Abfrage dient dazu festzustellen, ob ein- oder ausgeschaltet werden muß
Wenn also irgendeine LED (wg LED1 = 1 or LED2 = 1 or ... ) an ist, wird ausgeschaltet, sonst das Szenario eingeschaltet.
Fertig und Rücksprung in die Hauptscheife

p@ty
28.03.2013, 20:39
Ehre wem Ehre gebührt! ;)
Nein echt, ganz klasse und super Hilfe!!

Probiere auch schon die ganze Zeit damit rum!
24979

Viele Grüße,
p@

Searcher
29.03.2013, 05:36
Die drei LEDs auf dem Bild sagen mir was aber wozu die Motore??? Die Flurbeleuchtung kann man natürlich auch über eine Schalterkonstruktion, die über die Nockenwelle betätigt wird, schalten? Da kommen mir die Stromstoßrelais aber schon einfacher vor :-) Nicht für ungut.;)

p@ty
29.03.2013, 11:07
:) Ne, ist nur alles auf der Einschubplatte unter meinem Schreibtisch montiert damit man mal schnell einen Code aus probieren kann! Eigentlich für die Tastatur gedacht,
lässt sich alles schnell unter den Schreibtisch schieben und sieht gleich wieder "aufgeräumter" aus! ;)

Und ich muss für solche Bastelleien nicht immer in den Keller rennen und kann´s gemütlich oben machen ohne das die Chefin meckert! ^^

Viele Grüße,
p@

p@ty
10.07.2014, 12:03
Hey zusammen!
Muss mich erstmal entschuldigen - Sorry das ich so lange das Thema hier offen gelassen habe!

Hab an meinem Haus einen Anbau gemacht und bin kurz darauf Papa geworden! Hat alles etwas Zeit beansprucht aber jetzt kann ich mich zwischen durch auch mal wieder meinen Hobby´s widmen! ^^
Hatte den Code von Dir ausprobiert Searcher und der hat super funktioniert! Danke nochmal für Deine Mühe!
Kam leider nie dazu die Schaltung dafür mal auf Platine zu bannen!

Aber es funktioniert!! \\:D/ ...und das Platinenlayout habe ich auch schon fertig!

Von daher kann das Thema als erledigt abgehakt werden!
Danke Euch allen!

Viele Grüße,
p@