PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rnd - Wo ist der Seed Befehl?



Isator
11.03.2006, 16:17
Hallo,

ich hoffe ihr findet die "Überschrift" genauso kurios wie ich.

Ich wollte gerade mal ein Programm schreiben was per Zufall irgendwelche Led's an und aus macht.
Das habe ich halt mit x = Rnd(8 ) gelöst - Da aber wie erwartet immer die gleiche Reihenfolge auftrat habe ich in der Hilfe von RND() geguckt und einen Hinweis auf den Seed Befehl gefunden - Jedoch gibt es keine Erklärungen zum Seed Befehl!!! :(

Ich habe einfach mal so Sachen wie Seed = Zeit probiert - Wobei Zeit die Zeit war die seit dem starten des Programmes vergangen war ist.
Jedoch wurde Seed nicht einmal als Befehl blau markiert. Auch nicht Rseed und sonstige Möglichkeiten die in der Hilfe bei RND() standen.

Weiß jemand ob es den Befehl überhaupt noch gibt (lol?!?!) oder ob er eventuel umbenannt wurde in Bascom.

MfG
Isator


P.S.: Ich benutze Bascom Version 1.11.7.9

Dirk
11.03.2006, 16:46
Hallo Isator,

sieh dir das RND-Beispiel in der Bascom-Doku mal genauer an:
Das mit "seed" ist eine System-Variable namens ___rseed (beachte die Unterstriche!).
Mit ihr kann man einen neuen Anfangswert setzen:
Dim ___rseed As Word
___rseed = 10234

Statt 10234 kann man andere Werte nehmen (Timer, irgendein Sensor ...).

Gruß Dirk

Isator
11.03.2006, 17:36
Hi,

zeigt Bascom System Variablen nicht farbig an? (Schade eigentlich)

Hast du mal ein Beispiel für den richtigen Umgang mit __rseed - Ich komme jetzt nur so weit das immer alle leuchten.

Danke für die Erklärung!

MfG

Ratber
11.03.2006, 20:52
Egal was du als Wert für Rseed angibst du bekommst nur eine weitere Pseudozufällige Sequenz aufgetischt.

Schreib doch einfach das Beispiel ab in dein Programm und probiers aus.
so schwer zu verstehen ist das nun auch nicht.


Wenn du echte Zufallssequenzen willst dann nim nen freien AD-Eingang und häng nen kleinen Rauschgenerator drann (2 Transen und etwas Hühnerfutter) dann haste einen relkativ echten Zufallsgenerator.

Isator
12.03.2006, 13:55
Hi,

ich brauche keinen "perfekten" Zufall. Aber in dem Umgang mit __rseed stelle ich mich echt dämlich an...

Hiermal ein Codeschnipsel:


Dim __rseed as Integer
Do
__rseed = Zeit
x = Rnd(8 )
Print X
Loop



Wobei Zeit die Schleifen Durchgänge in der Hauptschleife sind.

Was stimmt bei dem Code nicht?

Ratber
12.03.2006, 14:20
Ganz einfach,es ist immernoch eine feste Folge denn wenn das Programm startet dann ist der Schleifenzähler "Zeit" immer der gleiche und damit auch die Seed's für den zufallsgenerator.

Für einen annähernd zufälligen Zufallsgenerator (Ich weiß,kleiner Scherz.Konnt ich mir nicht verkneifen) ist eine "unberechenbare" komponennte nötig.

Hast du den nichts in der Schaltung über dessen Einschaltzustand der Controller nicht 100% bescheidt weiß ?

Zb. nen Poti für ne Geschwindigkeitsreglung ?

Isator
12.03.2006, 14:25
Noch nicht - Das einzige was dran hängt sind 2 Motoren bis jetzt. Aber ich habe leider keinen Poti den ich dazwischen klemmen könnte. Ich muss demnächstmal ne Bestellung aufgeben.
Oder kann ich eventuell den Quarz benutzen?!

Ratber
12.03.2006, 17:56
Du meinst einfach den Xtal1/2 an nen AD-Port klemmen und so ein quasi zufälliges Signal zu bekommen ?

Is ne Möglichkeit aber damit destabiliserst du den Schwingkreis.

Man kann besser eine andere Resource des Controllers anzapfen aber dafür müßte ich mal wissen welchen Controller du nutzen willst.


Wie gesagt,wenn ein Taster im Spiel wäre nach dessen Betätigung der Zufallswert fällig ist wäre das kein akt.

Am Besten wäre wie gesagt ein Rauchgenerator mit ner Zehnerdiode.

Eine weitere Möglichkeit ist das du den Controller mit nem absichtlich instabilen RC-Oszillator betreibst.
Also als Widerstand nen PTC/NTC oder Fotowiderstand und einen möglichst billigen Kondensator.

Wenn du den Fotowiderstand in der nähe einer oder mehrerer der LED's unterbringen kannst dann reicht sogar der alleine.

Noch ne Möglichkeit:

Den AD-Wandler absichtlich nicht entstören (Kein 100nF,kein Elko,Eingang absichtlich in der Nähe von störquellen) und die Eingangsleitung möglichst lang lassen um sozusagen eine antenne zu schaffen.
Die Werte sollten jetzt recht gut fluktuieren (1-3 bit oder vieleicht auch mehr).
Normalerweise bekommen die Leute das immer unbeabsichtig hin also warum nicht mal mit Absicht ? :wink:



Such dir was aus.

Dirk
12.03.2006, 17:58
Hallo Isator,

ich würde den "Startwert" der Pseudozufallszahlen nicht bei jeder RND-Abfrage setzen, sondern nur am Anfang und evtl. vor einem größeren neuen Block von Zufallszahlen.
Für das ___rseed kann man den Timer nehmen, wenn die Stelle im Programm, wo ___rseed gesetzt wird, nicht immer nach dem Booten genau gleich ist (d.h. vom Booten bis zum Aufruf vergeht meist genau die selbe Zeit!). Man kann sich damit helfen, dass man z.B. den User eine Taste drücken läßt, bevor ___rseed mit dem Timer geladen wird.
Alternativ kann man z.B. einen Helligkeitssensor nehmen oder einen Geräuschsensor (oder daraus irgendeine Rechenformel, z.B. Helligkeit * Temperatur * Pferdemist - Wettervorhersage...).

Also so:


Dim __rseed as Integer

__rseed = Zeit

Do
x = Rnd(8 )
Print X
Loop


Gruß Dirk

Isator
12.03.2006, 18:21
Mh genau so habe ich es ja im Grunde. Er mist die Schleifendurchgänge in bis eine Taste gedrückt wird und den wert nimmt er dann für __rseed.

Aber irgendwie muss ich __rseed auch dazwischen noch tauschen können weil, man sieht bei 8 Lampen dann doch ziemlich schnell das Muster. Ich müsste also zwischen durch wegenmeiner die alten Schleifedurchgänge* die neuen schleifengänge nehmen, aber irgendwie bleibt es trotzdem gleich.

MfG

P.S: Ich habe mal __Rseed auf 2 und danach auf 3 gesetzt. Es blinken in beiden Fällen die gleichen LEd's in der gleichen Reihenfolge - Irgendwas stimmt mit __Rseed wohl doch nicht Oo

Ratber
12.03.2006, 18:31
Mh genau so habe ich es ja im Grunde. Er mist die Schleifendurchgänge in bis eine Taste gedrückt wird und den wert nimmt er dann für __rseed.

Also haste doch ne Taste zur verfügung.

Ja dann Timer starten und laufen lassen.
Wenn die Taste gedrückt wird mit dem Timerwert den Rseed füttern.
Danach RND(irgendwas) und schon haste deinen Zufallswert.

Hier mal ein Codebeispiel wie man es zuhauf im Web findet.


$regfile = "2313def.dat"
$crystal = 4000000
Config Portb = Output
Portb.5 = 0
Config Pind.1 = Input
Dim Z As Byte
Dim ___rseed As Word

Config Timer0 = Timer , Prescale = 1
Enable Timer0
Start Timer0

Do
Debounce Pind.1 , 1 , Generator , Sub
Loop

Generator:

'Blink-Blink...

Portb = 0

___rseed = Timer0
Z = Rnd(100)
***Hier machste dann was aus dem Wert******
Return

SprinterSB
13.03.2006, 09:57
Sehr gut geeignet als Seed ist bei AVR uninitialisierter SRAM-Inhalt, und dazu gehören auch die 32 Register :-)

Isator
13.03.2006, 14:24
Hi,
habe das Programm jetzt mal so übernommen wie du es da stehen hast. bis auf meine Board spezifischen Änderungen(Ports, Frequenz, ...)

Aber trotzdem habe ich JEDESMAL das exakt gleiche Muster!!!

Ich habe es ja schonmal geschrieben das egal welchen Wert ich für __Rseed nun eintrage das Ergebnis von RND() das Gleiche war.
Woran liegt das...?!!?! ich bin echt ratlos..


MfG

Ratber
13.03.2006, 15:31
Mit wem redest du ?

Dirk oder Meinereiner ?

Dirk
13.03.2006, 16:51
Hallo Isator,


Aber trotzdem habe ich JEDESMAL das exakt gleiche Muster!!!

Obwohl es ja nur Pseudo-Zufallszahlen sind, dürftest du ein "Muster" beim Aufleuchten deiner LEDs nicht erkennen können. So gut sind sie immerhin, dass sich die Sequenz nicht so schnell wiederholt, dass du das erkennen könntest.

Da muss was anderes sein, was dir die Suppe versalzt.

Stell mal das ganze Prog rein!

Gruss Dirk

Isator
13.03.2006, 17:29
Hi Dirk,
ich muss sofort zum Training, habe deshalb nicht so viel Zeit. Ich stell das Programm morgen rein.
Also er erzeugt bei mir ja 6 Zahlen. Diese Zahlen entsprechen halt den Lampen und das Muster erkenne ich schon sehr deutlich. Ich kopier morgen auch nochmal die Zahlen die er generiert. Ich lasse sie nämlich immer auf den PC übertragen.

MfG

Ratber
13.03.2006, 17:42
Anscheinend redet er nicht mit jedem :-$

Isator
14.03.2006, 14:07
Hi,

@ Ratber: Sry ^^ Eigentlich spreche ich nie jemanden direkt an. Schließlich möchte ich die Community erreichen. Ich hoffe du bist nicht zu sehr gekränkt ;)

So hiermal das Programm:



Do
Taste = Tastenabfrage()

If Taste <> 0 Then

Select Case Taste
Case 1
Call Licht
Case 2
Call Musik
Case 3
__rseed = Zeit
Call Zufall
Case 4
__rseed = Zeit
Call Motor
Case 5
Call Test
End Select

End If

Zeit = Zeit + 1
Loop

[...]
Sub Zufall
Config Portc = Output

Do



X = Rnd(6)
Portc.6 = 1
Portc.7 = 1

Portc.x = 0
Waitms 500
Portc.x = 1
Zeit = Zeit + 1
Print X
Loop
End Sub


Die anderen Subs habe ich mal rausgelassen.


MfG

Ratber
14.03.2006, 17:05
@ Ratber: Sry ^^ Eigentlich spreche ich nie jemanden direkt an. Schließlich möchte ich die Community erreichen. Ich hoffe du bist nicht zu sehr gekränkt

Nö,ich bin nicht gekränkt aber die Art zu diskutieren ist sehr irritierend.

Wie du oben siehst weiß man schnell nicht mehr welches Programm du getestet hast. :wink:


Zum Programm:

Du nutzt immernoch Statische Werte (Zeit) und hast deswegen die gleichen Werte beim Zufallsgenerator.

Nutz doch mal den Timer wie vorgeschlagen
Da die Zeit bis zum Tastendruck nicht definiert ist bekommmst du so deinen Zufallswert.

Dirk
14.03.2006, 17:27
Hallo Isator,

dein Prog scheint ja so ganz o.k.
Allerdings:
Du must ___rseed mit dem Timer laden (wie Ratber geschrieben hat).

Ich würde das dann nicht jedesmal neu machen, wenn in deinem Menue die Taste gedrückt wird, sondern am Anfang des Progs (nur nach dem 1. Tastendruck).

Gruß Dirk