für einen elektronischen Würfel mit Arduino, was sonst ;), braucht man natürlich Zufallszahlen.
Nun habe ich mitbekommen das random() alleine immer wieder die gleiche Zahlenfolge erzeugt nach µC Reset.
Das kann man mit randomSeed() ändern. Ändert den Startwert für random(). Soweit ist mir das klar.
Was mir nicht klar ist, ist es sinnvoll vor jeden random() Aufruf immer ein randomSeed() zu starten oder reicht es randomSeed() einmal bei Sketchstart im setup aufzurufen und dann random() im Loop einfach machen lassen? Was bringt mehr Zufälle?
Gegenwärtige Idee wäre die Dauer des Tastendrucks zum würfeln auswerten, randomSeed() übergeben und dann mit random() eine Würfelaugenzahl erzeugen. Oder die Tastendruckdauer in [ms] noch mit irgendwas multiplizieren vor Übergabe an randomSeed()?
Es ist jetzt zwar keine direkte Antwort auf deine Frage.
Aber eine Anregung bzw eine Idee:
Benutz doch einen Analog-IN Eingang ohne Pulldown Widerstand.
Lass einfach einen Draht als Antenne fungieren. Die Störungen
sind doch ziemlich Random ?
Ein unbeschalteter analoger Eingang ist gut für des Startwert des Zufallsgenerator.
Die Random-Funktion mußte wenn sie richtig programmiert ist zwar eine vom Anfangswert abhängige Zahlenfolge liefern. Diese sollte aber statistisch auf den ganzen Datenraum verteilt und die nächsten Zahlen nicht vom jetzigen oder zukünftigen Zahlen abhängen also nicht vorhersagbar sein.
Die Tastaturdruckdauer kann als Zufallszahl herangezogen werden wenn man zB den Modulo 10 nimmt. Die Taste muß aber über Interrupt eingelesen werden da durch Polling nur bestimmte Werte möglich sind weil die Schleife einfach eine gewisse Zeit braucht um abgearbeitet zu werden und darum nur vielfache dieses Wertes möglich sind.
Alternativ kannst Du auch eine modulo-Wert des micros() Werts bei Tastendruck verwenden, da der Tastendruck bei beliebigen Zeitpunkten erfolgt und sicher nicht auf die µS genau gemacht werden kann. Auch hier Interruptabfrage der Taste.
also ist es sinnvoll vor jeden ramdom() immer wieder ein randomSeed() voranzustellen?
Dann werde ich mal die Tastendruckdauer mit Interrupt ermitteln und vielleicht einen offen Analogeingang noch dazu nehmen und miteinander multiplizieren. µs statt ms ist auch besser. Sind dann nicht wegen Interruptnutzung irgendwelche Pins nicht mehr nutzbar? Da war doch irgendwas.
Danke Euch für guten Hinweise.
Nochwas nebenbei. Warum zeigt das Forum bei nicht eingeloggt sein falsche Beitragserstellzeiten an? Fiel mir schon mehrfach auf. Uwe's Post soll zum Bsp. 14:34 Uhr erstellt wurden sein. Kann aber nicht sein. « Reply #3 on: Today at 02:34:38 PM » Logge ich mich ein, stimmt der Zeitstempel wieder. Könnte man vielleicht mal dem Forenadmin mitteilen zur Korrektur.
Doc_Arduino:
Nochwas nebenbei. Warum zeigt das Forum bei nicht eingeloggt sein falsche Beitragserstellzeiten an? Fiel mir schon mehrfach auf. Uwe's Post soll zum Bsp. 14:34 Uhr erstellt wurden sein. Kann aber nicht sein. « Reply #3 on: Today at 02:34:38 PM » Logge ich mich ein, stimmt der Zeitstempel wieder. Könnte man vielleicht mal dem Forenadmin mitteilen zur Korrektur.
Das ist die Zeit des Servers; aber frag mich nicht wo der Server sich befindet.
Ohne login weiß der Server nicht wo Du zuhause bist.
Grüße Uwe
wenn ich eingeloggt bin ist es die richtige Zeit. Sonst die falsche Zeit.
Edit beim tippen. Ach'so. Serverzeiten sind verschieden und werden beim Login wie Eisebaer schreibt korrigiert. Alles klar.
Ich überlege gerade wegen dem Interupt. Der Taster prellt ja. Dann würde ja der Interupt oder beide (je ein für gedrückt und nicht mehr gedrückt) während des prellens mir meine Drückzeit zu nichte machen. Kann man das entprellen mit der Bounce.h und Interrupt kombinieren oder gewinnt der Interrupt immer? Eigentlich ja, wird ja vorrangig behandelt. Ich bin da gerade in einer Endlosschleife im Kleinhirn ...
Nein, Bounce.h und Interrupt kann man nicht kombinieren. Das Prellen und mehrfache einlesen der micro()Zeit ist in diesem Fall nicht schlimm.
In der Interruptroutine liest Du micros() in eine globale Variable und setzt ein Flag das der Taster gedrückt wurde.
Im loop() kontrollierst Du das Flag und bei gesetztem Flag (kannst Du zum Entprellen eine 5mS Pause machen) verarbeitest Du die Micros-Zeit zu einer Zufallszahl, gibst sie an das Display aus und löscht das Flag. In diesem Fall ist eine mehrmaliges Update der Zeit-Variable wegen Prellen nicht schlimm.
ich glaube ich hab's noch nicht verstanden, also die Methode. Laut meiner Überlegung brauche ich 2 Interrupts. Einen wenn ich auf den Taster drücke. High nach Low. Und einen 2. Interrupt wenn ich den Taster los lasse. Low nach High Pegelwechsel. Ich nutze den internen PullUp am Eingang.
Wenn der Taster aber prellt. Dann springt doch der µC mehrfach zwischen beiden Interrupts hin und her und am Ende müßte ich nur die letzte Prellzeit erhalten. ???
Selbst wenn ich einmal kurz drücke und dann nochmal kurz drücken muß und dazwischen die Zeit messen möchte. Ich bekomme das prellen nicht aus dem Kopf und damit das hin und her springen.
das ist mir schon klar das ich die laufende Zeit jeweils abfragen muß und daraus die Differenz bilde.
Mir ist nur nicht klar wie das mit den entprellen funktionieren soll. Der Interrupt reagiert doch zum Bsp. auf ein LOW Signal. Der andere auf ein HIGH. Jetzt speicher ich den aktuellen µs Zähler. Jetzt lass ich den Taster los und speicher wieder den aktuellen µs Zeitzähler und bilde die Differenz. Das Problem was ich sehe ist. Wenn der Taster prellt spielen die Interrupts untereinander Ping Pong und messe nur die letzte Prellzeit. Verstehst Du mein Problem bzw. mein Denkfehler? Helf mir raus. :~
Das Pin angepaßte Bsp. aus meinem Buch (o'reillys Erik Bartmann) funktioniert auch nicht. LED 23 blinkt. Aber die tasterLED 8 reagiert nicht auf Tastendruck. Bleibt aus. Der Taster selbst funktioniert aber. Muß am Sketch liegen.
int ledPin = 23; // LED
int tasterLED = 8; // Taster-LED
int tasterPin = 12; // Taster
int interruptNumber = 0; // Interrupt-Nummer
volatile int statusLED = LOW; // LED-Status
void setup(){
pinMode(ledPin, OUTPUT);
pinMode(tasterLED, OUTPUT);
pinMode(tasterPin, INPUT);
digitalWrite(tasterPin, HIGH); // internen PullUp Widerstand aktiviert
attachInterrupt(interruptNumber, interruptroutine, FALLING);
}
void loop(){
for(int i = 0; i < 5; i++){
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
}
}
void interruptroutine(){
statusLED = statusLED^1;
digitalWrite(tasterLED, statusLED);
}
okay, Sketch kann nicht funktionieren, ich muß natürlich den Taster auch an den Pin mit dem gewählten Interrupt anschließen und nicht woanders. Kann ich dann trotzdem den internen Pullup verwenden? An Pin2 = INT.0 Traue mich das noch nicht so zu flashen.
Wegen der Zeitmessung mach ich morgen weiter. Bin da im Moment scheinbar total neben der Spur ...
so, habe mir das nochmal überlegt wie Du das meinen könntest.
Ich nehme die Zeit ab µC einschalten bis ersten Tastendruck. Die Zeit nehme ich für randomSeed(). Richtig?
Später lasse ich nur noch random() laufen solange die Taste gedrückt ist?
Du denkst kompliziert.
Schon modulo 6 von micros() ist eine gute Zufallszahl für einen Würfel, weil der Moment des Tastendrucks unmöglich genau auf die µS sein kann.
Wenn Du aber micros() bei Tastendruck nimmst, die dann in randomSeed() nutzt um den Startwert zu definieren und dann mit random() die Zufallszahl holst weiß ich nicht ob, die Zufälligkeit der Zufallszahl verbessert wird.
Dann wird millis also nicht kontinuirlich sondern in 2-er Schritten erhöht???
Dann mach modulo 12 und dividiere durch 2 oder modulo 60 und durch 10 dividieren.
Grüße Uwe