random Seed ohne analog read

hy, ich habe ein Arduino Uno und möchte auf meinem 4x4x4 led cube mittels Zufallszahlen eine Animation laufen lassen... Habe aber Probleme mit random Seed, also zufällige "Startpunkte" für die "pseudo" Zufallszahlen: - srand(time(NULL)); kann man ja leider in der arduino IDE nicht nutzen - alle I/O Pins sind belegt durch den cube, daher kein analogread möglich (oder können andere Pins "missbraucht" werden ?! ) - und randomSeed(millis()); bringt auch immer wieder die gleiche Animation :(

welche (einfache) möglichkeiten gibt es noch, zufällige "seeds" zuerzeugen ?

mfg

hobo

Könntest du nicht einfach beim Start des Sketches ein paar Werte über die analogen Eingänge lesen und nur die jeweils niedrigstwertigen Bits verwenden? Die sollten eigentlich immer ziemlich rauschen, egal was an den Eingängen hängt…
Die Bits könntest du dann alle hintereinander schreiben und die daraus entstandene Zahl an randomSeed weitergeben.
Das dürfte ja eigentlich auch in Sekundenbruchteilen machbar sein, fällt also nicht auf.

Irgendwie soetwas: (ungetestet)

int i;
long int seed = 0;

for (i = 0; i<64; i++)
{
   seed |= (analogRead(A0) & 0x01) << i;
}

analogSeed(seed);

And1G: Könntest du nicht einfach beim Start des Sketches ein paar Werte über die analogen Eingänge lesen und nur die jeweils niedrigstwertigen Bits verwenden? Die sollten eigentlich immer ziemlich rauschen, egal was an den Eingängen hängt... Die Bits könntest du dann alle hintereinander schreiben und die daraus entstandene Zahl an randomSeed weitergeben. Das dürfte ja eigentlich auch in Sekundenbruchteilen machbar sein, fällt also nicht auf.

Das weiß hoboPowa bereits; sein Problem ist daß er keine Analogen Eingänge frei hat da er alle Eingänge für den LED-Würfel braucht. Viele Grüße Uwe

Hmm ok, nach einem kleinen Test muss ich zugeben, dass ich mit meiner Idee wirklich falsch lag. Ich meine nämlich irgendwo mal gelesen zu haben, dass das letzte Bit beim ADC eigentlich immer kräftig rauscht... Scheint aber wohl doch nicht der Fall zu sein.

Mh, ich hätte da ne Idee, ob und wie´s funktioniert weis ich allerdings nicht. Der ATmega hat soweit ich weis einen internen Temperatursensor, der sollte doch einen gewissen zufälligen Wert liefern. Wenn gewünscht, dann würd ich auch helfen den Ansatz weiter auszuarbeiten. MfG Jago

Der bringt aber auch nicht wirklich zufällige Werte da der Arduino ja meist Raumtemperatur hat und deswegen nicht sonderlich unterschiedlich mißt. Das einzige was mir einfällt ist einen analogen Eingang oder das interne Temperatur messen und nur das niederwertigsten oder die beiden niederwertigsten Bits der Messung zu nehmen und aus mehreren Messungen einen 8 oder 10 Bit Wert zusammenstellen. Der müßte dann ziemlich zufällig sein. Grüße Uwe

Ich glaub wir komm der Lösung näher. Hab grad mal ins Datenblatt geschaut. Der interne Temperatursensor ist super ungenau +-10°C und gibt 380mV bei 85°C raus. 0,7 Vref an einer Diode abgegriffen dürfte den A/D Wandler ordentlich zum rauschen bring und wenn man dann noch die unteren Bits nimmt, dann sollte der Wert wirklich zufällig sein. Und? Lösung oder nicht Lösung? MfG Jago

PS.: Besser noch ne Germaniumdiode, die dürfte bei 0,3V oder so liegen (bei 25°C sinds 314mV muss man ggf schauen das der A/D Wandler nicht übersteuert wird.)

Jago, wie montiert man eine Germaniumdionde in den Atmega rein? Grüße Uwe

Aref ist kein Output-pin und sollte damit trotz aller belegten Pins noch für eine externe Beschaltung zu gebrauchen sein.

Hmm in wiefern würde denn ein Rauschsignal an Aref helfen?
Und kann es nicht den ADC beschädigen, wenn die Spannung, die anliegt höher ist als die Referenzspannung?

[quote author=Fat D link=topic=104270.msg783512#msg783512 date=1336207321] Aref ist kein Output-pin und sollte damit trotz aller belegten Pins noch für eine externe Beschaltung zu gebrauchen sein. [/quote] Ich bin heut schwer von Begriff. Was soll mit Aref gemacht werden?

Aref ist der Ausgang der Referenzspannung für den A/D-Wandler. Dieser wird beim ATmega328 intern auf die Versorgungsspannung, eine interne 1,1V Referenz oder gar nicht geschaltet. Im Falle daß er gar nicht beschaltet ist kann von außen eine Referenzspannung angelegt werden. Ein 0,1µF-Kondensator dient zur Stabilisation. Man kann eine "Zufallsspannung" als externe referenz anlegen und darum einen fixe Spannung wie zB von den LED als Zufälliges Meßergebnis lesen. Dazu muß aber die Referenzspannung größer als die Meßspannung sein.

Da fine ich es einfacher mehrere Meßungen zu mache und nur das niederwertigste Bit zu nehmen, da dazu keine zusätzliche Elektronk notwendig ist.

Viele grüße Uwe

Aref kriegt nicht das Rauschen selbst, nur eine niedrige Spannung damit eine rauschende interne Größe stärker ins Gewicht fällt.
Konsultieren wir das ATmega328P-Datenblatt (http://www.atmel.com/Images/doc8161.pdf), sehen wir in Kapitel 23.8, dass sich ein interner Temperatursensor über den ADC messen lässt, also lässt sich eine Größe ohne Verbrauch von Pins messen. Wenn man die Referenzspannung weiter reduziert (externe Diode an AREF), wird die Abtastgenauigkeit und damit die Schwankungsbreite weiter erhöht.
Weiterhin sagt das Datenblatt “Single ended channels that exceed VREF will result in codes close to 0x3FF.” (23.5.7), d.h. es ist möglich zu hohe Spannungen zu messen, der gemessene Wert wird aber irgendwo beim Maximum liegen.

Vielen dank für die vielen hilfreichen Antworten XD Hatte leider die letzten 2 Tage keine Zeit zum lesen und antworten... Außerdem stand ich beim schreiben des threads total aufm schlauch :blush: Man kann ja einfach im setup (oder sogar im Hauptprogramm) einen der analogen Pins oder der digtalen Pins mit PWM als input definieren, Seed bestimmen und danach wieder als output definieren und verwenden ... die Geschichte mit dem Temperaturfühler, Aref und dem A/D wandler werd ich mir anschauen, wenn ich mich tiefer in die ganze Materie eingearbeitet habe

MfG hobo

PS: sorry für den verwirrenden thread titel, ich war, ka warum, davon ausgegangen, dass ich die Pins nicht als input nutzen kann (weil der cube dran hängt) :~

hoboPowa: Man kann ja einfach im setup (oder sogar im Hauptprogramm) einen der analogen Pins oder der digtalen Pins mit PWM als input definieren, Seed bestimmen und danach wieder als output definieren und verwenden ... die Geschichte mit dem Temperaturfühler, Aref und dem A/D wandler werd ich mir anschauen, wenn ich mich tiefer in die ganze Materie eingearbeitet habe

Ich würde sagen nein, den Zufallswert für Seed kannst Du so nicht erhalten. Die Theorie einen Anfangs-Zufallswert zu bekommen ist einen unbeschalteten analogen Eingang auszulesen. Dieser fängt wie eine kleine Antenne elektromagnetische Störungen ein und gibt einen nicht vorhersagbaren Wert aus. Mit den PWM-Ausgängen geht das auf keinen Fall.

Da Du aber die analogen Eingänge beschalten hast ( Du hast den Schaltplan uns nie gegeben, darum muß ich den schlechtesten Fall annehmen, daß die Beschaltung das Pin, das als Eingang definiert wird, durch irgenwelche Widerstände oder Diodenstrecken auf ein definiertes Potential gebracht wird) kannst Du keinen zufälligen Wert lesen.

Deshalb mein Vorschlag, einen Analogen Eingang 8 mal zu lesen und das niederwertigste Bit jeder Messung, das ziemlich instabil ist, zu einer 8 Bit zahl zusammenzufassen und so einen Zufallswert zu erhalten. Dieser Vorschlag funktioniert auch bei einem beschaltenen Pin. Grüße Uwe

Na da habt ihr ja doch noch rausbekommen was ich meinte... :* Bin zur Zeit ein wenig in Zeitnot... ....Umzug.... MfG Jago

PS.: Eine "zufällige" Referenzspannung zu erzeugen ist nicht wirklich ein großer schaltungstechnischer aufwand. Spannungsteiler mit NTC, PTC oder [u]LDR[/u] sollte da eigentlich ausreichen.

Jago: PS.: Eine "zufällige" Referenzspannung zu erzeugen ist nicht wirklich ein großer schaltungstechnischer aufwand. Spannungsteiler mit NTC, PTC oder [u]LDR[/u] sollte da eigentlich ausreichen.

Bitte lies die Diskussion genauer. Das Problem ist nicht die Erzeugung sondern ohne Mehraufwand diese zu messen da hoboPowa alle PIN des Arduino verwendet hat. Grüße Uwe

Also irgendwie glaub ich wir reden aneinander vorbei. Mir ist schon klar wie die Problemstellung in diesem Thread aussieht (denk ich). Davon abgesehen war mein PS bezugnehmend auf deine Aussage das dass erzeugen der zufälligen Referenzspannung "aufwändig" wäre.

Da fine ich es einfacher mehrere Meßungen zu mache und nur das niederwertigste Bit zu nehmen, da dazu keine zusätzliche Elektronk notwendig ist.

Zugegeben, hätte ich kenntlich machen sollen. Wurde von dir auch garnicht so gesagt. Und auch mein Hintergedank der größeren Varianz geht nicht hervor.

Ansonsten ist doch alles soweit geklärt und das Thema eigentlich gelöst, sofern hoboPowa keine weiteren fragen hat.

vielen Dank für eure Hilfe, erzeugen des Seeds funktioniert jetzt :slight_smile:
jedoch hab ich keine gute(s) Erklärung/Tutorial dazu gefunden, was genau hinter analogRead steckt bzw wie das “auslesen” eines analogen Pins genau funktioniert… währ schön wenn jmd es kurz erklären könnte oder n Link zu einem Tutorial posten könnte

anbei das fertige Programm, ihr könnt ja mal reinschauen (aber bitte nicht zu sehr hauen :grin:)

pulse.txt (3.79 KB)

Der Atmega328 hat einen Analog-Digital-Converter (DAC). Dieser "quantifiziert" eine Spannung und gibt einen numerischen Wert zwischen 0 und 1023 zurück. Der Bereich 0 bis 1023 wird durch die Größe der Referenzspannung definiert. Damit der ATmega 6 Eingänge messen kann, ist ein Multiplexer zwischn den Eingängen und den Analog-Digital -Conwerter geschaltet, der immer einen Eingang mit dem ADC verbindet. Da die Umwandlung in mehrern Schritten erfolgt und damit sich während der gesamten Messung der Analogwert nicht ändert, wird eine kleiner Kondensator mit der Analogspannung geladen und die Umwandlung mit der Kondensatorspannung gemacht. Beantwortet das Deine Frage oder wolltest Du es genauer wissen?

Grüße Uwe