PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Zufalls Tabelle (Atmega32)



Lars Schütz
27.01.2013, 20:22
Hallo,
ich möchte gerne eine Zufalls Tabelle, für einen Led Cube erzeugen.
Es sollen also immer zufällig irgendwelche Led's leuchten.
Meine Idee ist diese:


$regfile = "m32def.dat"
$hwstack = 32
$swstack = 10
$framesize = 40
$crystal = 8000000
'----------------------------------------------------------------------------------
Ddra = 11111111 'Ausgänge setzten
Ddrb = 00001111
Ddrc = 01111111
Ddrd = 10000000
'----------------------------------------------------------------------------------
'Variablen setzen
Dim Bild As Word
Dim Maxbild As Word
Dim Ebene As Byte
Dim Dauer As Byte
Dim Temp As Word
Dim Datentabelle As Word
Dim I As Byte
Dim Random(64) As Byte
Dim Dauer2 As Word
'---------------------------------------------------------------------------------
'Hauptschleife

Do
Maxbild = 12 'Maxbild = Anzahl der Bilder
Maxbild = Maxbild - 1 'Maxbild -1, da er bei 0 anfängt zu zählen

For Bild = 0 To Maxbild 'Bilder ablaufen

For Dauer = 0 To 27 'Dauer des Bildes

For Ebene = 0 To 3 'Anzahl der Ebenen (bei mir 4)
'----------------------------------------------------------------------------------
Datentabelle = Bild * 16 'Berechnen der Tabelle
Temp = Ebene * 4
Datentabelle = Datentabelle + Temp
'---------------------------------------------------------------------------------
'Ausgabe des Bildes
Porta = Lookup(datentabelle , Muster)
Datentabelle = Datentabelle + 1
Portb = Lookup(datentabelle , Muster)
Datentabelle = Datentabelle + 1
Portc = Lookup(datentabelle , Muster)
Datentabelle = Datentabelle + 1
Portd = Lookup(datentabelle , Muster)

Waitms 5
'----------------------------------------------------------------------------------------
If Ebene = 3 Then
Exit For
End If
Next Ebene
If Dauer = 27 Then
Exit For
End If

Next Dauer
If Bild = Maxbild Then
Exit For
End If
Next Bild
'Ende der vor eingestellten Bilder

'--------------------------------------------------------------------------------------------
'Anfang Zufalls Schleife
For Dauer2 = 0 To 1000 'Ein Vorläufiger Wert, wie lang die Zufalls schleife laufen soll
'-----------------------------------------------------------------------------------------
'Dem Array wird ein Zufalls bit übergeben
For I = 1 To 64
Random(i) = Rnd(1)
If I = 64 Then Exit For
Next I
'---------------------------------------------------------------------------------------
'Ausgabe des Bildes
For Dauer = 0 To 27

For Ebene = 0 To 3
Temp = Ebene * 4

Porta = Lookup(temp , Rand)
temp = temp + 1
Portb = Lookup(temp , Rand)
Temp = Temp + 1
Portc = Lookup(temp , Rand)
Temp = Temp + 1
Portd = Lookup(temp , Rand)

If Ebene = 3 Then Exit For
Next Ebene
If Dauer = 27 Then Exit For
Next Dauer
If Dauer2 = 1000 Then Exit For
Next Dauer2
'Ende der Zufalls schleife
'------------------------------------------------------------------------------------------
Loop

End
'---------------------------------------------------------------------------------------------
'Hier nun mein Problem, gibt es eine Möglichkeit die Variablen aus dem Array so in die Tabelle zu geben?
Rand:
Data &B&RANDOM(1)0000000 , &B00000001 , &B00001000 , &B00000000
Data &B00000000 , &B00000000 , &B00010000 , &B00000000
Data &B00000000 , &B00000000 , &B00100000 , &B00000000
Data &B00000000 , &B00000000 , &B01000000 , &B00000000
'-------------------------------------------------------------------------------------------



Muster: 'Bilder die Ablaufen sollen
$include "muster.txt"


Was meint ihr?
Ist es möglich das so irgendwie so hin zu bekommen, oder bin ich auf dem Holzweg?

Gruß
Lars

Thomas E.
28.01.2013, 03:38
Wenn ich das richtig verstanden habe, willst du zur Laufzeit ein Array mit Zufallszahlen füllen und anschließend die Werte aus dem Array in eine Data-Table füllen. Eine Datentabelle kannst du aber nur mit festen Werten füllen, da sich diese im Flash befindet. Da allerdings bei der Verwendung der Funktion Random sowieso immer die gleichen Zufallszahlen herauskommen lassen diese sich auch vor der Compilierung in die Datentabelle schreiben. Hintergrund dazu: Random wird während dem Compilieren aus einem zufälligen Seed berechnet und die Werte fest auf den µC gebrannt. Also wird nach jedem Einschalten immer wieder die gleiche Folge an Mustern auf deinem Cube zu sehen sein.

Wenn du echte Zufallswerte wünschst, kannst du die einfach aus einem offenen AD-Eingang erzeugen, oder komplizierter, das Rauschen einer Diode auswerten. Auch der Weg über eine Systemzeit ist möglich. Aber selbst wenn du echte Zufallswerte erzeugen würdest, in eine Tabelle im Flash kommen die auf keinem Weg.

So, ich hoffe ich habe mich jetzt nicht verhadert, ist schon spät/früh heute... :)

021aet04
28.01.2013, 08:25
Ich habe vor kurzem auch das gleiche Problem gehabt das ich eine zufällige Reihenfolge benötigt habe.
In der Firma werden Motoren (bis zu 10) zufällig angesteuert (immer nur einer). Die Laufzeit der Motoren sollte auch zufällig sein.

Ich habe auch länger gesucht und auch verschiedene Möglichkeiten gefunden (u.A. auch den ADC aktivieren und nicht beschalten bzw mit einer "Antenne" versehen). Habe mich aber für einen Chaosgenerator entschieden, da es immer funktionieren soll (Industrie). Noch ist es in Planung, der Chaosgenerator funktioniert aber auf dem Breadboard schon. Habe diese Schaltung verwendet http://physics.mercer.edu/hpage/vilnius.html
Statt R3 habe ich ein 1k Poti eingebaut da es nicht gleich funtkioniert hat. Mit dem Oszi habe ich es dann so eingestellt bis ich eine zufällige Schwingung hatte (Wenn man es falsch einstellt wird es eher ein Sinus oder man hat keine Schwingung). Dieses Signal wertest du mit dem ADC aus (achte aber das du auch negative Spannungen hast).

Du kannst die Schaltung mit z.B. LTSpice simulieren. Habe ich zum Testen auch so gemacht.

MfG Hannes

Lars Schütz
28.01.2013, 17:50
Hallo,

ich habe es mir fast gedacht, das es so nicht zu realisieren ist :(.
Da die Platine schon soweit fertig ist, werde ich erstmal auf ein Zufalls Programm verzichten.
Ich werde eure Vorschläge bei meinem nächsten Cube mit einbeziehen.
Habt Vielen Dank für eure mühe

Gruß
Lars

Thomas E.
30.01.2013, 03:33
ich habe es mir fast gedacht, das es so nicht zu realisieren ist :(.
Da die Platine schon soweit fertig ist, werde ich erstmal auf ein Zufalls Programm verzichten.
Ich werde eure Vorschläge bei meinem nächsten Cube mit einbeziehen.
Habt Vielen Dank für eure mühe

Wenn du einen offenen AD-Eingang hast, könntest du diesen Einlesen und die daraus resultierenden Werte als Seed benutzen. Alternativ bleibt noch eine Zeit übrig. Also Möglichkeiten gibt es noch. :)

Lars Schütz
30.01.2013, 20:12
Und wie soll ich das Zufallsprogramm realisieren, ohne Datentabellen?
Bin noch Anfänger in Basic...

Gruß Lars

Thomas E.
31.01.2013, 03:15
Und wie soll ich das Zufallsprogramm realisieren, ohne Datentabellen?
Bin noch Anfänger in Basic...
Statt einer Tabelle kannst du einfach ein Array verwenden.
Siehe auch: Bascom Tabellen (RN-Wissen) (http://www.rn-wissen.de/index.php/Bascom_Tabellen#Tabellen_im_SRAM_.2F_ERAM_.2F_XRAM )

Klebwax
31.01.2013, 07:44
Kann man statt einer Tabelle nicht einfach die RND Funktion verwenden?

MfG Klebwax

Thomas E.
31.01.2013, 11:42
Kann man statt einer Tabelle nicht einfach die RND Funktion verwenden?
Soweit waren wir oben schon! RND erzeugt keine echten Zufallszahlen, der Threadersteller will aber welche. Mit RND würden nach dem Start immer wieder diesselbe Musterfolge auftreten.

radbruch
31.01.2013, 14:35
Hallo


RND erzeugt keine echten ZufallszahlenIch mag ja nicht gern klugscheissen, aber "echte" Zufallszahlen gibt es nicht!

Gruß

mic

Klebwax
31.01.2013, 16:01
Soweit waren wir oben schon! RND erzeugt keine echten Zufallszahlen, der Threadersteller will aber welche. Mit RND würden nach dem Start immer wieder diesselbe Musterfolge auftreten.

Das ist schon klar, es ging mir eher um die Frage:

Und wie soll ich das Zufallsprogramm realisieren, ohne Datentabellen?

Eine (pseudo)Zufallsfolge liefert typischerweise eine Funktion, ohne Tabelle. Nur den Startwert muß man sich durch einen von extern geholten Wert bestimmen. In C kann man den random seed einstellen, ich weiß nicht ob das in Basic auch so geht. Die wirkliche Frage ist eher, wo bekomme ich bei einer gegebenen Hardware einen Startwert her. Wenn es eine Starttaste gibt, kann man die Zeit vom Einschalten bis zum Drücken der Taste nehmen. Ob ein offener ADC Eingang etwas passendes liefert, muß man ausprobieren. Dann mit diesem Wert den random seed einstellen, oder wenn das nicht geht, sooft wie diese Zahl vorgibt RND aufrufen und das Ergebniss verwerfen. Ab dann ist das Muster sicher nicht mehr zu erkennen. Besser als eine Tabelle mit 16 Einträgen ist das allemal.

MfG Klebwax

Thomas E.
02.02.2013, 03:32
Ich wollte gerade aus Interesse heraus eine Funktion schreiben, die einen Zufallswert liefert und bin dabei auf etwas interessantes in der Bascom-Hilfe gestoßen:

The RND() function returns an Integer/Word and needs an internal storage of 2 bytes. (___RSEED). Each new call to Rnd() will give a new positive random number.

Notice that it is a software based generated number. And each time you will restart your program the same sequence will be created.

You can use a different SEED value by dimensioning and assigning ___RSEED yourself:

Dim ___rseed as word : ___rseed = 10234

Dim I as word : I = rnd(10)

When your application uses a timer you can assign ___RSEED with the timer value. This will give a better random number.



Also kann man den Seed von der RND-Funktion direkt mit einem Timerwert laden, was für die Anwendung des Threadstarters einen ausreichenden Zufall darstellt.
:)

radbruch
02.02.2013, 07:14
Also kann man den Seed von der RND-Funktion direkt mit einem Timerwert ladenBei einem Programm ohne Verzweigungen (z.B. direkt nach der Initialisierung) ist der Timerwert immer gleich, weil sich auch der Timer am Kontrollertakt orientiert!

Thomas E.
03.02.2013, 06:35
Bei einem Programm ohne Verzweigungen (z.B. direkt nach der Initialisierung) ist der Timerwert immer gleich, weil sich auch der Timer am Kontrollertakt orientiert!
Man darf eben nicht immer zur gleichen Zeit den Wert aus dem Timmer laden.

Lars Schütz
04.02.2013, 21:48
Nabend,

ich werde morgen oder übermorgen mal ein wenig mit euren Ideen herum experimentieren.
Ich könnte den Timer ja evtl. nach dem 50 Bild laden lassen, oder auch noch später (habe 7000 Bilder :D), was wäre Sinnvoll?
Den Timer früher oder später Initialisieren?

Mit freundlichem Gruß
Lars

radbruch
04.02.2013, 22:08
Ich könnte den Timer ja evtl. nach dem 50 Bild laden lassen,...Die Bilder haben eine feste Größe, die Ladezeit ist deshalb immer gleich und der Timerwert, und damit auch der Startwert des Zufallgeneratores, ist dann auch immer gleich. Es muss irgendwas sein das nicht mit dem Takt des Kontrollers läuft, z.B. ein externer Trigger über die Ladekurve eines Kondensators. Gut finde ich den Ansatz mit der Taste-gedrückt-Zeit als Startwert.

Gruß

mic

Lars Schütz
04.02.2013, 22:38
Gut finde ich den Ansatz mit der Taste-gedrückt-Zeit als Startwert.

Leider habe ich keinen Start Taster...
Muss ich unbedingt ein positives Signal am ADC Eingang haben oder kann dies auch von der Masse der Schaltung sein?
Ansonsten kann ich noch multigeplexte Ausgänge vom Atmega 32 anbieten.
Hier mal die Platine(An X1 wir ein Einschalter angeschlossen), glaube aber das nützt nichts...
24428

radbruch
05.02.2013, 07:01
Hallo

Mit einer LED-Matrix kann man auch die Helligkeit der Umgebung messen. Das wäre ein prima Startwert für den Zufallsgenerator:


http://www.youtube.com/watch?v=MhpReBX-s7w
(Video aus https://www.roboternetz.de/community/threads/50954-Ping-Pong-umprogrammieren?p=495721&viewfull=1#post495721)

https://www.roboternetz.de/community/threads/51672-LED-als-Sensor
https://www.roboternetz.de/community/threads/35322-LED-Sensor-am-RP6

Gruß

mic

Lars Schütz
06.02.2013, 14:27
So hier ist mein Code:


$regfile = "m32def.dat"
$hwstack = 32
$swstack = 10
$framesize = 40
$crystal = 8000000
'----------------------------------------------------------------------------------
Config Porta = Output
Config Portb = Output
Config Portc = Output
Config Portd = Output
'----------------------------------------------------------------------------------
'Variablen setzen
Dim Bild As Word
Dim Maxbild As Word
Dim Ebene As Byte
Dim Dauer As Byte
Dim Temp As Word
Dim Datentabelle As Word
Dim Dauer2 As Byte
Dim Dauer3 As Integer
Dim Dauer4 As Byte
Dim __rseed As Word
Dim Rand(64) As Byte
Dim I As Byte
Dauer2 = 27
'---------------------------------------------------------------------------------
'Hauptschleife

Do
Maxbild = 199 'Maxbild = Anzahl der Bilder
Maxbild = Maxbild - 1 'Maxbild -1, da er bei 0 anfängt zu zählen

For Bild = 0 To Maxbild 'Bilder ablaufen

For Dauer = 0 To Dauer2 'Dauer des Bildes

For Ebene = 0 To 3 'Anzahl der Ebenen (bei mir 4)
'----------------------------------------------------------------------------------
Datentabelle = Bild * 12 'Berechnen der Tabelle
Temp = Ebene * 3
Datentabelle = Datentabelle + Temp
'---------------------------------------------------------------------------------
'Ausgabe des Bildes
Porta = Lookup(datentabelle , Muster)
Datentabelle = Datentabelle + 1
Portb = Lookup(datentabelle , Muster)
Datentabelle = Datentabelle + 1
Portd = Lookup(datentabelle , Muster)

Waitms 5
'----------------------------------------------------------------------------------------
If Ebene = 3 Then
Exit For
End If
Next Ebene
If Dauer = 27 Then
Exit For
End If

Next Dauer
If Bild = 44 Then
Dauer2 = 4
Elseif Bild = 109 Then
Dauer2 = 27
Elseif Bild = 112 Then
Dauer2 = 12
Elseif Bild = 140 Then
Dauer2 = 27
End If
If Bild = Maxbild Then
Exit For
End If

Next Bild
'Ende der vor eingestellten Bilder
'-------------------------------------------------------
'Anfang Zufallsschleife

For Dauer3 = 0 To 5000 'vorläufiger Wert wie lange die schleife laufen soll

__rseed = Pina.1 'dieser Pin soll also den Zufallswert geben, er ist allerdings auch ein Port für eine Led, geht das?
For I = 1 To 64 'Zufallswerte werdem dem Array übergeben
Rand(i) = Rnd(1)

If I = 64 Then Exit For
Next I

For Dauer4 = 0 To 27 'Dauer eines Bildes

For Ebene = 0 To 3 'Multiplex

If Ebene = 0 Then
Porta.0 = Rand(64)
Porta.1 = Rand(1)
Porta.2 = Rand(2)
Porta.3 = Rand(3)
Porta.4 = Rand(4)
Porta.5 = Rand(5)
Porta.6 = Rand(6)
Porta.7 = Rand(7)
Portb.0 = Rand(8)
Portb.1 = Rand(9)
Portb.2 = Rand(10)
Portb.3 = Rand(11)
Portd.7 = Rand(12)
Portd.6 = Rand(13)
Portd.5 = Rand(14)
Portd.4 = Rand(15)
Portd.3 = 0
Portd.2 = 0
Portd.1 = 0
Portd.0 = 1
Elseif Ebene = 1 Then
Porta.0 = Rand(16)
Porta.1 = Rand(17)
Porta.2 = Rand(18)
Porta.3 = Rand(19)
Porta.4 = Rand(20)
Porta.5 = Rand(21)
Porta.6 = Rand(22)
Porta.7 = Rand(23)
Portb.0 = Rand(24)
Portb.1 = Rand(25)
Portb.2 = Rand(26)
Portb.3 = Rand(27)
Portd.7 = Rand(28)
Portd.6 = Rand(29)
Portd.5 = Rand(30)
Portd.4 = Rand(31)
Portd.3 = 0
Portd.2 = 0
Portd.1 = 1
Portd.0 = 0
Elseif Ebene = 2 Then
Porta.0 = Rand(32)
Porta.1 = Rand(33)
Porta.2 = Rand(34)
Porta.3 = Rand(35)
Porta.4 = Rand(36)
Porta.5 = Rand(37)
Porta.6 = Rand(38)
Porta.7 = Rand(39)
Portb.0 = Rand(40)
Portb.1 = Rand(41)
Portb.2 = Rand(42)
Portb.3 = Rand(43)
Portd.4 = Rand(44)
Portd.5 = Rand(45)
Portd.6 = Rand(46)
Portd.7 = Rand(47)
Portd.3 = 0
Portd.2 = 1
Portd.1 = 0
Portd.0 = 0
Elseif Ebene = 3 Then
Porta.0 = Rand(48)
Porta.1 = Rand(49)
Porta.2 = Rand(50)
Porta.3 = Rand(51)
Porta.4 = Rand(52)
Porta.5 = Rand(53)
Porta.6 = Rand(54)
Porta.7 = Rand(55)
Portb.0 = Rand(56)
Portb.1 = Rand(57)
Portb.2 = Rand(58)
Portb.3 = Rand(59)
Portd.4 = Rand(60)
Portd.5 = Rand(61)
Portd.6 = Rand(62)
Portd.7 = Rand(63)
Portd.3 = 1
Portd.2 = 0
Portd.1 = 0
Portd.0 = 0
End If


If Ebene = 3 Then Exit For
Next Ebene
If Dauer4 = 27 Then Exit For
Next Dauer4
If Dauer3 = 5000 Then Exit For
Next Dauer3
'Ende Zufall
Loop

End



Muster: 'Bilder die Ablaufen sollen
$include "muster.txt"

Leider leuchtet in der Zufallsschleife nie eine Led
Was ist falsch?

Gruß Lars