Hallo Zusammen, suche Code in "C" für einen Fehlerzähler/Nivellator. Ich habe nur noch wenig Speicher zur Verfügung, deshalb sollte es was "schlankes" sein... Zum Hintergrund: Es wird zyklisch ein Strom gemessen. Es wird eine Bewertung Strom ok/überstrom (wie 0/1) vorgenommen. Es sollen immer die letzten 30 Messungen betrachtet werden und wenn 20 davon in beliebiger Verteilung "Überstrom" anzeigen, soll eine Fehlermeldung ausgegeben werden. Ich könnte also ein Array damit füllen - verbraucht zuviel Platz. Ich könnte in einer 32-bit-Variable die einzelnen Bits verbiegen - ist mir zu kompliziert mit masking oder shifting. Ich suche eher sowas wie einen Nivellator mit +1/-1, dann die Höhe bewerten und Fehleralarm auslösen. Aber irgendwie komme ich nicht drauf... Grüße von der Pequod!
Jens Berkemeyer schrieb: > Ich könnte in einer 32-bit-Variable die einzelnen Bits verbiegen - ist > mir zu kompliziert mit masking oder shifting. Na ja, in dem Fall kommen dann alle anderen denkbaren Lösungen erst recht nicht für dich in Frage. Oliver
Wenn dir die 32bit-Variable von Hand zu kompliziert ist... gefällt dir nen Bitfeld eventuell besser?
Hi, also, Bits verbiegen oder Bitfeld und dann durchzählen kann ich natürlich machen, aber find ich nicht so schön, deshalb sucht ich ja eher was in Richtung Nivellator. Die Frage ist also: Gibts da überhaupt was, was man in der Richtung machen kann? Ich habe da keine Idee, aber das heisst ja nicht, daß es keine gibt. Wenn ich das per Addition/Suptraktion mache, müsste ich ja wissen, was rausfällt (wenn 0, dann nix / wenn 1, dann -1), aber dann wär ich ja wieder beim array/Bitfeld/Bits... Vielleicht hab ich auch gerad nur nen Knoten im Kopf..;-))
hmmm... du hast dann ja quasi einen ringpuffer mit 30 zeichen. überstrom-ereignis = 1 für die ersten 30 werte müsstest du meiner meinung nach in einer variable für jedes "überstrom ereignis" eine 1 addieren. sobald du da deine schwelle von 20 erreicht hast kannst du deinen alarm auslösen. und ab dem 31.wert für jedes "nicht-überstrom ereignis" 1 abziehen und für jedes überstrom ereignis +1 rechnen
>>Ich könnte in einer 32-bit-Variable die einzelnen Bits verbiegen - ist >> mir zu kompliziert mit masking oder shifting. Nimm doch eine 16-Bit-Variable und zähl in den Einer und Zehnerstellen jeweils den Pegel (+1, +0,+1) und parallel dazu in den Hunderterstellen die aktuelle Iteration.
1 | var += 100 + currPegel; |
2 | |
3 | if(var >= 3000) { |
4 | if(var >= 3020) { |
5 | // Reagiere
|
6 | }
|
7 | var = 0; |
8 | }
|
Oder verschwendet das jetzt auch schon zuviel Speicher ;-)?
Das ginge sogar leicht modifiziert mit einer 8 Bit Variablen
Pl Lp schrieb: >>>Ich könnte in einer 32-bit-Variable die einzelnen Bits verbiegen - ist >>> mir zu kompliziert mit masking oder shifting. > > Nimm doch eine 16-Bit-Variable und zähl in den Einer und Zehnerstellen > jeweils den Pegel (+1, +0,+1) und parallel dazu in den Hunderterstellen > die aktuelle Iteration. > >
1 | > var += 100 + currPegel; |
2 | >
|
3 | > if(var >= 3000) { |
4 | > if(var >= 3020) { |
5 | > // Reagiere |
6 | > } |
7 | > var = 0; |
8 | > } |
9 | >
|
und wie wirst du nach der 31./32./.. Messung das in der Summe enthaltene 1./2./... Messergebnis wieder los? Das ist ja genau der springende Punkt: Iregdnwo muss man sich die letzten 30 Messungen (oder zumindest deren Auswertergebnis) ablegen, damit man aus der Summe die ersten Messungen wieder rausrechnen kann, wenn neue Messergebnisse dazukommen. Das Auswerten von 20 Werten über einem Limit ist nicht das Problem. Das notwendige Speichern der 30 Werte ist sein Problem.
Jens Berkemeyer schrieb: > Ich könnte in einer 32-bit-Variable die einzelnen Bits verbiegen - ist > mir zu kompliziert mit masking oder shifting. Schieben ist doch einfach, das ist ne Grundfunktion jeder CPU. Du kannst daneben noch ne 8Bit-Variable mitführen, die zählt die einkommenden 1-er rauf und Bit30 runter. Und dann nur testen, ob sie >= 20 ist. Peter
1 | uint8_t nivellator( uint8_t bit ) // bit = 0 or 1 |
2 | {
|
3 | static uint32_t srg = 0; |
4 | static uint8_t count = 0; |
5 | |
6 | srg <<= 1; |
7 | srg |= bit; |
8 | count += bit; |
9 | if( srg & 1L<<30 ); |
10 | count--; |
11 | return count >= 20; |
12 | }
|
Peter
Karl Heinz Buchegger schrieb: > und wie wirst du nach der 31./32./.. Messung das in der Summe enthaltene > 1./2./... Messergebnis wieder los? > > Das ist ja genau der springende Punkt: Iregdnwo muss man sich die > letzten 30 Messungen (oder zumindest deren Auswertergebnis) ablegen, > damit man aus der Summe die ersten Messungen wieder rausrechnen kann, > wenn neue Messergebnisse dazukommen. > > Das Auswerten von 20 Werten über einem Limit ist nicht das Problem. Das > notwendige Speichern der 30 Werte ist sein Problem. Stimmt, da hab ich die Problemstellung falsch (mit hartem Cut) verstanden.
Moin, ah, vielen Dank Euch, insbesondere Peter. So wird es wohl funktionieren. Wenn ichs fertig habe, poste ich dann nochmal den Endstand. Ich will dann ja Motoren auf Über-/Unterstrom überwachen. Grüße von der Pequod!
Moin Zusammen, jetzt funktionierts und sieht bei mir so aus: Es wird der erste volle Messblock abgewartet und dann je nach Niveau eine 1 geliefert, wenn das Niveau überschritten ist. Wenn die Funktion 1 liefert, wird ein Fehlereintrag generiert. Die Variablen werden dann halt bei Initialisierung und nach Abschaltung der Pumpen zurückgesetzt. Das Gleiche gibts bei mir dann nochmal für Unterstromüberwachung.
1 | /*===========================================================================*/
|
2 | /*..... FUNCTION: tUINT8 uErrorNivellatorHi
|
3 | *..... PARAMETERS: errorbit(0/1), aggregate to monitor
|
4 | *..... DESCRIPTION: builds niveau of errors
|
5 | *..... RETURNS: TRUE when niveau exceeds limit after 1st complete cycles
|
6 | *..... AUTHOR: Berkemeyer
|
7 | *..... REMARKS: */
|
8 | static tUINT8 uErrorNivellatorHi( tUINT8 uErrorBit, tMON_AGGREGATE eAggregate ) |
9 | {
|
10 | uErrorBitsHi <<= 1; /*...switch position forward......*/ |
11 | uErrorBitsHi |= uErrorBit; /*...write errorbit to position...*/ |
12 | uErrorNivHi += uErrorBit; /*...add errorbit to niveau.......*/ |
13 | |
14 | if( MON_SEWAGE == eAggregate) |
15 | {
|
16 | if(6 >= uErrorCycsHi) /*...count first cycles...*/ |
17 | uErrorCycsHi++; |
18 | if( uErrorBitsHi & 1L<<6 ) /*...if 6th position before current position is 1...*/ |
19 | uErrorNivHi--; /*...then sub 1 from niveau.........................*/ |
20 | return (4 < uErrorNivHi) /*...return 1 if niv higher than 4...*/ |
21 | && (6 < uErrorCycsHi); /*...AND min cycles have been done...*/ |
22 | }
|
23 | else
|
24 | {
|
25 | if(30 >= uErrorCycsHi) /*...count first cycles...*/ |
26 | uErrorCycsHi++; |
27 | if( uErrorBitsHi & 1L<<30 )/*...if 30th position before current position is 1...*/ |
28 | uErrorNivHi--; /*...then sub 1 from niveau..........................*/ |
29 | return (20 < uErrorNivHi) /*...return 1 if niv higher than 20...*/ |
30 | && (30 < uErrorCycsHi);/*...AND min cycles have been done....*/ |
31 | }
|
32 | }
|
Grüße von der Pequod! Schlurf-Tock-Schlurf-Tock...
vielleicht so: eine 32bit-Variable also Puffer. Bei Fehler +1 ansosnten nicht, nach jeder Messung wird um eins nach links geschoben. So hast du das Gedächtnis über die letzten 32 Messungen. Die Fehleranzahl liese sich dann über die Bit-Quersumme berechnen. :-)
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.