www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zufallszahlen erzeugen


Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will eine Zufallszahl erzeugen und die auf dem Port darstellen.
Was im DEV c++ noch funktionier (natürlich habe ich die Ausgabe auf dem 
Bildschirm) macht im AVR Studio Probleme. Irgendwie will die Funktion 
srand (time(NULL)) nicht so richtig folgende Fehler treten auf:
../PERSONALFILZER.c:16: warning: implicit declaration of function 
'srand'
../PERSONALFILZER.c:16: warning: implicit declaration of function 'time'
../PERSONALFILZER.c:16: error: 'NULL' undeclared (first use in this 
function)
...usw
Was mag hie nicht stimmen??

define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <lcd.h>
#include <lcd.c>
#include <avr/pgmspace.h>
#include <math.h>


int main(void)
{
int a,b;

DDRA = 0xff;
srand (time(NULL));

   while(1)
    {
      b = rand()%10;
      PORTA = b;
    _delay_ms(5000);
    }
}


Gruß Ingo

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was haeltste davon dass es die Funktion time() nicht gibt?

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bringt mich jetzt nicht so richtig weiter???

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #include <lcd.c>
Und das hat da mit Sicherheit nichts zu suchen! .c-Dateien werden nicht 
mit #include eingebunden.

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dir fehlt die richtige Library, versuchs mal mit der <stdlib.h>.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs wrote:
> bringt mich jetzt nicht so richtig weiter???
Du kannst nunmal keine Funktion benutzen, die es nicht gibt bzw. die der 
Compiler nicht kennt. Du musst sie also entweder selber schreiben oder 
eine existente Funktion des Namens finden und sie dem Compiler bekannt 
machen.

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bitte schön...

http://www.roboternetz.de/wissen/index.php/Zufalls...

PS:
NULL kennt ein reiner C-Compiler auch nicht...

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nun ja im Dev C++ hat alles so funktioniert

#include <cstdlib>
#include <iostream>
#include <math.h>
using namespace std;

int main(void)
    {
              int a,b;
              cout <<("Zuffallsfaktor......");
              cin >> a;
              srand (time(NULL));
       {
              while(1)
              {
                  b = rand()%a;

                  cout << b << endl << endl;
                  if (b==0)
                   cout <<("................Treffer................")<< 
endl << endl;

                  system("PAUSE");
                  cout << endl << endl;
              }
       }

return EXIT_SUCCESS;

}

und da meckert der compiler nicht über NULL

@johannes
die lcd dateien befinden sich da weil ich die Zahlen später auf dem 
display brauche

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weisst du überhaupt was du tust ?

Nicht beleidigend gemeint, aber man hat den Eindruck als würdest du nach 
der Copy-and-Paste Methode mit vorhandennen Quelltexten arbeiten.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs wrote:
> nun ja im Dev C++ hat alles so funktioniert
> und da meckert der compiler nicht über NULL
Nun ist (wie der Name schon sagt) der devc++ ein C++-Compiler und der 
WINAVR (den Du ja vermutlich mit AVRStudio zusammen benutzt) ein 
C-Compiler. C und C++ haben zwar eine gewisse Schnittmenge, sind aber im 
Großen und Ganzen zwei ziemlich unterschiedliche Dinge! Wie wäre es, 
wenn Du Dich über die Programmiersprache, in der Du arbeiten willst, und 
die Plattform, auf der das ganze laufen soll, informierst, bevor Du 
damit anfängst?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs wrote:

> und da meckert der compiler nicht über NULL

Ja, und?

Es sagt ja niemand, das falsch geschriebener Code einen Fehler
erzeugen muss, aber er kann es eben.

NULL wird nur von <stdio.h> und <stddef.h> garantierterweise (gemäß
Standard) bereit gestellt.  Allerdings ist es natürlich anderen
Headerdateien nicht verboten, diese Konstante auch bereit zu stellen.
Allerdings kannst du natürlich statt NULL auch gleich 0 schreiben.

Aber zurück zum Problem: woher bitte soll dein Microcontroller ohne
Betriebssystem denn eine Kennung der aktuellen Uhrzeit besitzen?
Nichts anderes ist doch der Aufruf der Funktion time().

Um auf dem Controller ein random seed zu gewinnen, musst du dir schon
etwas mehr Mühe geben, und das Ganze hängt insbesondere davon ab,
über welche Art von Zufällen der Kram verfügt, der um deinen Controller
ringsum gruppiert ist.

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Laabs wrote:
> die lcd dateien befinden sich da weil ich die Zahlen später auf dem
> display brauche

Die kannst du gerne tuen.... nur dann #include bitte nur die .h und 
NICHT die .c...

Das ist Vergewaltigung des Präprozessors...

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:

> Aber zurück zum Problem: woher bitte soll dein Microcontroller ohne
> Betriebssystem denn eine Kennung der aktuellen Uhrzeit besitzen?
> Nichts anderes ist doch der Aufruf der Funktion time().

Ich glaube dem Ingo ist nicht bewusst dass er hier keinen PC sondern 
eine vollkommen andere Plattform ohne OS programmieren will?

Als seed eignet sich z.B. (wenn man es einfach machen will) ein 
Timerregister. Je nachdem, wann man es dann ausliest ist der Wert auch 
pseudozufaellig. Das duerfte sogar noch um einiges besser sein als der 
Aufruf von time(), der ja sehr definiert voraussagbar und nicht hoch 
aufgeloest ist.
Und klar ist auch, dass sich so gewonnener Zufall natuerlich nicht fuer 
irgendwelche kryptographischen Anwendungen eignet, aber darum wird's 
hier sicher sowieso nicht gehen.

Michael

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@chris
nee noch probiere ich und ich denke mal ALLE hier sind in irgendeiner 
Form durch anfängliches probieren zum Ziel gekommen..sicher auch DU

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael G. wrote:

> Als seed eignet sich z.B. (wenn man es einfach machen will) ein
> Timerregister.

Unter Umständen.  Wenn der Timer aber synchron mit dem CPU-Takt läuft,
ist die Chance (falls keine anderen physikalischen Effekte mit im
Spiel sind) gut, dass der Timer an der gleichen Stelle im Programmfluss
auch stets den gleichen Wert hat.

Ingo Laabs wrote:

> ...und ich denke mal ALLE hier sind in irgendeiner
> Form durch anfängliches probieren zum Ziel gekommen.

Naja, aber ein wenig drüber nachdenken, was da eigentlich gerade
passieren soll, darf man schon auch.  Eigentlich kannst du ja froh
sein, dass deine Bibliothek keine Funktion time() hat, so hat dich
wenigstens der Compiler mit der Nase drauf gestoßen, dass dein
copy&paste hier gar keine sinnvollen Ergebnisse bringen kann (weil
es die entsprechende Umgebung eben nicht hergibt).

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was Du unter "Probieren" verstehst verstehe ich unter Planlosigkeit ;) 
Und PC-Code zu kopieren und damit nen AVR programmieren zu wollen ist 
definitiv planlos, sorry.

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das sind Dinge, die muss mann aber erstmal wissen, gell

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt schon.

Da ist es jetzt an der Zeit die Beiträge zu lesen und zu verstehen, 
warum das nicht funktionieren kann. So lernt man :)

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Michael G. wrote:

> Unter Umständen.  Wenn der Timer aber synchron mit dem CPU-Takt läuft,
> ist die Chance (falls keine anderen physikalischen Effekte mit im
> Spiel sind) gut, dass der Timer an der gleichen Stelle im Programmfluss
> auch stets den gleichen Wert hat.

Sobald zumindest ein paar Funktionsaufrufe mit vom input abhaengiger 
Laufzeit und Interrupts auftreten duerfte das nicht mehr passieren. 
Ansonsten kann man  natuerlich z.B. mit dem Grundrauschen des ADC einen 
seed produzieren, das waere sogar ziemlich gut. Kommt sicher auf die 
Anwendung an fuer einfaches halte ich ersten Ansatz fuer OK.

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael

Columbus wollte auch nach Indien und ist in Amerika gelandet..und er 
hatte geplant.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich frag mich langsam ob dieser Beitrag hier ernst gemeint war oder ob 
das nur getrolle ist...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael G. wrote:

> Sobald zumindest ein paar Funktionsaufrufe mit vom input abhaengiger
> Laufzeit und Interrupts auftreten duerfte das nicht mehr passieren.

Ja, man braucht halt irgendwelche physikalischen Effekte dafür.  Wenn
man den 32-kHz-Oszillator benutzt, kann man dessen Anschwingverhalten
auch ausnutzen, das hat auch eine gewissen Zufälligkeit.  Bei neueren
AVRs kann man auch den 128-kHz-RC-Oszillator ,,anzapfen'' (bspw. über
einen watchdog-Interrupt), der ist auch komplett asynchron.

Man muss sich eben Gedanken machen, was dafür wirklich in Frage kommt.

Autor: xyz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Columbus wollte auch nach Indien und ist in Amerika gelandet..und er
>hatte geplant.

Ach verstehe ...
du machst den Zufallszahlenquatsch in der Hoffnung, dass was cooles bei 
rumkommt? Vielleicht nen Webserver oder so ?

Viel Glück

;P

Autor: Ingo Laabs (grobian)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
neee ich brauche einfach nur ne zufällige zahl(en) zwischen 1 und 8.
Habe es dann am PC probiert und die og lösung gefunden.
Das es so nicht auf den AVR übertragbar ist war mir schon klar. Ich 
wusste nicht das es die RANDOM-FUNKTION so in der Form nicht im AVR 
anwendbar ist. ´Deshal die Frage die hier für eiige Leute für ein wenig 
wirbel sorgt. Bin halt was C betrifft noch am Anfang..so wie wir es hier 
alle mal waren...ok??

so gleich Fußball, Bier kühlen  und dann Daumen drücken und das wird 
kein Zufall...wir gewinnen..

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die random()-Funktion funktioniert in der avr-libc praktisch genauso
wie auf einem PC: sie erzeugt eine Pseudo-Zufallszahlenfolge (allerdings
eines kleineren Wertebereichs durch den kleineren Datentyp "int").

srand(time(0)) ist übrigens auch auf einem PC mehr eine Krücke denn
eine richtige Lösung.  Wenn man bessere Entropiequellen hat (und auf
heutigen PCs hat man die praktisch immer), tut man gut daran, diese
zu nutzen statt der Systemzeit.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:

> srand(time(0)) ist übrigens auch auf einem PC mehr eine Krücke denn
> eine richtige Lösung.

Ja, untauglich vor allem fuer ernsthafte Anwendungen. Wenn's aber nur 
fuer nen Spiel oder sowas is isses i.d.R. OK.

Autor: Andreas W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entropiequellen sind zufällige nicht vorhersagbare Zustände. Weiß er 
sicher nicht.

Ein µC hat keine Zufälle. Die muss man sich immer irgendwo anders 
herholen. zum Beipsiel einen extra RC-Schwingkreis der läuft nicht so 
stabiel wie ein Quarz. Oder einen extra Rauschgenerator der termisches 
Rauschen für einen µC "auswertbar" macht. sowas in der Art halt.

Wenn du eine Zufallszahl per Knopfdruck machen möchtest. Dann kannst du 
auch das Knopfdrücken auswerten, also wie lange drückt einer, aber bitte 
das Prellen berücksichtigen, sonst wertest du nur das letzte Prellen 
aus, das liegt immer im ähnlichen Bereich.

Autor: Andreas W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso das "includen" der ".c" ist nicht wirklich gut. normalerweise 
werden code-dateien ".c" einzeln vom compiler übersezt und vom linker 
dann eingebunden. das solltest du auch machen. ich weiß jetzt nicht wie 
das bei AVR-Studio geht, aber ich schätze die lcd.c einfach ins projekt 
aufnehmen.
Die headerdatei (.h) lässt du included, dann sind in deiner Code-datei 
(.c) die lcd-funktionen bekannt.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat sich mal jemand den Link vom Roboternetz angeguckt? Die haben imho 
ne ziemlich gute Idee einen Seed zu produzieren. Und vor allem sehr 
einfach.

http://www.roboternetz.de/wissen/index.php/Zufalls...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon K. wrote:

> Hat sich mal jemand den Link vom Roboternetz angeguckt? Die haben imho
> ne ziemlich gute Idee einen Seed zu produzieren. Und vor allem sehr
> einfach.

Naja, das Einschaltmuster eines SRAMs ist exemplarabhängig relativ
stabil.  Es ist physikalisch (geometrisch) bedingt, in welche
Richtung die Flip-Flops vorzugsweise kippen, wenn die Betriebsspannung
angelegt wird.

Wenn es natürlich nur darauf ankommt, für verschiedene Geräte jeweils
verschiedene Startwerte zu erhalten, es dagegen nicht stört, wenn das
gleiche Gerät bei jedem Einschalten mit guter Wahrscheinlichkeit mit
der gleichen Folge startet, dann mag das gehen.  Ich würde allerdings
die Variante bevorzugen, den gesamten Speicher (vor der Initialisierung)
aufzusummieren, nicht nur ein Byte zu betrachten.

Autor: 3356 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was spricht denn gegen ein rueckgekoppeltes schieberegister ? Ein 
solches LFSR hat eine definierte Periode. Wenn man die genuegend Gross 
waehlt ... Ein 32 bit schieberegister hat eine Periode von 4 milliarden 
Samples. Das ist in den meisten Faellen brauchbar. Sonst kann man zu 
noch groesseren Laengen gehen. Application note 210 von Xilinx hat die 
Koeffizienten bis zu einer laenge von 168 bit gelistet. Dessen Periode 
ist 2^168, was fuer normale Anwendungen genuegend sein sollte.

Autor: Andreas W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotz komischen Start ist der thread echt interesant geworden.

Wo holt ihr den Startwert einer Zufallszahl auf einen µC her? oder wie 
macht ihr so sonst Zufallszahlen?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
3356 wrote:

> Was spricht denn gegen ein rueckgekoppeltes schieberegister ?

Was meinst du, was hinter rand() und random() dahinter steckt?

Genau: ein LFSR.

Autor: P.J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm die Funktion hier... ;-)

public int getRandomNumber()
{
    return 4;    // chosen by fair dice roll
                 // guaranteed to be random
}

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wärs für den Startwert mit Summe aus ein paar Bytes aus dem Stack, 
davon das Komplement, geteilt durch den Wert eines floatenden ports vom 
ADC, plus den Wert eines floatenden ports vom ADC. :-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timmo H. wrote:
> Wie wärs mit Summe aus ein paar Bytes aus dem Stack, davon das
> Komplement, geteilt durch den Wert eines floatenden ports vom ADC, plus
> den Wert eines floatenden ports vom ADC. :-)

Hast du's probiert?

Stack: wenn der Codepfad bis zur Initialisierung synchron war, steht
dort immer das gleiche drauf.

Floatender ADC-Port: dürfte eine Tendenz haben, auf einer der beiden
Endlagen zu liegen, je nachdem, wer dort als letztes Ladung
eingespeist hat.  Du müsstest eine kapazitive Einkopplung eines
50-Hz-Brumm oder so haben, damit du dort wirklich etwas anderes
lesen kannst.

Wie schon geschrieben, machen kann man viel, aber das hängt von der
ganz konkreten Umgebung ab, welche Zufallsquellen man heran ziehen
kann, um das LFSR zu initialisieren.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Simon K. wrote:
>
>> Hat sich mal jemand den Link vom Roboternetz angeguckt? Die haben imho
>> ne ziemlich gute Idee einen Seed zu produzieren. Und vor allem sehr
>> einfach.
>
> Naja, das Einschaltmuster eines SRAMs ist exemplarabhängig relativ
> stabil.  Es ist physikalisch (geometrisch) bedingt, in welche
> Richtung die Flip-Flops vorzugsweise kippen, wenn die Betriebsspannung
> angelegt wird.
>
> Wenn es natürlich nur darauf ankommt, für verschiedene Geräte jeweils
> verschiedene Startwerte zu erhalten, es dagegen nicht stört, wenn das
> gleiche Gerät bei jedem Einschalten mit guter Wahrscheinlichkeit mit
> der gleichen Folge startet, dann mag das gehen.  Ich würde allerdings
> die Variante bevorzugen, den gesamten Speicher (vor der Initialisierung)
> aufzusummieren, nicht nur ein Byte zu betrachten.

Den nicht-initialisierten RAM per XOR als seed zu nehmen schien mir 
damals am einfachsten, aber wie gesagt ist zu erwarten, dass der Wert 
eines Bits nicht unabhängig von der Bit-Nummer/Adresse/Nibble ist. 
Deshalb wäre eine pfiffigerer Operator als XOR eine Option.

Bei meinem AVR (ATtiny25) geht's aber ganz zuverlässig: Ich hab mal ne 
Uhr gebaut, wie als Wecker ein Klangspiel anstösst. Nun könnte man 
meinen, das Klangspiel würde recht zufällig bimmeln und streuen wie 
Lottozahlen. Aber das ist leider nicht so. Das Klangspiel bimmelte immer 
in ziemlich der gleichen Sequenz und irgendwann kennt man die auswendig.

Weil ich die Uhr nicht umprogrammieren wollte (8051 in asm **örgx**) hab 
ich die 2 Strippen genommen und ne Ansteuerplatine mit dem ATtiny25 
gemacht. Die Platine bekommt von der Uhr 1 Mintte lang Saft und das 
war's. Daher kann ich mir im Tiny25 keinen Zustand merken und hab die 
besagte seed und die Multiplikation in GF(2^n) implementiert (wenn man 
sich die Multiplikation in GF(2^n) anschaut wird man erkennen, dass LFSR 
kaum was anderes sind. In GF hat man allerding noch ein irreduzibles 
Erzeugerpolynom. Meine mathematische Intuition sagt mir aber, dass LFSR 
am besten funzt, wenn die dort verwendeten Polynome ebenfalls 
irreduzibel sind.)

rhabarberrhabarberrhabarber... Jedenfalls werd ich jetzt jeden Morgen 
von anderen Sphärenklängen vom Reich der Träume in die schnöde Realität 
befördert :-)

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.