Zufallszahlen und Schleifenaufruf (PIC)

Gast #3490889
Lesenswert?

Hallo,

ich habe folgendes Problem.
Hmm zuerstmal den Code:
1
            if ((time-(timestamp+refresh))>=0)
2
            {
3
                CCPR1L=rand()/330+149;
4
                refresh=rand()/6+3000;
5
                timestamp=time;
6
            }

time ist die Zeit seit Programmstart in ms. timestamp ist zum Zeitpunkt 
der ersten aufrufs der schleife mit 0 und refresh mit 1000 
initialisiert.

Mein Ziel ist es, dass die Schleife in einem zufälligen Zeitintervall 
von 3 bis etwa 8,5s aufgerufen wird. In der Schleife soll eigentlich nur 
ein Wert zwischen 149 und 248 in CCPR1L geschrieben werden und ein neues 
Zufallsintervall bis zum nächsten Aufruf der Schleife generiert werden.

Leider funktioniert das irgendwie überhaupt nicht und ich blicks nicht 
warum :(

Programmiert wird ein PIC 18f1320 mit MPLABX und XC8

Vllt weiß ja jemand Rat :)
Gast #3491093
Lesenswert?

Das CCP Modul brauche ich für eine PWM. Die PWM ist auch korrekt 
konfiguriert wenn ich manuell werte in CCPR1L schreibe kann ich den Duty 
Cycle verändern.

In refresh soll lediglich irgend ein Wert zwischen 0 und 5460 
(((2^15)-1)/6 - von rand()) stehen. Zusammen mit den +3000 ergibt das 
dann irgendwas zwischen 5460 und 8460 was 5,46 - 8,46 Sekunden 
entspricht.

Es hängt auf jedenfall an Zufallszahlengenerierung mit rand();


Ich bin leider nicht so geübt mit dem Debugger..was meinst du genau?
#3491102
Lesenswert?

bower schrieb:

> Es hängt auf jedenfall an Zufallszahlengenerierung mit rand();

WAS hängt an der Zufallszahlengenerierung mit rand()?

Woran machst du das fest? Stimmen die Zeiten nicht, oder was passiert? 
Kommen immer die gleichen Zahlen? Variieren die nicht? Stürzt das System 
ab? Compiliert der Code?


PS:
rand() ist jetzt keine wirklich wahnsinnig komplexe Funktion. Man kann 
also davon ausgehen, dass die nicht ausgerechnet auf deinem System 
fehlerhaft implementiert ist oder gar fehlt.

PS2:
Ich glaubs zwar nicht, dass es was ausmacht. Aber ich würde die 
magischen Konstanten 6 und 330 durch Ausdrücke von RAND_MAX ersetzen. 
Denn genau dazu ist es da.
#3491110
Lesenswert?

>if ((time-(timestamp+refresh))>=0)
Das würde für mich so logischer aussehen:
if(refresh>=time-timestamp)

Und unser Herr Mod. hat recht: Wenn du nicht mehr Infos geben willst 
solltest du dich nach einem Wahrsager-Forum umsehen.

Der Teil des Codes den du oben gepostet hast sieht eigentlich in Ordnung 
aus.
#3491131
Lesenswert?

Mark Brandis schrieb:
> Meinst Du die Funktion rand() aus der C Standardbibliothek?
>
> http://www.cplusplus.com/reference/cstdlib/rand/
>
> Vielleicht die Initialisierung vergessen?

viel schlimmer wäre eine dauerender erneuter Aufruf von srand. Ob der 
seed bei 0 startet oder wo anders, ist hingegen nicht so wild.

>> Hast du schon mal die Modulo-Rechnug statt Division probiert?
>>
1
rand()%100+149;
2
>> rand()%5461+3000;
>
> Oder das.

Könnte helfen. Obwohl. Theoretisch muss es wurscht sein. Er hat seine 
Divisionskonstanten so berechnet, dass der gewünschte Wertebereich 
rauskommt. Ob allerdings RAND_MAX auf seinem System tatsächlich den Wert 
32767 hat, ist eine andere Frage. Wäre aber ungewöhnlich.
#3491137
Lesenswert?

rand existiert beim XC8 Compiler (User Guide S. 376) und RAND_MAX ist 
gleich 32767.

Wie schnell läuft der Timer? Könnte es sein dass die Ausführung der ISR 
zu lange dauert. Schliesslich arbeitest du mit 32Bit Variablen auf einem 
8Bit Controller. Das Ganze könnte man auch mit 16Bit Variablen 
erledigen.
#3491147
Lesenswert?

Vorschlag


Ändere den Code mal testweise so ab
1
int checkTimes[] = { 5500, 8200 };
2
int checkPWM[] = { 150, 240 };
3
int checkCnt = 0;
4

5
....
6

7

8
            if ((time-(timestamp+refresh))>=0)
9
            {
10
/*
11
                CCPR1L=rand()/330+149;
12
                refresh=rand()/6+3000;
13
*/
14
                checkCnt++;
15
                checkCnt = checkCnt % 4;
16

17
                CCPR1L = checkTimes[ checkCnt / 2 ];
18
                refresh = checkPWM[ checkCnt % 2 ];
19

20
                timestamp=time;
21
            }
22

23
....

das spielt 4 Kombinationen aus kurzer und langer Zeit bzw. kleiner und 
grosser PWM durch. Wieder und immer wieder.

D.h. theoretisch tut es das. Passiert genau das nicht, dann ist rand() 
aus dem Schneider und du musst dir eine andere Codestelle suchen, der du 
die Schuld in die Schuhe schieben kannst. Passiert aber dieses 
Durchspielen der 4 Werte, dann ist rand() tatsächlich ei heißer 
Kandidat.

also: Änderung machen, compilieren, brennen, testen und das Ergebnis 
berichten.
Gast #3491246
Lesenswert?

Ich brech ab...

be stucki schrieb:
> Nochwas: Du sagtest, alle Variablen seien vom Typ unsigned long.
> Somit
> ist der Ausdruck(time-(timestamp+refresh))>=0immer wahr. Ein Wert vom
> Typ unsigned long kann nie negativ werden.

Max H. schrieb:
> be stucki schrieb:
>> ist der Ausdruck(time-(timestamp+refresh))>=0immer wahr. Ein Wert vom
>> Typ unsigned long kann nie negativ werden.
> Dann könnte man das probieren:
>> if(refresh>=time-timestamp)

Danke euch beiden....das wars.

Ouh man :D

Vielen dank!

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