Pages: [1]   Go Down
Author Topic: Definierte Einschaltdauer erzeugen  (Read 827 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

da ich mit der Materie noch nicht so vertraut bin, stehe ich vor einem wahrscheinlich eher kleinen Problem.
ich habe folgende Funktion an die ich die Variable startPump übergebe um den PWM Ausgang für eine Pumpe zu steuern. Mit dem Taster s_button schalte ich die Pumpe.
Nun würde ich gerne mit der Variable timePump noch die Einschaltdauer der Pumpe steuern.
Jetzt habe ich versucht mit millis (aus dem Beispiel "Blink without delay") ein Zeitglied zu bilden, jedoch mit dem Ergebniss dass die Einschaltdauer trotzdem immer um einige Sekunden schwankte.
Kann mir bitte jemand weiterhelfen?
Delay würde ich nur ungern nutzen.

Code:
void StartderPumpe(byte startPump, byte timePump){        //Neue Funktion; Übergabe START _ STOPP (PWM) und Einschaltdauer der Pumpe

  s_buttonState = digitalRead(s_button);

  if (s_buttonState != s_lastButtonState) {               // compare the buttonState to its previous state
    if (s_buttonState == HIGH) {                          // if the state has changed, increment the counter
      s_buttonPushCounter++;                              // if the current state is HIGH then the button went from off to on:
    }
  } 
  s_lastButtonState = s_buttonState;                      // save the current state as the last state, for next time through the loop
  if (s_buttonPushCounter % 2 == 0) {                     //Vergleich zwischen m_buttonPushCounter und Teiler, auf Rest 0 
    analogWrite(Pump, startPump);

  }
  else {
    analogWrite(Pump, 0);
  }
}
Logged

Heilbronn
Offline Offline
Full Member
***
Karma: 0
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

Und wo ist da was mit Zeitdauer in deinem Scetch?

Kannst mal den gesamten Code posten?

Grüße,
Jürgen

Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ja sorry, hier nochmal die Version mit der ich es bisher versucht hatte.
Der Code funktioniert soweit, jedoch ist dieEeinschaltdauer zu ungenau.


Code:
void StartderPumpe(byte startPump, int timePump){        //Neue Funktion; Übergabe START _ STOPP (PWM) und Einschaltdauer der Pumpe

  s_buttonState = digitalRead(s_button);

  if (s_buttonState != s_lastButtonState) {               // compare the buttonState to its previous state
    if (s_buttonState == HIGH) {                          // if the state has changed, increment the counter
      s_buttonPushCounter++;                              // if the current state is HIGH then the button went from off to on:
    }
  } 
  s_lastButtonState = s_buttonState;                      // save the current state as the last state, for next time through the loop
  if (s_buttonPushCounter % 2 == 0) {                     //Vergleich zwischen m_buttonPushCounter und Teiler, auf Rest 0 
   
    s_currentMillis = millis();
    if(s_currentMillis - s_previousMillis > timePump) {
    s_previousMillis = s_currentMillis;
   
  s_buttonPushCounter++; 
  }
    else {
    analogWrite(Pump, startPump);
  }
  }
 else {
    analogWrite(Pump, 0);
}
}
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 235
Posts: 20230
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mit dem geposteten Code kann ich Dir nichts sagen. Du schickst eine Funktion aber keine Information wie und wann sie aufgerufen wird.
Alles oder nichts ( den ganzen Code oder wir können Dir leider nicht helfen)
JuergenR hat Dich bereits nach dem gesamten Code gefragt.

Das ärgert mich jetzt. Man fragt Dich um den gesamten Code / Sketch und Du willst nicht damit rausrücken. Was ist das Problem den gesamten Sketch uns zu geben?
Grüße Uwe
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ärgern wollte ich bestimmt keinen, mein "geschreibsel" ist bestimmt kein Geheimniss  smiley-red

weil die Funktion aber richtig aufgerufen wird, dachte ich es reicht wenn ich danach frage wie ich das "Zeitglied" für die Einschaltdauer der Pumpe in dieser Funktion bilde. Natürlich dennoch hier der gesamte bisherige Code.

Code:
// this constant won't change:
const byte m_button = 4;
const byte s_button = 1;
const byte pinPot = 3;
const byte ledPin = 2;           // the pin that the LED is attached to
const byte Pump = 0;

// Variables will change:
byte m_buttonPushCounter = 0;    // (Menge) counter for the number of button presses
byte m_buttonState = 0;          // (Menge) current state of the button
byte m_lastButtonState = 0;      // (Menge) previous state of the button
byte s_buttonPushCounter = 0;    // (Start/Stop Taster) counter for the number of button presses
byte s_buttonState = 0;          // (Start/Stop Taster) current state of the button
byte s_lastButtonState = 0;      // (Start/Stop Taster) previous state of the button
byte ledState = LOW;             // ledState used to set the LED

unsigned long s_currentMillis = 0;
long s_previousMillis = 0;
unsigned long m_currentMillis = 0;
long m_previousMillis = 0;
long previousMillis = 0;         // will store last time LED was updated
//long interval = 3000;               // interval at which to blink (milliseconds)
int valPot = 0;                  // Zum zwischenspeichern des Potentiometerwert
byte pumpPoti;
byte pwmPump = 0;                //Sollwert der Pumpe (6-12V) von Potentiometer
byte blinks = 0;

void setup()
{
  pinMode (m_button, INPUT);                                 // m_Button pin als Eingang deklariert
  pinMode (s_button, INPUT);                                 // s_Button pin als Eingang deklariert
  pinMode (Pump, OUTPUT);                                    // pin 5  // OC0A
  pinMode(ledPin, OUTPUT);

  //Timer 0, A side
  TCCR0A = _BV (WGM00) | _BV (WGM01) | _BV (COM0A1);      // fast PWM, clear OC0A on compare
  TCCR0B = _BV (CS00);                                    // fast PWM, top at 0xFF, no prescaler                                   


  pwmPump = 0;                                            // PWM duty cycle


} // end of setup

void loop() {

  // read the pushbutton input pin:



  valPot = analogRead(pinPot);                            //Potentiometerwert einlesen
  pumpPoti = map(valPot, 0, 1023, 85, 255);              //Anpassung Potentiometerwert (0-1024) zu pumpPoti (6-12V=135-255)

  m_buttonState = digitalRead(m_button);

  if (m_buttonState != m_lastButtonState) {               // compare the buttonState to its previous state
    if (m_buttonState == HIGH) {                          // if the state has changed, increment the counter
      m_buttonPushCounter++;                              // if the current state is HIGH then the button went from off to on:
    }
  }
  m_lastButtonState = m_buttonState;                      // save the current state as the last state, for next time through the loop
  if (m_buttonPushCounter == 1){
    pwmPump = pumpPoti;
    m_currentMillis = millis();
    if(m_currentMillis - m_previousMillis > 25000) {      // Blinktakt 1 * LED freigeben
      m_previousMillis = m_currentMillis;
      if (blinks == false)
        blinks = true;
      else
        blinks = false;

    }
    Blinktakt(blinks);
  } 
  if (m_buttonPushCounter == 2){
    pwmPump = 135;
    m_currentMillis = millis();
    if(m_currentMillis - m_previousMillis > 50000) {      // Blinktakt 2 * LED freigeben
      m_previousMillis = m_currentMillis;
      if (blinks == false)
        blinks = true;
      else
        blinks = false;

    }
    Blinktakt(blinks);   
  }
  if (m_buttonPushCounter == 3){
    pwmPump = 180;
    m_currentMillis = millis();
    if(m_currentMillis - m_previousMillis > 75000) {      // Blinktakt 3 * LED freigeben
      m_previousMillis = m_currentMillis;
      if (blinks == false)
        blinks = true;
      else
        blinks = false;

    }
    Blinktakt(blinks);
  }
  if (m_buttonPushCounter == 4) {                     
    //m_buttonPushCounter = 0;
    pwmPump = 222;
    m_currentMillis = millis();
    if(m_currentMillis - m_previousMillis > 100000) {      // Blinktakt 4 * LED freigeben
      m_previousMillis = m_currentMillis;
      if (blinks == false)
        blinks = true;
      else
        blinks = false;

    }
    Blinktakt(blinks);
  }
  if (m_buttonPushCounter == 5) {
    m_buttonPushCounter = 1;
  }
  int m_time = 10;
  StartderPumpe(pwmPump, m_time);                       //Übergabe an "Void Start der Pumpe"
}

void StartderPumpe(byte startPump, int timePump){        //Neue Funktion; Übergabe START _ STOPP (PWM) und Einschaltdauer der Pumpe

  s_buttonState = digitalRead(s_button);

  if (s_buttonState != s_lastButtonState) {               // compare the buttonState to its previous state
    if (s_buttonState == HIGH) {                          // if the state has changed, increment the counter
      s_buttonPushCounter++;                              // if the current state is HIGH then the button went from off to on:
    }
  } 
  s_lastButtonState = s_buttonState;                      // save the current state as the last state, for next time through the loop
  if (s_buttonPushCounter % 2 == 0) {                     //Vergleich zwischen m_buttonPushCounter und Teiler, auf Rest 0 
   
    s_currentMillis = millis();
    if(s_currentMillis - s_previousMillis > timePump) {
    s_previousMillis = s_currentMillis;
   
  s_buttonPushCounter++; 
  }
    else {
    analogWrite(Pump, startPump);
  }
  }
 else {
    analogWrite(Pump, 0);
}
}


void Blinktakt(int interval) {                              //Neue Funktion Blinktakt der LED

  if(interval == true) {

    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis > 12500) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;   

      // if the LED is off turn it on and vice-versa:
      if (ledState == LOW)
        ledState = HIGH;
      else
        ledState = LOW;

      // set the LED with the ledState of the variable:
      digitalWrite(ledPin, ledState);
    }
  }
  if(interval == false){
    digitalWrite(ledPin, LOW);
  }
}

Zur Erklärung: mit dem m_buttoon kann ich 4 PWM Frequenzen für die Pumpe auswählen (Stufe 1 Potentiometerwert), mit s_button starte und stoppe ich die Pumpe. Die LED gibt den Status der Stufe wieder.
Also bitte nicht falschverstehen, der Code wird einigen die Tränen in die Augen treiben, aber mir geht es in diesem Projekt schließlich ums lernen :-)
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 235
Posts: 20230
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wie groß ist die Ungenauigkeit der Einschaltzeit denn?

Ich nehme an Du verwendest externe Pulldown Widerstände und eine Arduino UNO.

Einige programmtechnische Ratschläge:
Ich würde nicht einen Zähler für s_buttonPushCounter verwenden sondern eine Variable die TRUE oder FALSE sein kann.
Das vereinfacht
if (Start_buttonPushCounter % 2 == 0)
in
if (Start_buttonPushCounter)

Code:
if (blinks == false)
        blinks = true;
      else
        blinks = false;
Der else-Teil hat keinen Sinn. Laß ihn weg.

Du läßt die LEDS mit 25, 50, 75 oder 100 Sekunden blinken?

Die Pins 0 und 1 verwenden ist eine schlechte Idee; dort ist der USB Adapter angeschlossen. Den brauchst Du zum programmieren des Arduino. Benutze andere Pins.
Pin 0 ist kein PWM pin.

Die Variablen für die Zeit sollten "unsigned long" sein.

int m_time = 10;
Die Pumpe soll wirklich 10 Millisekunden eingeschaltet sein?

Grüße Uwe
« Last Edit: December 31, 2012, 11:35:34 am by uwefed » Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo Uwe,

danke für deine Anwort.
Also ich benutze einen attiny85 (8Mhz) den ich per ISP beschreibe, deswegen das pinout.
Deswegen (glaube ich) ergeben sich andere Zeiten für millis.
Ich erzeuge in der Funktion Blinktakt einen Grundtakt für die LED den ich bei den einzelnen Mengenstufen jeweils für bestimmte Zeit freigebe. Also Grundsätzlich scheint millis hier ja zu funktionieren. Zumindest blinkt die LED plausibel.

int m_time = 10; ist ein Fehler, von einem test normalerweise übergebe ich 10000 oder 20000, damit habe ich ein paar sekunden Laufzeit.

im bsp. "blink without delay" wird nur currentMillis mit unsigned deklariert, ist das ein Fehler? Ich dachte das hat was mit Minuszeit zutun oder so.

Edit: gerade fällt mir auf dass ich Timer 0 des Chips im fast pwm modus betreibe, weil das pwm soviel schöner ist als ohne. Die Pumpe läuft wesentlich besser, hier scheint wohl der Hund mit den millis begraben zu sein, oder?

« Last Edit: December 30, 2012, 04:23:35 pm by fckw » Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 235
Posts: 20230
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also ich benutze einen attiny85 (8Mhz) den ich per ISP beschreibe, deswegen das pinout.

Und wann wolltest Du uns das sagen?  smiley-eek smiley-eek smiley-eek

Bin mir nicht ganz sicher aber Timer0 müßte für millis() verwendet werden. Für PWM kannst Du Timer 1 verwenden.

Grüße Uwe
Logged

Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ja aber das Problem ist, dass ich bei Timer 1 kein fastpwm setzen kann, jedenfalls habe ich nichts darüber gefunden. <-- wenn hier jemand was darüber weiß, immer herdamit :-)
So läuft die Pumpe jedenfalls schlecht mit den normalen timings.

ich will ja auch keine fertige Lösung für meinen code.
Vielleicht kann ja jemand ein Beispiel auführen?

Problemstellung: Einer Funktion werden zwei Variablen übergeben (pwm, time) diese zwei Variablen bestimmen wie lange und mit welchen Tastverhältniss ein Ausgang gesetz wird.
So dass am Ende "analogwrite(Pin,pwm);" rauskommt und das "time" die Zeit von "analogwrite" bestimmt.
Wie würdet ihr sowas umsetzen, ohne delay zu verwenden?

« Last Edit: December 30, 2012, 06:10:47 pm by fckw » Logged

0
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3420
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
if (blinks == false)
        blinks = true;
      else
        blinks = false;
Der else-Teil hat keinen Sinn. Laß ihn weg.
D "if" auch nicht. Schreib doch gleich
Code:
blinks = true;
Logged

Check out my experiments http://blog.blinkenlight.net

Munich/Germany
Offline Offline
God Member
*****
Karma: 9
Posts: 642
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
if (blinks == false)
        blinks = true;
      else
        blinks = false;
Der else-Teil hat keinen Sinn. Laß ihn weg.
D "if" auch nicht. Schreib doch gleich
Code:
blinks = true;
Ich würde mal sagen der ursprüngliche Code macht durchaus Sinn (als Toggle).
Die korrekte Kurzform davon wäre:
Code:
blinks = !blinks
Logged

_______
Manfred

0
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3420
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Upps, hatte ich übersehen. Hast Du recht!
Logged

Check out my experiments http://blog.blinkenlight.net

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 235
Posts: 20230
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ihr habt recht, da hatte ich einen Blödsinn gesagt.
Entschuldige fckw
Grüße Uwe
Logged

Pages: [1]   Go Up
Jump to: