Forum: Mikrocontroller und Digitale Elektronik Programm zählt Variable hoch wenn Taster gedrückt, wie unterbinden?


von Christian K. (hmpfknpf)


Lesenswert?

Hallo!

Ich bin absoluter Programmier-Anfänger und hab keine Ahnung wie ich 
meine Fehler beheben kann.

Der Code ist im Anhang.

Ich bin momentan am Programmieren von eimer RC-Lichtanlage.
Die Schaltung der einzelnen LED's soll über einen 1-0-1 Taster an der 
Funke gesteuert werden, das Funktioniert auch fast gut.
Das Problem ist wenn ich den Taster gedrückt halte wird die Variable SM 
jedesmal um 1 veränder. das macht ein genaues wählen der gewünschten 
Beleuchtungsart fast zum russischen Roulette.
Was ich möchte ist das ich den Taster gedrückt halten kann und die 
Variable um 1 verändert wird, danach muss ich den Taster erneut drücken 
um die Variable wieder um 1 zu verändern.

ich hoffe das ganze ist verständlich was ich genau möchte :D


Gruß
hmpfknpf

1
int ch4;                  //Der Kanal den man auslesen möchte
2
int StandlichtL = 13;     //Pin für das Standlicht links
3
int StandlichtR = 5;      //Pin für das Standlicht rechts
4
int AbblendlichtL = 10;   //Pin für die Bi-Xenoneinheit links    
5
int AbblendlichtR = 11;   //Pin für die Bi-Xenoneinheit Rechts
6
int SM = 0;               //Merker für Standlicht an oder aus                                               
7
int AM = 0;               //Merker für Abblendlicht an oder aus
8
int ANZ=3;                //Anzahl der Schaltstufen des Lichtschalters 
9
int i;                                     
10
int del = 20;             //Pause wird benötigt für das Aufdimmen vom Xenon
11
int helligkeit = 90;      //Helligkeit des Abblendlichts
12
int dim = 10;             //Schritte für das Aufdimmen vom Xenon
13
14
void setup() 
15
{
16
  pinMode(7, INPUT);      //Pin 7 Eingang z Auswerten d Funksignals
17
  pinMode(StandlichtL, OUTPUT);
18
  pinMode(StandlichtR, OUTPUT);
19
  pinMode(AbblendlichtL, OUTPUT);
20
  pinMode(AbblendlichtR, OUTPUT);
21
  Serial.begin(9600); 
22
}
23
24
void loop() 
25
{
26
  ch4 = pulseIn(7, HIGH, 11000);                          
27
28
29
  {
30
    Serial.print("Channel 4:"); 
31
  Serial.println(ch4);
32
  Serial.print ("Standlicht:");
33
  Serial.println (SM);
34
  Serial.print ("Abblendlicht:");
35
  Serial.println(AM);
36
delay (100);
37
}
38
if (ch4 >1700)   
39
  {
40
      ++SM;      
41
  }
42
if (ch4 <1100)                                        
43
{
44
     --SM;                            
45
 }
46
  
47
  
48
if (SM==0)                                              
49
 {
50
  digitalWrite (StandlichtL, LOW);
51
  digitalWrite (StandlichtR, LOW);
52
  digitalWrite (AbblendlichtL, LOW);
53
  digitalWrite (AbblendlichtR, LOW);
54
  }
55
  
56
if (SM==1)                                                
57
 {
58
 digitalWrite (StandlichtL, HIGH);
59
 digitalWrite (StandlichtR, HIGH);
60
 digitalWrite (AbblendlichtL, LOW);
61
 digitalWrite (AbblendlichtR, LOW);
62
 AM=0;
63
 }
64
if (SM==2 && AM==0)                                      
65
 {                                                        
66
     digitalWrite (StandlichtL, HIGH);           
67
     digitalWrite (StandlichtR, HIGH);         
68
     analogWrite (AbblendlichtL, helligkeit);            
69
     analogWrite (AbblendlichtR, helligkeit);            
70
     delay (del);                                         
71
     analogWrite (AbblendlichtL, LOW);                
72
     analogWrite (AbblendlichtR, LOW);                
73
     delay (del*2);                                   
74
     for(i=0; i<=helligkeit; i+=dim)                     
75
76
     {
77
       analogWrite (AbblendlichtL, i);
78
       analogWrite (AbblendlichtR, i);  
79
       delay (del);
80
     }                                                
81
 AM=1;
82
 }
83
84
   
85
if (SM==2 && AM==1)                                      
86
 {
87
     digitalWrite (StandlichtL, HIGH);                 
88
     digitalWrite (StandlichtR, HIGH);                 
89
     analogWrite (AbblendlichtL,helligkeit);           
90
     analogWrite (AbblendlichtR,helligkeit);           
91
 }
92
 
93
 
94
 if (SM==3)
95
 {
96
       digitalWrite (AbblendlichtL, HIGH);                 
97
       digitalWrite (AbblendlichtR, HIGH);                  
98
       digitalWrite (StandlichtL, HIGH);                    
99
       digitalWrite (StandlichtR, HIGH);                    
100
 }
101
 
102
 
103
 if (SM>ANZ)                                                  
104
 {
105
   SM=ANZ;
106
 }
107
 if (SM<0)                                                
108
 {
109
   SM=0;
110
 }
111
112
}

: Verschoben durch Moderator
von Max H. (hartl192)


Lesenswert?

Christian Kern schrieb:
> if (ch4 >1700)
>   {
>       ++SM;
>   }
> if (ch4 <1100)
> {
>      --SM;
>  }
Ich habe zwar nicht viel Ahnung von dem Arduino Zeug und vermute, dass 
du hier die Tasten einließt, aber versuchs mal so:
1
if ((ch4>1700)&&(ch4_old<1700))
2
{
3
      ++SM;
4
}
5
if ((ch4<1100)&&(ch4_old>1100))
6
{
7
     --SM;
8
}
9
ch4_old=ch4;


P.S. In "Projekte & Code" bist du Falsch:

Beschreibung "Projekte & Code":
> Hier könnt ihr eure Projekte, Schaltungen oder Codeschnipsel
> vorstellen und diskutieren. Bitte hier keine Fragen posten!

: Bearbeitet durch User
von Christian K. (hmpfknpf)


Lesenswert?

Hallo Max

Danke für die Idee aber ich habs grade probiert aber da kommt nix raus 
Was funktioniert.

Habe gerade den Hinweiß bekommen ich solle mit Timern arbeiten??

Hat da jmd vielleicht ne idee?

Ich weiß echt nicht nach was ich googeln soll..

von Horst (Gast)


Lesenswert?

Danegger-Entprellung

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Dann brauchst Du noch eine Variable die Dir anzeigt das der Knopf 
schonmal gedrückt worden ist, sobald dann der Taster losgelassen wird 
setzt Du die Variable zurück.
Schau mal in die Doku von Deinem Arduino-Sketch, wenn es da sowas wie 
PeDas Tastenentprellung mit einzel und dauer gibt einfach Deinen Code 
auf einzelne Taster Events anpassen ...

von Max H. (hartl192)


Lesenswert?

Habe ich das eigentlich richtig verstanden, dass die Taste mit
> ch4 = pulseIn(7, HIGH, 11000);
eingelesen und dann mit
> if (ch4 >1700)
>   {
>       ++SM;
>   }
> if (ch4 <1100)
> {
>      --SM;
>  }
abgefragt wird?

Und die Taste hängt nicht direkt an µC sondern über eine Fernsteuerung?

von Teo D. (teoderix)


Lesenswert?

Probier's mal so.
1
 if ((ch4>1700)&&(ch4_old<1700))
2
 {
3
       ++SM;
4
       ch4_old=ch4;
5
 }
6
 if ((ch4<1100)&&((ch4_old>1100)||(ch4_old==0))
7
 {
8
      --SM;
9
      ch4_old=ch4;
10
 }
11
// Achtung Pseudo-Code
12
if (Taster nicht betätigt)
13
{
14
    ch4_old=0;
15
]

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Max H. schrieb:
> Und die Taste hängt nicht direkt an µC sondern über eine Fernsteuerung?

Es ist recht unüblich, daß eine FB nur einen Puls sendet. Die Gefahr 
einer Fehlerkennung ist viel zu groß. Auch hat dann die AGC des 
Empfängers keine Möglichkeit, sich auf das Signal einzuregeln.
Ein FB sendet einen Code aus mehreren Bits und den muß man dekodieren.
Dann kann man auch erkennen, ob der Knopf kurz oder lange gedrückt wird.

von Simpel (Gast)


Lesenswert?

Man benutzt dafür ein Hilsflag, das nur dann einmalig den Statuswert der 
asuzuwertenden Variable ("Tastendruck") auf 1 setzt, wenn es z.B. von 0 
auf 1 wechselt.

Prinzip:

If Flag=0 AND Taste=1 Then
    Tastendruck=1
    Flag=1
End if

Der Wert von "Tastendruck" bleibt dann auf 1
und kann dann irgendwann im Programm übernommen bzw. ausgewertet werden. 
Unmittelbar danach wird dort die Variable "Tastendruck" auf 0 
zurückgesetzt.
Erst wenn das Programm dann wieder bereit ist, einen neuen Tastendruck 
anzunehmen, wird auch "Flag" auf 0 zurückgesetzt und damit die Erfassung 
wieder "scharf" gemacht.

von Karl H. (kbuchegg)


Lesenswert?

Peter Dannegger schrieb:
> Max H. schrieb:
>> Und die Taste hängt nicht direkt an µC sondern über eine Fernsteuerung?
>
> Es ist recht unüblich, daß eine FB nur einen Puls sendet. Die Gefahr
> einer Fehlerkennung ist viel zu groß. Auch hat dann die AGC des
> Empfängers keine Möglichkeit, sich auf das Signal einzuregeln.
> Ein FB sendet einen Code aus mehreren Bits und den muß man dekodieren.
> Dann kann man auch erkennen, ob der Knopf kurz oder lange gedrückt wird.

Ich komm immer mehr zur Überzeugung, dass der TO einen wesentlichen 
Punkt nicht richtig rausgearbeitet hat.
Ich denke im gegenständlichen Fall geht es in Wirklichkeit um eine 
Modellbau-Fernsteuerung, bei der am Sender ein entsprechender 
Taster/Schalter sitzt.
D.h. wir reden hier eigentlich von RC-Signalauswertung. Daher auch das 
pulsin im Code mit Vergleich der Pulszeiten.

: Bearbeitet durch User
von Simpel (Gast)


Lesenswert?

@K.H.

davon bin ich ausgegangen. Einen gültig erkannten RF_Befehl kann man ja 
als "TasteXY=1" wie gezeigt weiterverarbeiten, um bei Dauerdrücken einen 
Einzelbefehl zu isolieren. Mit dem Rücksetzen von "Flag" wird vom Prog 
bestimmt, wann es bereit ist den nächsten Einzelbefehl zu erlauben.

von Mat (Gast)


Lesenswert?

So wie das  Teo Derix geschrieben hat müsste es schon funktionieren.
Da RC Signale im "Ruhezustand" 1.5ms Pulsdauer haben und ich nehm an bei 
gedrückt in die eine Richtung 2ms und in die andere Richtung 1ms.
Du musst also beurteilen ob das Signal gerade von 1.5ms auf 1 bzw. 2ms 
gewechselt hat und nicht schon länger diese Pulszeit hat.

gruß

von Peter D. (peda)


Lesenswert?

Mat schrieb:
> Da RC Signale im "Ruhezustand" 1.5ms Pulsdauer haben und ich nehm an bei
> gedrückt in die eine Richtung 2ms und in die andere Richtung 1ms.

Dann braucht man eine Hysterese.
Z.B. 1,4-1,6 = losgelassen, >1,8 gedrückt links, <1,2 gedrückt rechts.
Und nur beim Übergang von losgelassen auf gedrückt wird eine Aktion 
durchgeführt.

von Simpel (Gast)


Lesenswert?

Es müssen die einzelnen Tastendrücke durch Nichtdrücke separiert werden. 
Dann kann man, unabhängig von der Dauer des Tastendrucks, einen Zähler 
damit inkrementieren, oder sonstwas Definiertes damit machen.

Einfache Tasten-RC-Sender sollten aus ökonomischen Gründen bei 
ungedrückter Taste gar keine "Pulsdauer" versenden. ;-)

von Mat (Gast)


Lesenswert?

Stimmt, eine Hysterese braucht er natürlich, aber die hat er sich auch 
schon eingebaut.
Signale kürzer 1.1ms und Signale größer 1.7ms, alles andere ist nicht 
gedrückt :)

lg

von oldmax (Gast)


Lesenswert?

Hi
Das Zauberwort ist nicht nur Entprellen sonder auch Flankenauswertung. 
Dabei nimmst du den aktuellen Eingang und machst mit einem abgelegten 
alten Wert eine Exclusiv Oder-Verknüpfung. Das Ergebnis ist nur bei 
einem Unterschied 1 und das ist dein Flankenmerker. Nach der ExOR 
schreibst du den aktuellen Wert in die Ablage. Im Programm fragst du das 
Flankenbit ab und löst deine Aufgabe je anch Status. Nach der Arbeit 
wird es gelöscht. Erst wenn wieder eine Flanke kommt, wird die Aufgabe 
erneut angefasst. Aber, Sowohl Signalwechsel von 1 nach 0 und umkekehrt 
sind Flanken. Daher musst du das Ergebnis der ExOr noch mit dem alten 
oder neuen Status verunden. And mit alt ist Wechsel von 1 nach 0 und And 
mit Neu ist Wechsel von 0 nach 1.
Keine große Sache.
Gruß oldmax

von Peter D. (peda)


Lesenswert?

Mat schrieb:
> Stimmt, eine Hysterese braucht er natürlich, aber die hat er sich auch
> schon eingebaut.

Nö.
Wenn der Wert nahe 1,1 oder 1,7 ist, wirst Du ständig Flanken erhalten.

Hysterese ist ein Totbereich, in dem der letzte Zustand beibehalten 
wird.
Quasi ein Schmitt-Trigger für die Zeitdauer.

von Christian K. (hmpfknpf)


Lesenswert?

Hallo!

Danke für die Hilfe :)

Mit dem Code von Teo Derix hats funktioniert :)

Herzlichen Dank an alle Beteiligten.

Gruß
hmpfknpf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.