Arduino Forum

International => Deutsch => Topic started by: Hermann_88 on Feb 14, 2015, 07:46 pm

Title: Tasterprogramm
Post by: Hermann_88 on Feb 14, 2015, 07:46 pm
Hallo Leute!

Ich habe wieder einmal eine Frage! Und zwar möchte ich eine LED hoch und runterdimmen mit 2 Tastern. Beim Hochdimmen gibt es keine Probleme. Nur beim runterdimmen springt der Wert der Led wenn sie aus ist wieder nach oben. Ein weiteres Problem ist, wenn die Led hochgedimmt ist und der Taster erneut betätigt wird dimmt die led vom Neuem.
Wie kann man das verhindern!

Der bisherige Code sieht daweil so aus. Bin für jede Hilfe dankbar!
Euer Hermann_88

Code: [Select]

int ledpin = 9;
int Taster1 = 2;
int Taster2 = 4;

int value1 = 0;
int value2 = 0;


void setup (){
 
  Serial.begin(9600);
  pinMode(ledpin,OUTPUT);
  pinMode(Taster1,INPUT);
  pinMode(Taster2,INPUT);
}
void loop (){
  value1 = digitalRead(Taster1);
  value2 = digitalRead(Taster2);
 
  if(value1 == HIGH) {
    for (value1 <=255 ; value1 +=2;){
    analogWrite(ledpin, value1);
    delay(50);
    if (value1 == 255){
  break;
      }
     
    }
  }
 
  if(value2 == HIGH) {
   
    for (value2 >= 255; value2 -=2;){
    analogWrite(ledpin, value2);
    delay(50);
     if (value2 == 0){
    break;
      }
  }
  }
}


EDIT BY MOD: added code tags
MOVED INTO PROPER LANGUAGE SECTION
Title: Re: Tasterprogramm
Post by: Serenifly on Feb 14, 2015, 08:49 pm
1. HIGH ist 1. Nicht 255. Du solltest da nicht mit dem Rückgabe-Wert von digitalRead() arbeiten, sondern die Schleifen-Variable per Hand auf ihren Ausgangswert setzen.

1. Selbst wenn du von 255 immer wieder 2 abziehst, kommst du nicht genau auf 0, da die Zahl ungerade ist. Du solltest die Abfrage auf > 255 oder < 0 machen. Nicht auf einen bestimmten Wert.

3. Die for-Schleife ist hier sowieso Fehl am Platz. Einfach wenn der Taster gedrückt wurde einmal inkrementieren, bzw. dekrementieren.
Title: Re: Tasterprogramm
Post by: combie on Feb 14, 2015, 09:25 pm
Meine Taster gehen gegen GND
Interne Pullup aktiviert


Code: [Select]

const int ledpin = 9;
const int Up     = 2;
const int Down   = 4;
const unsigned long speed   = 10; // kleinere Zahl schnelleres dimmen


struct Automat
{
  int dim = 0;
  unsigned long lastHit;
  Automat()
  {
    lastHit = millis();
    analogWrite(ledpin,dim);
  }
 
  void handle()
  {
    if(millis() - lastHit >= speed)
    {
      lastHit = millis();
      int neuerdim = dim;
      if(!digitalRead(Up)) neuerdim++;
      if(!digitalRead(Down)) neuerdim--;
      neuerdim = constrain(neuerdim,0,255);
      if(neuerdim != dim)
      {
        dim = neuerdim;
        analogWrite(ledpin,dim);
      }
    } 
  }
} Dimmer;

void setup ()
{
  pinMode(Up,INPUT_PULLUP);
  pinMode(Down,INPUT_PULLUP);
}
void loop ()
{
  Dimmer.handle();
}
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 14, 2015, 10:03 pm
Hallo Combie!

Das Programm ist wirklich toll. Ein einziges Problem dabei ist, dass die LED auch bei einem ganz kurzen HighSignal ganz hochdimmen soll. In dem Programm muss man den Taster dafür gedrückt halten. Würde das noch irgendwie gehn, die Funktion einzubauen?

LG
Title: Re: Tasterprogramm
Post by: combie on Feb 14, 2015, 10:21 pm
Klar kann man das!

Dann müsste man in der handle Methode einen einfachen endlichen Automaten einbauen.
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 14, 2015, 10:27 pm
Hi

Haha ist einmal nicht schlecht, dass es funktionieren würde. Nur ich bin ein totaler Anfänger und check das mit den Automaten nicht ganz. Es wäre echt lieb wenn du mir wenn du willst, das ein wenig erklären könntest. Welche Zeile im Programm, was macht.
Ich wäre dir echt dankbar dafür  :smiley-grin:

LG Hermann
Title: Re: Tasterprogramm
Post by: combie on Feb 14, 2015, 10:49 pm
Quote
Welche Zeile im Programm, was macht.
Was verstehst du denn nicht?
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 14, 2015, 10:50 pm
wie man so einen automaten strukturiert und was das mit dem millis() auf sich hat
Title: Re: Tasterprogramm
Post by: combie on Feb 14, 2015, 11:22 pm
Millis?
Dimmen hat was mit Zeit zu tun.
Du verwendest delay() dafür.
Dein Programm blockiert an den Stellen.



Zum endliche Automaten oder FSM gibts hier einige Threads
z.B. dieser hier: http://forum.arduino.cc/index.php?topic=297390.msg2073686#msg2073686 (http://forum.arduino.cc/index.php?topic=297390.msg2073686#msg2073686)
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 08:57 am
Ok, aber wie kann ich dem sagen, dass er nur auf den Tastendruck der 2 Taster hören soll?
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 09:16 am
Ich habs geschafft. Danke für deine Hilfe! :D
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 09:52 am
Ok ja ein Problem ist jetzt doch noch aufgetreten. Und zwar kann beim ersten aktivieren, die LED nicht hochdimmen. Es muss zuerst der runterdimmtaster betätigt werden. Dann funktioniert alles einwandfrei.
Code: [Select]

const unsigned int dimpin     = 3; // pin -- R -- LED -- GROUND
const unsigned int tasterpin1  = 4 ; // Pin -- Taster -- GROUND
const unsigned int tasterpin2  = 2 ; // Pin -- Taster -- GROUND
const unsigned int dimSpeed   = 50; // mS pro dimschritt



enum  AutomatenStatus {A_Taster1, A_Taster2, A_DimUp, A_DimDown};

struct Automat {
 AutomatenStatus status;
 unsigned long lastHit;
 byte dim;
 Automat() // Konstruktor
 {
   lastHit = millis();
   dim     = 0;
   status = A_Taster1;
   status = A_Taster2;
 }
} Astatus;


void setup()
{
 pinMode(tasterpin1, INPUT_PULLUP);
 pinMode(tasterpin2, INPUT_PULLUP);
 analogWrite(dimpin, Astatus.dim);
}

void loop()
{
 handleDim();
}

void handleDim()
{
 switch (Astatus.status)
 {
   case A_Taster1: if (!digitalRead(tasterpin1)) // low = taster gedrückt
     {
       Astatus.status = A_DimUp;
       Astatus.lastHit = millis();
     }
     break;

   case A_DimUp:  if (millis() - Astatus.lastHit > dimSpeed) // low = taster gedrückt
     {
       Astatus.lastHit = millis();
       Astatus.dim++;
       analogWrite(dimpin, Astatus.dim);
     }
     if (Astatus.dim == 255)
     {
       Astatus.status = A_Taster2 ;
     }
     break;
case A_Taster2: if (!digitalRead(tasterpin2)) // low = taster gedrückt
     {
       Astatus.status = A_DimDown;
       Astatus.lastHit = millis();
     }
     break;

 

   case A_DimDown:  if (millis() - Astatus.lastHit > dimSpeed) // low = taster gedrückt
     {
       Astatus.lastHit = millis();
       Astatus.dim--;
       analogWrite(dimpin, Astatus.dim);
     }
     if (Astatus.dim == 0)
     {
       Astatus.status = A_Taster1;
     }
     break;
 }
}
Title: Re: Tasterprogramm
Post by: combie on Feb 15, 2015, 10:37 am
Hast du dich schon per Google über endliche Automaten kundig gemacht?
Generationen von Programmierer haben sich da schon einen Kopf drum gemacht.
Und jetzt bist du dran :D :D :D


Ja, ich weiß, vieles im Netz ist sehr theoretisch.
Zu theoretisch.

---------

Du solltest dir mal ein Bild malen.

Mit diesen Dingen:
Die nötigen Zustände (um dein Ziel zu erreichen)
Übergänge (welche und warum Zustandswechsel)

Oder erst einmal eine Liste der Zustände:
(man kann hier im Forum so schlecht malen)
1. LampeIstAus
2. HochDimmen
3. LampeIstAn
4. RunterDimmen
Diese Zustände sollten doch für deinen Zweck reichen, oder?

Dann gehts jetzt an die Übergänge:
Im Zustand 1 wird auf den HochDimTastenDruck gewartet. Wenn gedrückt wird zu Zustand 2 gewechselt.
Im Zustand 2 wird die Helligkeit erhöht. Wenn voll an wird zu Zustand 3 gewechselt.
Im Zustand 3 wird auf den RunterDimTastenDruck gewartet. Wenn gedrückt wird zu Zustand 4 gewechselt.
Im Zustand 4 wird die Helligkeit verringert. Wenn total aus wird zu Zustand 1 gewechselt.

Die Lampe beginnt im Aus Zustand.
Die Zustände rauf und runter dimmen können nicht unterbrochen werden.

Stimmt das so?
Entsprechen die Regeln deinen Vorstellungen?

Wenn ja, hast du da jetzt ein Muster, welches man in Software gießen kann.




In meinem Stil würde das dann so aussehen:
Code: [Select]
const unsigned int dimpin      =  3; // pin -- R -- LED -- GROUND
const unsigned int UpTaster    =  4; // Pin -- Taster -- GROUND
const unsigned int DownTaster  =  2; // Pin -- Taster -- GROUND
const unsigned int dimSpeed    = 50; // mS pro dimschritt




struct Automat
{
  typedef enum  AutomatenStatus {A_On, A_Off, A_DimUp, A_DimDown};
  AutomatenStatus status;
  unsigned long lastHit;
  byte dim;
  Automat() // Konstruktor
  {
    pinMode(UpTaster, INPUT_PULLUP);
    pinMode(DownTaster, INPUT_PULLUP);
    lastHit = millis();
    dim     = 0;
    status  = A_Off;
    analogWrite(dimpin,dim);
  }
 
void handle()
{
  switch (status)
  {
    case A_Off:
      if (!digitalRead(UpTaster)) // low = taster gedrückt
      {
        status  = A_DimUp;
        lastHit = millis();
      }
      break;

    case A_DimUp: 
      if (millis() - lastHit > dimSpeed)
      {
        lastHit = millis();
        dim++;
        analogWrite(dimpin,dim);
      }
      if (dim == 255)
      {
        status = A_On ;
      }
      break;
     
   case A_On: if
      (!digitalRead(DownTaster)) // low = taster gedrückt
      {
        status  = A_DimDown;
        lastHit = millis();
      }
      break;

    case A_DimDown: 
      if (millis() - lastHit > dimSpeed)
      {
        lastHit = millis();
        dim--;
        analogWrite(dimpin, dim);
      }
      if (dim == 0)
      {
       status = A_Off;
      }
      break;
  }
}
};





Automat Dimmer;
void setup()
{
}

void loop()
{
   Dimmer.handle();
}


*ungetestet*
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 06:24 pm
Ok da kommt so eine Fehlermeldung, die heißt
undefined reference to `setup'
undefined reference to `loop'
Title: Re: Tasterprogramm
Post by: combie on Feb 15, 2015, 06:28 pm
Nein!
Du hast vermutlich nicht alles kopiert.
Title: Re: Tasterprogramm
Post by: AndreasVan on Feb 15, 2015, 06:29 pm
Fehler beim kopieren würd ich sagen, bei mir gehts  8)
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 06:51 pm
Hahaha sorry  :smiley-lol:

Ok das mit dem Dimmen haut jetzt super hin und den Automaten versteh ich jetzt auch schon besser. Ein Problem hab ich jetzt noch. Und zwar das eigentliche Projekt soll wie folgt ablaufen.

Mit dem einen Taster soll eine rgb in rot und blau, sprich violett, hochdimmen. Danach sollen die selben LED´s pulsweitenmoduliert über 2 analoge Eingänge gesteuert werden können. Zum Schluss soll dann durch den Taster die LED wieder runterdimmen. Die PWM habe ich selber geschafft zu programmieren. Nur wenn ich die zwei Programme zusammenfüge stören die sich gegenseitig und die LED beginnt zu flackern. Hast du da irgendwelche Tipps für mich oder sogar die Lösung?

Bin dir aber jetzt schon mal sehr dankbar. Ohne dich hätte ich das Projekt nicht einmal annähernd weitergebracht.
Title: Re: Tasterprogramm
Post by: combie on Feb 15, 2015, 06:56 pm
Neue Bedingungen -- führt zu -- neuen Zuständen
Also: Den Automaten erweitern.


Nein, eine fertige Lösung habe ich nicht.

Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 06:59 pm
Ok, aber prinzipiell würde das funktionieren?
Title: Re: Tasterprogramm
Post by: combie on Feb 15, 2015, 07:13 pm
Male dir die Zustände auf Papier auf.
Male die Übergänge dazu.
Dann siehst du ob deine Logik funktioniert.
Gieße die Logik in Software.
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 15, 2015, 08:21 pm
Ok bisheriger stand ist wie folgt. Erstes Problem ist, wenn ie LED hochgedimmt hat und kein analog Input anliegt, ist die LED aus. Ich möchte das die LED auf dem Wert ist und von diesem Wert weg moduliert werden kann. Das nächste Problem ist, wenn der zweite Taster betätigt wird, leuchtet die LED ganz hell und dimmt dann erst herunter. Irgendwelche Ideen?

Derzeitiges Programm:

const unsigned int UpTaster    =  4; // Pin -- Taster -- GROUND
const unsigned int DownTaster  =  2; // Pin -- Taster -- GROUND
const unsigned int dimSpeed    = 50; // mS pro dimschritt
const int rot = A0;  // Analog input pin that the sensor is attached to
const int blau = A1;  // Analog input pin that the sensor is attached to

const int analogOutrot = 9; // Analog output pin that the LED is attached to
const int analogOutblau = 10; // Analog output pin that the LED is attached to
const int analogOutstaerke = 3;

int wert1 = 0;        // value read from the pot
int wert2 = 0;
int outputrot = 0;        // value output to the PWM (analog out)
int outputblau = 0;


struct Automat
{
  typedef enum  AutomatenStatus {A_On, A_Off, A_DimUp, A_DimDown,A_PWM};
  AutomatenStatus status;
  unsigned long lastHit;
  byte dim;
  Automat() // Konstruktor
  {
    pinMode(UpTaster, INPUT_PULLUP);
    pinMode(DownTaster, INPUT_PULLUP);
    pinMode(rot, INPUT);
    pinMode(blau, INPUT);
    lastHit = millis();
    dim     = 0;
    status  = A_Off;
    analogWrite(analogOutrot,dim);
    analogWrite(analogOutblau,dim);
  }
 
void handle()
{
  switch (status)
  {
    case A_Off:
      if (!digitalRead(UpTaster)) // low = taster gedrückt
      {
        status  = A_DimUp;
        lastHit = millis();
      }
      break;

    case A_DimUp: 
      if (millis() - lastHit > dimSpeed)
      {
        lastHit = millis();
        dim++;
        analogWrite(analogOutrot,dim);
        analogWrite(analogOutblau,dim);
      }
      if (dim == 255)
      {
        status = A_PWM ;
      }
      break;
     
      case A_PWM:
     
       wert1 = analogRead(rot);           
  // map it to the range of the analog out:
      outputrot = map(wert1, 0, 1023, 0, 255); 
 
  // change the analog out value:
  analogWrite(analogOutrot, outputrot);         
   
 
  wert2 = analogRead(blau);
  outputblau = map(wert2, 0, 1023, 0, 255);
  analogWrite(analogOutblau, outputblau);
  status = A_On;
     
   case A_On: if
      (!digitalRead(DownTaster)) // low = taster gedrückt
      {
        status  = A_DimDown;
        lastHit = millis();
      }
      break;

    case A_DimDown: 
      if (millis() - lastHit > dimSpeed)
      {
        lastHit = millis();
        dim--;
        analogWrite(analogOutrot,dim);
        analogWrite(analogOutblau,dim);
      }
      if (dim == 0)
      {
       status = A_Off;
      }
      break;
  }
}
};





Automat Dimmer;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
   Dimmer.handle();
 
}
Title: Re: Tasterprogramm
Post by: combie on Feb 16, 2015, 08:43 am
Quote
Irgendwelche Ideen?
Aber sicher!

Quote
Ich möchte das die LED auf dem Wert ist und von diesem Wert weg moduliert werden kann.
Wie soll das gehen?
Du könntest Motor betriebene Potis einsetzen. (welche sich selber auf die richtige Position drehen)
Oder anstelle der Potis auf Drehencoder setzen.
Oder die Bedienmannschaft so trainieren, dass sie das Poti vor dem runter dimmern ganz aufdreht.




Quote
Das nächste Problem ist, wenn der zweite Taster betätigt wird, leuchtet die LED ganz hell und dimmt dann erst herunter.
Wenn du meinem Dimmer Automaten den dim Wert vorbesetzt, dann läuft er auch ab da los, wenn der in einen Dim Zustand fällt.
Title: Re: Tasterprogramm
Post by: Hermann_88 on Feb 16, 2015, 07:20 pm
Ok ich hab mich mit dem ganzen relativ lang herumprobiert. Dabei gibt es jetzt noch folgende Probleme. In der Case A_PWM (siehe Programm), ist die Pulsweitenmodulation eingebaut. Da ist es so, dass nur ein Wert ausgelesen wird. Ich möchte aber die LED´s durchgehend regeln können, bis der zweite Taster betätigt wurde. Wie mache ich das?

2. nachdem alle LED´s runtergedimmt haben, soll der ganze Zyklus von neuem starten. Danke für eure Hilfe im Voraus.

const unsigned int UpTaster    =  4; // Pin -- Taster -- GROUND
const unsigned int DownTaster  =  2; // Pin -- Taster -- GROUND
const unsigned int dimSpeed    = 50; // mS pro dimschritt
const int warm = A0;  // Analog input pin that the sensor is attached to
const int kalt = A1;  // Analog input pin that the sensor is attached to
const int staerke = A2;  // Analog input pin that the sensor is attached to
const int analogOutwarm = 9; // Analog output pin that the LED is attached to
const int analogOutkalt = 10; // Analog output pin that the LED is attached to
const int analogOutstaerke = 3;

int wert1 = 0;        // value read from the pot
int wert2 = 0;
int wert3 = 0;
int outputwarm = 0;        // value output to the PWM (analog out)
int outputkalt = 0;
int outputstaerke = 0;

struct Automat
{
  typedef enum  AutomatenStatus {A_On, A_Off, A_DimUp, A_DimDown,A_PWM};
  AutomatenStatus status;
  unsigned long lastHit;
  byte dim;
  Automat() // Konstruktor
  {
    pinMode(UpTaster, INPUT_PULLUP);
    pinMode(DownTaster, INPUT_PULLUP);
    pinMode(warm, INPUT);
    pinMode(kalt, INPUT);
    lastHit = millis();
    dim     = 0;
    status  = A_Off;
    analogWrite(analogOutwarm,dim);
    analogWrite(analogOutkalt,dim);
  }
 
void handle()
{
  switch (status)
  {
    case A_Off:
      if (!digitalRead(UpTaster)) // low = taster gedrückt
      {
        status  = A_DimUp;
        lastHit = millis();
      }
      break;

    case A_DimUp: 
      if (millis() - lastHit > dimSpeed)
      {
        lastHit = millis();
        dim++;
        analogWrite(analogOutwarm,dim);
        analogWrite(analogOutkalt,dim);
      }
      if (dim == 62)
      {
        status = A_PWM ;
      }
      break;
     
     case A_PWM:
     
      wert1 = analogRead(warm);           
      // map it to the range of the analog out:
      outputwarm = map(wert1, 0, 1023, 0, 255); 
 
      // change the analog out value:
      analogWrite(analogOutwarm, outputwarm);         
   
      wert2 = analogRead(kalt);
      outputkalt = map(wert2, 0, 1023, 0, 255);
      analogWrite(analogOutkalt, outputkalt);
      status = A_On;
      break; //!!!!!!!
    
   case A_On:
     if (!digitalRead(DownTaster)) // low = taster gedrückt
      {
        status  = A_DimDown;
        lastHit = millis();
      }
      break;

    case A_DimDown: 
      if (millis() - lastHit > dimSpeed)
      {
      Serial.print("A_DimDown: dim=");
      Serial.println(dim);
        lastHit = millis();
        dim--;
        //analogWrite(analogOutwarm,dim);
        //analogWrite(analogOutkalt,dim);
      Serial.print("A_DimDown: outputkalt=");
      Serial.println(outputkalt);
        analogWrite(analogOutwarm,outputwarm--);
        analogWrite(analogOutkalt,outputkalt--);
      if (outputwarm < 0) outputwarm=0;
      if (outputkalt < 0) outputkalt=0;
if(dim == -194){
       status = A_Off;
}
      break;
  }
}
}
};





Automat Dimmer;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
   Dimmer.handle();
   wert3 = analogRead(staerke);
  outputstaerke = map(wert3, 0, 1023, 0, 255);
  analogWrite(analogOutstaerke, outputstaerke);
 
}
Title: Re: Tasterprogramm
Post by: combie on Feb 16, 2015, 08:55 pm
Du solltest wirklich mal anfangen die Code BBCode Tags zu verwenden!
Bitte nutze sie.



Quote
Da ist es so, dass nur ein Wert ausgelesen wird. Ich möchte aber die LED´s durchgehend regeln können, bis der zweite Taster betätigt wurde. Wie mache ich das?
Mich wundert das nicht.
Der Automat bleibt nur für eine Runde in dem Zustand.
Warum?
Weil du in der Runde einen Zustandswechsel einleitest.
Ändere das.