Forum: Mikrocontroller und Digitale Elektronik LED´s sollen aufeinander zu laufen und "abprallen"


von Tim (Gast)


Lesenswert?

hey, ich bin grad beim schreiben meines ersten eigenen programms und 
will erreichen, dass ein 4 bit lauflicht von led 7 nach led 4 läuft und 
dort "abprallt" udn wieder zurück zu 7 ... und imme rso weiter.

das gelcihe mit led 0 - 3.

also dass die 4 leds aufeinander zulaufen und aneinander "abprallen"..

hab leider erst geringe erfahrung im mc bereich und brauche dringend 
hilfe.


hier der code, der übrigends überhaupt nicht funktioniert !


.def rechts = R17       ;festlegen von register 16 als rechtslauf
.def links = R18      ;festlegen von register 17 als linkslauf
.def temp = R16        ;festlegen von register 15 als zwischenablage


  ldi temp, 0xFF      ;
  out DDRB, temp      ;ddrb als output festlegen

rechtslauf:

  ldi rechts, 0b0000111  ;bit für LED 8 (7) setzen

  dec rechts        ;erniedrige um 1

  eor rechts, 0b0000100  ;wenn rechts nidriger als "4" springe zu 
linkslauf

  breq linkslauf

  out PORTB, rechts    ;ausgabe des aktuellen wertes


linkslauf:

  ldi links, 0b00000000  ;bit für LED 1(0) setzen.

  inc rechts        ;erhöhe um 1

  eor links, 0b00000011  ;wenn links höher als "3" springe zu rechtslauf

  eor rechts, 0b0000100  ;wenn rechts nidriger als "1" springe zu 
linkslauf

  breq rechtslauf

  out PORTB, links    ;ausgabe des aktuellen wertes



Tim

von Tim (Gast)


Lesenswert?

achja, stk500 atmel mega 8 515l

von Tim (Gast)


Lesenswert?

hab die registe rnochmal geändert deswegen stimmt die erleuterung nicht!

von Stefan T. (_distance_07)


Lesenswert?

Hallo Tim, ich bin zwaz auch erst seit gestern dabei, aber das dein Code 
nicht funktionieren kann, erkenne ich schon jetzt.

Die eor Verknüpfung ist so ..- glaube ich- ... auch nciht richtig.

Zumal du nicht festgelegt hast wann der wider zurücklaufen soll, sprich 
nahc dem Abprallen.

Wäre es nicht irgendwie einfacher, nen Wert festzulegen, der die ledßs 4 
mal nach recht und 4 mal nach links laufne lässt ? Und dass dan für 
beide Seiten ?


Aber ich kann dir da wirklich auch nicht helfen, da ich absoluter 
Neuling bin.


MFG

Stefan

von Magnus Müller (Gast)


Lesenswert?

Tim wrote:
> achja, stk500 atmel mega 8 515l
                             ^^^^
                             Häää?

von Stefan T. (_distance_07)


Lesenswert?

Das letzte soll nen "L" sein glaube ich... habe ich auch auf meinem 
Controller stehen

MFG

Stefan

von Thomas (kosmos)


Lesenswert?

ldi temp, 0b10000001
out portx, temp

ldi temp, 0b01000010
out portx, temp

...
...

dazwischen halt entsprechende Pausen sonst siehst du von den geflimmere 
nichts

du kannst auch ein Bit nach links oder rechts schieben

ldi temp, 0b00000001
rol temp             ;dann wird daraus 0b00000010
out portx,temp
rol temp             ;dann wird daraus 0b00000100

eleganter wäre es aber du legst es in eine Tabelle und arbeitest mit dem 
Befehl lpm

zum umrechnen von binär nach dezimal kannst du einfach den Windows 
Taschenrechner in der Wissenschaftlichen Ansichst benutzen.

http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf 
Befehlsübersicht
http://www.atmel.com/dyn/resources/prod_documents/doc1233.pdf LPM 
Beispiel
http://www.atmel.com/dyn/resources/prod_documents/doc1925.pdf ziemlich 
zum Schluss ist das Beispielprogramm von Atmel das du dir dazu auch mal 
anschauen kannst

von Florian (Gast)


Lesenswert?

Hallo Tim.

Probier mal das hier. Das müßte funktionieren
1
.include"m8def.inc"
2
3
.def  temp1  =  r16
4
5
.org 0x00
6
rjmp reset
7
8
9
reset:
10
;stack init
11
ldi  temp1,low(ramend)
12
out spl,temp1
13
14
ldi temp1,high(ramend)
15
out  sph,temp1
16
17
;portb als Ausgang
18
ldi  temp1,0b11111111
19
out  ddrb,temp1
20
21
;Hauptschleife
22
23
main:
24
ldi zl,low(tabelle*2);Zeiger auf tabelle laden
25
ldi zh,high(tabelle*2)
26
27
loop:
28
lpm temp1,z+;Wert aus tabelle holen
29
tst temp1;testen ob Wert 0 ist
30
breq main;wenn ja, neu anfangen
31
out portb, temp1;auf portb ausgeben
32
rcall pause;1 sek pause
33
rjmp loop;nächstes Muster ausgeben
34
35
36
;1 Sekunde Pause bei 8 Mhz
37
pause:
38
; ============================= 
39
;   Warteschleifen-Generator 
40
;     8000000 Zyklen:
41
; ----------------------------- 
42
; warte 7999992 Zyklen:
43
          ldi  R17, $48
44
WGLOOP0:  ldi  R18, $BC
45
WGLOOP1:  ldi  R19, $C4
46
WGLOOP2:  dec  R19
47
          brne WGLOOP2
48
          dec  R18
49
          brne WGLOOP1
50
          dec  R17
51
          brne WGLOOP0
52
; ----------------------------- 
53
; warte 6 Zyklen:
54
          ldi  R17, $02
55
WGLOOP3:  dec  R17
56
          brne WGLOOP3
57
; ----------------------------- 
58
; warte 2 Zyklen:
59
          nop
60
          nop
61
; ============================= 
62
63
ret
64
65
66
67
tabelle:
68
.db 0b10000001,0b01000010,0b00100100,0b00011000,0b00100100,0b01000010,0,0



gruß Florian

von Herr M. (herrmueller)


Lesenswert?

Halli Hallo,

Tabellen oder Spaghetticode find ich zu langweilig zum lernen ;-)

Ich habe nach einigem Überlegen eine Schleifen-Lösung gefunden, da hat 
der Tim was zu knobeln:
1
  .def  Temp=  R16
2
  .def  Leds=  R17
3
  .def  Hilfs=  R18
4
  .def  Zaehl=  R19
5
6
RESET:                           
7
      ldi temp,low(Ramend)
8
      out SPL,temp
9
      ldi temp,high(Ramend)
10
      out SPH,temp
11
12
  ldi temp,$FF
13
  out DDRB,temp
14
15
Start:
16
  ldi Leds,$18
17
  ldi Hilfs,$18
18
19
  ldi Zaehl,6
20
Loop:
21
  out PORTB,Leds
22
                          ;rcall Delay  
23
  cpi Zaehl,4
24
  brge OutLoop
25
  add Leds,Hilfs
26
  lsl Hilfs
27
  lsr Leds
28
  rjmp Inloop
29
OutLoop:
30
  lsr Hilfs
31
  lsl Leds
32
  sub Leds, Hilfs
33
InLoop:
34
  dec Zaehl
35
  brne Loop
36
37
Endlos: rjmp Start

Das Programm kann man mit dem AVR Studio testen. Zum im Prozessor 
auführen -muss noch die Delay Routine eingefügt werden und für den 
STK500 die Leds invertiert werden, anstatt Out PortB,Leds :  mov 
temp,Leds -  com Temp -  Out PortB,temp



Zum Selbertüfteln hab ich keine Kommentare eingefügt. Viel Spass.

von Arno H. (arno_h)


Lesenswert?

Hallo,
da die LED symmetrisch leuchten sollen, können jeweils 2 parallel 
betrieben werden und die Ansteuerung beschränkt sich auf das Hoch- und 
Runterzählen von 4 Ausgängen.

Arno

von whatever (Gast)


Lesenswert?

Es gibt bei dem ganzen ein menschliches Problem. Das Gehirn kann 2 
Zustände in das Gesehene interpretieren: 2 LEDs die aneinander 
vorbeilaufen und 2 die aneinander abprallen. Welchen von beiden Du 
wahrnimmst ist sowohl zufällig als auch von äußeren Umständen 
beeinflussbar. Würdest Du zB einen kurzen Knackton ausgeben wenn die 
LEDs in der Mitte sind, würdest Du die Wahrnehmung vom abprallen 
erhöhen. Generell kannst Du mit diesem zweideutigen Muster aber keine 
eindeutige Wahrnehmung erzeugen!

von Chris (Gast)


Lesenswert?

über mir: da is was dran :P

von Tim (Gast)


Lesenswert?

vielen vielen dnak an alle die ihren senf dazugegeben haben.

.. das mit dem abprallen soll keine visuell reell wahrnehmbare sache 
sien, sondern möchte ich einfach mal versuchen etwas herum zu 
programmieren.

tim

von Gast (Gast)


Lesenswert?

grübel machste kleine Gummi-Ringe um die LEDs, dann wird das mit dem 
Abprallen schon klappen. Aber wie kriegst Du sie dazu, auf ihren zwei 
ungleich langen Beinchen aufeinander zuzulaufen..? Schwierig, 
schwierig.. ;-)

Trotzdem schönes WE

von ju (Gast)


Lesenswert?

an gast
mach dir ein gummiring an die birne, dann klappt es bei dir auch.
sonst bin ich immer höflich

von Christian L. (lorio)


Lesenswert?

Es kommt drauf an...find ich:

1. o------o
2. -o----o-
3. --o--o--
4. ---oo---
5. --o--o--
6. -o----o-

Ich fine dies erzeugt eher den "Abprall-"Effekt, und:

1. o------o
2. -o----o-
3. --o--o--
4. ---oo---
5. ---oo---
6. --o--o--
7. -o----o-

erscheint mir eher als "Durchlauf-"Effekt.

Gruß
Christian

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Das koennte optisch wirklich krass sein... das muss ich doch glatt mal 
ausprobieren ;)

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Schaut Euch das mal an: ich sehe einen Abpralleffekt. Sieht jemand von 
Euch den Lauf-Effekt?

http://coremelt.net/passthrough.php?path=files%2Fpics%2Fvideos%2Favr%2Fbouncing_leds.avi

von Oops (Gast)


Lesenswert?

Ich finde die Geschwindigkeit zu gleichmäßig um den Abpralleffekt 
erkennbar zu machen.
Das Abprallen in der Realität beruht ja auf Elastizität und 
Beschleunigung.
Die Geschwindigkeit sollte also irgendwie nach dem Abprallen anwachsen.

Gruss
Oops

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Ja... das ist wohl wahr... ;) Koennte man sogar berechnen, Stichwort 
elastischer Stoss. Aber das is mir dann doch nen bissel zu bloede 
jetzt... war ja nicht meine Idee (=

von whatever (Gast)


Lesenswert?

Bei dem Video stimmt es, die längere Pause in der Mitte erzeugt 
abprallende LEDs. Sehr interessant! Danke!

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Komischerweise sollte da keine Pause sein... ich hab naemlich extra 
diese Stelle nich zwei mal gemacht ;D

Hier der Code:
1
    while (1)
2
    {
3
       for (i=0; i<5; i++)
4
       {
5
         PORTB = ~((1 << i) | (1 << (7-i)));
6
         for (a=0; a<4; a++)
7
           _delay_ms(50);
8
       }
9
10
       for (i=2; i>=0; i--)
11
       {
12
         PORTB = ~((1 << i) | (1 << (7-i)));
13
14
         for (a=0; a<4; a++)
15
           _delay_ms(50);
16
       }
17
    }

Verbessern kann man das jetzt noch indem man die laufgeschwindigkeiten 
dynamisch so anpasst, dass der Apralleffekt realistischer wirkt. 
Allerdings ist das bei einem Stoss in der Tat verhaeltnismaeszig 
gleichmaeszig, also ohne dass die abprallenden Koerper da nochmal 
quadratisch beschleunigen wuerden oder so nen Krampf ;) Durch 
Reibungsverluste werden die halt langsamer wenn sie sich voneinander 
entfernen... das sollte man irgendwie beruecksichtigen. Aber schneller 
werden sie nach dem abprallen keinesfalls.

Michael

von Magnus Müller (Gast)


Lesenswert?

Michael G. wrote:
> Komischerweise sollte da keine Pause sein... ich hab naemlich extra
> diese Stelle nich zwei mal gemacht ;D

Ändere mal die Werte der ersten for-Schleife wie folgt:


aus

>        for (i=0; i<5; i++)

machst du
1
for (i=0; i<4; i++)

Gruß,
Magnetus

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.