Hallo, wollte mal fragen ob der eine oder andere einen guten Tip für nen Suchalgo hat den ich Programmieren muss. Ich hab einen Sinus mit <1Khz, davon lese ich mittels ADC ca. eine Periode ein, Phasenlage ist dabei nicht bekannt. Diese lege ich mittels DMA in 32 Werten im Speicher ab. Ich muss nun den Nulldurchgang der steigenden Flanke (also von negativ nach positiv) bestimmen. Das heist ich muß zwei aufeinanderfolgende Werte aus der Tabelle suchen. Den an Null nähsten negativen Wert und desen folge Wert welcher logischerweise positiv sein muss. Somit habe ich die Zwei Werte (den negativen und darauf folgende postive) die dem Nullpunkt am nähsten sind. Ich weis jetzt nur nicht wie ich die Suche in C umsetze kann ohne einen riesen Code zu bekommen der mir ein haufen der Rechenleistung frisst. Hat zufällig jemand nen guten Ansatz?? P.S. Hardware Lösungen gehen nicht, da ich den Sinus einlesen muss um noch andere Sachen damit anzustellen. Das ganze soll dann auf einem dsPIC33 bzw PIC24 laufen.
Suche im Array nach dem ersten negativen Wert. Ab dem gefundenen Index+1 suche nach dem ersten positiven Wert. Der erste gefundene positive Wert hat automatisch einen negativen Wert als Vorgänger -> Nulldurchgang. Dabei das Abbruchkriterium Index >= 31 beachten. Viele Grüße, Stefan
Hört sich gut an deine idee, aber ich hab bedenken das der Code probleme macht wenn die Abtastung bei negativer halbwelle beginnt. Aber ich hab mir gestern Abend nochmal ein bisschen das Hirn zermatert und da ist folgender pseudo Code rausgekommen. a=0; b=1; while(Startbit = 1) { if(a=30 || b=31) { Setze Startbit zurück; } if(Speicher[a]<0 && Speicher[ b]>0) { Schreibe Speicher[a] in Variable; //Negativer Wert Schreibe Speicher[ b] in Variable; //postiver Wert } else { a++; b++; } } Die While Schleife wird bei setzen des Startbit 30 mal durchlaufen und dabei immer 2 aufeinander folgende Werte überprüft ob der erste noch negativ (<0) und der zweite positiv(>0) ist. Wenn das der Fall ist hab ich den Nulldurchgang von neg nach pos. Wenn nicht gehe eine Stelle weiter (a++, b++). jetzt muss ich nur noch ein "Abbruch" Kriterium oder Meldung einabuen wenn kein Nulldurchgang detektiert ist.
Jens Großmann wrote: > Hört sich gut an deine idee, aber ich hab bedenken das der Code probleme > macht wenn die Abtastung bei negativer halbwelle beginnt. Dann überprüfst du eben den ersten Arrayeintrag ob er nicht schon negativ ist. > Aber ich hab mir gestern Abend nochmal ein bisschen das Hirn zermatert > und da ist folgender pseudo Code rausgekommen. Mal im Ernst: Programmieren ist nicht so deins, oder? Selten ein so kompliziertes Konstrukt for eine simple for-Schleife gesehen. > Die While Schleife wird bei setzen des Startbit 30 mal durchlaufen und > dabei immer 2 aufeinander folgende Werte überprüft ob der erste noch > negativ (<0) und der zweite positiv(>0) ist. D.h. du hast insgesamt 5 Vergleiche pro Schleifendurchlauf ! Nicht schlecht im Vergleich zu den 2, die Stefan vorschlägt. Satte 150% mehr.
Hehe gut hast recht. Ich komm auch eher aus der Hardware Gegend und muß für meine Diplomarbeit nun einen Controller programmieren. Ich hatte zwar mal im zweiten und dritten Semester C-Programmierung aber halt nur auf dem PC und nur oberflächlich ohne Vertiefung, meine Controller Erfahrungen waren bisher auch nur in Form von Assampler auf nem 8051. Und nun darf ich das bisschen Restwissen von C und Controllern zusammen bringen und mein Glück versuchen. Aber es ist ja noch kein Meister vom Himmel gefallen :-) Dann werde ich mir dochnochmal Stefans Konstrukt durch den Kopf gehen lassen und mal mein Code mit ner for Schleife testen.
Wenn schon in einer Schleife, dann so
1 | for( i = 0; i < 32 - 1; ++i ) |
2 | if( Speicher[i] < 0 && Speicher[i+1] > 0 ) |
3 | break; |
4 | |
5 | if( i == 32 - 1 ) |
6 | // kein positiver Nulldurchgang gefunden
|
7 | else
|
8 | // Nulldurchgang bei Speicher[i] und Speicher[i+1]
|
Sind immer noch 3 Vergleiche pro Schleifendurchgang. Weniger werdens nur mit einer Strategie wie Stefan sie vorschlägt. Das klassische "space-for-time" Verhalten: Man gewinnt Laufzeit, indem man in die Codegröße investiert. Ob das allerdings bei einer Arraygröße von 32 viel ausmacht?
Eine klassische Dreizeilenlösung nach dem Vorschlag von Stefan:
1 | #define N 32
|
2 | int speicher[N]; |
3 | |
4 | int get_zero(void) { |
5 | int i; |
6 | |
7 | for(i=0; i<N && speicher[i]>=0; i++); |
8 | for( ; i<N && speicher[i] <0; i++); |
9 | return i<N ? i : 0; |
10 | }
|
Der Funktionswert ist der Index des ersten nichtnegativen Array-Elements, dessen Vorgänger negativ ist, oder 0, falls ein solches Element nicht existiert.
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.