PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zufallszahl 1-4



Goldenflash
30.07.2005, 16:03
Hallo,
Ich habe erst vor kurzem mit AVR angefangen und gestern erst mit Bascom (bin also ein blutiger Anfänger :cheesy: )
Mein größter Vorteil ist da noch dass ich jedoch Visual Basic kann.

Jetzt zu meinem Problem:
Ich möchte eine Zufallszahl 1 bis 4 erzeugen. Dass das nicht einfach mit RND getan ist, ist mir klar. Auf meinem PC konnt ich einfach die Uhrzeit für eine Berechnung benutzen, aber da es keine Benutzereingaben gibt und auch nichts gemessen wird, bekomme ich einfach keine zufälligen Zahlen! :(

Kennt jemand einen "guten" Algorithmus oder eine andere Möglichkeit mein Problem zu lösen?

Danke schonmal

Gruß Florian

Marco78
30.07.2005, 20:34
Wird die Zahl nur einmal pro Programmstart gebraucht oder zu verschiedenen Laufzeiten im Programm?
Wenn zweiteres kannst du ja einen Timer Programmieren und da immer einen Zähler um 1 erhöhen. Dann hast du auch zu unterschiedlichen Zeiten eine ähnliche Zahl wie die Uhrzeit.

Goldenflash
30.07.2005, 20:37
Also es geht darum dass 4 LED's leuchten, aber immernur eine, und welche leuchtet soll zufällig entschieden werden. Das ist das einzige was das Prgramm machen soll, somit leuchten die LED's leider immer in der selben Reihenfolge.

Gruß Florian

PS Ich benutze eine AT90S4433 (fals das irgendwie einen Unterschied machen sollte)

Marco78
30.07.2005, 21:08
Wenn sollen sie denn zufällig leuchten? Wen jemand eine Taste drückt oder alle drei Sekunden?

ICH_
30.07.2005, 22:35
gibts in bascom auch den vb-befehl randomize?

oe9vfj
31.07.2005, 05:13
Es gibt den Befehl RND() zur Erzeugung einer 'Zufallszahl'. In der BASCOM-Hilfe ist unter Index->RND einiges darüber beschrieben.

Marco78
31.07.2005, 07:12
Und da steht auch das es immer die gleichen Zufallszahlen sind. Und genau das ist ha nicht erwünscht und hat Goldenflash ja auch schon erkannt.

31.07.2005, 09:34
Es handelt sich bei "normalen" CPUs immer um deterministische Systeme, die somit bei identischen Start- und Laufzeitbedingungen immer alles gleich machen (deterministisch <-> vorhersagbar).

Echte Zufallszahlen gibt es in diesem Zusammenhang nicht. Es handelt sich immer um durch einen festen Algorithmus erzeugte Zahlen. Dabei wird eine Folge verwendet, deren nächster Wert von der aktuellen Position abhängt. Wenn die Werte dieser Folge im Mittel gleichmäßig verteilt sind, dann hat man einen "guten" Pseudozufallszahlengenerator.

In der Praxis werden verschiedene Folgen verwendet, alle arbeiten nach dem selben Prinzip. Der Startwert "seed" gibt die Startposition innerhalb der Folge vor. Dieser wird zusätzlich durch "randomize" in manchen Systemen auf einen Startwert gesetzt, der von einem seit Systemstart mitlaufenden Timer abhängt. Wenn die Zufallszahlen nicht sofort ab Reset, sondern nach einer undefinierten Pause (Der Benutzer drückt irgendwann mal eine Taste) benötigt werden, erreicht man dadurch immerhin eine zufällige Initialisierung. Die dann erzeugten Werte sehen zumindest zufällig aus, da sie jeweils aus einem anderen Bereich der Folge stammen.

Wenn die Zufallszahlen direkt ab Reset ohne undefinierte Pausen benötigt werden, wird alles wieder determinitisch ablaufen und man erhält immer die selben Zahlen.

Wirkliche Zufallszahlen erhält man nur, indem ein echt zufälliges Element wie z. B. ein Rauschgenerator verwendet wird. So kann man einfach die Impulse eines Rauschgenerators (Z-Diode plus Verstärker) in einem festen Zeitfenster zählen. Das gibt einen nicht vorhersagbaren Wert. Den verwendet man entweder direkt als Zufallszahl oder nutzt ihn, um den Startwert für den Pseudozufallszahlengenerator festzulegen.

Für den Hobbybereich ist hier die Art des Rauschen völlig egal. Zum Thema Rauschgenerator gibt es hier was zu lesen:
http://www.umnicom.de/Elektronik/Schaltungssammlung/Funktion/Rausch/Rauschgenerator.html
http://www.qsl.net/dk3wi/HF_Noise_Generator.html

talentraspel_kai
31.07.2005, 09:35
Und ich dachte, ich hätte mich eingeloggt ...

Goldenflash
31.07.2005, 09:56
Wenn sollen sie denn zufällig leuchten? Wen jemand eine Taste drückt oder alle drei Sekunden?

Alle 3 Sekunden. Wenn jemand eine Taste drücken müsste wäre es ja kein solches Problem :(

Marco78
31.07.2005, 10:32
Das blöd jetzt :(

Wie wäre es mit rauschen am ADC zu erzeugen und diese Zahl mit einbinden? Aber da kommt man auch langsam an eine Stelle wo man alles mit anderen ICs aufbauen kann und eigentlich keinen µC braucht.

SprinterSB
31.07.2005, 21:59
Was mit Preudozufall geht: Merke dir im EEPROM den letzten Zufallswert als seed für den nächstes Start-- ok, ist etwas stressig für's EEPROM.

'Richtige' Zufallswerte bekommst du folgendermassen:
Nach Power-On-Reset berechnest du einen Wert seed aus dem RAM-Inhalt. Dieser ist uninitialisiert und damit mehr oder weniger zufällig; zumindest für AVR-SRAM. Diesen Wert kannst du als Startwert für deine RND-Routine nutzen.
Ich poste hier mal einen C-Code, der mir nach jedem Einschalten einen anderen 16-Bit-Wert liefert. Habs eben mal abgecheckt :-)

Meine BASIC-Zeiten sind seit C64 vorbei, vielleicht ist jemand so nett und übersetzt nach BASIC?


#define RAM_START 0x60
#define RAM_END (RAM_START + 0x400)

// Deklariere eine 16-Bit Variable seed.
// Lege sie in Section .noinit, damit sie vom Startupcode (crtm8.o)
// nicht überpinselt wird.
unsigned short seed __attribute__((section(".noinit")));

// Lege get_seed() in die Section .init0
// Diese wird direkt nach RESET-Interrupt aufgerufen,
// noch vor dem Startup-Code und Aufruf von main().

__attribute__((section (".init0")))
__attribute__((naked))
void get_seed()
{
unsigned char *pram;
unsigned short _seed = 0;

for (pram = (unsigned short*) RAM_START; pram < (unsigned short*) RAM_END; pram++)
_seed += *pram; // Oder sonst was...

seed = _seed;
}

// !!! Wichtig: get_seed() NICHT aufrufen!!!
void main()
{
...
... = seed;
...
}