Forum: Mikrocontroller und Digitale Elektronik 2 alternative Geschwindigkeiten nutzen Neopixel-Strip


von Jack L. (ja_li)


Lesenswert?

Hallo liebe Mikrocontroller-Spezialisten,

ich habe einen Sketch (Larson Scanner Shade), den ich (irgendwie 
physisch umschaltbar) mit 2 alternativen Geschwindigkeiten über einen 
Arduino laufen lassen will.

Also z. B. mit dem im Code sichtbaren Delay(60) und nach einem 
Umschalten z. B. mit einem Wert von 30.

Es soll ein Neopixel-Strip beliebig lange mit einem Wert laufen und nach 
einem Ändern der Geschwindigkeit mit dem anderen, jederzeit umschaltbar, 
ohne irgendetwas für die Dauer des Leuchteffektes gedrückt halten zu 
müssen.

Eine stufenlose Regelung der Geschwindigkeit, falls das ohne Flackern 
möglich wäre, ginge alternativ dazu auch.

Ich habe selbst mit Pushbutton und Potiknopf sehr lange rumprobiert. Ich 
kriege es (vielleicht liegt es am Alter) einfach nicht hin!

Für eine funktionierende Lösung wäre ich sehr dankbar!

Hier der Sketch in der Grundform:
1
#include <Adafruit_NeoPixel.h>
2
3
#define N_LEDS 60
4
#define PIN     6
5
6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRB + NEO_KHZ800);
7
8
void setup() {
9
  strip.begin();
10
}
11
12
int pos = 0, dir = 1; // Position, direction of "eye"
13
14
void loop() {
15
  int j;
16
17
  // Draw 5 pixels centered on pos.  setPixelColor() will clip any
18
  // pixels off the ends of the strip, we don't need to watch for that.
19
20
  strip.setPixelColor(pos - 2, 0xFF0000);
21
  strip.setPixelColor(pos - 1, 0xFF0000);
22
  strip.setPixelColor(pos    , 0xFF0000);
23
  strip.setPixelColor(pos + 1, 0xFF0000);
24
  strip.setPixelColor(pos + 2, 0xFF0000);
25
26
  strip.show();
27
  delay(50);
28
29
  // Rather than being sneaky and erasing just the tail pixel,
30
  // it's easier to erase it all and draw a new one next time.
31
  for(j=-2; j<= 2; j++) strip.setPixelColor(pos+j, 0);
32
33
  // Bounce off ends of strip
34
  pos += dir;
35
  if(pos < 0) {
36
    pos = 1;
37
    dir = -dir;
38
  } else if(pos >= strip.numPixels()) {
39
    pos = strip.numPixels() - 2;
40
    dir = -dir;
41
  }
42
}

von Alex D. (daum)


Lesenswert?

Jack L. schrieb:
> Es soll ein Neopixel-Strip beliebig lange mit einem Wert laufen und nach
> einem Ändern der Geschwindigkeit mit dem anderen, jederzeit umschaltbar,
> ohne irgendetwas für die Dauer des Leuchteffektes gedrückt halten zu
> müssen.

Das Klingt so als würdest du einen Interrupt dafür brauchen, schau dir 
mal das an: 
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

von Jack (Gast)


Lesenswert?

Danke Alex für die sicher sehr gute Anregung!
Könnte man einen einfachen Schiebe- oder Kippschalter nutzen, zusammen 
mit dem Interrupt, um den loop im Sketch auf auf den jeweils anderen 
Delaywert umzuschalten?
Vielleicht ist die Frage von mir auch ein wenig naiv formuliert, ich bin 
leider darin kein Experte und bitte um Nachsicht?!

von Dirk B. (dirkb2)


Lesenswert?

Jack L. schrieb:
> Also z. B. mit dem im Code sichtbaren Delay(60) und nach einem
> Umschalten z. B. mit einem Wert von 30.

Im gezeigten Code ist kein Delay(60)

Klar kannst du vor dem delay ein Pin abfragen und davon abhänging ein 
entsprechendes delay ausführen.

Ist auch nicht viel anders als mit Tastendruck eine LED anzuschalten.
(meist das erste oder zweite Programm in einem Tutorial („Hello World“ 
für Mikrocontroller))

von Patrick C. (pcrom)


Lesenswert?

Keine delay benutzen aber millis().
Damit ist der micro immer verfuegbar und kann man einfach mehrere 
geschindigkeiten programmieren

von Sascha W. (sascha-w)


Lesenswert?

Jack schrieb:
> Danke Alex für die sicher sehr gute Anregung!
> Könnte man einen einfachen Schiebe- oder Kippschalter nutzen, zusammen
> mit dem Interrupt, um den loop im Sketch auf auf den jeweils anderen
> Delaywert umzuschalten?
> Vielleicht ist die Frage von mir auch ein wenig naiv formuliert, ich bin
> leider darin kein Experte und bitte um Nachsicht?!
Also wenn du nur 2 Geschwindigkeiten brauchst und einen Schalter 
verwendest, dann geht's so am einfachsten:
1
if (digitalRead(schalter_pin)) {
2
  delay(kurz);
3
} else {
4
  delay(lang);
5
}

Sascha

von Matthias S. (da_user)


Lesenswert?

1
delay(map(analogRead(A0), 0, 1023, 0, 500)

Damit sollte man das Delay mit einem Poti an A0 zwischen 0 und 500ms 
einstellen können.

Aber wie Patrick C. auch schon angesprochen hat:

Patrick C. schrieb:
> Keine delay benutzen aber millis().

Delay ist meistens doof, da blockierend. Lieber in jedem 
Schleifendurchlauf prüfen, ob die (Delay-)Zeit seit der letzten Aktion 
schon abgelaufen ist. Da ist das Example "Blink without Delay" ein gutes 
Beispiel.
Meines Erachtens ist das eines der wichtigsten Beispiele.

von Jack (Gast)


Lesenswert?

@Dirk B.: Danke fürs Aufpassen und die Anregung! Die "6" von 60 sollte 
eine "5" werden. Mea culpa!

@Patric C.: Thanks! Der Tipp ist mir beim Lesen immer wieder begegnet. 
Muss etwas dran sein. Aber ich hab´s halt nie SO hingekriegt, die 
richtigen Codezeilen im Sketch an der richtigen Stelle zu platzieren, 
dass es gefunzt hat.
Die "Prüfung der Syntax" hat nicht gemeckert, aber der Streifen blieb 
tot.

von Jack (Gast)


Lesenswert?

@Sascha W.:

So einen gekürzten Code hatte ich immer gesucht, aber es war in den 
Beispielen (wenn sie nicht "nur" einfache Leds benutzten, statt 
Neopixel) doch immer ziemlich verschachtelt mit den Bedingungen.

Ich hatte ursprünglich dummerweise versucht, jeweils das ganze void loop 
zu doppeln und dazwischen Code für ein Umschalten hinzukregen - 
vergeblich.

SO probiere ich das heute Abend einfach mal aus!

DANKE!

von Jack (Gast)


Lesenswert?

@ Matthias S.:

Diesen Code für die Poti-Umsetzung nehme ich mir nachher in der Praxis 
auch gerne versuchsweise am Strip vor.

Wenn das klappt, habe ich 2 Alternativen mit Knopf und Poti.

Eine sollte passen! DANKE!

von Jack (Gast)


Lesenswert?

Noch eine Nachtrag-Frage vom Unwissenden an den Spezi
@Sascha W.:

Macht es technisch einen Unterschied, ob ich einen Push-Button mit 
Widerstand zu GND nehme ODER einen Schiebeschalter bzw. Kippschalter 
einsetze?

Heißt: Wird auch dabei jeweils auf der Seite, die zum Pin geht ein 10 
KiloOhm Widerstand eingesetzt, wie beim Push-Button beschrieben, oder 
ist das - je nach Schalter-Typ unterschiedlich?

Ich will halt nur einmal den Impuls setzen, damit es losgeht und nicht 
dauernd den Taster/Button gedrückt halten, wie bei den Led-Beispielen zu 
dem Thema.

Danke vorab schon mal für die Geduld mit einem schon ziemlich alten 
Newbi!

von Jens (Gast)


Lesenswert?

Hallo Jack,

das macht schon einen Unterschied: Ein Taster liefert das Signal, 
solange Du drückst, der Schiebeschalter bleibt in seiner Stellung und 
liefert das Signal dauerhaft - wohl das, was Du willst.

Der 10k-Widerstand dient dazu, den Eingang des Prozessors definiert auf 
den jeweils anderen Pegel zu legen, wenn Taster oder Schiebeschalter 
nicht betätigt sind. In beiden Fällen also z.B. ein 10k zu 5V und 
Schalter zu Masse.

Wenn Du den Eingang mit
 pinMode ( schalter_pin, INPUT_PULLUP );
konfigurierst, wird ein interner Pullup (Widerstand gegen 5V) aktiviert, 
Du brauchst dann nur noch einen Schalter gegen Masse.

Wenn Du nur einen Taster hast, kann man das Schaltverhalten natürlich 
auch in Software nachbilden.

Gruß
Jens

P.S.: Es gibt wohl kaum ein Thema, zu dem mehr Tutorials geschrieben 
wurden...

von Jack (Gast)


Lesenswert?

@ Jens:

DANKE für die zusätzliche Schalter-Info!
Werde mir morgen bei Conrad o. ä. für alle Fälle einen entsprechenden 
Schalter (für Dauerstellungen) besorgen und mal testen, was am besten 
geht.

Bisher war der Widerstand immer in den Beispielen auf der anderen 
Tasterpin-Seite zu Masse hin gesetzt, aber das ist ja wohl nur der 
Unterschied, ob es anfangs HIGH oder LOW sein soll (falls ich das 
richtig verstehe).

Lieben Dank noch mal für die freundliche Hilfe!

von Jack L. (ja_li)


Lesenswert?

ERFOLGS-BERICHT:

Juchhu, Hurra! Ihr seid die Besten!

Heute war ein echter Geling-Tag für mich!
Danke, danke, danke!

Endlich kein Frust mehr im Bauch, und ich kann die Platine löten und die 
"Baustelle" demnächst erfolgreich schließen.
... dank eurer gut nachvollziehbaren Hilfe!

Ich habe sowohl die Potentiometer-Version zum Laufen gekriegt, als auch 
die mit dem Taster/Schalter. Hat bestens geklappt!

Beim Poti habe ich nur statt "0" und "500" als Bandbreite für die 
Speed-/Zeitwerte meine beiden Wunschwerte als Begrenzungen eingesetzt. 
So habe ich nicht nur einen winzigen Ausschnitt beim Drehknopf für die 
Einstellung auf MEINE "richtige" Geschwindigkeit, sondern eine weiche 
stufenlose Regelung zwischen den Wunschwerten über den gesamten 
Drehbereich des Potentiometer-Knopfes. Klasse!

Schalter oder Poti ist noch nicht entschieden. Letztlich wird der Platz 
im/am Arduino-Gehäuse darüber entscheiden, der nach dem Einbau der 
Platine noch übrig bleibt.

Ich danke meinen Helfern hier ganz herzlich für die Ersparung wertvoller 
Lebenszeit und das Erfolgs-Erlebnis!

von Dirk B. (dirkb2)


Lesenswert?

Du kannst auch mit einem Schalter einen sanften Übergang programmieren.

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.