Hilfe: IR Remote Steuerung, MSGEQ7 + RGB-LED Streifen

Guten Abend zusammen,

ich wende mich hier im Forum zum ersten mal an die Community und hoffe ihr könnt mir helfen.
Mittlerweile habe ich etliche Stunden damit verbracht meinen Arduino Uno Code ans laufen zu bringen, leider vergebens.

Mein Projekt: RGB-LED Streifen angesteuert über Musik Spectrum Analyse mit dem MSGEQ7 Chip.

Funktion 1: Weißlicht- AN/AUS
Funktion 2: MSGEQ7 - AN/AUS
Steuerung über IR-Remote via Tastendruck

Der Code für “Funktion 1” klappt über die Remote. Allerdings “Funktion 2” bekomme ich nicht über die Remote gesteuert bzw beide Funktionen zusammen in den Code zu verpacken…

Meine Programmier Kenntnisse sind noch auf Anfängerniveau und ich Hoffe ihr könnt mir ein paar Tipps geben um zu Lösung zu kommen.

hier beiden meine Codes:

Funktion 1:

#include <IRremote.h>
int bright;
int before;
int ledPinR = 10;
int ledPinG = 9;
int ledPinB = 11;

int RECV_PIN = 3; //data out of IR receiver connects to pin 11

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup(){
irrecv.enableIRIn(); // start the receiver
before=0; //LED is turned off
pinMode(ledPinR,OUTPUT);
pinMode(ledPinG,OUTPUT);
pinMode(ledPinB,OUTPUT);

}

void loop() {
if (irrecv.decode(&results)) {

if (results.value==0xFFA25D){ //Code to turn the LED ON/OFF- taste
if(before==0){ // if the LED was turned off, then we turn it on
digitalWrite(ledPinR,HIGH);
digitalWrite(ledPinG,HIGH);
digitalWrite(ledPinB,HIGH);

before=1; //LED is now turned on
}
else{
digitalWrite(ledPinR,LOW);
digitalWrite(ledPinG,LOW);
digitalWrite(ledPinB,LOW);
;
//if the LED was turned on, then we turn it off
before=0;
bright=255;

}}

irrecv.resume();
}}

Funktion 2:

int analogPin = 0;
int strobePin = 5;
int resetPin = 6;
int ledPinR = 9;
int ledPinG = 10;
int ledPinB = 11;
int spectrumValue[7];
int filter = 260;
void setup() {

Serial.begin(9600);
pinMode(analogPin, INPUT);
pinMode(strobePin, OUTPUT);
pinMode(resetPin, OUTPUT);
pinMode(ledPinR, OUTPUT);
pinMode(ledPinB, OUTPUT);
pinMode(ledPinG, OUTPUT);
digitalWrite(resetPin, LOW);
digitalWrite(strobePin, HIGH);
}

void loop() {

digitalWrite(resetPin, HIGH);
digitalWrite(resetPin, LOW);
for (int i = 0; i < 7; i++) {
digitalWrite(strobePin, LOW);
delayMicroseconds(30);
spectrumValue = analogRead(analogPin);
_ if (spectrumValue < filter) {_
_ spectrumValue = 0;
}

spectrumValue = map(spectrumValue*, 0, 750, 0, 255);*
* digitalWrite(strobePin, HIGH);
Serial.print(spectrumValue);
Serial.print(" ");
}
int redvalue = (spectrumValue[0] + spectrumValue[1] + spectrumValue[2]);
int greenvalue = (spectrumValue[3] + spectrumValue[4]);
int bluevalue = (spectrumValue[5] + spectrumValue[6]);
if (redvalue > 255)
{
redvalue = 255;
}
if (greenvalue > 255)
{
greenvalue = 255;
}
if (bluevalue > 255)
{
bluevalue = 255;
}*_

* Serial.print(redvalue);*
* Serial.print(" ");*
* Serial.print(greenvalue);*
* Serial.print(" ");*
* Serial.print(bluevalue);*
* Serial.println();*

* analogWrite(ledPinR, redvalue); *
* analogWrite(ledPinG, greenvalue);*
* analogWrite(ledPinB, bluevalue);*
}

Verpacke doch erst mal beide Funktionen in eigene Funktionsdefinitionen. Bei den globalen Variablen aufpassen, dass sich keine Dopplungen ergeben, dann eine umbenennen (auch in der Funktion)

Also sowas wie (Pseudocode):

alle includes 

Globale Variablen

void setup() {
  allgemeine Initialisierung - IR
  Initialisierung für Funktion 1
  Initialisierung für funktion 2
}

void funktion1 () {

}

void funktion2 () {

}

void loop() {
  ircode = ircode_empfangen();
  if (ircode == 1) {
     funktion1();
  }
  if (ircode == 2) {
     funktion2();
  }

}

Gruß Tommy

Die Antwort wurde dir doch im parallel-Forum schon gegeben.

@Tommy Vielen Dank für die schnelle Antwort. Ich habe mich direkt ran gesetzt und deinen Tipp versucht umsetzten. Scheint nur ein Fehler zu sein. Denn die LED´s reagieren nicht…

#include <Adafruit_NeoPixel.h>
#include <IRremote.h>

int before;
int ledPinR = 10;
int ledPinG = 9;
int ledPinB = 11;

int RECV_PIN = 3;

int analogPin = 0; // MSGEQ7 OUT
int strobePin = 7; // MSGEQ7 STROBE
int resetPin = 8; // MSGEQ7 RESET
int spectrumValue[7];

int filterValue =240;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup(){
irrecv.enableIRIn(); // start the receiver
before=0; //LED is turned off
pinMode(ledPinR,OUTPUT);
pinMode(ledPinG,OUTPUT);
pinMode(ledPinB,OUTPUT);
//Serial.begin(9600);
// Read from MSGEQ7 OUT
pinMode(analogPin, INPUT);
// Write to MSGEQ7 STROBE and RESET
pinMode(strobePin, OUTPUT);
pinMode(resetPin, OUTPUT);

}

void GewitterAn() {
for (int i = 0; i < 7; i++)
{
digitalWrite(resetPin, LOW);
digitalWrite(strobePin, LOW);
delayMicroseconds(30); // Allow output to settle

spectrumValue = analogRead(analogPin);

  • // Constrain any value above 1023 or below filterValue*
    spectrumValue = constrain(spectrumValue*, filterValue, 100);*
    * // Remap the value to a number between 0 and 255*
    spectrumValue = map(spectrumValue*, filterValue, 100, 0, 255);*
    * // Remove serial stuff after debugging*
    _ //Serial.print(spectrumValue*);
    //Serial.print(" ");
    digitalWrite(strobePin, HIGH);
    //Serial.println();
    // Write the PWM values to the LEDs*

    * // I find that with three LEDs, these three spectrum values work the best*
    * analogWrite(ledPinR, spectrumValue[2]);
    analogWrite(ledPinG, spectrumValue[2]);
    analogWrite(ledPinB, spectrumValue[2]);*_

}}
void GewitterAus() {
* for (int i = 0; i < 7; i++)*
* {*
* digitalWrite(resetPin, LOW);*
* digitalWrite(strobePin, LOW);*
* delayMicroseconds(30); // Allow output to settle*
_ spectrumValue = analogRead(analogPin);
* // Constrain any value above 1023 or below filterValue*
spectrumValue = constrain(spectrumValue*, filterValue, 100);*
* // Remap the value to a number between 0 and 255*
spectrumValue = map(spectrumValue*, filterValue, 100, 0, 255);*
* // Remove serial stuff after debugging*
//Serial.print(spectrumValue*);
//Serial.print(" ");
digitalWrite(strobePin, HIGH);
//Serial.println();
// Write the PWM values to the LEDs*

* // I find that with three LEDs, these three spectrum values work the best*
* //analogWrite(ledPinR, spectrumValue[2]);
//analogWrite(ledPinG, spectrumValue[2]);
//analogWrite(ledPinB, spectrumValue[2]);*_

}}
void loop() {
* if (irrecv.decode(&results)) {*
* if (results.value==0xFFA25D){*
* if(before==0){ //*
* digitalWrite(ledPinR,HIGH);*
* digitalWrite(ledPinG,HIGH);*
* digitalWrite(ledPinB,HIGH);*

* before=1; //LED on*
* }*
* else{*
* digitalWrite(ledPinR,LOW);*
* digitalWrite(ledPinG,LOW);*
* digitalWrite(ledPinB,LOW);*
* ;*
* // LED off*
* before=0;*

* }}*
* if (results.value==0xFF52AD) {*
* GewitterAn();*
* }*
* if (results.value==0xFF52AD) {*
* GewitterAus();*
* }}*

* irrecv.resume();*
}

#include <Adafruit_NeoPixel.h>
...
int ledPinR = 10;
int ledPinG = 9;
int ledPinB = 11;

Was verwendest Du, NeoPixel oder RGB-LEDs?

@HotSystems
Da hast du recht. Dort habe ich auch eine Antwort bekommen. Nur so einfach ist die Umsetzung dann doch nicht :confused:

Dann baue doch die beiden Antworten von Hotsystems und mir erst mal zusammen und stelle den Code bitte in Codetags </> oben links beim Edit.

Dann schauen wir nochmal.

Gruß Tommy.

@agmue Die Ansteuerung der LED´s funktioniert einbandfrei. Das zusammenführen der Codes nur nicht so richtig.

das_tobi:
@agmue
Die Ansteuerung der LED´s funktioniert einbandfrei. Das zusammenführen der Codes nur nicht so richtig.

Jede eingebundene Bibliothek kann zu Problemen führen. Wenn Du RGB-LEDs hast, brauchst Du die Neopixel-Bibliothek nicht.

@agmue Gut erkannt, Respekt! die Bibliothek hat sich unnützerweise eingeschlichen. Das ist mir nicht aufgefallen.

@tommy56 Nun Hab ich eure Tips berücksichtig und alles zusammengeführt. Hoffentlich stell ich mich bei euch nicht zu doof an aber werde mir Mühe geben. Ledan() und Ledaus() klappt perfekt. Allerdings bei Gewitteran() (etwas verwirrender Name vllt) unzwar der Code bzw die Ansteuerung für die Spectrum analyse funktioniert nicht. Bei Tastendruck leuchten alle RGB durchgängig und erneutes drücken reagiert nichts mehr. Der Spectrum-Code einzeln auf dem Arduino also vor dem einfügen in die Funktion, läuft er noch fehlerfrei…

#include <IRremote.h>
int bright;
int before;
int ledPinR = 10;
int ledPinG = 9;
int ledPinB = 11;

int RECV_PIN = 3; 

// MSGEQ7
int analogPin = 0; 
int strobePin = 5; 
int resetPin = 6; 
int spectrumValue[7];
int filterValue =240;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup(){
  irrecv.enableIRIn(); 
  before=0; 
  //Serial.begin(9600);
  // MSGEQ7 OUT
  pinMode(analogPin, INPUT);
  pinMode(strobePin, OUTPUT);
  pinMode(resetPin, OUTPUT);

  // Set analogPin's reference voltage
  analogReference(DEFAULT); // 5V

  // Set startup values for pins
  digitalWrite(resetPin, LOW);
  digitalWrite(strobePin, HIGH);
 
  
}

void loop() {
  if (irrecv.decode(&results)) {
    
    if (results.value==0xFF906F){ 
    if(before==0){
    ledan();
    before=1;
    }
    else{
      ledaus();
      before=0;
  }}

  if (results.value==0xFFA25D){ 
    if(before==0){
    gewitteran();
    before=1;
    }
    else{
      gewitteraus();
      before=0;
  }}

  irrecv.resume();
}}


void gewitteran() {
 
  // Set reset pin low to enable strobe
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);

  // Get all 7 spectrum values from the MSGEQ7
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(strobePin, LOW);
    delayMicroseconds(30); 

    spectrumValue[i] = analogRead(analogPin);

    spectrumValue[i] = constrain(spectrumValue[i], filterValue, 100);

    spectrumValue[i] = map(spectrumValue[i], filterValue, 100, 0, 255);

    // Remove serial stuff after debugging
    //Serial.print(spectrumValue[i]);
    //Serial.print(" ");
    digitalWrite(strobePin, HIGH);
  }

  //Serial.println();

  //LEDSpectrum EIN
  analogWrite(ledPinR, spectrumValue[2]);
  analogWrite(ledPinG, spectrumValue[4]);
  analogWrite(ledPinB, spectrumValue[5]);

}



void gewitteraus() {
 
  
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);

  // Get all 7 spectrum values from the MSGEQ7
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(strobePin, LOW);
    delayMicroseconds(30); 

    spectrumValue[i] = analogRead(analogPin);

    spectrumValue[i] = constrain(spectrumValue[i], filterValue, 100);

    spectrumValue[i] = map(spectrumValue[i], filterValue, 100, 0, 255);

    // Remove serial stuff after debugging
    //Serial.print(spectrumValue[i]);
    //Serial.print(" ");
    digitalWrite(strobePin, HIGH);
  }

  //Serial.println();

  //LEDSpectrum ausgeschaltet
  //analogWrite(ledPinR, spectrumValue[2]);
  //analogWrite(ledPinG, spectrumValue[4]);
  //analogWrite(ledPinB, spectrumValue[5]);

}

void ledan() {

  digitalWrite(ledPinR,HIGH);
  digitalWrite(ledPinG,HIGH);
  digitalWrite(ledPinB,HIGH);
}


void ledaus() {

  digitalWrite(ledPinR,LOW);
  digitalWrite(ledPinG,LOW);
  digitalWrite(ledPinB,LOW);
}

das_tobi:
@agmue Gut erkannt, Respekt! die Bibliothek hat sich unnützerweise eingeschlichen. Das ist mir nicht aufgefallen.

Danke, aber so schwierig war das nicht für mich. Die LEDs in meinem Avartar-Bildchen sind NeoPixel, daher ist mir die Bibliothek bakannt.

Vorneweg: Den MSGEQ7 kenne ich nicht, daher verstehe ich wohl auch diese Zeilen nicht:

   spectrumValue[i] = constrain(spectrumValue[i], filterValue, 100);
    spectrumValue[i] = map(spectrumValue[i], filterValue, 100, 0, 255);

Anstelle MSGEQ7 habe ich ein Poti angeschlossen und ein paar Anschlüsse verlegt. Eine RGB-LED habe ich nicht, daher drei einzelne LEDs. Außerdem unterscheidet sich die Anzeige von Gewitter an und aus.

Dieses Programm macht jetzt was auf Fernbedienungsdruck:

#include <IRremote.h>
const int ledPinR = 10;
const int ledPinG = 9;
const int ledPinB = 5;
const int RECV_PIN = 2;

int bright;
int before;

IRrecv irrecv(RECV_PIN);
decode_results results;

// MSGEQ7
const int analogPin = A0;
const int strobePin = 3;
const int resetPin = 6;
int spectrumValue[7];
int filterValue = 240;

void setup() {
  irrecv.enableIRIn();
  before = 0;
  Serial.begin(9600);
  Serial.println("Anfang");
  // MSGEQ7 OUT
  pinMode(analogPin, INPUT);
  pinMode(strobePin, OUTPUT);
  pinMode(resetPin, OUTPUT);
  // Set startup values for pins
  digitalWrite(resetPin, LOW);
  digitalWrite(strobePin, HIGH);

  // Set analogPin's reference voltage
  analogReference(DEFAULT); // 5V
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    if (results.value == 0xFF906F) {  // CH-
      if (before == 0) {
        ledan();
        before = 1;
      }
      else 
      {
        ledaus();
        before = 0;
      }
    }

    if (results.value == 0xFFA25D) {  // EQ
      if (before == 0) {
        gewitteran();
        before = 1;
      }
      else 
      {
        gewitteraus();
        before = 0;
      }
    }
    irrecv.resume();
  }
}


void gewitteran() {

  // Set reset pin low to enable strobe
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);

  // Get all 7 spectrum values from the MSGEQ7
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(strobePin, LOW);
    delayMicroseconds(30);

    spectrumValue[i] = analogRead(analogPin);
    spectrumValue[i] = map(spectrumValue[i], 0, 1023, 0, 255);

    // spectrumValue[i] = constrain(spectrumValue[i], filterValue, 100);

    // spectrumValue[i] = map(spectrumValue[i], filterValue, 100, 0, 255);

    // Remove serial stuff after debugging
    Serial.print("\t");
    Serial.print(i);
    Serial.print(": ");
    Serial.print(spectrumValue[i]);
    digitalWrite(strobePin, HIGH);
  }

  Serial.println();

  //LEDSpectrum EIN
  analogWrite(ledPinR, spectrumValue[2]);
  analogWrite(ledPinG, spectrumValue[4]);
  analogWrite(ledPinB, spectrumValue[5]);

}

void gewitteraus() {
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);
  // Get all 7 spectrum values from the MSGEQ7
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(strobePin, LOW);
    delayMicroseconds(30);

    spectrumValue[i] = analogRead(analogPin);
    spectrumValue[i] = map(spectrumValue[i], 0, 1023, 255, 0);
    // spectrumValue[i] = constrain(spectrumValue[i], filterValue, 100);
    // spectrumValue[i] = map(spectrumValue[i], filterValue, 100, 0, 255);

    // Remove serial stuff after debugging
    Serial.print("\t");
    Serial.print(i);
    Serial.print(": ");
    Serial.print(spectrumValue[i]);

    digitalWrite(strobePin, HIGH);
  }

  Serial.println();

  //LEDSpectrum ausgeschaltet
  analogWrite(ledPinR, spectrumValue[2]);
  analogWrite(ledPinG, spectrumValue[4]);
  analogWrite(ledPinB, spectrumValue[5]);

}

void ledan() {
  digitalWrite(ledPinR, HIGH);
  digitalWrite(ledPinG, HIGH);
  digitalWrite(ledPinB, HIGH);
}


void ledaus() {
  digitalWrite(ledPinR, LOW);
  digitalWrite(ledPinG, LOW);
  digitalWrite(ledPinB, LOW);
}

IR-Fernbedienung und PWM für die RGB-LED scheinen sich nun nicht zu stören. Darauf könntest Du aufbauen.

Das mit dem constrain und map ist Murks. Was soll das sein - eine Rauschunterdrückung?

Bei constrain wurden lower und upper limit vertauscht. (edit: Oder soll das invers reagieren?)

Gib Dir die spectrumValues vor und nach Konvertierung im seriellen Monitor aus, dann siehst Du Dein Problem.

  • Lass erstmal IR weg, lies vom MSGEQ7 Daten
  • bringe diese in einen für Dich sinnvollen Wertebereich (ser. Monitor ist Dein Freund)
  • sende diese Werte an einen PWM Ausgang, steuere also erstmal eine Farbe vom RGB Strip.

Wenn das klappt, sehen wir weiter. Einen Schritt nach dem anderen.

Gruß, Helmuth

P.S. Wenn Du den vom A/D Wandler gelesenen 10 Bit Wert durch 4 dividierst, bist Du im gültigen Wertebereich 0-255. Wie hoch ist Dein Grundrauschen? (Gemessenen Werte, wenn kein Audiosignal anliegt)

P.P.S. Ich habe bei IRremote nicht im Detail hingesehen, aber eine kurze Google Suche sagt mir "Well you can't use Arduino Pin 6 for the IR transmit function. Not with the way that an ATmega timer is used with IRremote. The IRremote library uses Timer 2 in a mode that only works with output on Arduino Pin 3." Also IR an Pin 3 und den MSGEQ woandershin. Korrektur, dies ist nur beim IR Senden wichtig.

@agmue @Helmuth

Danke für die produktiven Tipps. Ich werde das ganze in den nächsten Tagen versuchen zu testen und melde mich !

@Helmuth: Mein nicht näher untersuchter Verdacht geht in die Richtung, IR und PWM vertragen sich nicht hinsichtlich der Nutzbarkeit aller PWM-Pins. Daher habe ich durch Probieren eine funktionierende Pinbelegung herausgefunden.