Forum: Projekte & Code Arduino Sketch mittels Kippschalter anders "loopen" lassen


von Lars L. (lars_l785)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
Für Einige wahrscheinlich eine Kleinigkeit, für mich aber eine 
Herausforderung.

Ich habe mir etwas aus youtube nachgebaut und auch zum Laufen gebracht - 
alles gut. https://www.youtube.com/watch?v=Nhc9MvOH0Gs&t=276s

Dabei geht es darum, mittels Arduino zwei LED-Stripes (WS2812B) zum 
Laufen zu bringen und "Sound reactive" zu machen.

Mit einem Taster kann man immer zur nächsten "Szene" bzw. Effekt 
weiterschalten.
Drückt man diesen Taster mind. 500ms, dann wird ein automatisches 
Weiterschalten alle 20 Sekunden aktiviert.
So weit so gut.

Ich habe nun vor, weitere "Szenen" zu implementieren, die aber nicht im 
Automatikmodus vorkommen sollen. Diese Szenen sind alle in eigenen Tabs 
und werden entsprechend aufgerufen.

Ich verstehe zwar grob, was in dem Programm passiert, mir fehlt es aber 
an Tiefe, um das passend umzuprogrammieren.
Daher habe ich folgenden Ansatz:

Ich lasse den grundsätzlichen Programmablauf so, wie er ist. Der loop 
wird zu loop_0.
Dann füge ich eine Kopie davon darunter und nenne es loop_1. Dieser ruft 
entsprechend andere Szenen auf.
Mit einem Kippschalter möchte ich entscheiden, welcher Loop laufen soll.

Das sieht dann im Prinzip so aus, natürlich auf das wesentliche 
eingekürzt:
1
# define BTN_PIN 3                  // Push button on this pin [3]
2
# define DEBOUNCE_MS 20             // Number of ms to debounce the button [20]
3
# define SWITCH_PIN 4                  // Kippschalter zur Loopauswahl
4
5
//----------Definitionen/Verhalten des Buttons
6
uint8_t state = 0;
7
int buttonPushCounter = 0;
8
bool autoChangeVisuals = false;
9
Button modeBtn(BTN_PIN, DEBOUNCE_MS);
10
11
void incrementButtonPushCounter() {
12
  buttonPushCounter = (buttonPushCounter + 1) %16;
13
  EEPROM.write(1, buttonPushCounter);
14
}
15
//--------Ende-----------
16
17
void setup();
18
19
//-----Button------------
20
  modeBtn.begin();
21
  Serial.begin(57600);
22
23
  buttonPushCounter = 0;
24
  buttonPushCounter = (int)EEPROM.read(1); // load previous setting
25
  Serial.print("Starting pattern ");
26
  Serial.println(buttonPushCounter);
27
28
//--------Kippschalter
29
  pinMode(SWITCH_PIN,INPUT);
30
31
32
void loop_0() {
33
// der ursprüngiche Loop hier komplett rein
34
// Read button
35
  modeBtn.read(); 
36
  switch (state) {
37
    case 0:                
38
      if (modeBtn.wasReleased()) {
39
        Serial.print("Short press, pattern ");
40
        Serial.println(buttonPushCounter);
41
        incrementButtonPushCounter();
42
        autoChangeVisuals = false;
43
      }
44
      else if (modeBtn.pressedFor(LONG_PRESS))
45
        state = 1;
46
      break;
47
    
48
    case 1:
49
      if (modeBtn.wasReleased()) {
50
        state = 0;
51
        Serial.print("Long press, auto, pattern ");
52
        Serial.println(buttonPushCounter);
53
        autoChangeVisuals = true;
54
      }
55
      break;
56
  }
57
  
58
  // Switch pattern if on auto
59
  if(autoChangeVisuals){
60
    EVERY_N_SECONDS(PATTERN_TIME) { 
61
      incrementButtonPushCounter();
62
      Serial.print("Auto, pattern ");
63
      Serial.println(buttonPushCounter); 
64
    }
65
  }
66
67
  // Run selected pattern
68
  switch (buttonPushCounter) {
69
    case 0:
70
      red_dots();
71
      break;
72
  
73
    case 1:
74
      ambilight ();
75
      break;
76
77
// und so weiter
78
79
void loop_1() {
80
// der kopierte und modifizierte Loop
81
82
void loop () {
83
  if (digitalRead(SWITCH_PIN)==0) loop0();
84
  if (digitalRead(SWITCH_PIN)==1) loop1();
85
}
86
87
//hier folgen dann noch weitere Funktionen

Den originalen Sketch habe ich mal angehangen.
Leider funktioniert das nicht so, wie laienhaft von mir gedacht.
Zum Einen funktioniert die Umschaltung nicht sauber und zum anderen wird 
die LED Darstellung träge und flackert teilweise...

Macht man das evtl. besser über eine zweite "switch" Auswahl?
Könnte mir das bitte jemand erklären?

Für jeden Hinweis dazu wäre ich Euch dankbar...

: Bearbeitet durch User
von Walter T. (nicolas)


Lesenswert?

Lars L. schrieb:
> Zum Einen funktioniert die Umschaltung nicht sauber

Willkommen am Start Deiner Karriere als Hobbyprogrammierer. Die 
Umschaltung (= Transition <--) ist genau der Teil jeder Zustandsmaschine 
(<--), der praktisch den meisten Hirnschmalz benötigt.

Mit <-- habe ich mal die passenden Suchbegriffe für die weiteren 
Schritte markiert.

: Bearbeitet durch User
von Lars L. (lars_l785)


Lesenswert?

Hallo Walter,

vielen Dank. Ja, diese uralte und seit über 20 Jahre eingestaubte 
Leidenschaft, habe ich in den letzten Wochen erst wieder ausgegraben.
Damals habe ich noch Turbo Pascal und Basic gelernt, aber dann beruflich 
doch was ganz anderes gemacht.
Bei C++ steige ich jetzt irgendwie quer ein und es ist noch sehr holprig 
und vieles mit Try and Error. Mit der grundsätzlichen Logik kann ich 
schnell etwas anfangen. Trotzdem fehlt mir hier noch das Wording und 
insbesondere die Besonderheit im Rahmen des Loops zu programmieren ist 
noch bissl schwierig.... Macht aber trotzdem Spaß.

Ich versuche mal mit Deinen beiden Hints zu weiteren Erkenntnissen zu 
kommen.

Besten Dank und Lieben Gruß

von Walter T. (nicolas)


Lesenswert?

Lars L. schrieb:
> Damals habe ich noch Turbo Pascal und Basic gelernt

Perfekt, dann sitzen ja viele Sachen schon lange und müssen nur wieder 
aufgefrischt werden.

Kommst Du eher aus der Batch-Welt oder der GUI-Welt?

Wenn Du aus der Batch-Job-Welt stammst, wird die Haupt-Schwierigkeit 
sein, komplett die gegenteilige Sicht einzunehmen. Bei einer Batch will 
man ja, dass sie (möglichst schnell) fertig wird, und alles passiert 
hintereinander. Beim µC willst Du genau das Gegenteil - dass es nie 
endet. Und alles muss irgendwie gleichzeitig passieren.

Wenn Du aus der GUI-Welt mit Zuständen und Callback-Funktionen kommst, 
ist die Umstellung einfacher. Der einzige Unterschied ist, dass Du alles 
selbst machen musst.

: Bearbeitet durch User
von Lars L. (lars_l785)


Lesenswert?

:-D

Das ist eine sehr gute Frage.
Ich denke, es ist eher eine Mischung aus beidem.
Damals habe ich Soft und Hardwareprogrammierung im Rahmen einer 
vollschulischen Ausbildung gelernt. Das ganze ist aber nie im Feld zum 
Einsatz gekommen.
Ich habe dieses Wissen aber immer mal wieder hier und da eingesetzt:
Handy rooten, Satelliten Receiver modden, irgendwas irgendwo flashen 
oder manipulieren. Die reine oder konsequente Programmierung ist aber 
irgendwo auf der Strecke geblieben, wobei man doch sagen muss, dass man 
mit der erworbenen Denkweise eine Menge machen kann, wenn man sich 
irgendwo reinfuchst. Allerdings ist es eben meistens nur ein reinfuchsen 
für den jeweiligen Anwendungsfall gewesen. Man weiß von allem etwas, 
aber es reicht dann halt nicht, um von Null etwas eigenes auf die Beine 
zu stellen.

Jetzt schaue ich mir "enum" an. Das klingt im ersten Moment ganz 
brauchbar.
Mal schauen, wo die Reise tatsächlich hingeht.

von LostInMusic (Gast)


Lesenswert?

>void loop_0() {
>// der ursprüngiche Loop hier komplett rein

Finde ich verwirrend, weil loop_0 ja gerade keine Schleife ist. Dieser 
kleine, aber feine Unterschied sollte auch sprachlich deutlich gemacht 
werden, etwa so:

void Mode_Original() {
// hier der ursprüngliche Inhalt des Original-Loops
// ...

void Mode_EigeneMuster() {
// ...

von Lars L. (lars_l785)


Lesenswert?

Sorry, ich verstehe den Einwand.

Da gibt es wohl ganz unterschiedliche Wahrnehmungen zu.
Das ist sogar aus einer Erklärung an einer ganz anderen Stelle, die aber 
bei mir nicht so ohne weiteres funktioniert.

Aber Du hast es schon ganz richtig interpretiert.

von foobar (Gast)


Lesenswert?

Dein Ansatz ist zwar nicht schön, sollte prinzipiell aber funktionieren.

Wie hast du deinen Schalter angechlossen?  Einfach zwischen Pin und GND? 
Dann fehlt ein Pullup.  Änder mal dein

  pinMode(SWITCH_PIN,INPUT);
in
  pinMode(SWITCH_PIN,INPUT_PULLUP);

von Lars L. (lars_l785)


Lesenswert?

Ja ich habe ihn direkt so angeschlossen (auch ohne Vorwiderstand)

Pullup habe ich jetzt mal versucht.

Vielen Dank für den Hinweis.

Das scheint jedenfalls schon was gebracht zu haben.

Jedenfalls läuft das Urprogramm wieder einigermaßen.
Ich habe allerdings den Eindruck, dass es noch ein wenig flackert.

Wenn ich wieder umschalte werden einige Drückversuche beim Button noch 
werden derzeit aber noch ignoriert bzw. nicht entsprechend vereinbart.

Ich muss da nochmal im Detail nachschauen. War jetzt nur eben auf die 
Schnelle...

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Und vor allem gehört so eine Diskussion NICHT ins Forum "Projekte & 
Code". Hier sollen nur (halb)fertige Projekte vorgestellt und diskutiert 
werden. Keine Anfänger- und sonstige Probleme diskutiert werden. Das 
gehört in "uC & Elektronik". Bitte mal verschieben.

von Lars L. (lars_l785)


Lesenswert?

Tut mir Leid.
Im Prinzip war es ja fertig und läuft.
Mit dem neuen Ziel wäre es nun halbfertig und somit zur Diskussion 
gestellt.

Ok, mit einer Anfängerfrage.

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.