Hallo zusammen, ich habe gerade ein kleines Denkproblem oder Programmierproblem oder wie auch immer: Ich nehme den Timer0 eines Attiny13 und lasse ihn munter im Prozessortakt von 0 bis 255 zählen. Irgendwann dazwischen drücke ich ne Taste und mache zahl=TCNT0%6 Eigentlich würde ich mir nun erwarten, dass die Variable zahl "zufällige" Werte zwischen 0 und 5 beinhalten sollte... Irgendwie kommt der Wert 1 aber gar nie vor... Danke schonmal!
Dann setz halt den Vorteiler rauf, oder schreib zahl=(TCNT0>>1)%6. Gruß, Magnetus
Interessant. Oder hast du auch eine Frage ;-) Theoretisch sollte es so gehen, davon abgesehen, dass die Zahlen 0 bis 3 eine höhere Wahrscheinlichkeit haben. Wie oft hast du das denn getestet. Auch wenn die Zahlen etwa gleich verteilt sind, kann es lange dauern, bis eine bestimmte Zahl 'gezogen' wird. Wie wird das Ergebnis ausgegeben? Wenn du zum Beispiel je nach Zahl Pins einschaltest (LED zum Beispiel), kannst du mal probieren, ob die Ausgabe richtig funktioniert oder ob eine LED nicht richtig angeschlossen ist. Aus den Informationen fällt mir jetzt nicht ein, woran das sonst liegen könnte.
Ich gebe das auf LEDs aus, ja. Habe so etwa 60 mal probiert, da sollte die Zahl 1 auf jeden Fall vorkommen. LEDs sind richtig dran. Von Hand kann ich die entsprechenden einschalten. Kanns am Vorteiler liegen? der Wert 0 kommt ja auch vor, es ist echt nur Wert 1 der nicht vorkommt. Das mit der Wahrscheinlichkeit, dass 0 bis 3 öfter vorkommen muss ich nochmal überdenken ;-) Edit: ah ok, wegen 252-255 Also noch nen overflow-compare bei 251 einbauen ;)
Mit Modulo kommen immer wieder die Zahlen 0,1,2,3,4,5, 0,1,2… Am Ende des Zählerregisters ist: 252%6=0 253%6=1 254%6=2 255%6=3 Das heißt, der letzte 'Zahlendurchlauf' wird angefangen, aber die Zahlen 4 und 5 nicht mehr erreicht. Aber das macht aber nicht viel aus. Mit 'auf jeden Fall' sollte man bei Zufallswerten vorsichtig sein, das gibt es beim Zufall nicht. Aber trotzdem sollte die 1 statistisch gesehen zehn mal vorgekommen sein. Das ist doch schon öfter. Kannst du vielleicht die Registerwerte direkt irgendwie ausgeben lassen? Wie geschrieben fällt mir so kein Grund für das Problem ein, außer, dass der Zufall dir einfach noch keine 1 geschenkt hat ;-)
warum benutzt dui nicht die random funktion? ums wirklich zufällig zu machen kännte man die beim ersten Tastendruck mit der TCNT initialisieren
ich finds auch ein wenig komisch. ich lade jetzt auf jeden fall beim Timer-Overflow-INT ne 4 ins timer-register, dann sollte das mit der Gleichverteilung ok sein ;-) Ja, ich finds auch komisch. hab sonst leider keine möglichkeit für ne ausgabe, ist ein attiny13. Ja, doofer Zufall... Wahrscheinlich gewinne ich auch deshalb nie was bei Wetten... ;)
Vlad Tepesch schrieb: > warum benutzt dui nicht die random funktion? > ums wirklich zufällig zu machen kännte man die beim ersten Tastendruck > mit der TCNT initialisieren Die würde schon etwa 75% vom attiny einnehmen, hatte ich davor mal drin :(
Zwischen Timer starten und stoppen dürfte eine gerade Anzahl von Taktzyklen liegen. Dadurch kann die 1 nie erscheinen. hans
Er hat nicht geschrieben, dass er den Timer anhält. Und da die 0 vorkommt, die 1 aber nicht, scheint es auch kein Problem mit dem Überlauf zu sein. Hast du mal versucht, den Modulowert zu ändern, einfach mal bis 2 oder sogar nur bis 1 zu zählen?
Dussel schrieb: > Er hat nicht geschrieben, dass er den Timer anhält. Und da die 0 > vorkommt, die 1 aber nicht, scheint es auch kein Problem mit dem > Überlauf zu sein. > > Hast du mal versucht, den Modulowert zu ändern, einfach mal bis 2 oder > sogar nur bis 1 zu zählen? genau, mein timer wird ganz am anfang gestartet und läuft ununterbrochen bis ans ende der zeit :-P das mit nem anderen modulo versuch ich jetzt mal...
Das Problem an dem Verfahren ist, dass der Zähler nicht "frei" läuft sondern mit dem selben Takt in dem die Befehle ausgeführt werden. Warum kann das zu Problemen führen? Einfaches Beispiel: wenn du den Zählerstand immer im Raster von 2 Befehlen ausliest, dann wirst du immer gerade oder immer ungerade Zahlen bekommen. Lösungsvorschläge: Zähler langsamer laufen lassen, Zähler nicht bei 256 sondern bei einer möglichst großen Primzahl zurücksetzen (CTC).
Andreas Schwarz schrieb: > Einfaches Beispiel: wenn du den > Zählerstand immer im Raster von 2 Befehlen ausliest, dann wirst du immer > gerade oder immer ungerade Zahlen bekommen. Ich glaube das war den Beteiligten prinzipiell klar. Hannes Jochriem schrieb: > Irgendwann dazwischen drücke ich ne Taste und mache > zahl=TCNT0%6 Die Frage war ja warum drückt er nie bei 1, bzw. könnte das durch etwas in seinem Programm verhindert werden. Aber vielleicht postet der TS ja mal sein ganzes Programm für die Experten. Damit diese nicht sowas wie "hängt evtl. ne Tastenentprellung am Timer0" (als Extrembeispiel) abfragen müssen. frank
frank schrieb: >> Zählerstand immer im Raster von 2 Befehlen ausliest, dann wirst du immer >> gerade oder immer ungerade Zahlen bekommen. Dann dürften aber überhaupt keine ungeraden Werte vorkommen. Was machst du in der Zeit wo nichts passiert? Sleep oder endlos schleife?
>Dann dürften aber überhaupt keine ungeraden Werte vorkommen.
In dem (einfachen) Beispiel nicht, aber in der Realität gibt es ja auch
Befehle mit anderen Längen. Die verhindern eine 1 nicht, können aber die
Wahrscheinlichkeit dafür stark verringern.
Dann währe noch die Frage ob du den Wert in einer In-Routine ausliest oder das Taster Input Register nur Pollst (was einiges erklären würde).
Wenn Du im Main den Taster abfragst, hast Du immer eine bestimmte Befehlsfolge die abläuft und da der Timer mit dem gleichen Takt läuft, sind bestimmte Timerwerte weniger wahrscheinlich oder können sogar ganz entfallen. Die Lösung ist ganz einfach, Du fragst die Taste nicht im Main ab, sondern im Timerinterrupt. Der Timerinterrupt zählt ne Variable 0..5 rum. Wird die Taste losgelassen, wird diese Variable gespeichert und angezeigt. Dann ist jeder Interrupt (fast) gleichlang und damit jede Zahl gleich wahrscheinlich, unabhängig vom Main. Will man es exakt gleichlang machen, nimmt man einige Takte früher einen Compareinterrupt der die CPU idle setzt. Dann hat man keine unterschiedliche Interruptlatenz mehr. Peter
Andreas Schwarz schrieb: > Das Problem an dem Verfahren ist, dass der Zähler nicht "frei" läuft > sondern mit dem selben Takt in dem die Befehle ausgeführt werden. Warum > kann das zu Problemen führen? Einfaches Beispiel: wenn du den > Zählerstand immer im Raster von 2 Befehlen ausliest, dann wirst du immer > gerade oder immer ungerade Zahlen bekommen. Er wird aber beim Tastendruck ausgelesen und nicht einfach alle n Takte, und dadurch kommt das Zufallselement ins Spiel. > Zähler nicht bei 256 sondern bei einer möglichst großen Primzahl > zurücksetzen (CTC). Dann aber bitte eine, die ein Vielfaches von 6 ist ;-)
Peter Dannegger schrieb: > Wenn Du im Main den Taster abfragst, hast Du immer eine bestimmte > Befehlsfolge die abläuft und da der Timer mit dem gleichen Takt läuft, > sind bestimmte Timerwerte weniger wahrscheinlich oder können sogar ganz > entfallen. Sprichst du von der Entprellung, oder wo soll da eine Abhängigkeit vom Timerwert herkommen?
Rolf Magnus schrieb: > Peter Dannegger schrieb: >> Wenn Du im Main den Taster abfragst, hast Du immer eine bestimmte >> Befehlsfolge die abläuft und da der Timer mit dem gleichen Takt läuft, >> sind bestimmte Timerwerte weniger wahrscheinlich oder können sogar ganz >> entfallen. > > Sprichst du von der Entprellung, oder wo soll da eine Abhängigkeit vom > Timerwert herkommen? Das könnte natürlich sein, dass das alles von der Entprellung abhängt. Ich verwende dein debounce-Makro, Peter, und frage es in der Main ab: while (1) { if(debounce()) { for (i=0; i<20; i++) { wuerfel(i%6); long_delay(100); } for (i=5; i>0; i--) { wuerfel(i); long_delay(500); } zahl = TCNT0%6; wuerfel(zahl); for (i=0; i<3; i++) { long_delay(350); PORTB |= 0b00111100; long_delay(350); wuerfel(zahl); } } } return 0; } Ist glaub ich nicht ganz aktuell mit dem von gestern, hatte Probleme mit dem Sync ;)
Rolf Magnus schrieb: > Sprichst du von der Entprellung, oder wo soll da eine Abhängigkeit vom > Timerwert herkommen? Nein. Die Mainloop läuft ja nicht in 0 CPU-Takten, sondern benötigt eine gewisse Zeit. Würde sie z.B. 256 Zyklen benötigen, dann liest Du immer den gleichen Timerwert. Benötigt sie eine gerade Anzahl, dann kriegst Du auch nur gerade Timerwerte. Je nach Zykluszahl der Mainloop hast Du also ne Abhängigkeit, von Zufall kann dann keine Rede mehr sein. Im Timerinterrupt hast Du dagegen immer die gleiche Zeitdauer pro Würfelwert. Ich würde in diesem speziellen Fall auch garkeine übliche Entprelling vorsehen. Zu Anfang eine Totzeit (~500ms), ehe der Würfel losrollt und nach dem Loslassen eine Sperrzeit (~2s) gegen Schummeln. Peter
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.