Go Down

Topic: Tasterprogramm (Read 3393 times) previous topic - next topic

Hermann_88

Feb 14, 2015, 07:46 pm Last Edit: Feb 14, 2015, 08:38 pm by leo72
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

Serenifly

#1
Feb 14, 2015, 08:49 pm Last Edit: Feb 14, 2015, 09:02 pm by Serenifly
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.

combie

#2
Feb 14, 2015, 09:25 pm Last Edit: Feb 15, 2015, 09:27 am by combie
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();
}
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Hermann_88

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

combie

Klar kann man das!

Dann müsste man in der handle Methode einen einfachen endlichen Automaten einbauen.
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Hermann_88

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

combie

Quote
Welche Zeile im Programm, was macht.
Was verstehst du denn nicht?
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Hermann_88

wie man so einen automaten strukturiert und was das mit dem millis() auf sich hat

combie

#8
Feb 14, 2015, 11:22 pm Last Edit: Feb 15, 2015, 09:44 am by combie
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
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Hermann_88

Ok, aber wie kann ich dem sagen, dass er nur auf den Tastendruck der 2 Taster hören soll?

Hermann_88

Ich habs geschafft. Danke für deine Hilfe! :D

Hermann_88

#11
Feb 15, 2015, 09:52 am Last Edit: Feb 16, 2015, 09:21 am by uwefed Reason: add CODE TAGs
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;
 }
}

combie

#12
Feb 15, 2015, 10:37 am Last Edit: Feb 15, 2015, 11:15 am by combie
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*
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Hermann_88

Ok da kommt so eine Fehlermeldung, die heißt
undefined reference to `setup'
undefined reference to `loop'

combie

Nein!
Du hast vermutlich nicht alles kopiert.
Es ist offensichtlich, dass uns die Umstände alleine nicht glücklich oder unglücklich machen.
Es ist die Art unserer Reaktion darauf, die unsere Gefühle bestimmt.

Go Up