Neopixel + Arduino Uno - Farbe per Schalter ändern

Guten Spätnachmittag, liebe Community.

Ich habe mir - mithilfe eines 3D-Druckers - die Portal Gun aus dem Videospiel Portal & Portal 2 ausgedruckt.
Was natürlich auch auf keinen Fall fehlen darf, ist die enstprechende Beleuchtung, weshalb ich mir Arduino und Neopixel gekauft habe.
Ich versuche mich nun schon ein Weilchen vertraut zu machen, aber finde leider nichts sonderlich hilfreiches.

Folgendes soll passieren:
Wenn die Portal Gun, bzw. der verbaute Arduino Pro Trinket eingeschaltet wird, sollen die 2 angeschlossenen Ringe und der Streifen Blau aufleuchten. Beim betätigen eines Schalter oder eines Knopfes soll die Farbe dauerhaft auf Orange wechseln, bei erneutem Drücken wieder auf Blau zurück, und so weiter.

Ich bin nicht ganz unerfahren was programmieren angeht, falls jemand also ein Tutorial oder ähnliches für mich hat, wäre das auch schon super.

Ich hab mich testweise mal ein wenig herumgespielt und folgenden Code aus kleinen Stücken zusammengesetzt (großteils in der Hoffnung, dass es dann funktioniert)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  - Note: on most Arduinos there is already an LED on the board
    attached to pin 13.

  created 2005
  by DojoDave <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Button
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setPixelColor(0, (255, 127, 0)); //Blue, 60 Pixels
  strip.setPixelColor(1, (255, 127, 0)); //Blue, 60 Pixels
  strip.setPixelColor(2, (255, 127, 0)); //Blue, 60 Pixels
  strip.setPixelColor(3, (255, 127, 0)); //Blue, 60 Pixels
  strip.setPixelColor(4, (255, 127, 0)); //Blue, 60 Pixels
  strip.setPixelColor(5, (255, 127, 0)); //Blue, 60 Pixels
  strip.setPixelColor(6, (255, 127, 0)); //Blue, 60 Pixels
  strip.show();
  
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    strip.setPixelColor(1, (255, 127, 0)); //Blue, 60 Pixels
    strip.show();
    digitalWrite(ledPin, HIGH);
  } else {
    strip.setPixelColor(0, (255, 127, 0)); //Orange, 60 Pixels
    strip.show();
    digitalWrite(ledPin, LOW);
  }
}

Der Code hat mehr oder weniger auch funktioniert. Zuerst wollte ich das ganze mit colorWipe machen, da kam dann aber immer gleich die Meldung "'colorWipe' not declared in scope" oder irgendwas in die Richtung.
Danach hab ich es mit strip.setPixelColor(...) probiert. Das hat funktioniert. Wenn ich den Code hochgeladen habe, hat der erste Pixel kurz Blau aufgeleuchtet. Beim betätigen des Knopfes hat er, solange der Knopf gedrückt war, Blau geleuchet. Dann hab ich mir den Farbcode für Orange rausgesucht, welcher jetzt überall vertreten ist, allerdings wurden keine Farben angezeigt. Egal auf welche Farbe ich welchen Pixel gesetzt habe, außer Blau wird nichts angezeigt.

Ich bin mit meinem Latein gerade ein wenig am Ende und weiß auch nicht mehr, wo ich nachschauen soll.
Vielen Dank für hilfreiche Antworten und einen schönen Abend euch noch. :slight_smile:

  if (buttonState == HIGH) {
    strip.setPixelColor(1, (255, 127, 0)); //Blue, 60 Pixels
    strip.show();
    digitalWrite(ledPin, HIGH);
  } else {
    strip.setPixelColor(0, (255, 127, 0)); //Orange, 60 Pixels
    strip.show();

wenn Taster gedrückt setzt du strip1, wenn nicht strip2, außerdem sind die Farben eh alle gleich.

ardubu:
wenn Taster gedrückt setzt du strip1, wenn nicht strip2, außerdem sind die Farben eh alle gleich.

Entschuldigung, ich verstehe leider nicht ganz, was du damit meinst.

Hi

(255, 127, 0) soll, laut Kommentar, 1x Blau und 1x Orange sein. Eher unwahrscheinlich :wink:
Die erste Zahl interpretiere ich als LED-Nummer - da Du aber eh immer die gleiche Farbe auf die Stripes schreibst, passiert Da augenscheinlich Nichts.
Ändere Mal ein paar der 3er-Zahlen in den Klammern.

MfG

versuch es mal so:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  - Note: on most Arduinos there is already an LED on the board
    attached to pin 13.

  created 2005
  by DojoDave <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Button
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setPixelColor(0, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.setPixelColor(1, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.setPixelColor(2, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.setPixelColor(3, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.setPixelColor(4, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.setPixelColor(5, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.setPixelColor(6, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.show();
  delay(2000);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    strip.setPixelColor(1, strip.Color(255, 127, 0)); //Orange, 60 Pixels(255, 127, 0)); 
    strip.show();
    digitalWrite(ledPin, HIGH);
  } else {
    strip.setPixelColor(1, strip.Color(0, 0, 255)); //Blue, 60 Pixels(0, 0, 255)); 
    strip.show();
    digitalWrite(ledPin, LOW);
  }
}

hast du einen Pulldownwiderstand am Taster verbaut?

postmaster-ino:
Hi

(255, 127, 0) soll, laut Kommentar, 1x Blau und 1x Orange sein. Eher unwahrscheinlich :wink:
Die erste Zahl interpretiere ich als LED-Nummer - da Du aber eh immer die gleiche Farbe auf die Stripes schreibst, passiert Da augenscheinlich Nichts.
Ändere Mal ein paar der 3er-Zahlen in den Klammern.

MfG

Hallo. Danke für deine Antwort. Scheinbar habe ich mich nicht klar genug ausgedrückt, als ich gesagt habe, dass ich den Code, der jetzt oben steht im NACHHINEIN bearbeitet habe, um festzustellen ob der LED Strip überhaupt in der Lage ist, Orange anzuzeigen, was er, für mich nicht verständlicherweiße, nicht wahr. Ich habe verschiedenste Kombinationen ausprobiert, aber außer dem Blau von ganz am Anfang hat leider nichts funktioniert.

ardubu:
hast du einen Pulldownwiderstand am Taster verbaut?

Ich habe mir ein Tutorial angesehen, in dem ein Widerstand verbaut war, also ja, falls dieser Widerstand der "Pulldownwiderstand" ist, dann vermutlich schon.

Zu dem Code!

Vielen Dank, das hat mir schon enorm weitergeholfen. :slight_smile:

Wüsstest du vielleicht noch einen Weg, wie ich dafür sorgen kann, dass nach dem Betätigen des Schalters die Farbe von Blau dauerhaft auf Orange umschaltet, und erst dann wieder zurück auf Blau schaltet, wenn der Schalter erneut betätigt wird? Also, wie ein Flip-Flop-Schalter theoretisch?

Korlimann:
Also, wie ein Flip-Flop-Schalter theoretisch?

Prinzipiell so für die eingebaute LED:

const byte T1 = 2; // Taster
uint32_t aktMillis, tasterMillis;
bool ledStatus, aktT1, altT1;

void setup()
{
  pinMode(T1, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop(void) {
  aktMillis = millis();
  altT1 = aktT1;
  if (aktMillis - tasterMillis >= 30)
  {
    tasterMillis = aktMillis;
    aktT1 = digitalRead(T1);
  }
  if (altT1 && !aktT1)
  {
    ledStatus = !ledStatus;
    if (ledStatus)
    {
      digitalWrite(LED_BUILTIN, HIGH);
    } else {
      digitalWrite(LED_BUILTIN, LOW);
    }
  }
}

ich habe dein Programm mal etwas umgeschrieben, probier mal ob es das macht was du möchtest.

#include <Adafruit_NeoPixel.h>

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

// constants won't change. They're used here to set pin numbers:
const int tasterPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
bool tasterState, tasterState_alt, State;// Variablendeklaration (global)

void setup() {
  Serial.begin(115200);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(tasterPin, INPUT_PULLUP);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  for (byte i=0;i<7;i++)   strip.setPixelColor(i, strip.Color(0, 0, 255)); //Blue, 60 Pixels
  strip.show();
  delay(1000);
}

void loop() {
   tasterAbfrage();
   ausgabe();  
 
}
void tasterAbfrage()
{
 const byte debounce_delay = 10;
 static uint32_t debounce_time;
 if (millis()-debounce_time>debounce_delay)tasterState = digitalRead(tasterPin); //einlesen des Tasters
   
 if (tasterState != tasterState_alt) // bei Pegelwechsel 
    {
     debounce_time=millis();
     if(!tasterState)//wenn Taster gedrückt
        State=!State;
        tasterState_alt = tasterState; // state aktualisieren
        }
}
void ausgabe()
{
    if (!State) {
    for (byte i=0;i<7;i++) strip.setPixelColor(i, strip.Color(255, 127, 0)); //Orange, 60 Pixels(255, 127, 0));
    strip.show();
    digitalWrite(ledPin, HIGH);
  } else {
         for (byte i=0;i<7;i++) strip.setPixelColor(i, strip.Color(0, 0, 255)); //Blue, 60 Pixels(0, 0, 255));
         strip.show();
         }
}

ardubu:
ich habe dein Programm mal etwas umgeschrieben, probier mal ob es das macht was du möchtest.

Hey!
Vielen lieben Dank, es funktioniert perfekt. :slight_smile:

Ich hab mich jetzt selber daran gesetzt, zu versuchen sowas zu schreiben, und nur interessenhalber, könntest du, oder jemand anderes mir sagen, was ich denn bei folgendem Code falsch gemacht habe?

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  - Note: on most Arduinos there is already an LED on the board
    attached to pin 13.

  created 2005
  by DojoDave <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/Button
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

int buttonColour = 0;        // 0 = Blue || 1 = Orange 
boolean buttonPressed = false; 

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  for(int i=0; i<60; i++) {
    strip.setPixelColor(i, strip.Color(0, 0, 255)); //Blue, 60 Pixels
    }
  strip.show();
  delay(2000);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    buttonPressed = true;
    delay(50);
    if(buttonColour == 0 && buttonPressed == true) {
      buttonColour = 1;
      for(int i=0; i<60; i++) {
         strip.setPixelColor(i, strip.Color(253, 95, 0)); //Blue, 60 Pixels
      }
      strip.show();
      buttonPressed = false;
    }
    else if(buttonColour == 1 && buttonPressed == true) {
      buttonColour = 0;
      for(int i=0; i<60; i++) {
      strip.setPixelColor(i, strip.Color(0, 0, 255)); //Blue, 60 Pixels
      }
      strip.show();
      buttonPressed = false;
    }
    
  } 
}

An und für sich funktioniert das, manchmal muss man aber auch erst 3 mal drücken, bevor die Farbe wechselt, und komischerweiße, WÄHREND der Knopf gedrückt ist, leuchtet es in einem nicht ganz reinlichen Weiß.

Wenn buttonState == HIGH ist, hast Du mit jedem Durchgang von loop ein Blinken, durch delay(50) in der Frequenz gebremst. Welche Farbe übrig bleibt, ist Zufall.