Forum: Mikrocontroller und Digitale Elektronik Einfacher Zufallsgenerator


von Sven Löffler (Gast)


Lesenswert?

Hallo zusammen,

ich bräuchte mal wieder "Starthilfe" ;-)

Ich möchte gerne einen "einfachen Zufallsgenerator" programmieren. Ziel 
ist es, über einen Taster eine von 30 LEDs aufleuchten zu lassen. Welche 
LED aufleuchtet, sollte "zufällig" sein.

Ich habe evtl. daran gedacht, einfach die Zeit zu messen, wann der 
Taster gedrückt wird. Also eine Schleife bis 30 zählen zu lassen. Ist 
die Schleife bei 1 und der Taster wird betätigt, leuchtet LED1, ist die 
Schleife bei 2 und der Taster wird betätigt, leuchtet LED2 usw. Zum 
Schluss geht das wieder von vorne los.

Nun ist die Frage: Ist das so überhaupt möglich ?

Besten Dank im Voraus !

Viele Grüße
Sven

von Gast (Gast)


Lesenswert?

Warum sollte das nicht möglich sein?
Inkrementiere den Zähler in der Schleife und fertig :-)

von Schrotty (Gast)


Lesenswert?

im Prinzip der "elektronische Würfel".
Den kennt fast jeder, der mal mit Elektronik gebastelt hat.
Da findest sicher jede Menge darüber im Netz

von Ingo L. (grobian)


Lesenswert?

rauschen am AD Wandler auslesen

von Winfried (Gast)


Lesenswert?

Du kannst ein Pseudozufallsgenerator verwenden:

http://madgyver.roboterbastler.de/index.php?id=32,143,0,0,1,0

Damit der immer einen anderen Initialisierungswert beim Einschalten 
bekommt, benutzt du das EEPROM, wo du den Startwert ablegst, der z.B. 
bei jedem Einschalten um 1 erhöht wird.

von Commtel @. (commtel)


Lesenswert?


von Route_66 (Gast)


Lesenswert?

@Sven Löffler
Deine Idee ist vollkommen machbar: der (Timer im) Controller zählt ja im 
Hintergrund so schnell, daß die Zeiten zwischen den Tastendrücken wohl 
immer zufällig sind. Es kann bestimmt kein Mensch mikrosekundengenau 
einen Tastendruck wiederholen.

von Sven Löffler (Gast)


Lesenswert?

Zunächst mal vielen Dank für die zahlreichen Antworten.

Ich bekomme irgendwie die Verbindung zwischen Abfrage des Tasters, des 
aktuellen Wertes sowie das ausgeben der entsprechenden LED nicht hin.

Versuchshalber möchte ich es ganz einfach mit 3 LEDs machen. Controller 
ist ein Atmega8515.

Oh man, ich muss erstmal wieder ins Programmieren rein kommen. Ich 
schreibe übrigens in assembler. Vielleich kann mir nochmal jemand 
helfen.

Viele Grüße
Sven

von Z8 (Gast)


Lesenswert?

na dann her mit der Quelle!

von Karl H. (kbuchegg)


Lesenswert?

Sven Löffler wrote:

> Oh man, ich muss erstmal wieder ins Programmieren rein kommen. Ich
> schreibe übrigens in assembler. Vielleich kann mir nochmal jemand
> helfen.

Zeig doch mal das Programm, so wie du es bis jetzt hast.

Im Grunde ist das doch einfach. Der Prinzipielle Aufbau sieht so aus

   Initialisieren (Port auf Ausgang/eingang schalten.
                   Pullup ein, wenn notwendig)

   Zähler = 0
   Zähler am Port ausgeben

loop:
   Wenn Taste nicht gedrückt
        -> goto loop

   Zähler um 1 erhöhen
   Wenn Maximum erreicht
      -> Zähler wieder auf 0

   Zähler am Port ausgeben

   goto loop

von PillePalle (Gast)


Lesenswert?

moin

Einfacher 24 Bit pseudo Generator
Der Wert steht nach aufruf in Rand1 - Rand3
Rand ist im einfachsten Fall ein Register


Init_Random:        ;first time
  ldi  TEMP,$AA  ;Init the random number generator
  mov  RAND1,TEMP  ;since a 00,00,00 state will not
  mov  RAND2,TEMP  ;progress.
  mov  RAND3,TEMP  ;you can get a timer to pre load first time
  ret
**********************************************************
 simple 24bit random generator
**********************************************************
simpler:

  rol  RAND1    ;Shift the bits ->Carry
  rol  RAND2    ;RAND are register or Ram
  rol  RAND3
  BRCC rr2
  ldi TEMP,0x87
  eor RAND1,TEMP
rr2:
  ret
*********************************************************

von Z8 (Gast)


Lesenswert?

Hi PillePalle,

mit nur einem rückgekoppelten Bit, dürfte die Zufallszahl
ziemlich "regelmäßig" sprich berechenbar.
Gerade beim ersten Durchlauf steht es auf einem ungünstigen
Init.-wert (0xAA). Bei jedem zweiten Takt wird das Low-Byte
mit 0x87 geladen. Das nenne ich nicht mehr "zufällig".

Z8

von Sven Löffler (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Karl Heinz,

ich habe versucht, dass jetzt mal in ein Programm zu fassen. Wirklich 
gelungen ist mir das wohl nicht. Auf Tastendruck leuchten immer nur alle 
LEDs. Das Programm habe ich als Dateianhang beigefügt.

von Karl H. (kbuchegg)


Lesenswert?

Sven Löffler wrote:

> gelungen ist mir das wohl nicht. Auf Tastendruck leuchten immer nur alle
> LEDs. Das Programm habe ich als Dateianhang beigefügt.

Vielleicht solltest du noch mal das Tutorial von Anfang an durchmachen. 
Scheinbar hast du schon ziemlich viel wieder vergessen :-)

ldi temp, 0b00000000            ; Port B als Ausgang
out DDRB, temp

Äh, nein.
Ein Portpin wird auf Ausgang gesetzt, indem man für den entsprechenden 
Pin eine 1 ins DDR Register schreibt.

ldi temp, 0b11111111            ; Port A als Eingang
out DDRB, temp

Vergleich mal den Kommentar mit dem was tatsächlich passiert.


Wie sind deine Taster angeschlossen?
Brauchst du einen Pullup Widerstand? Wenn ja, dann solltest du den auch 
einschalten.


Diese Sequenz

cpi zaehl, 4                    ; Z�hler mit Max ( 4 ) vergleichen
brcc Endloop                    ; wenn 4 erreicht, springe zu Endloop

EndLoop:
clr zaehl                       ; Z�hler auf null setzen.

ist nicht wirklich davon abhängig ob der Wert in zaehl irgendwas ist. 
Wenn das Carry gecleared ist, wird nach EndLoop gesprungen, wenn es 
nicht gecleared ist, wird der branch nicht genommen und statt dessen bei 
... EndLoop weiter gemacht. Im Endeffekt: Egal wie das Carry steht, es 
wird immer bei EndLoop weitergemacht (Und dort passiert daher immer: clr 
zaehl :-)
Warum eigentlich das Carry abfragen? Es gibt doch einen so schönen brne 
(Branch if not equal)


Wie sind deine LED angeschlossen? Wann leuchten die? Wenn der 
Ausgangspin auf 0 oder auf 1 ist (welches von beiden)

Das hier
  ldi zaehl, 0b11111111           ; Z�hler auf null
  out PortB, zaehl
lässt mich vermuten, dass die Led leuchten wenn eine 0 am Ausgang ist

Das hier allerdings
  clr zaehl                       ; Z�hler auf null setzen.
  out PortB, zaehl                ; Z�hlerwert auf Port B ausgeben.
lässt mich das Gegenteil vermuten.

von P. S. (Gast)


Lesenswert?

Hast du das nur schnell zusammengekritzelt, oder auch mal versucht 
nachzuvollziehen, was dein Controller da tun soll?

Loop:                           ; Schleife

sbic PINA, 0
rjmp loop

Was soll danach noch gross passieren...?

von Armin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe mir für den ATTiny13 einen Pseudozufallsgenerator für 
Modellbahnbeleuchtung etc beschrieben, der ist zwar etwas fett, aber 
dafür sind die Zahlen ziemlich gut gleichverteilt und die Periode ist 
mindestens 100000 Bytes lang. Wem's hilft, bitte sehr (Anhang). Bestimmt 
kann man manches optimieren, gerade was den Platzbedarf angeht, aber ich 
kopiere gerne Code einfach hin und her und habe keine Lust jedesmal 
nachzusehen, welche Register so genutzt werden, daher die vielen pushs 
und pops um diese zu sichern. Bin aber für Anregungen offen, denn die 
MC-Programmierung betreibe ich erst seit ein paar Wochen.
Gruß
Armin

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ein einfaches Beispiel ist im C-Projekt
   Beitrag "Re: Miniprojekt: Lagerfeuer-LED (ATtiny25)"

Als Startwert dient nicht-initialisierter RAM-Inhalt. Das Projekt ist 
für AVR, und dort ist der RAM-Inhalt nach PowerUp mehr oder weniger 
zufällig.

Weiter geht's dann mit Pseudo-Zufall, weil's so einfach ist natürlich 
hausgemacht :-)

Johann

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.