-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: C-Code für Windmesser

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2012
    Beiträge
    8

    C-Code für Windmesser

    Anzeige

    Hallo Forengemeinde,

    vor ein paar Wochen habe ich endlich meinen Windmesser fertig stellen können

    Klicke auf die Grafik für eine größere Ansicht

Name:	IMG_0247.jpg
Hits:	31
Größe:	19,7 KB
ID:	27853
    Klicke auf die Grafik für eine größere Ansicht

Name:	IMG_0248.jpg
Hits:	26
Größe:	34,4 KB
ID:	27854
    Klicke auf die Grafik für eine größere Ansicht

Name:	IMG_0249.jpg
Hits:	25
Größe:	30,2 KB
ID:	27856
    Klicke auf die Grafik für eine größere Ansicht

Name:	Datenblatt_Windmesser.jpg
Hits:	30
Größe:	101,2 KB
ID:	27857

    Leider ergibt sich in meinem C-Code ein Problem: Da ich die maximale Windspitze speichern möchte, habe ich eine einfach Abfrage per if-Verzweigung eingefügt. Diese funktioniert auch super, nur leider gibt es (scheinbar) bestimmte Zustände in meinem Code, der dann den max-Wert vom Wind mit "655.3" anzeigt (maximaler int-Wert, siehe Bild). Daraus folgt, dass meine ganze Windmessung manchmal fehlerhaft ist...

    Meine Frage: Sieht irgendjemand von euch das Problem, welches diesen Zustand verursacht? Mein Kollege und ich sind mittlerweile "betriebsblind" und haben keine Idee mehr.

    Tests mit einem Schmitt-Trigger und einer "1-Sekunden-Mittelwert-Bildung" (aktuelle Windgeschwindigkeit im Display) brachten auch keinen Erfolg...

    Ich habe meinen Code als zip-Datei angefügt

    Viele Grüße und danke bereits im Voraus,

    Daniel
    Angehängte Dateien Angehängte Dateien
    Geändert von daniel031287 (25.03.2014 um 18:41 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Zum einen gibt es da ggf. ein Hardware-Problem: Reed Kontakte können prellen und damit sehr kurze falsche Pulse geben. Das müsste man noch in Hardware oder Sorftware berücksichtigen, etwa indem man nach einer Flanke erst einmal für die nächsten etwa 2-10 ms alle weiteren Pulse ignoriert.


    In der Software gibt es vermutlich noch Probleme: Die Variablen, die in ISR und Hauptprgramm genutzt werden, müssen in aller Regel als Volatile markiert werden. Sonst gibt es Probleme mit Optimierung (ohne kann es noch laufen). Ohne Optimierung wird delay.h aber nicht richtig funktionieren.


    Kleinere Probleme kann es geben wenn die Auskommentierten LCD Befehle in der Timer ISR genutzt werden - das kann eine vergelichsweise große Verzögerung geben, und damit ggf. einige Ausreißer (nach unten) bei der Windmessung.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2012
    Beiträge
    8
    Hallo Besserwessi,

    danke für deine Antwort. Wie sieht denn genau die volatile-Deklaration aus? (sorry für diese vllt. dumme Frage, bin jedoch nur "Hobbdy-Programmierer"...).
    Und du redest von der header-datei "delay". Dort muss ebenfalls etwas optimiert werden? Was denn genau?

    Du redest von auskommentierten LCD-Befehlen in der Timer-ISR. Ist das auf meinen Quelltext bezogen? Ich sehe da so keine LCD-Befehle. Zumindest nicht in den/der Timer-ISR.

    Das hardware-technische Entprellen habe ich bereits mit einem Schmitt-Trigger mittels OP realisiert. Hat jedoch leider keine Verbesserung gebracht...

    Schönen Abend noch und gute Nacht

    Daniel

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Damit der der Compiler den zugriff auf Variablen nicht wegoptimieren darf, kann man bei der Variablendeklaration ein volatile davor setzen. Als etwa
    volatile long Wind ;

    Damit optimiert der Compiler den Zugriff auf diese Variabel nicht so sehr, weil ihm gesagt wird das sich der Wert ggf. von extern verändern kann, etwa durch die ISR. Gebraucht wird dies für Variablen die Im Hauptprogramm und einer ISR benutzt werden. Wie viele der Zugriffe der Compiler ohne das Volatile wegoptimiert ist schwer zu sagen - es kann also teilweise auch ohne funktionieren, muss aber nicht - es macht da auch wenig Sinn zu spekulieren wie viel ggf. noch geht - einfach die in der ISR benutzten Variablen als volatile kennzeichnen.

    Damit die Delay Funktionen aus delay.h richtig funktionieren muss man mit Optimierung übersetzten, also beim Compiler die Einstellungen -O1. -O2 oder -Os haben. Am Code selber muss man da nichts einstellen, sondern die Einstellung erfolgt in der IDE oder im Makefile.

    Der zu große Wert beim Wind könnte gut vom Prellen kommen: ein Entprellen in Software ist da deutlich flexibler und auch zuverlässiger als die HW Lösung: also testen ob die Zeit zu klein ist, und dann den Wert verwerfen.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo,
    [QUOTE=Besserwessi;596939]Damit der der Compiler den zugriff auf Variablen nicht wegoptimieren darf, kann man bei der Variablendeklaration ein volatile davor setzen. Als etwa
    volatile long Wind ;QUOTE]

    Ein Beispiel:
    Code:
      while (Wind)
        {
           // mach was
        }
    Ein optimierender Compiler findet, dass die Schleife viel schneller ist, wenn Wind nur einmal in ein Register geladen wird und dann vergleicht man immer das Register ...

    Wenn Wind jetzt aber ein Port ist oder von einer ISR verändert wird, geht das daneben und die Schleife wird nie beendet!

    Mit volatile wird der Compiler gezwungen, bei jeder Verwendung von Wind auch den Code für einen Zugriff auf diese Speicherstelle zu erzeugen.

    MfG Peter(TOO)

    - - - Aktualisiert - - -

    Hallo Daniel
    Zitat Zitat von daniel031287 Beitrag anzeigen
    Das hardware-technische Entprellen habe ich bereits mit einem Schmitt-Trigger mittels OP realisiert. Hat jedoch leider keine Verbesserung gebracht...
    Ein Schmitt-Trigger kann nicht entprellen, der macht aus dem Rauschpegel nur eine schöne Rechteckspannung

    Ein guter mechanischer Schnapp-Kontakt verhält sich beim Schliessen mehr wie ein Ball. Der hüpft auf seinem Gegenkontakt eine weile rum. Bei guten Kontakten dauert die Hüpfzeit so um die 2-10ms. Beim Öffnen sieht es meist etwas besser aus, aber auch da prellt es.
    Schlimmer sind Schiebeschalter, bei welchen die Kontakte aufeinander gleiten. Durch die Unebenheiten der der Kontakte tritt dabei prellen währenden des ganzen Verschiebevorgangs auf.

    Entprellen ist also ein zeitliches Problem.
    Rein per Hardware entlädt man dazu einen Kondensator und zwar so, dass dieser beim ersten Kontaktschluss entladen wird. Die Zeitkonstante muss dann so gewählt werden, dass sich der Kondensator nicht wieder auf den anderen Logikpegel aufladen kann, bevor der nächste Prell-Impuls auftritt.

    Nun bekommt man ein neues Problem:
    Logik-Eingänge haben zwischen den definierten Pegelbereichen einen undefinierten Bereich. Hier kann es sogar vorkommen, dass bei bestimmten Pegeln der Eingang schwingt.

    Hier hilft dann der Schmitt-Trigger, indem er dafür sorgt, dass immer definierte Pegel am Logik-Eingang anliegen.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2012
    Beiträge
    8
    Guten Morgen,

    ich habe einige Variablen nun als volatile deklariert. Zustätzlich habe ich mich noch schlau gelesen... wieder was dazu gelernt, danke für den Tipp

    Ich hatte noch die Idee, statt einen Schmitt-Trigger einen schnellen Komparator einzusetzen... nur ob das dann wirklich hilft, ist fraglich.

    Der Nachteil beim Software-Entprellen ist doch aber der, dass ich Zeit verstreichen lasse, in der schon der nächste Impuls kommen kann? Wenn ich das Programm nun dort "Zwangsanhalte", laufe ich Gefahr, Impulse bei sehr viel Wind nicht mitzubekommen.
    Oder sehe ich das nun falsch?

    Viele Grüße und ein schönes Wochenende,
    Daniel

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.03.2011
    Beiträge
    1.400
    Zitat Zitat von daniel031287 Beitrag anzeigen
    Der Nachteil beim Software-Entprellen ist doch aber der, dass ich Zeit verstreichen lasse, in der schon der nächste Impuls kommen kann? Wenn ich das Programm nun dort "Zwangsanhalte", laufe ich Gefahr, Impulse bei sehr viel Wind nicht mitzubekommen.
    Das ist prizipiell so. Wenn die "Prellpulse" ähnliche Zeiten haben, wie das Nutzsignal, ist der Sensor ungeeignet. Ob man die Auswertung in Software oder in Hardware
    Zitat Zitat von Peter(TOO)
    Rein per Hardware entlädt man dazu einen Kondensator und zwar so, dass dieser beim ersten Kontaktschluss entladen wird. Die Zeitkonstante muss dann so gewählt werden, dass sich der Kondensator nicht wieder auf den anderen Logikpegel aufladen kann, bevor der nächste Prell-Impuls auftritt.
    macht, ist dabei egal. Der Vorteil der Software ist auf jeden Fall, das man Zeitkonstanten ohne Lötkolben ändern kann.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  8. #8
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Zeit die der Schalter mechanisch Prellen kann, muss man so oder so Ausklammern. Ob man das analog oder digital macht,macht da keinen Unterschied. Die Softwarelösung ist da eher noch exakter einstellbar. Normal sollte die Zeit vom Prellen auch so kurz sein, das so kurze Pulse auch bei Sturm kaum vorkommen können. Die Vielleicht 2 ms die ein Reed Kontakt prellt, würden immer noch 250 Hz Signal erlauben, was wohl theoretisch 100 m/s entspräche. Da hat man dann andere Probleme, wenn es mehr wird. Zu sehr übertreiben darf an es mit der Zeit zum entprellen aber halt auch nicht.

    Bei der analogen Lösung ist ein Schmidt Trigger schon passend - ein Komparator hilft da nicht wirklich weiter. Die Eingänge beim AVR sind bereits Schmidt-trigger Eingänge - im Prinzip würden da passend bemessene Widerstände / Kondensatoren schon reichen. Man darf auch beide Methoden zum Entprellen kombinieren, also trotz analogem Teil noch mal in Software unrealistisch kurze Zeiten zu verwerfen.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2012
    Beiträge
    8
    Okay, dann werde ich mich da die Tage mal "ranwagen" und software-technisch entprellen... werde da aber erst Mitte nächster Woche zu kommen, da ich ein paar Tage im Center Parc bin... also nicht wundern, dass bis dahin nichts von mir kommt.

    Sobald ich das Entprellen software-technisch realisiert habe, werde ich den Code hier mal hochladen und eure Meinung abwarten...

    Schönes We,

    Daniel

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2012
    Beiträge
    8
    Moin zusammen,

    ich habe mir nun ein paar Gedanken gemacht und mich ein wenig eingelesen: Das Software-Entrprellen (scheint) ja am sinnvollsten zu sein, wenn man es über Timer realisiert, um unnötige Warteschleifen zu verhindern und das Programm kurze Zeit zu "blocken".
    Jedoch habe ich bereits 2 Timer in Verwendung: Sprich, wenn ich nun so programmieren würde, dass der Reed-Kontakt einen externen Interrupt auslöst, würde meine Int-Routine ausgeführt.
    Angenommen, ich würde dann eine Variable hochzählen. Meinetwegen bis 5 Zeiteinheiten. Wenn diese 5 Zeiteinheiten erreicht sind, soll nochmal geschaut werden, ob das Signal (in meinem Fall) immer noch "high" ist. Wenn das der Fall ist, soll die Geschwindigkeit errechnet werden.
    ABER: Um diese Zeiteinheiten hochzuzählen, würde die Software aus der Int-Routine rausgehen, um zum Beispiel die Timer0-Overflow-Routine aufrufen, um die Variable hochzuzählen. Wenn dies erledigt ist, springt er wieder in die Int-Routine vom Reed-Kontakt zurück. Oder wird dieser Zähler hardwaremäßig hochgezählt, ohne dass die Int-Routine dafür verlassen werden muss?

    ISR(INT0_vect){
    volatile unsigned long int us = 0;
    volatile unsigned long int millisekunde = 0;

    //Entprellzeit
    _delay_ms(10);

    //Interrupt an INT0 -> PD2
    //alter Wert 32
    us = (volatile unsigned long int) TCNT1 * 32;
    TCNT1 = 0;

    millisekunde = us / 1000;

    // v = s/t
    // Durchmesser Schale Mitte = 92mm
    //Umfang = 92mm * pi = 2890mm
    //laut Datenblatt Windweg = 0,4m
    //Wert 1445

    wind = 2890 / millisekunde; //*10 für Kommastelle
    GIFR |= (1 << INTF0);
    }
    Eine einfache Wartezeit von nun beispielsweise 10ms wäre doch auch eine Entprellung? 10ms sind aber sehr wahrscheinlich zu hoch gegriffen...

    Ich habe gerad irgendwie einen "Knoten im Kopf"...
    Hoffentlich ist das nun auch rübergekommen, wo gerad mein Problem ist.

    Gruß
    Geändert von daniel031287 (03.04.2014 um 17:28 Uhr)

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Code+Schaltpläne für einige I²C/SPI ADCs, DACs, LED-Treiber, ... für AVR, ARM, AVR32
    Von kruemeltee im Forum Eigene fertige Schaltungen und Bauanleitungen
    Antworten: 0
    Letzter Beitrag: 22.08.2011, 20:34
  2. Code-Schloss mit Tastatur, LCD und Logger. Code-Beispiel
    Von Stray_Cat im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 2
    Letzter Beitrag: 05.06.2009, 11:31
  3. Mal wieder die Windmesser ;-)
    Von Björn im Forum Elektronik
    Antworten: 102
    Letzter Beitrag: 31.12.2005, 14:40
  4. Code für Interrupt?
    Von Felixx87 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 22.09.2005, 17:41
  5. Suche C-Code für Matrixtastaturabfrage für PIC µC
    Von the_Ghost666 im Forum Software, Algorithmen und KI
    Antworten: 0
    Letzter Beitrag: 25.02.2005, 19:25

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •