mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ersten postiven und negativen Wert des nulldurchgang bestimmen


Autor: Jens Großmann (Firma: fa. Seuffer) (willi-helmchen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan Kleinwort (_sk_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jens Großmann (Firma: fa. Seuffer) (willi-helmchen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Jens Großmann (Firma: fa. Seuffer) (willi-helmchen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn schon in einer Schleife, dann so
  for( i = 0; i < 32 - 1; ++i )
    if( Speicher[i] < 0 && Speicher[i+1] > 0 )
      break;

  if( i == 32 - 1 )
    // kein positiver Nulldurchgang gefunden
  else
    // 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?

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine klassische Dreizeilenlösung nach dem Vorschlag von Stefan:
#define N 32
int speicher[N];

int get_zero(void) {
  int i;

  for(i=0; i<N && speicher[i]>=0; i++);
  for(   ; i<N && speicher[i] <0; i++);
  return i<N ? i : 0;
}

Der Funktionswert ist der Index des ersten nichtnegativen 
Array-Elements,
dessen Vorgänger negativ ist, oder 0, falls ein solches Element nicht
existiert.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.