Hallo liebe Community... mitlerweile hab ich das mit dem PWM in den Griff bekommen aber habe noch ein anderes Problem: Wie kann ich einen Random Wert, also eine Zufällige Zahl in einem Festgelegten bereich, z.B. 155 generieren? Hab hier im Forum leider nichts brauchbares Gefunden. Grüße Sebastian
hm hab mal folgenden code gebastelt:
1 | #include <avr/io.h> |
2 | |
3 | int x=0; |
4 | |
5 | unsigned short get_seed() |
6 | {
|
7 | unsigned short seed = 0; |
8 | unsigned short *p = (unsigned short*) (RAMEND+1); |
9 | extern unsigned short __heap_start; |
10 | |
11 | while (p >= &__heap_start + 1) |
12 | seed ^= * (--p); |
13 | |
14 | return seed; |
15 | }
|
16 | |
17 | int main (void) |
18 | {
|
19 | srand(get_seed()); |
20 | x = (rand() %11); // Begrenzung von 0 - 10 |
21 | }
|
Funktioniert das ganze?
google mal nach "lineare Kongruenzmethode". Nach dieser Formel arbeiten viele Zufallsgeneratoren.
Ich werd erstmal heut abend mein Programm Testen und euch dann berichten. Grüße Sebastian
@sebastian, filtere mal alle Addressen aus die durch dein Program als globale Variablen schon belegt sind, also den Seed des RNGs selber auch. Dann wirst du feststellen das ein RESET eines schon unter Strom stehenden Controllers immer den gleichen Wert liefert. Ich mache es immer so: - ich benutze ein 32Bit LFSR als RNG - diesem LSFR Code kann man die Polynome vorgeben - ich benutz 2 unterschiedliche Polynome A und B - beim Powerup der MCU lade ich aus dem EEPROM ein 32 Bit Wert als Seed - diesen schicke ins LFSR mit Polynom A und speicher das Resultat zurück in den EEPROM an gleicher Stelle - dieser Seed wird als akuelles Register des LFSR benutzt - zur Laufzeit benutze ich das LFSR mit Polynom B Somit laufen 2 LFSR in parallel. Das eine wird immer nur beim RESET aktualisert und dessen Seed steht im EEPROM. Das andere LFSR wird damit initialisiert. Beide LFSR benutzen andere Polynome. Das ist zwar nicht echt zufällig, aber eben beweisbar immer pseudozufällig im Gegensatz zu deiner Methode. Bei einem RESET wird nämlich der SRAM nicht ständig mit Zufallsdaten gefüllt, bzw. ist es garnicht gesagt das der SRAM ohne Strom nach Einschalten ein zufällig Inhalt aufweisen muß. Gleiches gilte für Methoden wie mit dem ADC und Rauschen. Das Rauschen des ADCs muß nicht echt zufällig sein sondern systembedingt. Gruß Hagen PS: in der Codelib nach "Glühwürmchen" suchen, dort findest die meinen LFSR Source für WinAVR GCC und auch in main() oben besprochene Initialisierung.
okay danke für deinen Tipp ich werd heut abend dann mal Test und Programmierstunden einrichten ;)
falls du andere Polynome brauchst (müssen von spezieller Form sein damit die maximale Periode von 2^32-1 erreicht wird) dann sag es. Gruß Hagen
Hallo, Sorry, dass ich den alten Thread hochhole, aber ich habe auch eine Frage bzgl. dieses Themas. Ich habe mehrere µC, die das komplett gleiche Programm laufen haben. Nun muss ich eine Random-Zahl generieren, die bei allen aber unterschiedlich sein muss. Zur Zeit mach ich das mit der Rand()-Funktion, aber die Zahlen sind alle gleich! Jemand deine Idee? Besten Dank! mfg Andy
du brauchst nen passenden seed. Ich würde als platzsparenden Zufallsgenerator einen nach Park-Miller-Carta basteln, hier einige funktionierende Codebeispiele: http://www.firstpr.com.au/dsp/rand31/ Als seed kannst du die Zeit nehmen. Sprich du bastelst dir entweder irgendwie die aktuelle Uhrzeit rein oder, was viel besser wär, eine "Systemuhr". Einen Timer (frequenz nahezu egal), der eine globale Variable hochzählt. Das höchste der Gefühle wär natürlich wenn du dir daraus die Unix Systemzeit errechnen lässt und das dann als seed nimmst.
Was ist mit Hardware? Das Rauschen einer Z-Diode, Trigger, Zähler - sollte echte Zufallszahlen hervorbringen und gibts bestimmt auch als fertigen Chip, oder? Frank
OK, danke erstmal für eure Hinweise. Was ich mir gedacht habe: Wie wärs, wenn ich von Anfang an einen Timer laufen lasse und wenn ich die Zahl brauche, mach ich Rand()*TCNT2/255. Ich glaube, ein bisschen unterschiedlich werden die Timer auf 2 Atmels schon laufen, oder glaubt ihr, dass die immer die gleichen Werte haben werden??
Was spricht denn gegen die Methode den Ram vor dem 1. Schreibzugriff auszulesen und alle Werte mit XOR zu verodern? Der Startzustand des Ram's müsste eigentlich jedes mal anders sein.
Ist er aber nicht. Die Speicherzellen haben recht hohe Tendenzen beim einschalten sehr oft den gleichen Zustand einzunehmen (Fertigungstoleranzen die einen Zustand bevorzugen lassen) Man kann mit der Methode gar recht sicher feststellen, ob man der sram gewechselt worden ist (für systeme in denen das möglich ist) Man kann aber recht volatile Meßwerte mit hernehmen. Ein floating ADC ist zwar auch nicht ganz zufällig, aber nett :-p
Maxxie schrieb: > Ist er aber nicht. Die Speicherzellen haben recht hohe Tendenzen beim > einschalten sehr oft den gleichen Zustand einzunehmen Wobei ich mir vosrtellen kann, dass ein XOR über alle nicht benutzten RAM-Zellen (so es genügend viele sind) in der Tat gar keinen so schlechten Zufallswert ergeben könnte. Das müsste man einfach mal mit hinreichend vielen Versuchen erfassen und dann als Plot darstellen.
Hallo, Wie gesagt, ich habs nun über den TCNT2 gelöst - meint ihr, ist das ein zuverlässiger Zufallszahlengenerator? Was mir noch in den Sinn gekommen ist: Gibt es eine Art Seriennummer im Atmel, die ich auslesen und für die Zufallszahlenberechnung heranziehen könnte?? THX Andy
>> Zur Zeit mach ich das mit der Rand()-Funktion ... > Wie gesagt, ich habs nun über den TCNT2 gelöst - meint ihr, ist das ein > zuverlässiger Zufallszahlengenerator? Es geht doch gar nicht um den Generator, sondern nur um den Anfangswert (seed = die Saat). Ich glaube nicht, dass der Timer immer anders losläuft und du damit zuverlässig jedesmal einen anderen Startwert hast. Sehr schön zum Erzeugen eines Saatwertes sind Benutzeraktionen oder extern angeschlossene Hardware (Endschalter, Taster, Zeichen über SIO...). Wenn ein Timer schnell hochläuft und der Zählerwert bei einem Pegelwechsel als Seed verwendet wird, kann ein Benutzer oder Ventil ziemlich sicher nicht denselben Startwert zweimal erzeugen. srand() muß ja nicht in der Nähe von rand() stehen, und es kann auch öfter aufgerufen werden.
Deshalb hab ich ja den Timer genommen. Nur ist die Frage, ob 2 µC die zugleich eingeschalten werden und die zugleich einen Zufallswert ausspucken sollen, denselben Wert ausgeben werden, oder ob die 2 Timer ein bisschen auseinanderlaufen werden. Hätte ich eine Art Seriennummer, die einzigartig ist, könnte ich ja diese zum Seed-Wert nehmen und ich hätte 2 verschieden laufenden Timer...
Andy schrieb: > BTW: Was ist srand()?? Ja, wie bitte? Du hängst dich an einen Thread und hast den nicht mal durchgelesen? Beitrag "Re: Random Zahl generieren" Das ist hart, meine Herren :-/ Mit srand() wird der Startwert für den Zufallszahlengenerator festgelegt. Als Stichworte für Guugel: srand() und rand(). Damit werden Zufallszahlen erzeugt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.