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:
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
Führ doch in der Hauptschleife immer wieder neue Messungen durch (plus
eine Wartezeit um die Ergebnisse auch sehen zu können) und schalte die
LEDs entsprechend an und aus. Dann siehst du leichter ob das unterste
Bit immer 0 ist.
a1 schrieb:> Seife schrieb:>> PORTB = (1<<PB3);>>> PB4
Was willst du mir damit sagen?
spess53 schrieb:> Hi>> Wenn ich das richtig sehe, machst du nur eine Messung.>> MfG Spess
Ja ich brauch ja auch nur genau eine 0 oder 1. Also es soll eine der
Beiden LEDs angehen.
Chris Herch schrieb:> Führ doch in der Hauptschleife immer wieder neue Messungen durch (plus> eine Wartezeit um die Ergebnisse auch sehen zu können) und schalte die> LEDs entsprechend an und aus. Dann siehst du leichter ob das unterste> Bit immer 0 ist.
Für leider auch nur dazu, dass die LED am PB4 dauerblinkt... :(
Seife schrieb:> a1 schrieb:>> Seife schrieb:>>> PORTB = (1<<PB3);>>>>>> PB4>> Was willst du mir damit sagen?Seife schrieb:> Ja ich brauch ja auch nur genau eine 0 oder 1.
Wenn Du dort PB4 einsetzt, hast Du doch an PB4 eine 1 (5V) oder eine 0
(0V)
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.
Hallo,
muss man nicht auch den ADCH Wert lesen, damit die Umwandlung richtig
funktioniert. Ich meine ich hätte da mal sowas gelesen ...
Viele Grüße
lboppi
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
Hi
>Zum Debuggen: Ich würde ja erstmal versuchen die Werte insgesamt>anzuzeigen
Erst mal überprüfen, ob beide LEDs wirklich leuchten. Also mal statisch
einschalten.
MfG Spess
>> 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
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
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"
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?
> 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.
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!
>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...
Rein statistisch gesehen können per Zufall auch tausend
1er kommen.
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.
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.
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.
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.
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.
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
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.
@ 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.
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
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 :)
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