Mit Drehschalter unterschiedliche Funktionen aufrufen

Hallo,

ich bin Gitarrenbauer und habe ein Gemma M0 Board (weil es so schön klein ist) die in einer Gitarre eingebaut werden muss (wird mit LiPo betrieben) und damit wird eine LED Streifen mit insgesamt 30 LEDs betrieben. Es gibt 3 LED Programmen die mittels eines Drehschalters aufgerufen werden (1 polig, 3 Positionen, analog). Eins davon ist sound reactive und wird mit einem Mikro angesteuert.

Weil Gemma nicht viele Eingänge hat, bin ich den Reistance Ladder-Weg gegangen. Es gibt Widerstände zwischen den Positionen und diese werden gemessen und darauf basierend wird ein LED Program aufgerufen.

Als blutiger Anfänger, habe ich folgendes schreiben und auf Gemma M0 hochladen können (Arduino IDE 2.1.1):

#include <FastLED.h>

const int switchPin = A0;      // Analog input pin for the 3-position switch
const int microphonePin = A1;  // Analog input pin for the microphone
const int ledPin = A2;         // Digital output pin for the LED strip

#define NUM_LEDS 30     // Number of LEDs in strip
#define LED_DATA_PIN 2  // Pin where LED data line is connected

CRGB leds[NUM_LEDS];

void setup() {
  //Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  FastLED.addLeds<WS2812, LED_DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.show();  // Initialize LED strip
}

void loop() {
  int switchValue = analogRead(switchPin);          // Read switch value
  int microphoneValue = analogRead(microphonePin);  // Read microphone value

  int switchPosition = map(switchValue, 0, 1023, 0, 2);    // Map switch value to 3 positions
  int brightness = map(microphoneValue, 0, 1023, 0, 255);  // Map microphone value to LED brightness

  switch (switchPosition) {
    case 0:
      soundReactiveRainbow(brightness);
      break;
    case 1:
      rollercoasterEffect(brightness);  // Execute the rollercoaster effect for position 1
      break;
    case 2:
      pulsedFadeEffect(brightness);
      break;
    default:
      // Handle unknown position
      break;
  }
}

void soundReactiveRainbow(int brightness) {
  uint8_t beat = beatsin8(50, 0, 255);
  fill_rainbow(leds, NUM_LEDS, beat, 8);
  FastLED.show();
}

void rollercoasterEffect(int brightness) {
  int hue = beatsin8(20);  // Vary the speed of color change
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(hue + i * 10, 255, brightness);
  }
  FastLED.show();
}

void pulsedFadeEffect(int brightness) {
  uint8_t beat = beat8(90);  // 90 bpm beat
  int fadeValue = map(beat, 0, 255, 0, brightness);

  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB(fadeValue, 0, 0);  // Red color
  }

  FastLED.show();
  delay(10);  // Adjust delay for desired fade in/out effect
}

Ich habe keine Probleme oder Fehlermeldungen. Es kompiliert und lädt hoch. Allerdings läuft es nicht oder es läuft, irgendwas fehlt oder stimmt nicht und ich merke es nicht. Jedenfalls keins von den LED Programmen können aufgerufen werden.

Ich füge auch mal Bilder dazu um die Verbindungen zu zeigen, vielleicht mache ich hier einen Fehler.

9602jjs3eftz


Habt ihr vielleicht einen Hinweis für mich? Ich wäre euch sehr dankbar wenn ihr helfen könntet!

Vielen Dank im Voraus!

Ist das nicht ein 3,3V Board?
evtl. hast du das mit den 5V schon getötet?!?

Ich sehe keine Seriellen Debugg Meldungen, welche über den Schalter Status berichten.
Das wäre zur Fehlersuche recht sinnvoll.

➜ Der Gemma M0 verbraucht 3,3 V und nicht 5 V

Hallo Combie,

Es hat einen USB Eingang und 5V wird runter gedreht. Im normalen Betrieb mit 3.7V LiPo gibt es keine Probleme.

Gemma hat dummerweise keine Debug-Funktion und ich wenig Ahnung wie ich serielle Verbindung einbauen bzw. benutzen soll... Wie im Code gesehen, musste ich die Serial.begin(9600) ausschalten. Sonst lief es auch nicht.

Vorab: Ich hab das Teil noch nie in der Hand gehabt oder gesehen.
Es gibt aber einige Sachen, die generell gelten :wink: (Zum Glück)

Als erstes: Wenn Du 5 Widerstände dran hast, dann hoffe ich, das die Farbringe stimmen und nicht die 2K - 5k :wink:

Das ist überflüssig.
Der switch/case kann sehr gut mit Bereichen arbeiten.
z.B. ginge:

  switch (switchPosition) {
    case 0 ... 100:
      soundReactiveRainbow(brightness);
      break;
    case 101 ... 200:
      rollercoasterEffect(brightness);  // Execute the rollercoaster effect for position 1
      break;
    case 201 ... 1023:
      pulsedFadeEffect(brightness);
      break;
    default:
      // Handle unknown position
      break;

Zum testen würde ich erstmal

ändern in

int brightness = 200;

um überhaupt erstmal etwas raus zu bekommen.

Und hier:

übernimmst Du die Helligkeit nicht.

In deinem Plan stehen 5V!
Ein falscher Plan ist eine Form von Betrug.

However, on the off chance you are using the official Arduino SAMD core and not the Adafruit version (which really, we recommend you use our version because it’s been tuned to our boards), and you want your Serial prints and reads to use the USB port, use SerialUSB instead of Serial in your sketch.

Das solltest du reparieren.
Sonst macht es die Fehlersuche unnötig schwer.

Ich verstehe dich aber die Abbildung dient nur dazu zu zeigen wie das ganze verdrahtet ist. ich hätte es erwähnen sollen.

Vielen dank, das habe ich in der Tat nicht gewusst.

Mein Schalter ist 1 polig 3 Positionen nur aber ich weiß was Du meinst, die Widerstände sind identisch :wink:

Ich versuche mal Deine Vorschläge und melde mich wieder.

Vielen Dank!

Es gab in der Tat einen physikalischen Fehler. LED data pin muss offensichtlich 0 sein. Jetzt läuft alles.

Nebenfrage. Kann man eine Funktion irgendwo draussen lagern bis sie gerufen wird? Ist das was ein Class macht?

Ich verstehe dich nicht!
Und nein, Klassen lagern nichts draußen.
Eher in sich drin.

Vielleicht suchst du Funktionspointer?

Es ist gut möglich. Ich denke es versuche mal diese dritte Funktion selber in den Code zu integrieren und falls ich es nicht schaffe, dann komme ich wieder hierher.

Und es tut mir wirklich Leid, dass ich den Jargon nicht kenne, es würde tatsächlich einiges einfacher machen.

So ich habe es halbwegs geschafft und am Freitag lief alles wie geplant.

Heute sehe ich, dass alle Positionen des Schalters (und es schaltet richtig, denke ich) das gleiche aufrufen.

Was genau meint ihr ich mache hier falsch?

#include <FastLED.h>

const int switchPin = A0;      // Analog input pin for the 3-position switch
const int microphonePin = A1;  // Analog input pin for the microphone
const int ledPin = A2;         // Digital output pin for the LED strip
#define DATA_PIN 0 //digital pin at which the data pin is connected
#define mic A1 //analog input from mic module
int mic_Value; //to save raw value from mic
int red, green, blue; //to store RGB color values

#define NUM_LEDS 30     // Number of LEDs in strip
#define LED_DATA_PIN 0  // Pin where LED data line is connected

CRGB leds[NUM_LEDS];

void setup() {
  //Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  FastLED.addLeds<WS2812, LED_DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.show();  // Initialize LED strip
}

void loop() {
  int switchValue = analogRead(switchPin);          // Read switch value
  int microphoneValue = analogRead(microphonePin);  // Read microphone value

  int switchPosition = map(switchValue, 0, 1023, 0, 2);    // Map switch value to 3 positions
  int brightness = map(microphoneValue, 0, 1023, 0, 255);  // Map microphone value to LED brightness

 

  switch (switchPosition) {
    case 0:
      soundReactiveRainbow(brightness);
      break;
    case 1:
      rollercoasterEffect();  // Execute the rollercoaster effect for position 1
      break;
    case 2:
      pulsedFadeEffect();
      break;
    default:
      // Handle unknown position
      break;
  }
}

void soundReactiveRainbow(int brightness) {
 int microphoneValue = analogRead(microphonePin); // Read microphone value
  int mappedMicrophone = map(microphoneValue, 0, 1023, 0, 255); // Map to a reasonable range
  
  uint8_t speed = map(mappedMicrophone, 10, 255, 1, 50); // Map microphone to speed range
  uint8_t beat = beatsin8(speed, 0, 255);
  fill_rainbow(leds, NUM_LEDS, beat, 8);
  FastLED.show();
}

void rollercoasterEffect() {
  int hue = beatsin8(20);  // Vary the speed of color change
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CHSV(hue + i * 10, 255, 255);
  }
  FastLED.show();
}

void pulsedFadeEffect() {
  uint8_t beat = beat8(90); // 90 bpm beat
  int fadeValue = map(beat, 0, 255, 0, 255); // Map beat to full color range
  
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB(fadeValue, 0, 0).fadeToBlackBy(255 - fadeValue); // Red color with fading effect
  }
  
  FastLED.show();
  delay(10); // Adjust delay for desired fade in/out effect
}

Was wird den aufgerufen?

Mittels eines Drehschalters, wird eine von 3 Funktionen gerufen bzw. selektiert. Egal welche Position des Schalters, es kommt immer Funktion 1.

Dann wird dein analogRead(switchPin) immer 0 liefern.

schau dir noch mal den Vorschlag von @my_xy_projekt an.
Der hat dir einen switch case mit Bereichsangaben empfohlen.
d.h. wirf den map raus.
Gib auf der seriellen Schnittstelle aus was du aktuell am analog Pin misst.
Stell entsprechend die Grenzen im switch case ein.
Du brauchst kein map.

Hast du das einmal versucht um dir Werte ausgeben zu lassen? Würde das debuging massiv erleichtern.