Rauschen am ADC als Zufallsgenerator

Gast #2505776
Lesenswert?

Hallo,
ich weiß das Thema gibt es hier schon ca 100 mal, hab mir auch schon 
diverse davon durchgelesen ohne schlauer zu werden.

Ich möchte gerne einen Zufallwert (0 oder 1) mit einem Attiny13 
generieren. Mein Plan war eine AD-Wandlung mit einem Floating Pin zu 
machen und das unterste Bit zu nehmen.

Mein Quellcode bisher:
1
#include <avr/io.h>
2

3
int main(void){            
4
  DDRB   = (1<<PB3) | (1<<PB4);
5

6
  ADMUX   = (1<<MUX1);
7
  ADCSRA  = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
8

9
  ADCSRA |= (1<<ADSC); // Start convertion
10
  while (ADCSRA & (1<<ADSC)); // Wait for conversion to complete
11

12
  ADCSRA |= (1<<ADSC); // Start convertion
13
  while (ADCSRA & (1<<ADSC)); // Wait for conversion to complete
14

15
  if((ADCL&0x01)){
16
    PORTB = (1<<PB3);
17
  }else{
18
    PORTB = (1<<PB4);
19
  }
20

21
  while(1){
22
  }  
23
}

Das Ergibniss ist allerdings immer, dass PB4 an geht....

Am Controller hängen ausschließlich 3V von einer Batterie und 2 LEDs mit 
Vorwiderstand.

Vielen Dank im Vorraus
Gast #2505889
Lesenswert?

Ich bin mir nicht ganz sicher, ob ich dich richtig verstanden habe, aber 
dann würde doch im if und im else zweig das selbe stehen und somit an 
PB4 immer eine 1 sein.

Was ich will, ist das entwerder PB4 oder PB3 auf 1 gehen und der andere 
auf 0.
Gast #2506309
Lesenswert?

Ist dein Problem eigentlich dass du nicht verstehst warum das unterste 
Bit des Ergebnisses immer 0 ist oder dass du nicht weißt wie du den 
Effekt richtig debuggen kannst?

Zum Debuggen: Ich würde ja erstmal versuchen die Werte insgesamt 
anzuzeigen
(Mehrere LEDs, LCD, Uart?) und mal schauen wie die sich verhalten.

Zum ADC-Ergebnis:
Soweit ich das richtig erinnere nutzt der ADC ne sample&hold Schaltung.
Bei 5V Referenz und 10Bit Auflösung müsste die Spannung im hold Kondi um 
gut 5mV rauschen... Ich vermute der ist schlicht leer und rauscht 
weniger als 5mV sodass der ADC konstant 0 ausgibt.

Gruß
Sven
Persönliche Seite #2506439
Lesenswert?

>
> Ich möchte gerne einen Zufallwert (0 oder 1) mit einem Attiny13
> generieren. Mein Plan war eine AD-Wandlung mit einem Floating Pin zu
> machen und das unterste Bit zu nehmen.


Warum eigentlich so kompliziert..... 9 Zeilen Assemblercode....ohne Pin.

gut, das ist mit Kanonen auf Spatzen geschossen, denn es gibt 8bit 
Quasizufallszahl aus, aber davon kannst Du jedes beliebige Bit 
auswerten.


;*********************************************************************** 
***
;                   Zufallszahlen (RANDOM = 1...FE)
;*********************************************************************** 
***
           ;RANDOM <> 0 zum Start
        RLF     RANDOM, W       ;
        RLF     RANDOM, W       ;
        BTFSC   RANDOM, 3       ;
        XORLW   1               ;
        BTFSC   RANDOM, 4       ;
        XORLW   1               ;
        BTFSC   RANDOM, 5       ;
        XORLW   1               ;
        MOVWF   RANDOM          ;
;*********************************************************************** 
***

Und grosse Entschuldigung, dass der Code fuer PIC ist..... :-(


Gruss

Michael
#2506647
Lesenswert?

Michael Roek schrieb:
> Und grosse Entschuldigung, dass der Code fuer PIC ist..... :-(

Besser wäre eine Entschuldigung, warum Du ihn nicht beschreibst, sondern 
nur als Blackbox hinstellst.

Ich vermute mal, das ist ein 8Bit-Schieberegister, d.h. die 
Pseudozufallsfolge wiederholt sich nach 255 Durchläufen. Das ist aber 
nicht sonderlich zufällig.

Üblich ist ein 32Bit-Schieberegister und man schiebt 31 mal, damit sich 
alle Bits ändern. Ist in vielen C-Libs schon implementiert, muß man also 
nur aufrufen.


Der ADC ist für Zufallszahlen nur sehr schlecht geeignet. Ein offener 
Eingang läuft durch Leckströme leicht ans Ende (GND oder VCC) und dann 
liefert er einen konstanten Wert. Oder er fängt sich 50Hz bzw. andere 
Störungen ein, ist also dazu exakt synchron.

Zufallszahlen kannst Du mit dem ADC nur dann erreichen, wenn Du damit 
die Spannung an einer Rauschdiode mißt.


Peter
Moderator Persönliche Seite #2506668
Lesenswert?

Seife schrieb:
> Mein Plan war eine AD-Wandlung mit einem Floating Pin zu
> machen und das unterste Bit zu nehmen.

Vergiss es.  Ein floating pin rauscht nicht, sondern hat eine Tendenz,
an einer der beiden Seiten "kleben" zu bleiben (weil die
Eingangskapazität entweder gerade hinreichend entladen oder aufgeladen
ist und kein nennenswerter Strom fließen kann, um diesen Zustand zu
ändern).  Selbst, wenn es wirklich "wackelt", dann ist es viel
wahrscheinlicher, dass du damit die 50-Hz-Periode der
Netzwechselspannung verfolgen kannst denn irgendeine Form von
Rauschen.

Du brauchst schon irgendwas am ADC-Eingang, was auch wirklich rauscht.
Habe ich vor vielen Jahren mal in einer Testreihe mit einer Z-Diode
demonstriert.  Es hat so leidlich funktioniert, sprich, wenn man
wirklich saubere 10 bit Auflösung bekommt, dann ergibt sich eine
minimale Gausskurve um den Mittelwert herum.

Habe mal die Suche nach meinen eigenen Beiträgen bemüht, hier ist das
Ergebnis von damals:

Beitrag "Re: wie erzeugt man eine zufallszahl"
Gast #2506846
Lesenswert?

Also die LEDs gehen definitiv beide. Zum Anzeigen des gesammten ADC 
Ergebnisses habe ich leider momentan keine Möglichkeit.
Meine Hoffnung war, dass ich vieleicht einfach irgend nen blöden Fehler 
beim ADC einstellen gemacht haben, den ihr entdeckt.

Mit Software zufällen haben ich es auch schon versucht, aber leider auch 
ohne ein zufälliges Ergbniss. Ich vermute, das es dran liegt, dass ich 
immer nach dem Start des µC genau einen Zufallswert brauche ich damit 
immer den gleichen Startwert habe. Kann das sein?
#2506873
Lesenswert?

> Ich vermute, das es dran liegt, dass ich immer nach dem Start des
> µC genau einen Zufallswert brauche ich damit immer den gleichen
> Startwert habe. Kann das sein?

Du meinst rand()?

Natürlich kann das sein und wird es sogar.
Aber dem lässt sich ja leicht abhelfen. Du hast ein EEPROM. Der 
Startwert wird aus dem EEPROM geholt, um 1 erhöht und wieder ins EEPROM 
für den nächsten Reset zurückgeschrieben. Selbiger Startwert wird dann 
mittels srand() dem C-Generator am Anfang in der main() zur Verfügung 
gestellt.

Problem gelöst.

Die Frage ist halt immer: Wie 'gut' müssen die Zufallszahlen sein. Für 
den Hausgebrauch reicht rand() sicher aus. Für eine Cas*ino ist er aber 
nicht geeignet.
Gast #2509321
Lesenswert?

DANKE!!

so hats geklappt.
Nur scheint mir der Zufall wirklich nicht gerade zufällig. Es kommt in 
ca 4 von 5 fällen auf eine 0 eine 1 bzw andersrum...
Ich werd mal versuchen den erhaltenen wert als seed für den nächsten zu 
nehmen.

Aber vielen Dank für die Hilfe!
#2509365
Lesenswert?

Seife schrieb:
> DANKE!!
>
> so hats geklappt.
> Nur scheint mir der Zufall wirklich nicht gerade zufällig. Es kommt in
> ca 4 von 5 fällen auf eine 0 eine 1 bzw andersrum...

Wieviele Zufallszahlen generierst du eigentlich pro Durchgang?

Dir ist schon klar, dass Zufälligkeit eine statistische Eigenschaft 
einer großeren Menge von generierten Zahlen ist?
D.h. rand muss beginnend mit einem bestimmten seed eine größere Menge 
von Zahlen generieren dürfen, ehe man dieser Menge die Eigenschaft 
Zufälligkeit zubillgen kann.
Gast #2509367
Lesenswert?

Ja ist mir theoretisch alles bewusst, aber ich erstelle leider pro 
Durchlauf nur eine Zahl.
Hab den Code jetzt dahingehen geändert, dass der Zufallszahl immer das 
Seed für die nächste ist und ich bin jetzt ziemlich zufrieden damit.

Vielen Dank nochmal an alle die geholfen haben.
#2509375
Lesenswert?

Seife schrieb:
> Ja ist mir theoretisch alles bewusst, aber ich erstelle leider pro
> Durchlauf nur eine Zahl.

Ich muss da jetzt trotzdem nochmal nachhaken.

Was ist ein Durchlauf?

Du sollst srand() in einem Programm nur ein einziges mal aufrufen. 
Direkt nachdem main() gestartet wurde, wäre zb ein guter Platz. Solange 
der µC dann weiterläuft, darfst du nie wieder srand() aufrufen! Du 
zerstörst damit die Zufälligkeit, auch wenn du es noch so gut meinst.
Gast #2509393
Lesenswert?

Mein Ziel war es einen "Entscheider" zu bauen, also ein kleines Gerät, 
bei dem nach dem Anschalten die grüne oder rote LED leuchtet.
Das beutet, dass ich bei jeden Einschalten auch nur genau eine 
Zufallszahl brauche.
Gast #2509429
Lesenswert?

Wenn ich mich mal einmischen darf.

Statistik ist (jedenfalls für mich) ein recht schwieriges Fach, bei man 
sich oft (zumindest ich) in der Beurteilung einer Situation oder der 
Herleitung einer Wahrscheinlichkeit irren kann. Dazu kommt das manche 
Ergebnisse dem sog. "gesunden Menschenverstand" zu widersprechen 
scheinen.

>Ja schon klar, aber die Chance, dass nach eine 1 noch eine 1 kommt
>sollte 50/50 sein, ist momentan bei mir aber eher 20/80...

Diese Formulierung und die Schlussfolgerung ist, ebenso wie die folgende

>Doch, vollkommen egal was vorher war ist die Warscheinlichkeit, dass
>eine 1 kommt 50%. Somit ist auch nach einer 1 die Chance auf noch eine 1
>50/50.

ist genau so ein Fall.

Wenn nämlich die Wahrscheinlichkeit eines einzelnen Ereignisses wie 1 
oder 0 50 zu 50 ist, dann ist die Wahrscheinlichkeit des zwei bestimmte 
dieser Ereignisse aufeinanderfolgen nicht auch wieder 50 zu 50.

Glücklicherweise ist dies einer der einfacheren Fälle zu denen ich meine 
Statistikwälzer nicht aus dem Regal holen brauche, aber wiegesagt, es 
ist keine Schande sich darin zu irren, wenn man nicht täglich damit zu 
tun hat.

Es ist nämlich so, das es für den Ausgang von zwei aufeinanderfolgen 
dieser Experimente (nämlich 0 oder 1 erzeugen) vier verschiedene 
Möglichkeiten gibt.

00
01
10
11

D.h. das die Wahrscheinlichkeit das auf eine 1 noch eine 1 folgt genau 
1/4= 0,25 beträgt was gut mit Deiner Beobachtung 20 zu 80 übereinstimmt.

Die Annahme, dass, weil die Wahrscheinlichkeit eines einzelnen dieser 
Ereignisse 50 zu 50 ist, dies auch für eine Kette von zwei oder gar mehr 
Ereignisse gilt, ist falsch, weil sie ausser acht lässt, wie 
wahrscheinlich die vorhergehenden Ereignisse sind.
Schon die erste 1 hatte ja eine Wahrscheinlichkeit von 0,5. Da das 
nächste dieselbe Wahrscheinlichkeit, die beiden aber nicht voneinander 
abhängen, gilt für die Gesamtwahrscheinlichkeit 0,5 * 0,5 = 0,25.
Man kann das sicher noch von verschiedenen Seiten beleuchten, aber 
vielleich ist Dir klar was ich meine.

Noch eines:

Wie Karl Heinz erwähnt hat, wird mit srand/rand (in der Regel) keine 
echte Zufallsfolge erzeugt, sondern nur eine sog. Pseudozufallsfolge.
An einen Entscheider aber, wie Du ihn bauen willst würde ich persönlich 
den Anspruch stellen, das er "echten" Zufall erzeugt. Die Idee mit dem 
AD-Wandler war also nicht schlecht und die Ergänzung durch eine Diode 
noch besser.
#2509581
Lesenswert?

Seife schrieb:
> Mein Ziel war es einen "Entscheider" zu bauen, also ein kleines Gerät,
> bei dem nach dem Anschalten die grüne oder rote LED leuchtet.
> Das beutet, dass ich bei jeden Einschalten auch nur genau eine
> Zufallszahl brauche.

Dann ist rand bzw. srand keine so gute Wahl.
Denn was du tun solltest ist, denn seed wieder herzustellen, damit rand 
dort weitermachen kann, wo es das letzte mal aufgehört hat. Nur 
blöderweise kommst du an den Seed nicht rann, so dass du ihn im EEPROM 
speichern kannst.

Glücklicherweise gibt es aber Zufallszahlengeneratoren im Web, bei denen 
du dann selbstverständlich Zugriff darauf hast.

Zb
http://stackoverflow.com/questions/1167253/implementation-of-rand
#2509584
Lesenswert?

Noname schrieb:

> Wenn nämlich die Wahrscheinlichkeit eines einzelnen Ereignisses wie 1
> oder 0 50 zu 50 ist, dann ist die Wahrscheinlichkeit des zwei bestimmte
> dieser Ereignisse aufeinanderfolgen nicht auch wieder 50 zu 50.

Du redest von bedingten Wahrscheinlichkeiten.
Den Fall haben wir hier aber nicht.
Bei einem guten Zufallszahlengenerator hängt das Ergebnis des Versuchs n 
nicht vom Eregbnis des Versuchs n-1 ab. Da existiert kein Zusammenhang.
Oder, wie Statistiker sagen: Kugeln haben kein Gedächtnis.

Lassen wir die 0 ausser acht, dann ist beim Roulett die 
Wahrscheinlichkeit das beim nächsten Wurf Rot kommt 50%. Völlig 
unabhängig davon ob davor keinmal, einmal oder zwangzigmal in Serie Rot 
kam.


Was du ausrechnest ist die Wahrscheinlichkeit, wie oft k mal 
hintereinander 1 kommt. Also die bedingte Wahrscheinlichkeit dass beim 
Versuch n eine 1 kommt, wenn vorher k mal ebenfalls 1 kam.

Die ist 25%. Interessiert hier aber keinen.

> weil sie ausser acht lässt, wie wahrscheinlich die vorhergehenden
> Ereignisse sind.

Und genau so soll es ja auch bei einem guten Zufallsgenerator sein, der 
eine Gleichverteilung erzeugt. Das Ergebnis n ist unabhängig vom 
Ergebnis n+1. Natürlich ist das mit algorithmischen Methoden nicht 
möglich, dass es gar keinen Zusammenhang gibt. Aber der Zusammenhang 
sollte so subtil sein, dass er sich im Ergebnis nicht auswirkt.

Wenn ich 10000 mal rand() aufrufe, dann kriege ich ungefähr in 50% der 
Fälle 0 und in ungefähr 50% der Fälle 1. Und natürlich kann es auch 
passieren, dass 10 mal in Folge 1 kommt. Wenn diese Verteilung sich (bei 
einer hinreichend großen Stichprobenmenge) nicht ergibt, dann hat das 
nichts mit bedingten Wahrscheinlichkeiten zu tun, sondern dann ist 
entweder rand() schlecht implementiert oder man hat sonst irgendeinen 
Fehler gemacht.
Gast #2511341
Lesenswert?

@ Karl Heinz

Tatsache ist, das ich genau wie Du davon ausgehe, das die Ereignisse 
nicht kausal voneinander abhängen, sie also stochastisch unabhängig 
sind.

Mein Fehler war, das ich den Satz des TO
>Ja schon klar, aber die Chance, dass nach eine 1 noch eine 1 kommt
>sollte 50/50 sein, ist momentan bei mir aber eher 20/80...
so interpretiert habe, als wenn er die Wahrscheinlichkeit das zweimal 
die 1 hintereinander kommt mit der Häufigkeit des tatsächlichen 
Auftretens vergleicht. Da hat mich wohl das 20/80 verführt.

Soweit so gut.

Aber Dir ist auch ein Lapsus unterlaufen, wenn ich das richtig sehe. 
Alles nicht so einfach. Hab ich ja schon gesagt ;-)

>>Du redest von bedingten Wahrscheinlichkeiten.
>Den Fall haben wir hier aber nicht.
Denn den Fall der bedingten Wahrscheinlichkeit hat man, wann immer man 
will. Die Anwendung der Definitionsgleichung der bedingten 
Wahrscheinlichkeit ist nicht auf solche Fälle beschränkt in denen 
tatsächlich eine kausale, temporale oder sonstige Abhängigkeit zwischen 
den Ereignissen besteht.

Vielmehr kann man feststellen ob zwei Ereignisse stochastisch unabhängig 
sind indem man die Wahrscheinlichkeiten des nachfolgenden 
(abschliessenden Ereignisses mit der Wahrscheinlichkeit des 
Gesamtereignisses vergleicht. Anders ausgedrückt führen die Gleichungen 
für bedingte Wahrscheinlichkeit und die Wahrscheinlichkeit von als 
unabhängig angenommenen Ereignissen zum selben Ergebnis falls die 
Ereignisse tatsächlich unabhängig sind.

Korrigiere mich bitte, wenn ich da aus Deiner Sicht was falsch oder 
ungeschickt darstelle. Entweder war es ok so oder ich lerne wieder was 
(oder nochmal). :-) (C ist leichter)

Die Ereignisse scheinen in dem Fall des Threads hier jedenfalls nicht 
stochastisch unabhängig gewesen zu sein.
#2511615
Lesenswert?

Einen sehr guten Zufall erhält man, wenn man eine Nutzereingabe per 
Tastendruck hat. Diese ist dann völlig unabhängig vom CPU-Takt, mit dem 
man einen Timer hochzählt.
Dazu nimmt man dann ausnahmsweise den externen Interrupt, um den Timer 
als Zufallzahl auszulesen. Das Entprellen der Taste geschieht dann wie 
üblich im Timerinterrupt.


Peter
Gast #2515669
Lesenswert?

Nutzereingabe habe ich leider auch nicht.

Nachdem ich jetzt diverse PRNG ausprobiert habe und keinen vernünftig 
zum laufen gebracht habe hab ich mir 120 Zufallsbits am PC erzeugt, die 
in den EEPROM geschrieben und lasse einen Zähler laufen der bei jeden 
Start dafür sorgt, dass das nächste Bit aus dem Speicher genommen wird.
Funktioniert allemal besser als das was ich zuvor hatte :)
Persönliche Seite #2515851
Lesenswert?

Seife schrieb:
> Nutzereingabe habe ich leider auch nicht.
>
> Nachdem ich jetzt diverse PRNG ausprobiert habe und keinen vernünftig
> zum laufen gebracht habe hab ich mir 120 Zufallsbits am PC erzeugt, die
> in den EEPROM geschrieben und lasse einen Zähler laufen der bei jeden
> Start dafür sorgt, dass das nächste Bit aus dem Speicher genommen wird.
> Funktioniert allemal besser als das was ich zuvor hatte :)

Hallo Seife,

prima Idee.
wenn Du von Beginn an alle Randbedingungen auf den Tisch gelegt 
haettest, waeren wir schnelle dorthn gekommen ;-)

Aber genauso haettest Du bei jedem Start den Anfangswert des RND 
hochzaehlen koennen..... 120Byte wenige Speicher....und - mit meiner 
Routine bei nur 9 ASM Anweisungen immerhin 255 anstelle von 210 Werten 
erhalten.



Gruss

Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren