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
> #include <lcd.c>
Und das hat da mit Sicherheit nichts zu suchen! .c-Dateien werden nicht
mit #include eingebunden.
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.
bitte schön... http://www.roboternetz.de/wissen/index.php/Zufallszahlen_mit_avr-gcc PS: NULL kennt ein reiner C-Compiler auch nicht...
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
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.
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?
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.
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...
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
@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
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).
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.
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 :)
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.
@Michael Columbus wollte auch nach Indien und ist in Amerika gelandet..und er hatte geplant.
Ich frag mich langsam ob dieser Beitrag hier ernst gemeint war oder ob das nur getrolle ist...
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.
>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
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..
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.
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.
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.
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.
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/Zufallszahlen_mit_avr-gcc
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.
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.
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?
3356 wrote:
> Was spricht denn gegen ein rueckgekoppeltes schieberegister ?
Was meinst du, was hinter rand() und random() dahinter steckt?
Genau: ein LFSR.
Nimm die Funktion hier... ;-) public int getRandomNumber() { return 4; // chosen by fair dice roll // guaranteed to be random }
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. :-)
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.
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 :-)
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.