Zufallszahlen erzeugen

#894092
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
#894108
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.
#894114
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
#894120
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?
Moderator Persönliche Seite #894123
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.
Persönliche Seite #894131
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
Moderator Persönliche Seite #894136
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).
Persönliche Seite #894143
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.
Moderator Persönliche Seite #894155
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.
Gast #894156
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
#894166
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..
Moderator Persönliche Seite #894168
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.
Gast #894197
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.
Gast #894202
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.
Moderator Persönliche Seite #894398
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.
Gast #894542
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.
Moderator Persönliche Seite #894625
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.
Persönliche Seite #894639
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren