Probleme bei einem PWM Signal in einer Pumpensteuerung

Moin brauche Hilfe bei der Formulierung eines PWM Befehls, ich hatte vorher ein einfaches <digitalWrite(pumpeEin; HIGH)>, was auch funktioniert, ich möchte die Pumpe jedoch runterfahren, kriege jetzt immer die Fehlermeldung:Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

    #include <Bounce2.h>            
    #include <SPI.h>                                                                              
    #include <Adafruit_GFX.h>                                 
    #include <Adafruit_SSD1306.h>                             
    #define OLED_RESET 4                                      
    Adafruit_SSD1306 display(OLED_RESET);
    int pumpeEin = 3;
    int messwert = 0;                                                                            
    byte value = 0;                                           
    int kontrollLed = 11;                                     
    unsigned int  mittelwert=0;                               
    unsigned int ausgabe =0;                                  
    byte tasterManuell = 8;                                   
    int zustandTaster = 0;                                    
    int pwm_val = 64;                                                   hier deklariere ich
                                              

    
    void setup()
    {

      //Code von Adafruit_Ind
      
      Serial.begin(9600);                                   
      display.begin(SSD1306_SWITCHCAPVCC, 0x3C);            
      display.display();                                    
      display.clearDisplay();                               
      display.setTextSize(1);                                   
      display.setCursor(0, 0);                              
      display.setTextColor(WHITE);                          
    
     
      pinMode ( pumpeEin, OUTPUT );                         
      pinMode (kontrollLed, OUTPUT);                       
      pinMode ( tasterManuell, INPUT );                     
      messwert = analogRead(A2);                            
       }
  
   void loop()
   {
         mittelwert = analogRead (A2);                        
         mittelwert = (mittelwert * 9 + messwert) / 10;       
                                                              
          
         
          
         ausgabe = ((mittelwert * 100)/650);                   
         zustandTaster = digitalRead (8);                     
   
     
        display.setCursor(0, 0);                              
        display.print("Humidity:");                           
        display.setCursor(72, 0);                             
        display.println(ausgabe);                             
        display.setCursor(90, 0);                             
        display.print ("%");                                 
        display.setCursor (0,10);                             
        display.print ("Schwellwert: 30%" );                  
        display.display();                                    
        display.clearDisplay();                               
        delay(200);                                           
      
    
    if ( ausgabe <= 30 )                                     
     {
           analogWrite(pumpeEin, pwm_val);                      
           display.setCursor(0, 0);                           
           display.print("Humidity:");                        
           display.println(ausgabe);                          
           display.setCursor(90, 0);                          
           display.print ("%");                               
           display.setCursor (0,10);                                
           display.print ("Schwellwert: 30%" );               
           display.setCursor (0,20);                          
           display.print("Giessvorgang starten");            
           display.display();                                 
           value = digitalRead (3);                           
           digitalWrite(kontrollLed, value);                  
           delay(1000);                                       //Giesszeit 1s.(experimentell ermittelt)
   
        }

  
    else if (zustandTaster == HIGH )                          //Zweite Bedingung : Wenn Taster betätigt ist( und damit Variable "zustandTaster" HIGH wahr ist) 
        {
            
          analogWrite(pumpeEin, pwm_val);                          
          value = digitalRead (3);                           
          digitalWrite(kontrollLed, value);                   
          display.setCursor (0,20);                           
          display.print("Giessvorgang manuell");              
          display.display();                                  
       } 
    else    
          {                                                   
        analogWrite(pumpeEin,0);                         
        value = digitalRead (3);                              
        digitalWrite(kontrollLed, value);                     
       }
   }

Berichtigung für den geneigten Leser:
das hochladen ist abgeschlossen, es funktioniert aber leider trotzdem nicht, kein Signal an Pin 3..
Vielen dank im vorraus

mittelwert = analogRead (A2);                        
         mittelwert = (mittelwert * 9 + messwert) / 10;

Da ich auch Anfänger bin, mit Vorsicht zu genießen...
Das ist ein seltsamer Mittelwert?
Du fragst (messwert) nur ein Mal im
setup() ab? Danach liest du den gleichen Pin im loop() einmal aus , multiplizierst den möglichen Messfehler mal 9 addierst den veralteten Wert dazu und teilst durch 10.
Ich verstehe das nicht. Kann aber auch an mir liegen.

Stefan

value = digitalRead (3);                           
digitalWrite(kontrollLed, value);

Einen PWM-Wert kann man so nicht zurücklesen, das sind wohl noch Überreste.

@Stefan, dies ist ein gleitender Mittelwert, und stabilisiert die Messung, es funktioniert ganz gut

Hombre_sin_nombre:
@Stefan, dies ist ein gleitender Mittelwert, und stabilisiert die Messung, es funktioniert ganz gut

Eher nicht, ich stimme Stefan vollkommen zu, möglicherweise so:

messwert = analogRead (A2);                       
mittelwert = (mittelwert * 9 + messwert) / 10;

Ja, so wird ein Mittelwert draus. Ich würde sogar vorschlagen

  messwert = analogRead (A2);                       
  mittelwert = (mittelwert * 7 + messwert) / 8;

Das geht schneller und spart ggf. ein paar hundert Bytes für die Division.

Was das fehlende PWM Signal betrifft, vermutlich schaltet digitalRead() den PWM Ausgang ab. Zumindest macht das digitalWrite() so. Zudem wäre zu prüfen, ob pwm_val=64 tatsächlich ausreicht, die Pumpe anzuwerfen.

Auch sonst enthält der Code noch mehr Stellen, an denen was schiefgehen kann.

messwert = analogRead (A2);                       
  mittelwert = (mittelwert * 7 + messwert) / 8;

kann aber auch nicht passen. Angenommen der Wert vo A2 ist 729 ,hab ich an einem Poti eingestellt und per 7-Segmentanzeige visualisiert. Am seriellen Monitor wird aber ein Mittelwert von 722 angezeigt , dieser geht nach einer ca. 1 Minute auf 723 und verweilt dort. Dreh ich am Poti auf 700 zurück sind Mittelwet seriell und 7-Segment gleich, nämlich 700.
Beim Hochdrehen auf 790 bei 7-Segment wird am Monitor nur 784 angezeigt.

Wenn sich der Wert sofort auf den neuen Wert ändern soll, darfst Du keinen Mittelwert bilden. Und wenn sich der Mittelwert schneller ändern soll, mußt Du ihn öfters berechnen. Wenn nur alle Minute ein neuer Mittelwert berechnet wird, dann kann sich auch die Anzeige nur alle Minute etwas ändern.

Wenn der Messwert aber bei 729 konstant stehen bleibt sollte auch der Mittelwert langsam auf 729 zugehen. Macht er aber nicht, bleibt bei 723 stehen . Keine Ahnung wie lange . Hab das nur ca 5 Minuten beobachtet.

Wenn sich messwert nicht ändert, bleibt bei Deiner Formel ein Fehler bestehen. Oder hast Du diesen Fehler schon korrigiert?

Ich verstehe es immer noch nicht.
Wenn ich einen Messfehler vermeiden möchte,
messe ich x mal , addiere die Werte und teile durch “x”. Dann habe ich den Mittelwert von 10 Messungen.
Den kann ich im nächsten Schritt mit dem letzten
Mittelwert mixen.

for(int i = 0; i < 11; i++ )      // 10x messen
{messwert= (messwert+ analogRead(A2));
delay (10);}      
 mittelwert= (mittelwert+(messwert/10))/2;

Hab ich da jetzt so nen Winkel in meiner Denke ?

Mal angenommen ich habe einen Messfehler in
Hombre_sins Programm. dann VERNEUNFACHE ich den Fehler
und mixe ihn mit dem EINFACHEN “richtigen” Wert aus der letzten Messung ?

Stefan

Zehnmal messen reicht doch schon für einen Mittelwert. Wenn die vorherige Messung "richtiger" oder "besser" wäre, müßte man doch garnicht nochmal messen?

Natürlich kann man das noch komplizierter und undurchsichtiger machen, nur darf man sich dann nicht darüber beschweren, daß nicht das herauskommt, was man gerne hätte.

StefanBoth:
Mal angenommen ich habe einen Messfehler in
Hombre_sins Programm. dann VERNEUNFACHE ich den Fehler
und mixe ihn mit dem EINFACHEN "richtigen" Wert aus der letzten Messung ?

Das siehst Du völlig richtig. Hinzu kommt noch, daß nicht mit der letzten Messung gemixt wird, sondern mit der allerersten.

for(int i = 0; i < 11; i++ )      // 10x messen

Das sind 11 Messungen!

StefanBoth:
Hab ich da jetzt so nen Winkel in meiner Denke ?

Es gibt verschiedene Mittelwerte.

  • Mittelwert: n Messungen durch n geteilt.
  • gleitender Mittelwert: zum mit n multiplizierten Mittelwert wird der Messwert addiert und die Summe durch n+1 dividiert.
  • Gewichteter gleitender Mittelwert, Exponentiell geglätteter Mittelwert …

Zu 2: Je größer n ist, desto “schwerer” ist der alte Mittelwert, desto langsamer ändert sich der Mittelwert.

Testprogramm:

uint32_t messwert, mittelwert, gewichtung = 7;

void setup()
{
  Serial.begin(9600);
  Serial.println("Mittelwertbildung");
  mittelwert = analogRead(A2) * 10;
}
void loop()
{
  if (millis() % 100)
  {
    messwert = analogRead(A2);
    mittelwert = ((mittelwert * gewichtung) + (messwert * 10) + gewichtung) / (gewichtung + 1);
    Serial.print("Meswert: ");
    Serial.print(messwert);
    Serial.print("\tMittelwert: ");
    Serial.print(mittelwert / 10);
    Serial.println();
  }
}

GleitenderMittelwert.png