mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik TCNT0 % 6 für "Zufallszahl"


Autor: Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann setz halt den Vorteiler rauf, oder schreib zahl=(TCNT0>>1)%6.

Gruß,
Magnetus

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;)

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-)

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum benutzt dui nicht die random funktion?
ums wirklich zufällig zu machen kännte man die beim ersten Tastendruck 
mit der TCNT initialisieren

Autor: Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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... ;)

Autor: Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 
:(

Autor: hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwischen Timer starten und stoppen dürfte eine gerade
Anzahl von Taktzyklen liegen. Dadurch kann die 1 nie erscheinen.

hans

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Bully (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Bully (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.