PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie denn "Zufall" programmieren



Cybrix
06.11.2006, 14:35
Moin

Ich will ein kleines Lauflicht für meine Freundin bauen!
Bloß das problem ist wie schreibe ich ein programm was eine zufällige zahl generiert im bereich ca 0-10!

ich will durch die zahl ein Unterprogramm aufrufen!

Hat jemand ne idee wie man sowas bewerkstelligen kann?

Das es ja in der digitaltechnik eigentlich keine zufälle gibt!

Gruß cybrix

magnetix48
06.11.2006, 14:45
Hallo Cybrix,

in Basic z.B. Bascom heißt der Befehl Rnd von Random, deutsch Zufall

Syntax: Variable = Rnd(10)

Mit der 10 gibst du die Obergrenze der Zufallszahl an

Gruß
Detlef

Cybrix
06.11.2006, 14:47
jo danke für die mühe aber ich programmierein C!

Aber vielleicht gibt es dafür ja auch ein befehl

SprinterSB
06.11.2006, 14:56
Hilft das?

https://www.roboternetz.de/wissen/index.php/Zufallszahlen_mit_avr-gcc

coCo
06.11.2006, 15:07
Was vielleicht auch noch eine Möglichkeit wäre, wäre die Dauer eines Tastendruckes messen und daraus einen "Zufallswert" generieren.

So haben wir das mal bei der Elektronik-AG in der Schule gemacht. (Mit einem R8C, gabs mal in der Elektor als "Weihnachtsgeschenk")

MfG

Cybrix
06.11.2006, 16:18
jo das ist genau das was ich gesucht habe danke

@coco

das muss in der software passieren da ich keine taster verwende

Cybrix
20.11.2006, 12:30
Ich habe das versucht aber irgendwo hängt das in der Funktionen das schmeist mir garnicht die Zahlen raus die ich maximal definiert habe

habe selbst in der stdlib.h die RANDOM_MAX auf 0x0007 verändert und im meinem Programm auch aber irgendwie wirft er mir immer größere zahlen raus als ich eingestellt habe vielleicht findet ja jemand von euc denn Fehler!

Hier mal ein Auszug aus dem Programm:




// ** Präprozessor ** //

#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#define RAND_MAX 0x0007


//Hauptprogramm


int main (void)
{

init();
int zufall=0; //Variable Zufall deklarieren


while (1)
{
zufall=rand();

switch (zufall)
{

case 0:

lauflr(); //Von links nach rechts durchlaufen
//zufall=zufall+1;
break;

case 1:

laufrl(); //Von rechts nach links durchlaufen
//zufall=zufall+1;
break;

case 2:

jede21lr(); //Jede erste zweite LED geht an von links nach rechts
//zufall=zufall+1;
break;
case 3:

jede21rl(); //Jede erste zweite LED geht an von rechts nach links
//zufall=zufall+1;
break;
case 4:

blink(); //LED`s blinken
//zufall=zufall+1;
break;
case 5:

blink2w(); //jede zweite LED blinkt im wechsel
//zufall=zufall+1;
break;
case 6:

jede22rl(); //Jede zweite LED geht an von rechts nach links
//zufall=zufall+1;
break;
case 7:

jede22lr(); //Jede zweite LED geht an von rechts nach links
//zufall=1;
break;
}
}
}

SprinterSB
20.11.2006, 13:04
RAND_MAX und RANDOM_MAX haben rein informativen Charakter. Ein Umdefinieren dieser Werte kann natürlich die Arbeitsweise der Bibliotheksalgorithmen nicht verändert und bleibt daher nutzlos!

SprinterSB
20.11.2006, 13:08
Wenn du nur Zahlen x von 0...max willst, dann kannst du das machen mit

x = foo () % (max+1); // foo() ist die Zufallsfunktion

max muss < RAND_MAX bz. RANDOM_MAX sein. Und zwar die Werte von *_MAX, die die Programmierer der avr-libc angegeben haben!

Beachte, daß dieses Kappen mit modulo Einfluss auf die Gleichverteilung nimmt!

Cybrix
20.11.2006, 13:34
Die gleichverteilung sollte schon ungefähr gleich bleiben!

Ich habs mal getestet! bei 20 durchläufen

Hat er folgende aufteilung:

Funktion 1 = 10%
Funktion 2 = 05%
Funktion 3 = 20%
Funktion 4 = 15%
Funktion 5 = 05%
Funktion 6 = 20%
Funktion 7 = 15%
Funktion 8 = 10%

gibt es da noch ne möglichkeit die Verteilung ungefähr gleich hin zukriegen?

Aber danke für die Hilfe jetzt funktioniert es wenigstens!

maw_hn
20.11.2006, 13:42
Was du auch machen kannst ist zu Beginn deines Programms einen Timer starten der ständig läuft. Bei Tastendruck kannst du den Zählerstand auslesen. Wenn du nur die niederwertigen 4 Bits ausliest hast du schon mal ne Zufallszahl im Bereich von 0 - 15.

Marco

Cybrix
20.11.2006, 14:25
Es muss in der Software passieren da ich alle pin`s verwende

vajk
20.11.2006, 15:17
.. also so als Anregung ... alle Pins .. Lauflicht .. nun, wenn Du das Licht Multiplexen würdest und das mit 1000 Hz .. könntest Du ab und zu aus einem externe Rauschgenerator was messen - da gibt es hier irgendwo einen Thread, der mit LEDs eine Lichtmessung durchführt .. das wäre doch ideal ...
... alternativ könntst Du auch den Zufall selbst berechnen und den Startwert immer "irgendwoher" zusammensuchen, aus einem Speicherbereich der sich ändert ... timer/val der hochzählt etc.
Oder Du könntest einfach die Quarzeitbasis "etwas ungenauer" aufbauen, sprich einen externen Taktgeber verwenden, der mit einem "Rauschen" überlagert ist ... so mit mini uC, der diese Variation in "grenzen" hält ...

SprinterSB
20.11.2006, 16:04
Die gleichverteilung sollte schon ungefähr gleich bleiben!

[...]

gibt es da noch ne möglichkeit die Verteilung ungefähr gleich hin zukriegen?

Die Verteilung ist doch gut für so wenige Stichproben. SIgnifikante Abweichungen seh ich da keine. Teste mal mit 10000 Werten, da sieht das schon anders aus.

Timer-Werte etc sind übrigens immer deterministisch (wäre schlimm, wenn's nicht so wäre).

Wie man zufällige Startwerte für eine Seed erhalten kann ist im Artikel beschrieben.

maw_hn
20.11.2006, 17:21
Timer- Werte sind nur dann determenistisch wenn du keine Benutzeraktion hast. Ich glaube nicht dass du es hinbekommst einen Taster mehrere Male hintereinander in einem absolut exakten Intervall zu drücken... Aber da er einen weiteren Input ausschliesst hat sich das eh erledigt...

Cybrix
20.11.2006, 17:47
Man soll sich auch irgendwann zu frieden geben!

Das ist mir jetzt zufall genug!

Also danke an euch alle die ihr mir geholfen habt!

Wenn interresse besteht lade ich mal ein kleines video von der platine in aktion hoch!

Mr.Roboto
11.06.2007, 09:10
#include <stdio.h>
#include<time.h>

int zufallszahl;


void main(void)
{
srand( time(NULL) );
zufallszahl = rand() % 10 + 1;
printf("Die Zufallszahl zwischen 1 und 10 lautet: %i",zufallszahl);
}


Die funktion srand(time(NULL)) setzt die systemzeit auf NULL, ohne diesen Befehl würde immer die selbe Zahl generiert werden.

Die Funktion rand() % 10 + 1 generiert zahlen zwischen 10 und 1, in dem du diese zahlen änderst, werden zahlen in dem neuen bereich generiert