Forum: Mikrocontroller und Digitale Elektronik Abfragen ob Taster mehrmals gedrückt wurde


von Chris (Gast)


Lesenswert?

Hallo Leute,
vielleicht könnt ihr mir helfen.

Ich habe eine Schaltung (Attiny 2313) an der LED´s hängen.

Jetzt möchte ich da zwei Taster integrieren,
die bei mehrmaligem betätigen verschiedene sachen auslösen.


1. Taster
Zum einen habe ich 6 LED´s die als Nebelscheinwerfer für ein RC Modell 
dienen. Diese möchte ich, das wenn der taster 1mal gedrückt wird, 
einschalten. Wenn ich den taster ein zweites mal drücke, sollen sie 
ausgeschaltet werden.


2. Taster
Dann habe ich noch ein Lauflicht am µC hängen.
Dieses möchte ich mit verschiedenen modi ausrüsten, die dann auch per 
Tasterdruck gewechselt werden können.
1es mal taster drücken lauflicht einschalten
2es mal taster drücken nächster lauflicht modi
3er mal taster drücken nächster lauflicht modi
usw....
10es mal taster drücken lauflicht ausschalten


Es wäre echt nett, wenn ihr mir helfen könntet.


MfG
Chris

von Chris (Gast)


Lesenswert?

Chris schrieb:
> Zum einen habe ich 6 LED´s die als Nebelscheinwerfer für ein RC Modell
> dienen.

die hängen an einem pin

von citb (Gast)


Lesenswert?

Ganz klar, wie hier beschrieben:

http://www.mikrocontroller.net/articles/Entprellung

citb

von Knut (Gast)


Lesenswert?

Welche Grundkenntnisse leigen denn vor? Wenig oder noch weniger?
Welche Programmiersprache?

Ansich ist das alles kein großer Akt, aber ohne Basics etwas viel bzw. 
man müsste ganz klein anfangen.

Ich würde sagen du haust dir erstmal das Tut rein.


Knut

von Chris (Gast)


Lesenswert?

also taster entprellen kann ich in soweit, das wenn ich einen taster 
drücke er eine led einschaltet...er dann in einer schleifen abfragt ob 
ich einen zweiten taster drücke...und wenn ich den dann drücke er die 
erste led ausschaltet und eine andere dafür ein

von Chris (Gast)


Lesenswert?

Knut schrieb:
> Welche Programmiersprache?

basic...sprich in BascomAVR

von Christopher G. (cbg)


Lesenswert?

Du willst eine Statemachine bzw einen Zustandsautomaten basteln. 
Siehe Artikel.

von Chris (Gast)


Lesenswert?

So...gelesen habe ich es, aber nicht wirklich verstanden da es in C 
Programmiert ist.

von Chris (Gast)


Lesenswert?

$regfile = ""
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
'---------------


Config Portb = Output
Dim Warten As Byte

Warten = 15

Portb = &B00000000
Waitms 180
Portb = &B11111111
Waitms 180
Portb = &B00000000
Waitms 180

Do
Portb = &B00100000
Waitms Warten
Portb = &B00110000
Waitms Warten
Portb = &B00111000
Waitms Warten
Portb = &B00011100
Waitms Warten
Portb = &B00001110
Waitms Warten
Portb = &B00000111
Waitms Warten
Portb = &B00000011
Waitms Warten
Portb = &B00000001
Waitms Warten
Portb = &B00000011
Waitms Warten
Portb = &B00000111
Waitms Warten
Portb = &B00001110
Waitms Warten
Portb = &B00011100
Waitms Warten
Portb = &B00111000
Waitms Warten
Portb = &B00110000
Waitms Warten
Portb = &B00100000
Loop
End                                                         'end program


das ist mein momentaner code für das lauflicht

von Karl H. (kbuchegg)


Lesenswert?

So wird das nichts.
Mach dich schlau über
* Timer
* DATA, READ, RESTORE

In DATA Anweisungen bringst du die auszugebenden Bitmuster unter. Für 
jedes Lauflichmuster ein eigenes DATA. Den jeweils ersten Wert eines 
DATA nimmst du als Anzahl der Bitmuster in diesem Lauflicht
Mittels RESTORE wechselst du die DATA und damit das Muster
und mittels dem Timer machst du das Timing, dass nach x Zeiteinheiten 
jeweils das nächste Bitmuster aus dem aktuellen DATA gelesen und 
ausgegeben wird.

In dem Moment, in dem du ein WAITMS im Programm hast um das Timing zu 
machen, kannst du vernünftige interaktive Bedienung schon vergessen. Das 
ist Müll.

Ohne mit einem Timer umgehen zu können, haben viele Dinge auf einem µC 
keinen Sinn. Timer sind deine Arbeitspferde.

von Chris (Gast)


Lesenswert?

Hast du dazu vielleicht einen Link
oder einen Ansatz ?

von Karl H. (kbuchegg)


Lesenswert?

Das schaut recht passabel aus
http://halvar.at/elektronik/kleiner_bascom_avr_kurs/

ansonsten: google mit "BASCOM Tutorial"

von Chris (Gast)


Lesenswert?

vielen dank.

ich werd mich mal einlesen

von Karl H. (kbuchegg)


Lesenswert?

Oh. Und natürlich die BASCOM Hilfe. In der BASCOM IDE einfach F1 
drücken.

von Chris (Gast)


Lesenswert?

ok...danke

vielleicht bekomm ich es ja hin :)
wenn nicht, dann kann ich euch ja bestimmt nochmal um rat fragen.

von Chris (Gast)


Lesenswert?

Also ich hab mir das jetzt mal durchgelesen...aber ich komme damit nicht 
so ganz klar...
bzw weiß nicht wie ich das in meinem fall umsetzen soll...
besonders bei der lauflicht animation

könnte mir nicht jemand bei dem code helfen ? vielleicht mit einem 
anfang..

Gruß
Chris

von Chris (Gast)


Lesenswert?

ich habs jetzt mit dem code probiert...halt angepasst auf den 
Attiny2313...aber es tut sich nix...es leuchtet nur die 1 led und wenn 
ich taster drücker passiert garnichts...

hilfe....

von Chris (Gast)


Lesenswert?

Chris schrieb:
> ich habs jetzt mit dem code probiert...halt angepasst auf den
http://halvar.at/elektronik/kleiner_bascom_avr_kurs/interrupts/

von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

Hi Chris,

zeig her deinen Code - funktionierts jetzt?

von Chris (Gast)


Lesenswert?

ich hab jetzt nochmal etwas weiter gebastelt...
jetzt bleibt die 1 led durchgehend an...
und wenn ich den taster drücke geht die 2 led an..wenn ich nochmal 
drücke geht sie aus (zu 99%)...
aber wie soll ich das programmieren, das es noch mein lauflicht bleibt ?

ein/ausschalten der nebelscheinwerfer klappt ja dann jetzt schonmal

von Chris (Gast)


Lesenswert?

Code sieht jetzt so aus,
das an PD3 der taster hängt für die nebelscheinwerfer

Dieser schaltet bei tastendruck die led´s an PB0 ein...wenn ich nochmal 
drücke schaltet er sie aus...Perfekt für die nebelscheinwerfer...


Aber wie programmier ich mein lauflicht mit nachlaufeffekt ?
das sich dann ja auch noch ändert bei tastendruck (taster an PD2)

von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

Code?

von Chris (Gast)


Lesenswert?

$regfile = ""
$crystal = 8000000
$hwstack = 32
$swstack = 10
$framesize = 40
'---------------

'LED1 an PB7
Led1 Alias Portb.7
Config Led1 = Output

'LED2 an PB0
Led2 Alias Portb.0
Config Led2 = Output

'TASTER1 an PD2
Taster1 Alias Pind.2
Config Taster1 = Input
Taster1 = 1 
'PullUp-Widerstand einschalten

'Wenn der Interrupt INT0 auftritt, dann springe zum Label On_int0
On Int0 On_int0

'Der Interrupt INT0 wird ausgelöst wenn der Pin PD2 gegen GND gezogen 
wird.
'Also beim Übergang von HIGH nach LOW. Der Interrupt wird nicht 
ausgelöst, wenn
'der Pin bereits gegen GND zieht.
Config Int0 = Falling                                       'fallende 
Flanke

'INT0 einschalten
Enable Int0

'Interrupts global einschalten. Das ist der Hauptschalter für alle 
Interrupts
Enable Interrupts


Do
   Toggle Led1
   Waitms 200
Loop

End


On_int0:
   Toggle Led2
Return




momentan ist er noch so

von Peter D. (peda)


Lesenswert?

Das hier dürfte exakt die Funktion sein, die Du suchst:

Beitrag "AVR Sleep Mode / Knight Rider"

Ist allerdings in C geschrieben.

Der Trick dabei ist, daß die Mainloop immer schnell durchläuft und 
dadurch die Tasten für den Menschen sofort reagieren.

Die Wartezeit wird über einen Timer gemacht, der sofort zum Main 
zurückkehrt, wenn er noch nicht abgelaufen ist.
Ansonsten wird das nächste Bitmuster ausgegeben und hochgezählt.

Die Bitmuster sind bequem in einer Tabelle definiert. Dadurch vermeidet 
man umständlichen Spaghetticode.

Den Sleepmode kann man auch weglassen, das Programm funktionert exakt 
gleich, nur der Stromverbrauch ist größer.


Peter

von Chris (Gast)


Lesenswert?

Ja, das würde perfekt passen...nur wie bekomm ich das in bas ?
Muss ja den code bearbeiten

von Peter D. (peda)


Lesenswert?

Bascom Manual:

Tabelle:
6.187 DATA
Action
Specifies constant values to be read by subsequent READ statements.


getkey:
6.195 DEBOUNCE
Action
Debounce a port pin connected to a switch.


Peter

von Chris (Gast)


Lesenswert?

??????

was meinst du damit ?
bin leider noch nicht so besonders weit was programmierung betrifft.

von Chris (Gast)


Lesenswert?

hab mir die zwei abschnitte mal durchgelesen...aber ich versteh es 
leider nicht wirklich :´-(

von Peter D. (peda)


Lesenswert?

Dann lies Dir mal Bascom Beispiele, Tutorials durch, z.B.:

http://halvar.at/elektronik/kleiner_bascom_avr_kurs/taster_entprellen/

Und fange klein an.
Dein Programm ist keine Black Box, sondern Du mußt es Schritt für 
Schritt aufbauen.


Peter

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt mal versucht einen Code zu basteln...
kann aber momentan nicht testen, da ich an meinem PC den µC nicht 
programmieren kann...muss ich warten bis ich wieder zu den eltern meiner 
freundin komme...
könntet ihr mir vielleicht sagen ob der code so funktioniert ?
Und wie ich das anstelle mit dem mehrfach drücken des tasters

Code als dateianhang

von Karl H. (kbuchegg)


Lesenswert?

Du machst immer noch den gleichen Fehler.

Solange du dich nicht von waitms verabschiedest, wird das nie was 
vernünftiges.

Vergiss fürs erste deine Taster. Die sind momentan für dich ein 
Nebenschauplatz.
Du musst erst mal die Technik lernen, wie man in regelmässigen 
Zeitabständen mithilfe eines Timers Aktionen ausführen lässt. Ohne Timer 
kommst du nicht weiter.
Timer laufen lassen und eine Interrupt Service Routine zb an den 
Timer-Overflow koppeln. In dieser Service Routine wird dann das 
Lauflicht realisiert, in dem bei jedem Aufruf (oder auch bei jedem x-ten 
Aufruf je nachdem welche Zeiten gewünscht werden) die jeweils nächste 
Led eingeschaltet wird.

Das ist dein erstes Zwischenziel. Und solange du das nicht erreichst, 
brauchst du dich um Taster überhaupt noch nicht kümmern.

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

so...hab mir jetzt das mit timer nochmal durchgelesen und mir im netz 
ein paar beispiele angeschaut...
hoffe es stimmt jetzt so...
wenn nicht...könntest mir vielleicht schreiben was nicht stimmt ?

von Chris (Gast)


Lesenswert?

ich seh gerade, ich hab die led anzahl falsch gemacht....der code ist 
grad für 8 led´s...sollte aber für 6 sein...
also nicht wundern

von Karl H. (kbuchegg)


Lesenswert?

1
      Tim0_isr:
2
    Portb = &B10000000
3
    Portb = &B11000000
4
    Portb = &B11100000
5
    Portb = &B01110000
6
    Portb = &B00111000
7
    Portb = &B00011100
8
    Portb = &B00001110
9
    Portb = &B00000111
10
    Portb = &B00000011
11
    Portb = &B00000001
12
    Portb = &B00000011
13
    Portb = &B00000111
14
    Portb = &B00001110
15
    Portb = &B00011100
16
    Portb = &B00111000
17
    Portb = &B01110000
18
    Portb = &B11100000
19
    Portb = &B11000000
20
    Portb = &B10000000

Noch nicht.
Die ISR wird regelmässig aufgerufen. Und bei JEDEM einzelnen Aufruf wird 
ein anderes Byte ausgegeben. Du musst zb in einer Variablen mitzählen, 
welches Byte bereits ausgegeben wurde und dann je nachdem das jeweils 
nächste ausgeben.
1
Tim0_isr:
2
3
  if cnt = 19 then
4
    cnt = 0
5
  else
6
    cnt = cnt + 1
7
8
  if cnt = 0  Portb = &B10000000
9
  if cnt = 1  Portb = &B11000000
10
  if cnt = 2  Portb = &B11100000
11
  if cnt = 3  Portb = &B01110000
12
  ....
13
14
return

Als erster Ansatz. die if-Leiste wird im Endeffekt nicht so bleiben, 
aber irgendwo musst du anfangen.

Die ISR hat innerhalb der Hauptschleife nichts verloren.

Die Aufruffrequenz der ISR wird noch viel zu hoch sein. Ausrechnen! 
Welchen Prescaler hast du benutzt, welche Frequenz kriegt daher der 
Timer und wie weit muss er zählen bis die ISR aufgerufen wird. Daraus 
kann man ausrechnen, wie oft dieses Ereignis in der Sekunde passieren 
wird
http://www.mikrocontroller.net/articles/FAQ    Punkt 9. Timer

von Karl H. (kbuchegg)


Lesenswert?

1
On_taster1:
2
3
Do
4
  Portb = &B00000000
5
  Waitms 200
6
  Portb = &B11111111
7
  Waitms 200
8
  Portb = &B00000000
9
  Waitms 200
10
11
      Tim0_isr:
12
    Portb = &B10000000
13
    Portb = &B11000000
14
    Portb = &B11100000
15
    Portb = &B01110000
16
    Portb = &B00111000
17
    Portb = &B00011100
18
    Portb = &B00001110
19
    Portb = &B00000111
20
    Portb = &B00000011
21
    Portb = &B00000001
22
    Portb = &B00000011
23
    Portb = &B00000111
24
    Portb = &B00001110
25
    Portb = &B00011100
26
    Portb = &B00111000
27
    Portb = &B01110000
28
    Portb = &B11100000
29
    Portb = &B11000000
30
    Portb = &B10000000
31
Loop

Nein. Innerhalb von On_taster1 hast du keine Schleife! Es gibt nur eine 
Schleife die dauernd läuft und das ist die hier
1
Do
2
   Debounce Taster1 , 0 , On_taster1 , Sub
3
   Debounce Taster2 , 0 , On_taster2 , Sub
4
Loop

Die Lichtfolge wird dadurch erreicht, dass vom Timer aus in 
regelmässigen Zeitabständen die ISR-Funktion Tim0_isr aufgerufen wird. 
Dort steckt die Schleife implizit drinnen! Das ist wie wenn jemand alle 
2 Sekunden bei dir im Büro zur Tür reinkommt und 'Jetzt' schreit. Du 
unterbrichst kurz deine Arbeit und schaltest die LEDs um. In Summe, wenn 
du das Umschalten richtig machst, ergibt sich dadurch auch ein 
Lauflicht, bei dem sich das angezeigte Muster alle 2 Sekunden ändert.

Deine Tasten-Sub stellen eine weitere Variable auf Blinklicht (zb wenn 
die Variable 0 ist) bzw. Lauflicht (wenn die Variable auf 1 ist). 
Innerhalb der ISR prüfst du als erstes ab, ob die variable auf Lauflicht 
steht (also ob sie 1 ist) und wenn nicht, dann lässt du nur die LED 
blinken indem du sie in den anderen Zustand schaltest.

von Chris (Gast)


Lesenswert?

das kapier ich jetzt gerade garnicht...
Der code in der FAQ ist total unverständlich für mich :(

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> das kapier ich jetzt gerade garnicht...
> Der code in der FAQ ist total unverständlich für mich :(

Der Code in der FAQ ist in C.
Das macht aber nichts, du kannst ihn weitestgehend in den Details 
ignorieren.
Wichtig ist die Beschreibung rundherum, die dir die Prinzipien 
vermitteln soll. Denn die finden sich auch in BASCOM wieder. Zwar mit 
einer anderen Schreibweise aber das Prinzip ist komplett identisch, weil 
es ja von der Hardware so vorgegeben ist.

von slow (Gast)


Lesenswert?

Liegt das Problem am Lernen können oder Lernen wollen?

Eins von beiden kann man ändern.

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

ok
hab den code jetzt so abgeändert wie du es geschrieben hast.
aber ich versteh nicht was du mit den variabeln meinst.

von Chris (Gast)


Lesenswert?

@ slow

ich will es ja lernen, nur tu ich mir recht schwer damit :(

von Chris (Gast)


Lesenswert?

ich hab leider ein schwäche was solche sachen betrifft.
auch in der schule viel mir damals das lernen schwer.
Brauche immer etwas länger bis ich solche sachen verstehe.
Darum sind mit beispiele immer eine sehr große hilfe.

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt nochmal etwas rumgebastelt...
mit verschiedenen Tutorials und beispielen die ich im netz gefunden 
habe...
nur bringt mit Bascom leider nen fehler :(

Was hab ich denn falsch gemacht ?
neue datei als anhang

von Chris (Gast)


Lesenswert?

achso...der timer ist noch nicht eingebaut...
momentan wieder mit waitms

von Chris (Gast)


Lesenswert?

er meint das Incr Taster1 falsch wäre

von Paul Baumann (Gast)


Lesenswert?

Taster1 Alias Pind.2
Config Taster1 = Input
Taster1 = 1
Dim Taster1 As Single

Taster1 ist doch nur ein Bit, das kann doch kein Datentyp "Single" 
sein.

MfG Paul

von Chris (Gast)


Lesenswert?

Danke...hab ich geändert
jetzt zeigt er Incr Taster1 auch nichtmehr als fehler an...

aber immer noch fehler bei:

Do
If Taster1 = 7
Then Taster1 = 1
Else
Incr Taster1
End If


IF THEN expected
Assignment Error [Then Taster1: 0   1:112]
LOOP expected

von Karl H. (kbuchegg)


Lesenswert?

Schau mal wo du das THEN stehen hast und wo es hingehört

von Chris (Gast)


Lesenswert?

Oh...ok ^^ bin ich wohl auf enter gekommen

Do
If Taster1 = 7 Then Taster1 = 1
Else
Incr Taster1
End If


jetzt kommt aber der fehler bei Incr Taster1

Invalid Datatyp [[0011] 24[PIND.2]]
Wrong Datatyp [PIND.2]
LOOP expected

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> Oh...ok ^^ bin ich wohl auf enter gekommen
>
> Do
> If Taster1 = 7 Then Taster1 = 1
> Else
> Incr Taster1
> End If


Und jetzt schaust du mal in die BASCOM Hilfe. Unter 'Language Reference' 
findest du das Stichwort IF-THEN-ELSE-ENDIF und siehst dir endlich in 
der Doku vom Hersteller an, wie das wirklich geschrieben werden muss

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:

> jetzt kommt aber der fehler bei Incr Taster1
>
> Invalid Datatyp [[0011] 24[PIND.2]]


Wie willst du denn einen Pin der auf Eingang konfiguriert ist um 1 
erhöhen?


Du brauchst eine Variable um dir selbst einen Zähler zu bauen!
1
DIM irgendwas AS INTEGER
Jetzt hast du eine Variable namens 'irgendwas'

Diese Variable entält einen Wert
1
  irgendwas = 5

und mit der kann man rechnen. zb kann man die erhöhen
1
  INCR irgendwas

die kann man auch abfragen, ob sie einen bestimmten Wert hat
1
  IF irgendwas = 7 THEN
2
    irgendwas = 0
3
  ELSE
4
    INCR irgendwas
5
  ENDIF

Anstelle von 'irgendwas' nimmt man natürlich eine Bezeichnung, die der 
Aufgabenstellung angemessen ist. Da es sich hier bei dir um einen Zähler 
handelt, wäre zb das englische Counter ein nicht so schlechter Begriff
1
DIM Counter AS INTEGER
2
3
.....

von Chris (Gast)


Lesenswert?

So stehts im Handbuch:

If A = 10 Then
Print "This part is executed."
Else
Print "This will never be executed."
End If


und wenn ich es genauso schreibe
If Taster1 = 4 Then
Taster1 = 1
Else
Incr Taster1
End If


bekomm ich trotzdem den selben fehler

von Chris (Gast)


Lesenswert?

ok...teste ich

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

so...jetzt habe ich alles überarbeitet...

nun sind auch alle fehler weg...
könnt ihr nochmal drüber schauen ob der code auch so funktionieren 
könnte ?

Vielen Dank übrigens für die ganze hilfe.

datei wieder im anhang

von Karl H. (kbuchegg)


Lesenswert?

Und jetzt machst du die Sache mit einer Variablen noch einmal. Und zwar 
ersetzt du hier


Effekt1:                                                    ' leds von 
links nach rechts
Led1 = 1
Waitms 100
Led2 = 1
Waitms 100
Led1 = 0
Waitms 100
Led3 = 1
Waitms 100
Led2 = 0
Waitms 100
Led4 = 1
Waitms 100
Led3 = 0
Waitms 100
Led5 = 1
Waitms 100
Led4 = 0
Waitms 100
Led6 = 1
Waitms 100
Led5 = 0
Waitms 100
Led6 = 0
Waitms 100
End

die ganze Litanei, in der ein Muster ausgegeben wird und danach gewartet 
wird durch einen Zähler und abhängig vom Zähler wird dann EIN TEIL des 
Musters ausgegeben und die Sub geht mit einem return sofort wieder 
zurück. Beim nächsten Aufruf kommt dann der nächste Teil des Musters. So 
wie ich dir das weiter oben schon skizziert habe.

Dein jetziger Zähler ist hingegen nicht sehr nützlich, so wie er 
eingebaut ist. Denn das schaltet die Effekte ja automatisch durch. Genau 
das willst du aber eigentlich ja nicht. Das willst du ja mit Tasten 
machen. Den zähler  brauchst du aber, damit in der Effektroutine klar 
ist, wie weiter gemacht werden muss, das wäre der primäre Zweck gewesen)


(Deine Eigeninitiative in allen Ehren. Aber: Mit jedem Schritt auf das 
Ziel zu, entfernst du dich gleich wieder 2 Schritte in die 
Gegenrichtung, weil du die Dinge die jetzt wirklich wichtig wären, 
nämlich Timer, einfach ignorierst. Anstelle dich darüber schlau zu 
machen und damit zu experimentieren baust du dein Programm jetzt in eine 
Richtung aus, in der du wieder in Kürze anstehen wirst. Solange du das 
Lauflicht nicht von sequentieller Abarbeitung und damit verbunden waitms 
hin zu ereignisgesteuert (timerbasiert) umbaust, kommst du deinem Ziel 
keinen Schritt näher.

von Chris (Gast)


Lesenswert?

ich hatte mir den code ja nur zusammengebastelt aus verschiedenen 
beispielen :)
da war der timer nicht drin...
den wollte ich ja noch einbauen wenn der rest vom code schonmal zum teil 
stimmt :)
den mach ich jetzt ja auch rein...
das meintest du ja mit "die ganze Litanei, in der ein Muster ausgegeben 
wird und danach gewartet
wird durch einen Zähler und abhängig vom Zähler wird dann EIN TEIL des
Musters ausgegeben und die Sub geht mit einem return sofort wieder
zurück. Beim nächsten Aufruf kommt dann der nächste Teil des Musters. So
wie ich dir das weiter oben schon skizziert habe."


oder ?


sprich
Tim0_isr:

  if cnt = 19 then
    cnt = 0
  else
    cnt = cnt + 1

  if cnt = 0  Portb = &B10000000
  if cnt = 1  Portb = &B11000000
  if cnt = 2  Portb = &B11100000
  if cnt = 3  Portb = &B01110000
  ....

return

das wieder reinbasteln

von Chris (Gast)


Lesenswert?

als was muss ich "cnt" deklarieren ?

Dim cnt As ?

bekomme sonst fehler.


Sorry das ich so anstrengend bin :(

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

ist echt zum verzweifeln :(

von Patrick B. (p51d)


Lesenswert?

Hallo

cnt ist dein Zähler. Der hat je nach gewünschtem Zählumfang 8Bit (char) 
oder 16 bit oder 32Bit.

Ich kenne mich bei Bascom zwar nicht aus, aber ich versuche dein Problem 
mal etwas Abstrakt zu lösen:
1
DIM cnt AS INTEGER                    // 16Bit Zählumfang
2
DIM muster AS CHAR                    // 8Bit Zählumfang
3
4
Timer ISR (z.B alle 1sec)--------------------------------
5
if muster = 1 then
6
  if cnt = 0 then XXXX endif
7
  if cnt = 1 then XXXX endif
8
  if cnt = 2 then XXXX endif
9
  if cnt = 3 then XXXX endif
10
endif
11
if muster = 2 then
12
13
  if cnt = 0 then YYY endif
14
  if cnt = 1 then YYY endif
15
  if cnt = 2 then YYY endif
16
  if cnt = 3 then YYY endif
17
endif
18
// Variable cnt immer schön hochzählen bis letztes Muster 
19
// ausgegeben wurde, dann zurücksetzen
20
- if cnt == 3 then cnt = 0
21
- else cnt = cnt + 1
22
23
24
Main-----------------------------------------------------
25
Do
26
  Debounce taster1 -> Machwas
27
  Debounce taster2 -> muster ++
28
  if muster > 2 then muster = 1
29
loop
Wobei ich nicht sicher bin, ob verschachtelte If-Abfragen gehen. 
Ansonsten kannst du ja auch die Musterwerte als Variablen definieren und 
diese dann für die ISR im Main anpassen.

Hoffe du hast kommst jetzt etwas besser nach, was die Anderen meinen...
Viel Glück
MFG
Patrick

von Chris (Gast)


Lesenswert?

den befehl char gibt es leider nicht :(
wird zumindest nicht farblich hinterlegt

von Patrick B. (p51d)


Lesenswert?

Dann nim halt einen Integer.

Achja, zum Fehler:
1
Do
2
If Zaehler = 4 Then
3
Zaehler = 1
4
Else
5
Incr Zaehler
6
End If
7
8
Select Case Zaehler
9
Case 1 : Gosub Effekt1
10
'Case 2 : Gosub Effekt2
11
'Case 3 : Gosub Effekt3
12
'Case 4 : Gosub Effekt4
13
'Case 5 : Gosub Effekt5
14
'Case 6 : Gosub Effekt6
15
Loop
16
End Select
17
18
19
End

Von mir aus gesehen sind "Loop" und "End Select" vertauscht. Du must 
erst den Select schliessen, da ja dieser im DO-Loop enthalten sein soll.

In die ISR kannst du ja noch anstelle der Verschachtelten If-Abfrage von 
mir eine Select Anweisung nehmen, um die Muster-Schritte 
Zählerwertspezifisch auszugeben. Das Muster kannst du ja dann über 
If-Abfragen auswählen.

Achja, kleiner Tipp: Kann man bei Bascom nicht mit Tabs arbeiten? Denn 
dann siehst du wo welche Schleifen und der gleichen noch offen sind.

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

Das wird doch jetzt alles durcheinander oder ?

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Versprich mir, dass du es wenigstens studierst

von Patrick B. (p51d)


Lesenswert?

Chris schrieb:
> Das wird doch jetzt alles durcheinander oder ?

Was wird durcheinander?

Chris schrieb:
> den befehl char gibt es leider nicht :(

Aber byte gibt es. Ist ebenfalls 8 Bit gross.

Zum Programm:
Lies nochmals nach, was der Unterschied zwischen einer ISR und einer 
Funktion ist. Du möchtest die ISR vom Programm aus aufrufen, wie eine 
normale Funktion. Die ISR wird aber vom AVR selber angesprungen:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Interruptgesteuerter_Programmablauf
Die ISR wird NIE von deinem Programm aufgerufen. Sie wird nur vom AVR 
aufgerufen, wenn der entsprechende Event eintritt (INT0, Timer 
overflow...).

Auserdem hast du unterschiedliche Namen für die ISR definiert (Config 
und unten "Tim0_isr", "Timer_isr").

Bei On_taster2 fehlt ein Return.

Achja, bist du dir beim Timer sicher? So wie ich es sehe, wird die ISR 
mit ~31kHz angesprochen, was eine Durchlauffrequenz des gewählten 
Musters mit ~8kHz bewirkt. Der Prescaler soweit runter, dass die 
Frequenz <5Hz wird, ansonsten wirst du nicht viel von den Muster 
mitbekommen. Fall der Prescaler nicht reicht kannst du dir ja eine 
Software-Verzögerung basteln.

Ich empfehle dir DRINGEND gewisse Grundlagen zu erarbeiten.
http://halvar.at/elektronik/kleiner_bascom_avr_kurs/
Ausserdem ist das Tutorial hier auch sehr hilfreich. Oder RN-Netzwerk 
hat ebenfalls gute Infos...

Edit: SRY, war schon jemand schneller.

von Chris (Gast)


Lesenswert?

So....danke allen schonmal für die viele hilfe....
ich weiß...mit mir ist es nicht einfach...

Ich hab jetzt eben mal die datei von Karl Heinz Buchegger studiert...

ich versuche es zu verstehen...
sag mir ob ich falsch liege...

das mit den tastern stimmt jetzt nicht so, wie ich es wollte oder ?
Das 1 Taster zum ein/ausschalten der nebelscheinwerfer ist
und 1 anderer taster zum durchschalten der lauflicht animation.

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:

>
> das mit den tastern stimmt jetzt nicht so, wie ich es wollte oder ?

Richtig.

Die Taster schalten 4 'Lauflichtmodi durch'. Ganz will ich deine Arbeit 
dann doch nicht machen. Aber wir sitzen sonst übermorgen immer noch da, 
bis du dich endlich über Timer drübertraust.

  Modus 1: nach links
  Modus 2: nach rechts
  Modus 3: Wechselblinken
  Modus 4: Dauerlicht bzw. alles aus

Der eine Taster erhöht die Modusnummer, der andere verringert sie.
Schau dir an, wie die ISR realisiert ist. Bei jedem Aufruf entscheidet 
sie anhand der Modusnummer und anhand einer Sequenznummer, welche LED 
bei diesem Aufruf einzuschalten sind. Das wars dann auch. Bis die ISR 
nach einer gewissen Zeit erneut vom Timer aufgerufen wird und erneut 
entscheidet was es jetzt, zu diesem Zeitpunkt, zu tun gibt.

Die Hauptschleife wertet nur noch die Tasten aus und legt ihre 
Ergebnisse in Variablen ab, die dann in der ISR herangzogen werden um zu 
entscheiden was zu tun ist.

Ach und noch was. Das Programm läuft auf einem Mega16. Das regfile musst 
du also anpassen, wenn du es ausprobierst. Ich habs absichtlich 
möglichst banal aufgebaut. Zum einen weil ich mit BASCOM auch nicht so 
firm bin zum anderen damit du die Logik dahinter verstehen kannst.

von Chris (Gast)


Lesenswert?

Die logik hab ich auf jedenfall zum großteil schon verstanden...

den fertigen code konnte ich jetzt leichter kapieren, als immer nur die 
kurzen programm fetzen :)

Ok, dann hab ich das richtig verstanden mit den 2 tastern...
das bekomme ich dann hin die richtig zu schreiben :)

Und wie läuft das mit der animation ?
Wenn ich das richtig verstehe was du meintest,
dann wiederholt der solange die animation bis ich den taster drücke..
Stimmt doch so oder ?

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:

> Und wie läuft das mit der animation ?
> Wenn ich das richtig verstehe was du meintest,
> dann wiederholt der solange die animation bis ich den taster drücke..
> Stimmt doch so oder ?

Ja.
Aber "er" macht das, in dem der Timer regelmässig reinplatzt und 'jetzt' 
schreit. Die ISR sieht sich dann die Variablen an und stellt fest welche 
LED zu schalten sind.

Und weil der Timer ständig reinplatzt und 'jetzt' schreit, laufen die 
Animationen bis zum Stromabnschalten. Oder eben bis mittels der Taster 
ein anderer Modus gewählt wird.

von Chris (Gast)


Lesenswert?

Ok :)
jetzt hab ich es verstanden...

ich glaub da hättet ihr wirklich noch tagelang versuchen können, mir das 
beizubringen :D

jetzt muss ich dann nur noch die zahlen anpassen, da es ja mehr als 3 
modi werden
und den code für den einen taster umschreiben


viiiiiiiiiiiiiiiiiiiiielen dank :)

von Chris (Gast)


Lesenswert?

Hy....
So...hab´s jetzt auf den µC geschrieben
nun hab ich aber folgendes problem:

die geschwindigkeit passt nicht, aber Bascom lässt mich den Prescale nur 
mit 1,8,64,256 und 1024 laufen...ich bräuchte aber ne geschwindigkeit 
von ca 120
wie bekomm ich das hin ?


das er nach dem letzten modi wieder von vorne beginnt hab ich schon 
hinbekommen

von Chris (Gast)


Lesenswert?

bzw, wie passe ich die geschwindigkeit vom timer an ?

von Karl H. (kbuchegg)


Lesenswert?

Schau dir den Anfang der ISR an.
Was denkst du, könnte dieses Variablen Hochzählen dort bewirken.
1
  Teiler = Teiler + 1
2
  If Teiler > 5 Then
3
    Teiler = 0
4
5
    .....



Wenn du in deinem Zimmer sitzt und alle 2 Sekunden platzt dein Kollege 
rein um dich daran zu erinnern, dass du die Lampen schalten musst dann 
hast schalten deine Lampen alle 2 Sekunden. Logisch.
Platzt er aber rein und du zählst mit und schaltest nur bei jedem 2-ten 
mal die Lampen um, dann schalten deine Lampen alle 4 Sekunden.

Mit anderen Worten: Obwohl die Erinnerung alle 2 Sekunden kommt, hat 
dein händisch realisiertes Lauflicht eine Taktrate von 4 Sekunden.

Zählst du jeweils 3 Erinnerungen, ehe du reagierst dann hat dein 
Lauflicht eine Zeitkonstante von 6 Sekunden, usw. usw.

D.h. du musst nicht unbedingt deinen Freund bitten, nicht alle 2 
Sekunden reinzuplatzen. Du kannst auch ganz einfach eine bestimmte 
Anzahl an Erinnerungen auslassen um zu verzögern.

Und jetzt schau mal was dieses
1
  If Teiler > 5 Then
alles umfasst. Sprich, wo das zugehörige END IF ist. Ich hab den Code 
extra eingerückt, damit man es leicht findet.

von Chris (Gast)


Lesenswert?

habs hinbekommen :)
jetzt flitzt der KITT Scanner genau in der richtigen geschwindigkeit :)

von Chris (Gast)


Lesenswert?

danke nochmal

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

So...ich habe jetzt meine Lauflichter fertig programmiert.

Jetzt möchte aber komischerweiße mein anderer taster zum 
ein-/ausschalten der nebelscheinwerfer (neblis)

Was hab ich falsch gemacht ?

von Chris (Gast)


Lesenswert?

Chris schrieb:
> So...ich habe jetzt meine Lauflichter fertig programmiert.
>
> Jetzt möchte aber komischerweiße mein anderer taster zum
> ein-/ausschalten der nebelscheinwerfer (neblis)

nachtrag:

möchte nicht mehr...

von Chris (Gast)


Lesenswert?

egal mit welchem code ich es versuche...die led´s sind von anfang an 
eingeschaltet...und wenn ich den taster drücke flackern sie nur kurz :(

von Patrick B. (p51d)


Lesenswert?

Versuchs mit einer Variable, die du toggelst und dann an die LED 
weitergibst. Ich weiss nicht, ob du ein Ausgang in Bascom so einlesen 
kannst.
Achja, pass die Namen der Funktionen noch an...
1
DIM Nebellicht_on AS INTEGER
2
Nebellicht_on = 0
3
4
Neblis = 0
5
6
DO
7
  Debounce...
8
  Debounce...
9
Loop
10
11
Nebellicht:
12
  If Nebellicht_on = 1 Then
13
      Nebellicht_on = 0
14
  Else
15
      Nebellicht_on = 1
16
  End If
17
  Neblis = Nebellicht_on
18
  Return

Oder es könnte auch ein Hardwarefehler sein...

von Chris (Gast)


Lesenswert?

hardwarefehler schließe ich eigentlich aus...aber kann ich auch nochmal 
schauen

von Chris (Gast)


Lesenswert?

ne...der code geht leider nicht

von Karl H. (kbuchegg)


Lesenswert?

Logisch.

In der Musterausgabe beschreibst du mit

        Portb = &B11111100

ständig den ganzen Port. Daher kannst du Neblis zuweisen soviel du 
willst, das wird beim nächsten Interrupt jedesmal wieder mit 0 
überschrieben.

von Chris (Gast)


Lesenswert?

genau das dachte ich mir ebe auch ^^

wie kann ich das machen dann ?

von Karl H. (kbuchegg)


Lesenswert?

Ist zwar jetzt keine schöne Lösung, aber merk dir in einer Variablen ob
das Nebellicht ein oder aus sein soll. Und in der Interrupt Routine ganz
am Ende setzt du dann den Portpin noch einmal einzeln. Die Musterausgabe
löscht dann zwr den Potpin auf jeden Fall, aber bei Bedarf wird er dann
ein paar µs später wieder eingeschaltet.


Die Variable wird natürlich vom Taster umgestellt. Sollte klar sein.

Tip: Wenn du eine variable zwischen 0 und 1 hin und herschalten willst, 
geht auch

   Variable = 1 - Variable

dann brauchst du kein so aufwändiges if then else

von Chris (Gast)


Lesenswert?

aber das komische ist...
wenn die ja auf 0 gesetzt werden jedesmal...warum sind die dann die 
ganze zeit an ? normal müssten die doch dann die ganze zeit aus sein

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> aber das komische ist...
> wenn die ja auf 0 gesetzt werden jedesmal...warum sind die dann die
> ganze zeit an ? normal müssten die doch dann die ganze zeit aus sein

Das kommt drauf an, wie sie angeschlossen sind. Man kann beides machen: 
Ein Licht, welches bei 0 leuchtet bzw ein Licht welches bei 1 leuchtet. 
Beides ist möglich. Portpin auf 0 bedeutet nicht automatisch per 
Naturgesetz, dass eine Lampe aus sein muss. Es hängt von der 
Aussenbeschaltung ab.

von Chris (Gast)


Lesenswert?

hab auch gerade festgestellt das ich die verkehrt herum am µC 
angeschlossen habe...^^


wie meinste das ?

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> hab auch gerade festgestellt das ich die verkehrt herum am µC
> angeschlossen habe...^^
>
>
> wie meinste das ?


Variable einführen

Die Variable wird in der tasterroutine zwischen 0 und 1 hin und her 
geschaltet.

Und am Ende der ISR:

  Wenn Variable auf 1 dann
    Nebelscheinwerfer einschalten

von Chris (Gast)


Lesenswert?

ich möchte das sie am anfang ausgeschaltet sind...
und beim ersten knopf druck eingschaltet werden
und beim zweiten knopf druck ausgeschaltet werden wieder

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> ich möchte das sie am anfang ausgeschaltet sind...
> und beim ersten knopf druck eingschaltet werden
> und beim zweiten knopf druck ausgeschaltet werden wieder


Ja.
Hab ich schon verstanden.
Also programmiers.

Dein grundsätzlicher Ansatz war ja nicht schlecht, nur musst du das 
eigentliche ein/ausschalten des Lichtes wegen der Portüberschneidung in 
der ISR machen. Das ist alles.

Man könnte das auch anders, sauber, lösen, aber dann wird der Aufwand 
noch höher.

von Chris (Gast)


Lesenswert?

Dim neblis_eingeschaltet As Byte


If neblis_eingschaltet = 1 then PORTB.1 = 1
Elseif neblis_eingeschaltet = 0 then PORTB.1 = 0
End if

Return





Meinste so ?

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> Dim neblis_eingeschaltet As Byte
>
>
> If neblis_eingschaltet = 1 then PORTB.1 = 1
> Elseif neblis_eingeschaltet = 0 then PORTB.1 = 0
> End if
>
> Return
>
>
>
>
>
> Meinste so ?

Funktionierts?

(Ich kann dir doch nicht ewig alles bis auf Codeebene vorbeten. SChön 
langsam musst du auch mit textuellen Beschreibungen des zu machenden 
klarkommen.)

von Chris (Gast)


Lesenswert?

ne, funktioniert nicht :(

von Chris (Gast)


Lesenswert?

ich probier hier seit 4std mit allen möglichen codes rum und keiner geht 
:(

von Karl H. (kbuchegg)


Lesenswert?

1
...
2
3
DIM Nebel as Byte          ' <------- A
4
5
6
....
7
8
9
10
' ***************************************************
11
Decmodus:
12
  Nebel = 1 - Nebel       ' <-------  B
13
  Return
14
15
16
.....
17
18
19
Tim0_isr:
20
  ...
21
22
    Elseif Modus = 6 Then
23
      Modus = 0
24
25
    End If
26
  
27
    if Nebel = 1 then    ' <--------  C
28
      Portb.0 = 1
29
    end if
30
31
  End If
32
  Return

A)   Variable einführen
B)   Bei Tastendruck die Variable zwischen 0 und 1 hin und herschalten
C)   In der ISR, nach der Ausgabe der Bitmuster abfragen
     ob das Nabellicht leuchten soll und wenn ja, dann machen
     (oder umgekehrt, je nachdem wie es angeschlossen ist. Fakt ist
     aber, dass der Portpin vorher auf jeden Fall auf 0 gesetzt
     wurde und jetzt gegebenenfalls auf 1 korrigiert werden muss)


Habs doch, denke ich, ausführlich beschrieben

von Chris (Gast)


Lesenswert?

so in der art hatte ich es auch schon


auf jeden fall "funktioniert" es jetzt
nur das wenn ich den taster drücke und die led´s ausschalte gehen sie 
zwar aus aber flackern ganz schwach durchgehend

von Chris (Gast)


Lesenswert?

bzw...was heißt schwach...das sind ultrahelle weiße led´s...blitzt also 
schon recht hell

von Karl H. (kbuchegg)


Lesenswert?

Tja.
Dann musst du das 2 malige Zuweisen an PORTB loswerden.

In der ISR:

  anstelle der direkten Ausgabe der Musterbytes an PORTB
  das MUsterbyte erst mal in einer neuen Variable halten

  Je nach Zustand vom Nebel noch zusätzlich das Bit 0 setzen
  ( Get mit SET)

  und erst dann das Komplett-Ergebnis auf PORTB ausgeben

von Chris (Gast)


Lesenswert?

Oo
damit hab ich noch nie gearbeitet

von Karl H. (kbuchegg)


Lesenswert?

Chris schrieb:
> Oo
> damit hab ich noch nie gearbeitet

Dann wirds Zeit.

F1 und in der Hilfe nachlesen.

von Chris (Gast)


Lesenswert?

Kann ich eigentlich nicht einfach PortD.4
als Output deklarieren und die daran hängen ?

von Chris (Gast)


Lesenswert?

oder einen der anderen PortD...6 z.b.

von Chris (Gast)


Lesenswert?

na wer sagts denn...:D
ich mach mir hier so ne scheiß mühe...
dabei hätt ich es einfach an nen anderen port hängen können :D

jetzt funktioniert es einwandfrei

von Patrick B. (p51d)


Lesenswert?

Ich kann mir nicht recht helfen, aber irgendwie habe ich das Gefühl, 
dass du KEINEN der Ratschläge die wir dir gegeben haben, befolgt hast.

Dein Programm wurde jetzt ausschliesslich durch intensive Betreuung 
realisiert.
Arbeite dich für das nächste Mal zuerst in die Grundlagen ein...

- Maskieren
- Schieben
- Bits setzen
- Bits löschen
- Entprellen
- Funktionen <-> ISR
- Timer, PWM, ADC...
- RS232, SPI, I2C...
...

Kauf dir ein kleines Demo-Board wo alles forhanden ist (ein paar Taster, 
LEDs...) und fang ganz von Vorne an. Wenn du auf C umsteigst, kannst du 
ja dem Tutorial hier folgen und dich in die Materie MCU einarbeiten...

Ich denke, dass beim nächsten Mal die Leute nicht so viel Geduld und 
solches Verständniss haben werden...
(Das Wissen für so ein Programm hatten wir in der Lehre beim 
Berufskundeunterricht innerhalb von einem halben Tag erarbeitet).

Viel Erfolg beim Experimentieren
MFG
Patrick

von Karl H. (kbuchegg)


Lesenswert?

Patrick B. schrieb:
> Ich kann mir nicht recht helfen, aber irgendwie habe ich das Gefühl,
> dass du KEINEN der Ratschläge die wir dir gegeben haben, befolgt hast.
>
> Dein Programm wurde jetzt ausschliesslich durch intensive Betreuung
> realisiert.
> Arbeite dich für das nächste Mal zuerst in die Grundlagen ein...
>
> - Maskieren
> - Schieben
> - Bits setzen
> - Bits löschen
> - Entprellen
> - Funktionen <-> ISR
> - Timer, PWM, ADC...
> - RS232, SPI, I2C...

Ich hab so das Gefühl, es hapert auch beim Konzept einer Variablen. Ich 
denke sogar, das ist momentan eines seiner Hauptprobleme. Die 
Vorstellung, das es sowas wie Schächtelchen geben kann, die einen Namen 
haben und in denen man Werte parken und wieder abholen kann.

von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

Irgendwie frag ich mich, warum Chris das macht?  Warum tut er sich das 
an?
Ein Lauflicht programmieren und eine LED ein-/ausschalten, da kann er 
irgendein China-Gimmick auch nehmen, ausschlachten und einbauen.

Denn wenn es sein Hobby wäre, dann soll es ja Spaß machen und man ist 
wissbegierig und möchte das alles selbst verstehen und erkennen.. und 
wenn man nicht das Potential dafür hat, dann wird es wohl auch kaum sein 
Hobby werden.

Also Chris - warum dieses Projekt?

von Chris (Gast)


Lesenswert?

ganz einfach...
weil ich so ein blödes china ding nicht nach meinen eigenen 
vorstellungen machen kann...
und auch in kein 1:15 modell eingebaut bekomme.

Ich tue mir halt einfach schwer mit der programmierung...
bauen ist ja kein problem...nur in sachen code hapert es

vb.net programmieren kann ich ja auch etwas, aber das ist ja ein klein 
wenig anders

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.