Forum: Mikrocontroller und Digitale Elektronik LED-Lauflicht wie Gummiball?


von Tim (Gast)


Lesenswert?

Hallo,

mein Name ist Tim und ich lerne gerade die Programmierung von 
Mikrocontrollern. Für einen kleinen Einstieg wollte ich wie oft zu sehen 
auf meinem kleinen Testboard LEDs leuchten lassen.
Die 8 LEDs sind alle an Portc angeschlossen und leuchten wenn ich einen 
Pin "einschalte".

Es hat ein wenig gedauert, aber ich habe es jetzt erfolgreich geschafft 
zu verstehen wie man Schleifen macht und was Variablen und Bits sind 
usw. und meine 8 LEDs laufen jetzt auch schön hin und her (ich war ganz 
erfreut! :). Nun möchte ich aber die 8 LEDs so als Lauflicht leuchten 
lassen, dass es aussieht als ob es auf einer Seite wie ein Gummiball 
hüpft. Da bin ich dann gescheitert, ich weiß einfach nicht wie ich 
vorgehen kann.

Ich habe als Entwicklungsumgebung luna-avr und mein Programm sieht jetzt 
so aus:
1
avr.device = atmega32
2
avr.clock = 20000000
3
avr.stack = 16
4
5
portc.mode = output, pulldown
6
7
dim i as byte
8
9
do
10
  for i=0 to 7
11
    portc = led.ByteValue(i)
12
    waitms 50
13
  next
14
  for i=6 downto 1
15
    portc = led.ByteValue(i)
16
    waitms 50
17
  next
18
loop
19
20
21
data led
22
  .db 0b00000001
23
  .db 0b00000010
24
  .db 0b00000100
25
  .db 0b00001000
26
  .db 0b00010000
27
  .db 0b00100000
28
  .db 0b01000000
29
  .db 0b10000000
30
enddata

Hat Jemand einen Tip für mich? :)

Ciao, Tim

von Christian F. (cmf) Benutzerseite


Lesenswert?

Tim schrieb:
> Nun möchte ich aber die 8 LEDs so als Lauflicht leuchten
> lassen, dass es aussieht als ob es auf einer Seite wie ein Gummiball
> hüpft. Da bin ich dann gescheitert, ich weiß einfach nicht wie ich
> vorgehen kann.

Wie meinst du das? Etwa so?:


(x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x)
(x) (x) (x) (x)
(x) (x) (x)
(x) (x)
(x)
(x) (x)
(x) (x) (x)
(x) (x) (x) (x)
(x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x)

von Tim (Gast)


Lesenswert?

ähm, also die LEDs sind alle in einer Reihe und es leuchtet immer nur 
eine LED die hin und her läuft. Ich wollte die LED jetzt aber nicht 
gleichmäßig hin und herlaufen lassen, sondern dass sie an einer Seite 
praktisch wie abgestoßen wird, also schneller zu einer seite geht wie 
Gravitation und dann davon wieder wegspringt und langsamer wird.

Ciao, Tim

von Maik W. (werner01)


Lesenswert?

Servus,

Na sann schau mal ins Tabellenbuch, und such dir die Formel für die 
Beschleunigung raus ,also igendwas mit x² und die Sprunghöhe für den 
"Gummiebsll" gibst Du auf den LED's aus .Also LED1 = 1m ,LED2 = 2m und 
so weiter ....



viel Glück

von Dieter M. (Gast)


Lesenswert?

Du willst also, dass Wartezeit von einem Zustand zum nächsten nicht 
konstant ist, sondern sich entsprechend der Position ändert

versuch in einem ersten Schritt mal

waitms (50 * i)


Von da aus kommst Du bestimmt auf bessere Ideen.
Viel Spaß

von Dieter M. (Gast)


Lesenswert?

Ok, wenn Du jetzt beides zusammen nimmst, hast Du die Lösung ja schon 
komplett.

:-)

von Maik W. (werner01)


Lesenswert?

Stichwort "Fallbeschleunigung" und halt "inverse Fallbeschleunigung"...
Also jetzt solltest Du aber darauf kommen.....

von Wurf (Gast)


Lesenswert?


von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der positive Teil einer Sinuskurve ist ausreichend nah an der 
Parabelform, die ein geworfener Körper (und also auch der Gummiball) 
fliegt

In Textform sähe das also so aus:
1
y ^
2
  |    ##       ##
3
  |   #  #     #  #     #
4
  |  #    #   #    #   #  etc. ...
5
  | #      # #      # # 
6
  | #      # #      # #
7
  |#        #        #
8
  |#        #        #
9
  |#        #        #
10
--------------------------> t

von Tim (Gast)


Lesenswert?

Vielen Dank! ich hab das mal umgesetzt:
1
avr.device = atmega32
2
avr.clock = 20000000
3
avr.stack = 16
4
5
portc.mode = output, pulldown
6
7
dim i as byte
8
9
do
10
  for i=0 to 7
11
    portc = led.ByteValue(i)
12
    waitms 10*(i+1)
13
  next
14
  for i=7 downto 0
15
    portc = led.ByteValue(i)
16
    waitms 10*(i+1)
17
  next
18
loop
19
20
21
data led
22
  .db 0b00000001
23
  .db 0b00000010
24
  .db 0b00000100
25
  .db 0b00001000
26
  .db 0b00010000
27
  .db 0b00100000
28
  .db 0b01000000
29
  .db 0b10000000
30
enddata

das +1 habe ich hereingenommen und auch die Schleifenzahlen angepasst, 
weil sonst die eine LED gar nicht angeht. Das sieht schon besser aus und 
kommt schon ganz nah ran, aber irgendwie wirkt das irgendwie noch 
unnatürlich.

Ciao, Tim

von Tim (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Der positive Teil einer Sinuskurve ist ausreichend nah an der
> Parabelform, die ein geworfener Körper (und also auch der Gummiball)
> fliegt
>
> In Textform sähe das also so aus:
> y ^
>   |    ##       ##
>   |   #  #     #  #     #
>   |  #    #   #    #   #  etc. ...
>   | #      # #      # #
>   | #      # #      # #
>   |#        #        #
>   |#        #        #
>   |#        #        #
> --------------------------> t

ahhh das wars!!! An die sin/cos-funktionen traue ich mich aber noch 
nicht heran, weil ich nicht verstehe wie man das umrechnen muss, das 
sind keine normalen sin/cos-funktionen wie im Taschenrechner. Auch 
dachte ich das muss ja irgendwie einfacher gehen als mit einer langen 
Formel. Aus der Schulzeit kann ich mich erinnern, dass man quadratisch 
ansteigende Werte als Ersatz nehmen kann und so hab ich das so gemacht 
durch ein bisschen herumprobieren:
1
avr.device = atmega32
2
avr.clock = 20000000
3
avr.stack = 16
4
5
portc.mode = output, pulldown
6
7
dim i as byte
8
9
do
10
  for i=0 to 7
11
    portc = led.ByteValue(i)
12
    waitms (i+3)^2
13
  next
14
  for i=6 downto 0
15
    portc = led.ByteValue(i)
16
    waitms (i+3)^2
17
  next
18
loop
19
20
21
data led
22
  .db 0b00000001
23
  .db 0b00000010
24
  .db 0b00000100
25
  .db 0b00001000
26
  .db 0b00010000
27
  .db 0b00100000
28
  .db 0b01000000
29
  .db 0b10000000
30
enddata

Sieht suuuper aus, Danke vielmals, bin ganz stolz! :)
Ciao, Tim

von Wurf (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Der positive Teil einer Sinuskurve ist ausreichend nah an der
> Parabelform, die ein geworfener Körper (und also auch der Gummiball)
> fliegt
>
> In Textform sähe das also so aus:
> y ^
>   |    ##       ##
>   |   #  #     #  #     #
>   |  #    #   #    #   #  etc. ...
>   | #      # #      # #
>   | #      # #      # #
>   |#        #        #
>   |#        #        #
>   |#        #        #
> --------------------------> t

Warum Sinus, wenn auch das Quadrat und die Wurzel reicht ?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wurf schrieb:
> Warum Sinus, wenn auch das Quadrat und die Wurzel reicht ?

Warum Quadrat und Wurzel, wenn doch 'ne simple Tabelle ausreichen würde?

von Maik W. (werner01)


Lesenswert?

sinus tabelle reicht nat. auch, ist nicht so rechenintensiv, der 
Controller braucht für sowas max. 1 MHz. Also runtertackten und Energie 
sparen...

von Jobst M. (jobstens-de)


Lesenswert?

Programmiere eine Schleife, welche (in feinen Stufen) von 0 - 2 zählt.

Dann ist die Formel: (x-1)^2

Sollte ausreichen + Viel Spaß


Gruß

Jobst

von Werner (Gast)


Lesenswert?

Maik Werner schrieb:
> Stichwort "Fallbeschleunigung" und halt "inverse Fallbeschleunigung"...

Was ist eine "inverse Fallbeschleunigung"? Die Erdebeschleunigung ist 
überall gleich und kann sich nicht wegen jedem Ball, der irgendwo 
geworfen wird, ändern.

Rufus Τ. Firefly schrieb:
> Der positive Teil einer Sinuskurve ist ausreichend nah an der
> Parabelform, die ein geworfener Körper (und also auch der Gummiball)

Was hat die Sinuskurve mit der Parabel zu tun, außer dass sie dir von 
der Form her so ähnlich vorkommt.
1
cos(x) = 1 - x²/2 + x^4/24 - ...
Für den µC ist sie noch viel komplizierter zu berechnen.

Zur Steuerung der LED-Kette reicht bei konstanter "Wurfhöhe" eine 
Tabelle mit vorher berechneten Umschaltzeitpunkten. Ein Timer kann dann 
den Takt liefern.

von Martin (Gast)


Lesenswert?

Schau dir mal die Bit-Shift Funktionen an

x = y >> z
x = y << z

y >>= z
y <<= z

von Tim (Gast)


Lesenswert?

Martin schrieb:
> Schau dir mal die Bit-Shift Funktionen an
>
> x = y >> z
> x = y << z
>
> y >>= z
> y <<= z

Ich habe das mal so eingebaut und es sieht wirklich noch natürlicher aus 
als vorher!! Aber was passiert da genau wenn ich << oder >> verwende? 
mit >> gings gar nicht. Dann ahbe ich noch + 10 dazugezählt weil es zu 
schnell war:
1
avr.device = atmega32
2
avr.clock = 20000000
3
avr.stack = 16
4
5
portc.mode = output, pulldown
6
7
dim i as byte
8
9
do
10
  for i=0 to 7
11
    portc = led.ByteValue(i)
12
    waitms (1 << i) + 10
13
  next
14
  for i=6 downto 0
15
    portc = led.ByteValue(i)
16
    waitms (1 << i) + 10
17
  next
18
loop
19
20
21
data led
22
  .db 0b00000001
23
  .db 0b00000010
24
  .db 0b00000100
25
  .db 0b00001000
26
  .db 0b00010000
27
  .db 0b00100000
28
  .db 0b01000000
29
  .db 0b10000000
30
enddata

Das sieht aber insgesamt schon sehr natürlich aus und ist sozusagen 
perfekt. Jetzt will ich nur noch verstehen wieso :)

Ciao, Tim

von Roland P. (pram)


Lesenswert?

<< verschiebt die Bits:

0b00000001 << 0 = 0b00000001 = 1
0b00000001 << 1 = 0b00000010 = 2
0b00000001 << 2 = 0b00000100 = 4
0b00000001 << 3 = 0b00001000 = 8

usw.

1 << i entspricht daher (2 hoch i)
Wichtig, in C führt der ^ Operator eine XOR-Funktion durch und nicht 
"hoch", ich weiß nicht, ob das bei dir auch so ist.

Gruß
Roland

von led (Gast)


Lesenswert?

Hab ihr das ganze auch in C ?

von Physiker (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Der positive Teil einer Sinuskurve ist ausreichend nah an der
> Parabelform, die ein geworfener Körper (und also auch der Gummiball)
> fliegt

Hat die Sinuskurve irgendetwas, was diesen Unfug rechtfertigt?

Bei 8 LEDs reicht eine Tabelle mit vorher berechneten 
Verzögerungszeiten.

von Ein Gast (Gast)


Lesenswert?

led schrieb:
> Hab ihr das ganze auch in C ?

Das wirst du doch wohl selber hinkriegen oder was verstehst du nicht?

von Harald W. (wilhelms)


Lesenswert?

Tim schrieb:
> ähm, also die LEDs sind alle in einer Reihe und es leuchtet immer nur
> eine LED die hin und her läuft.

Im INet nennt man sowas knight rider lauflicht. Das musst Du dann
nur hochkant stellen.
Gruss
Harald

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Am universellsten ist es wirklich, dir eine Tabelle zu machen, indem an 
der ersten Stelle die LED Nummer (oder das gewünschte Bitmuster) steht 
und an der zweiten ein Timerwert, der bestimmt, wie lange dieses Muster 
leuchten soll. Damit kriegst du jedes beliebige Pattern hin und kannst 
durch mehrere Tabellen auch verschiedene Programme in den MC 
programmieren.

von Schlumpf (Gast)


Lesenswert?

Hallo Tim,

erstmal ein Kompliment an dich. Es ist schön zu sehen, dass du dich 
offensichtlich mit viel Begeisterung und Enthusiasmus duch die Materie 
frisst.

Eine weitere Möglichkeit wäre, dass du alle Zustände, die deine LEDs 
einnehmen sollen in eine Tabelle ablegst (so wie du es ja jetzt schon 
gemacht hast) und diese Tabelle dann einfach ganz normal abarbeitest.
Also du veränderst nicht die Geschwindigkeit, mit der die Tabelle 
abgearbeitet wird, sondern den Inhalt der Tabelle.

Dazu musst du deine Tabelle um ein paar Einträge erweitern, dass du eine 
bessere Zeitauflösung bekommst.

Am Besten nimmst du ein kariertes Blatt Papier und zeichnest horizontal 
die Zeit ein und vertikal nimmst du 8 "Kästchen" wovon jedes eine LED 
darstellt.
Dann markierst du zu jedem Zeitpunkt, welche LED da leuchten soll. Und 
diese Tabelle überträgst du dann in dein Programm.

Das wird dann irgendwie so aussehen:

data led
  .db 0b00000001
  .db 0b00000010
  .db 0b00000100
  .db 0b00001000
  .db 0b00010000
  .db 0b00010000
  .db 0b00100000
  .db 0b00100000
  .db 0b00100000
  .db 0b01000000
  .db 0b01000000
  .db 0b01000000
  .db 0b01000000
.... usw..
enddata

den Zähler passt du dann an die Anzahl der Tabelleneinträge an.

Vorteil dieser Methode: Du brauchst keine Mathematik und du kannst jedes 
x-beliebige LED-Muster einfach darstellen.
Nachteil, du brauchst mehr Speicher, da du ja die größere Tabelle 
abspeichern musst.

Sowas nennt man dann Look-Up-Table oder LUT

von Michael H. (michael_h45)


Lesenswert?

Tim schrieb:
> ähm, also die LEDs sind alle in einer Reihe und es leuchtet immer nur
> eine LED die hin und her läuft.

Man merkt, dass man alt wird, wenn das "Gummiball" und nicht mehr 
"Knight Rider" heißt! =)

von qwertzuiop (Gast)


Lesenswert?

Er will aber kein "Knight Rider", was einer Bewegung konstanter 
Geschwindigkeit entspricht, sondern "Gummiball". Dort ist die Änderung 
der Geschwindigkeit, die Beschleunigung konstant.

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.