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
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
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.
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.
Die for-Schleife ist hier sowieso Fehl am Platz. Einfach wenn der Taster gedrückt wurde einmal inkrementieren, bzw. dekrementieren.
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?
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
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.
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;
}
}
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
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)
LampeIstAus
HochDimmen
LampeIstAn
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:
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();
}
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.