Forum: Mikrocontroller und Digitale Elektronik Switch().case funktioniert nicht wie gewünscht


von Atmega (Gast)


Lesenswert?

Hallo,

ich habe auf meinen Atmega den Arduino Bootlader drauf gemacht und dann 
meinen Sketch aufgespielt. Eigentlich soll nach jedem Drücken des Taster 
eine andere Led erleuchten, aber irgendwie leuchtet gar keine. Insgesamt 
soll ein Motor entweder mit einem Poti gesteuert werden oder per Zufall.

Hier ist mein bisheriger Code
1
const int analogInPin = A0;  // Analog input pin for potentiometer
2
const int analogOutPin = 9; // Analog output pin for motor driver
3
const int direction1 = 12; // motor output 1
4
const int direction2 = 13; // motor output 2
5
const int button_mode = 11; // game mode
6
const int led1 = 8;
7
const int led2 = 7;
8
const int led3 = 6;
9
const int led4 = 5;
10
int sensorValue = 0;        // value read from the pot
11
int gamemode=1, mode_pushed=0;
12
long duration=0, lasttime=0, nowtime=0;
13
int mode_old=0;
14
void setup() {
15
pinMode(analogInPin, INPUT);
16
pinMode(analogOutPin, OUTPUT);
17
pinMode(direction1, OUTPUT);
18
pinMode(direction2, OUTPUT);
19
pinMode(led1, OUTPUT);
20
pinMode(led2, OUTPUT);
21
pinMode(led3, OUTPUT);
22
pinMode(led4, OUTPUT);
23
24
25
}
26
27
void loop() {
28
  
29
mode_pushed = digitalRead(button_mode);
30
if(mode_old ==0 && mode_pushed==1)
31
{
32
gamemode+=1;
33
duration=0;
34
if (gamemode>4) gamemode=1;
35
}
36
mode_old=mode_pushed;  
37
38
switch(gamemode){
39
case 1: // manual speed selection
40
sensorValue = analogRead(analogInPin) / 4;
41
digitalWrite(direction1, HIGH);
42
digitalWrite(direction2, LOW);
43
analogWrite(analogOutPin, sensorValue);   
44
analogWrite(led1, HIGH);        
45
break;
46
47
case 2: // random mode easy
48
nowtime=millis();
49
if(nowtime>lasttime+duration){
50
lasttime=nowtime;
51
if(random(5)>0){
52
duration=random(3000,15000);
53
digitalWrite(direction1, HIGH);
54
digitalWrite(direction2, LOW);
55
sensorValue=random(37,65);
56
}
57
else{
58
duration=random(1500,5000);
59
digitalWrite(direction2, HIGH);
60
digitalWrite(direction1, LOW);
61
sensorValue=random(42,65);    
62
}
63
analogWrite(analogOutPin, sensorValue);
64
analogWrite(led2, HIGH);
65
}  
66
break;
67
68
case 3: // random mode medium
69
nowtime=millis();
70
if(nowtime>lasttime+duration){
71
lasttime=nowtime;        
72
if(random(5)>0){
73
duration=random(3000,15000);
74
digitalWrite(direction1, HIGH);
75
digitalWrite(direction2, LOW);
76
sensorValue=random(40,100);
77
}
78
else{
79
duration=random(1500,5000);
80
digitalWrite(direction2, HIGH);
81
digitalWrite(direction1, LOW);
82
sensorValue=random(47,100);       
83
}
84
}
85
analogWrite(analogOutPin, sensorValue);
86
analogWrite(led3, HIGH); 
87
break;
88
89
case 4: // random mode hard
90
nowtime=millis();
91
if(nowtime>lasttime+duration){
92
lasttime=nowtime;        
93
if(random(5)>0){
94
duration=random(3000,15000);
95
digitalWrite(direction1, HIGH);
96
digitalWrite(direction2, LOW);
97
sensorValue=random(40,200);
98
}
99
else{
100
duration=random(1500,5000);
101
digitalWrite(direction2, HIGH);
102
digitalWrite(direction1, LOW);
103
sensorValue=random(50,150);       
104
}
105
}
106
analogWrite(analogOutPin, sensorValue);
107
analogWrite(led4, HIGH);
108
break;
109
default:
110
delay(5);
111
}
112
}

von Karl H. (kbuchegg)


Lesenswert?

Atmega schrieb:

> mode_pushed = digitalRead(button_mode);

Bin ich blind?

Oder wo genau legst du für den Pin 'button_mode' fest, dass das ein 
Eingang sein soll?


Wenn du Code ein wenig übersichtlicher schreiben würdest, vielleicht 
nicht alles auf einmal sondern dich in Schritten dem Ziel näheren 
würdest, dann würdest du in Summe auch viel schneller zum Ziel kommen.

von Marcel P. (souko)


Lesenswert?

Hi,
naja, HIGH wird bei Arduino soweit ich weiss als "1" gespeichert.

Du nimmst analogWrite um deine LED's anzusteuern. Das würde heissen, 
dein HIGH wird als
1
analogWrite(led0, 1);
 übersetzt.

und ein Analogwert von 1 sieht man nicht bei den LED's.
Ersetze das mal durch
1
digitalWrite(led0, HIGH);
dann klappts bestimmt auch mit dem leuchten ;-)

EDIT: Und das was kbuchegg schreibt, ist auch nicht zu verachten !

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

PS;
davon unabhängig erhebt sich dann auch noch die Frage, wie dein Taster 
angeschlossen ist und ob du an diesem Eingangspin einen Pullup (oder 
Pulldown) Widerstand brauchst.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl H. schrieb:
> Wenn du Code ein wenig übersichtlicher schreiben würdest
Das beste, was dafür je erfunden wurde, ist Indentation.
Auf Deutsch: Einrückungen.

von Atmega (Gast)


Lesenswert?

Marcel P. schrieb:
> und ein Analogwert von 1 sieht man nicht bei den LED's.
> Ersetze das mal durch

Hi,
mit digitalWrite klappt das nun bedingt. Die Led leuchtet zwar, aber 
immer. Auch wenn ich den Taster gedrückt habe.

Karl H. schrieb:
> PS;
> davon unabhängig erhebt sich dann auch noch die Frage, wie dein Taster
> angeschlossen ist und ob du an diesem Eingangspin einen Pullup (oder
> Pulldown) Widerstand brauchst.

Hi,
ich habe am MC PIN den Taster und einen 10k Widerstand. Der Widerstand 
ist mit GND verbunden und der andere Pol vom Taster mit +.

von Joe F. (easylife)


Lesenswert?

Wie lange wartet denn "delay(5);" in "default:"?
5 Sekunden?

von Atmega (Gast)


Lesenswert?

Karl H. schrieb:
> Oder wo genau legst du für den Pin 'button_mode' fest, dass das ein
> Eingang sein soll?

Habe ich vergessen, aber nun geändert. Problem besteht aber immer noch.

von Karl H. (kbuchegg)


Lesenswert?

Atmega schrieb:
> Marcel P. schrieb:
>> und ein Analogwert von 1 sieht man nicht bei den LED's.
>> Ersetze das mal durch
>
> Hi,
> mit digitalWrite klappt das nun bedingt. Die Led leuchtet zwar, aber
> immer. Auch wenn ich den Taster gedrückt habe.

Gut, das ist jetzt nicht weiter verwunderlich.
Ich seh in deinem Programm, wenn ich mir die analogWrite durch 
entsprechende digitalWrite ersetzt denke, immer nur Stellen an denen du 
die LED einschaltest, aber nichts wo du sie jemals wieder ausschalten 
würdest.


Sagte ich eigentlich schon, dass es oft sehr zielführend ist, ein 
Programm in Schritten aufzubauen?

> ich habe am MC PIN den Taster und einen 10k Widerstand. Der Widerstand
> ist mit GND verbunden und der andere Pol vom Taster mit +.

Gut zu wissen.

Nichts desto trotz wird dein Taster noch prellen.
AUch wenn bei einem nackten AVR die Pins defaultmässig auf Input stehen, 
würde ich trotzdem nicht versäumen, das in Setup noch mal entsprechend 
zu wiederholen. Also, wo ist die entsprechende Einstellung für 
button_mode in setup()?

von Atmega (Gast)


Lesenswert?

Karl H. schrieb:
> Nichts desto trotz wird dein Taster noch prellen.
> AUch wenn bei einem nackten AVR die Pins defaultmässig auf Input stehen,
> würde ich trotzdem nicht versäumen, das in Setup noch mal entsprechend
> zu wiederholen. Also, wo ist
 die entsprechende Einstellung für
> button_mode in setup()?
Habe ich bei mir schon hinzugefügt. Kann allerdings meinen ersten 
Beitrag ja nicht mehr editieren. :-)

Karl H. schrieb:
> Sagte ich eigentlich schon, dass es oft sehr zielführend ist, ein
> Programm in Schritten aufzubauen?

Ja.

Karl H. schrieb:
> Ich seh in deinem Programm, wenn ich mir die analogWrite durch
> entsprechende digitalWrite ersetzt denke, immer nur Stellen an denen du
> die LED einschaltest, aber nichts wo du sie jemals wieder ausschalten
> würdest.

Wo schalte ich die dann am besten wieder aus? In den anderen cases?

von Karl H. (kbuchegg)


Lesenswert?

Ehe wir da jetzt noch ein paar mal hin und her hampeln.
Probier das mal
1
const int button_mode = 11; // game mode
2
const int led1 = 8;
3
const int led2 = 7;
4
const int led3 = 6;
5
const int led4 = 5;
6
7
uint8_t gamemode = 0;
8
uint8_t mode_old = 0;
9
uint8_t mode_pushed = 0;
10
11
void setup() {
12
  pinMode(button_mode, INPUT);
13
14
  pinMode(led1, OUTPUT);
15
  pinMode(led2, OUTPUT);
16
  pinMode(led3, OUTPUT);
17
  pinMode(led4, OUTPUT);
18
}
19
20
21
void loop() {
22
  
23
  mode_pushed = digitalRead( button_mode );
24
  if( !mode_old && mode_pushed )
25
  {
26
    gamemode++;
27
    if( gamemode > 4 )
28
      gamemode = 0;
29
  }
30
  mode_old = mode_pushed;  
31
32
  if( gamemode & 0x01 )
33
    digitalWrite( led1, HIGH );
34
  else
35
    digitalWrite( led1, LOW );
36
37
  if( gamemode & 0x02 )
38
    digitalWrite( led2, HIGH );
39
  else
40
    digitalWrite( led2, LOW );
41
42
  if( gamemode & 0x04 )
43
    digitalWrite( led3, HIGH );
44
  else
45
    digitalWrite( led3, LOW );
46
47
  delay( 10 );
48
}

wenn das nicht klappt, dann lass dir mal das Ergebnis vom digitalRead 
vom PinMode direkt auf eine LED ausgeben. Mglw. hast du den Taster am 
falschen Pin angeschlossen (oder die LED).

Bei jedem Tastedruck sollte sich das LED Muster verändern (es stellt die 
Binärzahl dar)

: Bearbeitet durch User
von Atmega (Gast)


Lesenswert?

Karl H. schrieb:
> Ehe wir da jetzt noch ein paar mal hin und her hampeln.
> Probier das mal

Vielen Dank für die Mühe, aber der Code war etwas zu ungewohnt für mich 
und deswegen habe ich mich noch mal selber rangesetzt.
1
const int analogInPin = A0;  // Analog input pin for potentiometer
2
const int analogOutPin = 9; // Analog output pin for motor driver
3
const int direction1 = 12; // motor output 1
4
const int direction2 = 13; // motor output 2
5
const int button_mode = 11; // game mode
6
const int led1 = 8;
7
const int led2 = 7;
8
const int led3 = 6;
9
const int led4 = 5;
10
int sensorValue = 0;        // value read from the pot
11
int gamemode=1, mode_pushed=0;
12
long duration=0, lasttime=0, nowtime=0;
13
int mode_old=0;
14
void setup() {
15
pinMode(analogInPin, INPUT);
16
pinMode(button_mode, INPUT);
17
pinMode(analogOutPin, OUTPUT);
18
pinMode(direction1, OUTPUT);
19
pinMode(direction2, OUTPUT);
20
pinMode(led1, OUTPUT);
21
pinMode(led2, OUTPUT);
22
pinMode(led3, OUTPUT);
23
pinMode(led4, OUTPUT);
24
25
26
}
27
28
void loop() {
29
  
30
mode_pushed = digitalRead(button_mode);
31
delay(100);
32
if(mode_old ==0 && mode_pushed==1)
33
{
34
gamemode+=1;
35
duration=0;
36
if (gamemode>4) gamemode=1;
37
}
38
mode_old=mode_pushed;  
39
40
switch(gamemode){
41
case 1: // manual speed selection
42
sensorValue = analogRead(analogInPin) / 4;
43
digitalWrite(direction1, HIGH);
44
digitalWrite(direction2, LOW);
45
analogWrite(analogOutPin, sensorValue);   
46
digitalWrite(led4, LOW);  
47
digitalWrite(led1, HIGH);        
48
break;
49
50
case 2: // random mode easy
51
nowtime=millis();
52
if(nowtime>lasttime+duration){
53
lasttime=nowtime;
54
if(random(5)>0){
55
duration=random(3000,15000);
56
digitalWrite(direction1, HIGH);
57
digitalWrite(direction2, LOW);
58
sensorValue=random(37,65);
59
}
60
else{
61
duration=random(1500,5000);
62
digitalWrite(direction2, HIGH);
63
digitalWrite(direction1, LOW);
64
sensorValue=random(42,65);    
65
}
66
analogWrite(analogOutPin, sensorValue);
67
}  
68
digitalWrite(led1, LOW);        
69
digitalWrite(led2, HIGH);        
70
break;
71
72
case 3: // random mode medium
73
nowtime=millis();
74
if(nowtime>lasttime+duration){
75
lasttime=nowtime;        
76
if(random(5)>0){
77
duration=random(3000,15000);
78
digitalWrite(direction1, HIGH);
79
digitalWrite(direction2, LOW);
80
sensorValue=random(40,100);
81
}
82
else{
83
duration=random(1500,5000);
84
digitalWrite(direction2, HIGH);
85
digitalWrite(direction1, LOW);
86
sensorValue=random(47,100);       
87
}
88
}
89
analogWrite(analogOutPin, sensorValue);
90
digitalWrite(led2, LOW);  
91
digitalWrite(led3, HIGH);  
92
break;
93
94
case 4: // random mode hard
95
nowtime=millis();
96
if(nowtime>lasttime+duration){
97
lasttime=nowtime;        
98
if(random(5)>0){
99
duration=random(3000,15000);
100
digitalWrite(direction1, HIGH);
101
digitalWrite(direction2, LOW);
102
sensorValue=random(40,200);
103
}
104
else{
105
duration=random(1500,5000);
106
digitalWrite(direction2, HIGH);
107
digitalWrite(direction1, LOW);
108
sensorValue=random(50,150);       
109
}
110
}
111
analogWrite(analogOutPin, sensorValue);
112
digitalWrite(led3, LOW);
113
digitalWrite(led4, HIGH);  
114
break;
115
default:
116
delay(5);
117
}
118
}

So funktioniert es jetzt. Das delay(100) musste ich einsetzen weil sonst 
oft ein Tastendruck doppelt oder zweifach gezählt wurde.

Vielleicht hilft es ja irgendjemandem.^^

von Cpp (Gast)


Lesenswert?

Atmega schrieb:
> mich noch mal selber rangesetzt
Die Formatierung hättest du aber behalten können.

> Vielleicht hilft es ja irgendjemandem.^^
Lies dir mal was zur Entprellung durch.

von Cpp (Gast)


Lesenswert?

Cpp schrieb:
>> Vielleicht hilft es ja irgendjemandem.^^
Upps, da hab ich wohl die flasche Zeile(n) Zitiert :-( Die hier sollte 
es sein:

> So funktioniert es jetzt. Das delay(100) musste ich einsetzen weil sonst
> oft ein Tastendruck doppelt oder zweifach gezählt wurde.

von Amateur (Gast)


Lesenswert?

Also beim Lesen des Codes von "Karl Heinz" wird man nicht HIGH.
Im Gegensatz zu dem Geschreibsel von "Atmini".

von Arduino (Gast)


Lesenswert?

Cpp schrieb:
> Die Formatierung hättest du aber behalten können.

Man hätte auch einfach mal in der IDE die Taste Strg-T drücken können.

von Atmega (Gast)


Lesenswert?

Arduino schrieb:
> Man hätte auch einfach mal in der IDE die Taste Strg-T drücken können.

Oh, danke für den Tip!

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.