Forum: Mikrocontroller und Digitale Elektronik ESP8266 Tip1 Firmwareentwicklung : präzises Timing


von r_u_d_i (Gast)


Angehängte Dateien:

Lesenswert?

Firmware Tips Folge: 1 präzises Timing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Hi


Der Timer 'os_timer' löst nur bis 1 ms auf
Hier mal ein insider Tip zum ausprobieren.

Damit kann man die Auflösung bis zur clock ( 12.5ns ) verwenden.
1
static inline unsigned get_ccount(void)
2
{
3
        unsigned r;
4
        asm volatile ("rsr %0, ccount" : "=r"(r));
5
        return r;
6
}


Bei 80 MHz clock wird das Spezial Register 'CCOUNT' inkrementiert, und 
zwar geschieht das alle 12.5ns ( 80 MHz ) bei jedem clock tick.

Hier einmal mein Beispiel Code:
1
..
2
static inline unsigned get_ccount(void);
3
..
4
5
6
7
static inline unsigned get_ccount(void)
8
{
9
        unsigned r;
10
        asm volatile ("rsr %0, ccount" : "=r"(r));
11
        return r;
12
}
13
14
15
16
void user_init(void)
17
18
{
19
20
while(1) 
21
22
{
23
24
char ticks1 [32];
25
char ticks2 [32];
26
27
unsigned tick1;
28
unsigned tick2;
29
unsigned tickdiff;
30
31
32
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
33
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
34
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
35
36
// 1. Register CCOUNT formatierte Übergabe an Variable
37
os_sprintf(ticks1, "%lu", tick1);
38
// 2. Register CCOUNT formatierte Übergabe an Variable + Diff Value
39
os_sprintf(ticks2, "%lu %lu", tick2, tickdiff); 
40
41
42
// ich hab neben dem OLED am SPI auch ein MCP23S17 über SPI am ESP8266
43
// und betreibe ein einfaches 16 Zeichen x 2 Display daran
44
// daher ganz simple LCD Ausgabe anstatt Uart
45
46
lcdCmd(clearDisplay);       // LCD Command für Clear Display ausführen
47
lcdGoto(0);                 // LCD Command Gehe Postion 0
48
lcdWriteString(ticks1);     // LCD Print Register CCOUNT Gesamt Ticks
49
lcdGoto(0x40);              // LCD Command Gehe Postion 0x40 (zweite Zeile)
50
lcdWriteString(ticks2);     // LCD Print Register CCOUNT Gesamt Ticks
51
52
os_delay_us(10 *1000*1000); // Pause : Ablesen der Werte am LCD
53
54
lcdCmd(ClearDisplay);       // LCD Command für Clear Display ausführen
55
56
57
} // while
58
} // user_init

Der Wert von 1 sagt aus, dass zwischen den beiden Abfragen 12.5ns 
vergangen sind.


Ein weiterer Ansatz wäre aus der API,
1
uint32 system_get_time(void);

Damit kann man dann relative Zeitwerte abrufen z.b. vergangene Zeit 
zwischen zwei interrupts oder auch andere.

Der Nachteil:
Die Auflösung ist im API Ansatz nur in us

Daher denke ich mal, dass der INLINE ASM code gut zu gebrauchen ist.
Viel Spas damit.

..

lg

rudi ;-)

von Flip (Gast)


Lesenswert?

Das wird ja erstaunlich gut optimiert wenn nur  1 takt für 
funktionsaufruf und wert kopieren benötigt wird.

von Flip (Gast)


Lesenswert?

Wie groß ist CCOUNT und wie handlest du Überläufe?

von r_u_d_i (Gast)


Lesenswert?

Flip schrieb:
> Wie groß ist CCOUNT

32bit

> und wie handlest du Überläufe?

in Folge 2

:)

von r_u_d_i (Gast)



Lesenswert?

Flip schrieb:
> Das wird ja erstaunlich gut optimiert

hier sieht es schon ein wenig anders aus


1
..
2
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
3
os_delay_us(1);
4
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
6
..
7
8
// Bild tickdiff 122


und hier auch
1
..
2
3
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
4
os_delay_us(2);
5
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
6
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
7
8
..
9
10
// Bild tickdiff 194


auch hier:

1
..
2
3
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
4
os_delay_us(1);
5
os_delay_us(1);
6
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
7
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
8
9
..
10
11
// Bild tickdiff 243

Nebentip: Unbedingt immer mitdenken beim Ansatz


lg
rudi ;-)

von r_u_d_i (Gast)


Lesenswert?

Mal genauer betrachtet:
1 Mikrosekunden [µs] =   1 000 Nanosekunden [ns]
http://www.einheiten-umrechnen.de/einheiten-rechner.php?typ=zeit

Bild 1
mit einem delay 1µs  zwischen den beiden Abrufen ergeben sich 122 ticks
122 ticks zu je 12.5 ns = 1525 µs

./. + 525 µs


Bild 2
mit einem delay 2µs zwischend den beiden Abrufen ergeben sich 194 ticks
144 ticks zu je 12.5 ns = 1800 µs

./. - 200 µs


Bild3
mit 2x je einem delay 1µs zwischend den beiden Abrufen ergeben sich 243 
ticks
243 ticks zu je 12.5 ns = 3037,5 µs


./. + 1037.5 µs


lg
rudi  ;-)

von r_u_d_i (Gast)



Lesenswert?

Mal ein Testergebnis mit einer while (mtick < 100 )

dabei wird vor der while schleife das CCOUNT abgerufen und der Wert 
gespeichert, dann wird die while schleife 100 mal den abruf des 
Registers CCOUNT immer wieder in die zweite Variable speichern.

Jetzt werden die Ticks ausgerechnet die dafür gebraucht wurden

spannendes Ergebnis:

1
..
2
int mtick = 0 ;              // counter variable
3
..
4
..
5
6
// start
7
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
8
while (mtick < 100 ) 
9
{
10
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
11
mtick++;
12
}
13
14
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
15
..

dann die formation mit kontroll counter variable
1. zeile
erster Ticks abruf bei start || counter (100 aufrufe )
1
os_sprintf(ticks1, "%lu %i", tick1, mtick);

dann die formation mit erechneter worktime
2. zeile
letzter Ticks abruf (100) nach dem start || tickdiff
1
 
2
os_sprintf(ticks2, "%lu %lu", tick2, tickdiff);


wie gesagt,
ich hab neben dem OLED am SPI auch ein MCP23S17 über SPI am ESP8266
und betreibe ein einfaches 16 Zeichen x 2 Display daran
daher ganz simple LCD Ausgabe anstatt Uart


die spannende ausgabe:
1
lcdCmd(clearDisplay);       // LCD Command für Clear Display ausführen
2
lcdGoto(0);                 // LCD Command Gehe Postion 0
3
lcdWriteString(ticks1);     // LCD Print Register CCOUNT Gesamt Ticks
4
lcdGoto(0x40);              // LCD Command Gehe Postion 0x40 (zweite Zeile)
5
lcdWriteString(ticks2);     // LCD Print Register CCOUNT Gesamt Ticks
6
7
8
// liefert das angehängte Bild: 595 ticks für 100 durchläufe
9
// 595 * 12.5 ns = 7437,5 µs




Gegenprobe zur Optimierung wie im ersten Post ohne Delay?
Bitteschön
1
...
2
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 100 ) 
6
{
7
// tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
8
mtick++;
9
}
10
11
// nun ausserhalb der while .. wird es optimiert?
12
13
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
14
15
16
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
17
..


Bild 2 liefert die Antwort: ja

..



Tip:
Der Inline ASM Code eigent sich auch hervoragend zur Eigenüberwachung, 
Abgleich und andere.


lg
rudi ;-)

btw: Das bietet sich jetzt gerade zu an :)

Wer hat Lust auf eine Gegenüberstellung?
Xtensa ./. GCC

:)

wäre doch mal interessant?
hab beides da, werde für mich mal einfache beispiele ausprobieren und 
bei zeiten dann mal per push posten.

von r_u_d_i (Gast)



Lesenswert?

sorry - Bild2 jetzt attached
:)

von r_u_d_i (Gast)



Lesenswert?

Klar kann ich das auch noch machen:

Hier mal ein simples Contolling mit der API
1
uint32 system_get_time(void);



Ich bleib gleich bei dem Beispiel
und sende die time ergebnise jetzt einfach einmal per uart raus:

dazu ergänze ich jetzt
1
..
2
char wert3[32];  // für die formatierte uart ausgabe
3
4
..
5
unsigned t1;    // API time variable 1
6
unsigned t2;    // API time variable 2
7
..


bevor ich die ticks am start hole füge ich die api ein und hole den time 
wert 1, nachdem der zweite tick wert eingelesen wurde nach den 100 
durchläufen hole ich den time wert 2 und gebe ihn dann am schluss
formatiert auf den Uart aus.
1
t1 = system_get_time();     // API get time
2
// start
3
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
4
while (mtick < 100 ) 
5
{
6
// tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
7
mtick++;
8
}
9
10
// nun ausserhalb der while .. wird es optimiert?
11
12
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
13
14
t2 = system_get_time();     // API get time
15
16
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
17
..
18
..
19
20
os_sprintf(wert3, "t1: %lu \r\n", t1);    // formation time 1
21
uart0_sendStr(wert3);                     // ausgabe am Uart ( bild ) 
22
23
os_sprintf(wert3, "t2: %lu \r\n", t2);    // formation time 2
24
uart0_sendStr(wert3);                     // ausgabe am Uart ( bild ) 
25
26
os_sprintf(wert3, "t2 - t1 = %lu \r\n\r\n", t2-t1);    // formation differenz in µs 
27
uart0_sendStr(wert3);                     // ausgabe am Uart ( bild ) 
28
29
..


und wenn wir schon dabei sind, die ticks messung 2 in der while,
damit der nicht 'weg' optimiert wird

finale:

1
...
2
...
3
4
t1 = system_get_time();     // API get time
5
// start
6
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
7
while (mtick < 100 ) 
8
{
9
tick2 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
10
mtick++;
11
}
12
13
14
t2 = system_get_time();     // API get time
15
16
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
17
..
18
..


Diesmal Bild attached

have phun!

lg

rudi ;-)

von Ronny S. (phoenix-0815)


Lesenswert?

Abend,

das Display kannst auch im 4 Bit Modus direckt am ESP betreiben.

Mit dem MCP23S17 kann man schön einen Grafik Controller an SPI 
betreiben.

Schau Dir ma z.B. den T6963C ist sehr verbreitet und gut zu gebrauchen.

Den must dann zwar im 8 Bit Modus betreiben aber das past dann schon.

Oder nimst einen SED133x Controller der kann auch eine höhre Auflösung.

Am ADC nimst 8 zu 1 Multiplexer für Touch.

Grafiken legst auf der SD Karte ab und lädst die nur bei bedarf nach 
dann kannst auch Animierte Grafiken laufen lassen über SPI.

Naja den Rest schicke ich Dir dann per Mail will hier nicht deinen 
Thraed Karpern.

Gruß

von r_u_d_i (Gast)


Lesenswert?

Ronny S. schrieb:

> Abend,
>
> das Display kannst auch im 4 Bit Modus direckt am ESP betreiben.

Du Ganove :) kommst mir wieder zuvor! mit nibbles?
..

>
> Mit dem MCP23S17 kann man schön einen Grafik Controller an SPI
> betreiben.

ich hab den von adafruit 3.2" also 320 x 240, mit touch und sd

>
> Schau Dir ma z.B. den T6963C ist sehr verbreitet und gut zu gebrauchen.

jo - genau

>
> Den must dann zwar im 8 Bit Modus betreiben aber das past dann schon.
>
> Oder nimst einen SED133x Controller der kann auch eine höhre Auflösung.
>
> Am ADC nimst 8 zu 1 Multiplexer für Touch.

Du sprichst mir aus der Seele - 4051 hab ich vorgesehen, passt normal, 
oder Ronny?


>
> Grafiken legst auf der SD Karte ab und lädst die nur bei bedarf nach
> dann kannst auch Animierte Grafiken laufen lassen über SPI.

aber bitte nicht die FW 0.9.5 nehmen, der wtd schlägt zu
ich bleib bei der 0.9.3 bis espressif eine komplette neue skd freigibt.

>
> Naja den Rest schicke ich Dir dann per Mail

her damit - dann gehts los.

> will hier nicht deinen
> Thraed Karpern.

he he - was sagst zur auflösung, reicht doch für ein oszi? oder nicht?
da bist du der fachmann! :)


:)

lg
rudi ;-)

von Ronny S. (phoenix-0815)


Lesenswert?

Hallo Rudi,

immer eins nach dem anderen bis zum Mini Oszi für Audio ist da noch ein 
weiter Weg für Dich.

Bringe erst mal ein Grafik Controller da sauber zum laufen am SPI und 
dann entscheide was Du weiter machst damit.

Bau mal den T6963C erstmal ein in die Firmware mit einer Auflösung von 
240x128 wenn das läuft sehen wir weiter was machbar ist.

Gruß

von r_u_d_i (Gast)


Angehängte Dateien:

Lesenswert?

Ronny S. schrieb:

> immer eins nach dem anderen bis zum Mini Oszi für Audio ist da noch ein
> weiter Weg für Dich.

Na ja -
mein wifi 4chn osci läuft ja schon auf android
da nehm ich audio jack auch schon her :)
und der esp schaufelt schön die daten
( bild )

im moment lernt der espler pcm
http://www.ti.com/product/pcm1803a
und er lernt es schön :)
aber dazu mehr in Folge 6 :)
..
>
> Bringe erst mal ein Grafik Controller da sauber zum laufen am
> SPI und dann entscheide was Du weiter machst damit.

Ja ok - im Moment mach ich das mit dem MCP23S17 dazwischen, weil ich da 
mehr Möglichkeiten habe, ok werde dann mal wieder zurückrudern und den 
HW SPI nehmen. Aber nur weil du es bist :)

>
> Bau mal den T6963C erstmal ein in die Firmware mit einer Auflösung von
> 240x128 wenn das läuft sehen wir weiter was machbar ist.

puh - also ganz ehrlich ?
Bei mir laufen derzeit 1920 x 1080 -
warum willst du so winzig?

den T6963C glaub ich hatte ich doch schon -
es geht mittlerweilen : SSD1306 SSD1351 SSD1289  SSD1322 SSD1305

bevor wir den schönen Thread zuschaufeln lass uns das doch per mail 
abstimmen, das ist ja ein FW Tip thread zu präzise timing

;-)

von r_u_d_i (Gast)


Lesenswert?

Kontrolliertes Timing
~~~~~~~~~~~~~~~~~~~~~
Hinweis: wann man wo welches Timing braucht muss man sich genau 
überlegen


das wird 'nur' 1 tick
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 100 ) 
6
{
7
// empty
8
mtick++;
9
}
10
11
t2 = system_get_time();     // API get time
12
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
13
..
14
..



das werden 3 ticks !
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 100 ) 
6
{
7
// empty 
8
mtick++;
9
}
10
11
asm ("nop");                // "Ersteinrichtung = 1 Tick, Ausführung = 1 Tick"
12
13
t2 = system_get_time();     // API get time
14
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
15
..
16
..


das werden 'nur' 4 ticks !
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 100 ) 
6
{
7
// empty 
8
mtick++;
9
}
10
11
asm ("nop");
12
asm ("nop");
13
14
t2 = system_get_time();     // API get time
15
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
16
..
17
..


das werden auch 'nur' 3 ticks !
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 1 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
12
t2 = system_get_time();     // API get time
13
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
14
..
15
..





das werden 'nur' 5 ticks !
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 100 ) 
6
{
7
// empty 
8
mtick++;
9
}
10
                            // bisher 1 tick
11
asm ("nop");                // 2 ticks
12
asm ("nop");                // + 1 tick
13
asm ("nop");                // + 1 tick
14
                            // werden 5 ticks!
15
16
t2 = system_get_time();     // API get time
17
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
18
..
19
..



;-)

das werden 14 ticks !
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 3 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
t2 = system_get_time();     // API get time
12
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
13
..
14
..


3 x 2 x 2 = 12 + while 3 - 1 = 14



dann mal testen:

1 Durchlauf

1 x 2 x 2 = 4 + while 1 - 1 = 4
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 1 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
12
t2 = system_get_time();     // API get time
13
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
14
..
15
..


sind aber nur 3 ticks



2 Durchläufe

2 x 2 x 2 = 8 + while 2 - 1 = 9
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 2 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
12
t2 = system_get_time();     // API get time
13
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
14
..
15
..


sind 9 ticks, ok




5 Durchläufe

5 x 2 x 2 = 20 + while 5 - 1 = 24
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 5 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
12
t2 = system_get_time();     // API get time
13
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
14
..
15
..


sind 24 ticks, ok



das werden ?? ticks bei 100 Durchläufen?

100 x 2 x 2 + while 100 - 1 = 499 ??
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 100 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
t2 = system_get_time();     // API get time
12
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
13
..
14
..

ups
es werden 598 ticks ;)

mhm

100 x 2 x 2 + while 100 - 1 + "100" - 1 = 598

mhm..

dann nochmal testen:

das werden ?? ticks !
1
..
2
t1 = system_get_time();     // API get time
3
// start
4
tick1 = get_ccount();       // Spezial Register CCOUNT Abruf und Übertrag
5
while (mtick < 10 ) 
6
{
7
asm ("nop");
8
mtick++;
9
}
10
11
t2 = system_get_time();     // API get time
12
tickdiff = tick2 - tick1;   // Wieviel Ticks verbraucht
13
..
14
..

ticks: 49

10 x 2 x 2 = 40 + while 10 - 1 = 49 .. ok


Wer kommt drauf was zwischen durchlauf 1 und ab 2 anders ist?

;-)

lg
rudi ;-)

"hausaufgaben" müssen sein :)

10 x 2 x 2 = 40 + while 10 - 1 = 49

gegenprobe:

30 durchläufe
30 x 2 x 2 = 120 + while 30 - 1 = 149
und?

Bingo!

40 durchläufe
40 x 2 x 2 = 160 + while 40 - 1 = 199
und?

Bingo!

50 durchläufe
50 x 2 x 2 = 200 + while 50 - 1 = 249
und?

Bingo!


60 durchläufe
60 x 2 x 2 = 240 + while 60 - 1 = 299
und?

Bingo!

70 durchläufe
70 x 2 x 2 = 280 + while 70 - 1 = 349
und?

Bingo!

80 durchläufe
80 x 2 x 2 = 320 + while 80 - 1 = 399
und?

Bingo!

90 durchläufe
90 x 2 x 2 = 360 + while 90 - 1 = 449
und?

Bingo!

100 durchläufe
100 x 2 x 2 = 400 + while 100 - 1 = 499
und?

nö - 598

was ist mit den 100? und 598?
100 x 2 x 2 = 400 + while 100 - 1 = 499
wir haben aber 598?

also step by step
klammer wert ist rechnerischer soll


 91 durchläufe = 454 ticks (91*2*2+while 91-1=454)
 92 durchläufe = 459 ticks (92*2*2+while 92-1=459)
 93 durchläufe = 464 ticks (93*2*2+while 93-1=464)
 94 durchläufe = 469 ticks (94*2*2+while 94-1=469)
 95 durchläufe = 474 ticks (95*2*2+while 95-1=474)

~~~~~~~~~~~~~~~bis hier her alles ok ~~~~~~~~~~~~~
mhm?

 96 durchläufe = 574 ticks (96*2*2+while 96-1=479)
 97 durchläufe = 580 ticks (97*2*2+while 97-1=484)
 98 durchläufe = 586 ticks (98*2*2+while 98-1=489)
 99 durchläufe = 592 ticks (99*2*2+while 99-1=494)
100 durchläufe = 598 ticks (100*2*2+while 100-1=499)

es sind in diesem 'abschnitt' immer 6 ticks mehr als vorherige wert
vorher waren es 5 ticks mehr.

zwischen 95 und 96 durchläufen 'kippt' es
auf

96*2*2+while 96-1 + 100-1

Ein Überlauf um 100 ticks und dann eine differenz weiterer werte um 6.

kippt es bei 2+95 also bei 96 + 95 = 191 durchäufen?
Test

190 durchläufe = 1138 ticks (190*2*2+while 190-1 + 190 - 1 = 1038 )
195 durchläufe = 1168 ticks (195*2*2+while 195-1 + 195 - 1 = 1168 )
200 durchläufe = 1198 ticks (200*2*2+while 200-1 + 200 - 1 = 1198 )
..
1200 ....= 7198      ( = 7198 )

nein, es kippt nicht mehr
warum kippt es bei 95-96?
warum ist es zwischen 1 und ab 2 Durchläufen anders?

Jemand eine Idee bevor Teil 2 'Überlauf' kommt?

:)

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
Noch kein Account? Hier anmelden.