-
        

Ergebnis 1 bis 8 von 8

Thema: Verzögerte PWM ausgabe. Ansatz gesucht.

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.03.2005
    Ort
    Schifferstadt
    Alter
    35
    Beiträge
    318

    Verzögerte PWM ausgabe. Ansatz gesucht.

    Anzeige

    Hallo zusammen,

    ich steh momentan auf dem Schlauch. Ich lese über Getadc(0) einen Analogwert ein und gebe diesen 1:1 über pwm1a wieder aus. Jetzt ist es aber so, das der Wert sprungartig = 1023 ist. Dann würde meine PWM auch sprungartig auf den Wert 1023 springen. Das will ich aber verhindern. Wenn der Wert des ADC sprungartig ansteigt, soll meine PWM auf diesen Wert langsam ( 1-3 sec ) hochlaufen. Mir fehlt aber momentan der Lösungsansatz dafür. Kann mir bitte jemand einen Denkanstoß geben ?

    Gruß Kay

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    19.02.2008
    Ort
    Pohlheim
    Alter
    27
    Beiträge
    240
    du hast ja deinen ADC in eine Variable geladen. Den vorherigen Wert machst du auch in eine Variable. Dann schaust du ob der neue Wert kleiner oder größer is und zählst in einer schleife einfach den wert um 1 hoch bzw. runter und wartest ein paar millisekunden. Das machst du solange bis dein Wert dem Getadc entspricht.



    Oder ist es wichtig, dass dieser Teil des Codes den restlichen Code nicht aufhält?

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    15.05.2009
    Beiträge
    25
    Ich denke du könntest einen Tiefpass, ein PT1-Glied implementieren, siehe zB hier: http://de.wikipedia.org/wiki/PT1-Gli...etes_PT1-Glied

    Das sorgt für ein "weiches" Sprungverhalten und damit Dämpfen von hohen Frequenzen.

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    10.03.2005
    Ort
    Schifferstadt
    Alter
    35
    Beiträge
    318
    Danke für die Antworten. Wait wollte ich zuerst auch benutzen, aber es kann durchaus sein, das der Wert auch wieder sprungartig zurückgeht. Dann muss die PWM allerdings in diesem Moment auch zurück gehen. Nur beim ansteigen soll es langsam mit ansteigen.

    Gruß Kay

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.01.2006
    Beiträge
    4.556
    Dann prpüfe doch einfach auf ADC > PWM und führe nur
    wenn Ja ein "for PWM = PWM TO ADC Step xyz " aus was
    Du bei ADC < PWM überspringst....

    Gruß Richard

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.07.2006
    Ort
    Karlsruhe/München
    Alter
    27
    Beiträge
    587
    Quick 'n' Dirty Vorschlag, der was von Tiefpass hat.

    Ich notier dir das ganze aber in C, da ich von Basecom absolut garnichts halte. (DA TOTAL INEFFIZENT!)
    Code:
    16 Bit variablen: 
    currentadcval: Momentaner ADC wert
    preadcval: ADC wert vom Vorherigen durchlauf
    diff: Differenz der Werte
    
    void pwm_output(currentadcval){
    if(currentadcval>preadcval){
    diff=currentadcval-preadcval;
    PWM+=diff/4; // Faktor entsprend skalieren, aber nicht zu groß machen und immer Potenzen von 2 verwenden! (Hät den Code klein!)
    }else{
    PWM=currentadcval;
    }
    preadcval=currentadcval;
    }
    So, wenn du die Funktion jetzt alle 1/4 sec aufrufst (ja nicht zu oft, sonst wird die Änderung zu krass), sollte das ganze passen.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    15.05.2009
    Beiträge
    25
    @ s.o. :
    Ich glaube bei deiner Funktion treten zwei Probleme auf.

    Fall 1: Die ADC-Messung steigt stark an und bleibt dann auf einem Wert oder sinkt ganz leicht. Dann wird im ersten Schritt zwar verzögert, aber im zweiten Schritt der PWM-Wert sofort nachgeführt, weil in den else-abschnitt gesprungen wird.
    Beispiel:
    ADC: 0; 0; 1; 1; ...
    PWM: 0; 0; 0,25; 1; ...

    Fall 2: Der ADC-Wert steigt stark an, und steigt dann ganz leicht weiter... in diesem Fall wird die Variable "diff" sehr sehr klein, und PWM kaum erhöht, der Zielwert also gar nicht erreicht.

    Beispiel:
    ADC: 0; 0; 0,9; 0,91; 0,92; ...
    PWM: 0; 0; 0,225; 0,2275; 0,23; ...

    Im Anhang ein Plot von den zwei Problemen
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken sim_192.png  

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.07.2006
    Ort
    Karlsruhe/München
    Alter
    27
    Beiträge
    587
    Ja, du hast recht, das mit der Differenz führt zu Fehlern. Anderer Vorschlag: Ringpuffer und die ADC Werte mitteln. Falls ADC Wert kleiner als das Mittel, den ausgeben, sonst das Mittel. (Verbraucht aber deutlich mehr Rechenpower)
    Wenn jemand eine Lösung OHNE das Speichern alter Werte hat, dann wäre ich darauf gespannt wie ein Fuchs.

    EDIT: Ich habe den Fehler gefunden: (hoffentlich!)
    Code:
    16 Bit variablen:
    currentadcval: Momentaner ADC wert
    preadcval: ADC wert vom Vorherigen durchlauf
    diff: Differenz der Werte
    
    void pwm_output(currentadcval){
    if(currentadcval>preadcval){
    diff=currentadcval-PWM;
    PWM+=diff/4; // Faktor entsprend skalieren, aber nicht zu groß machen und immer Potenzen von 2 verwenden! (Hät den Code klein!)
    }else{
    PWM=currentadcval;
    }
    preadcval=currentadcval;
    }

Berechtigungen

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