Arduino Lichtorgel - Kurzanleitung

Schaltplan

Schaltplan der Lichtorgel (für Werte der Widerstände siehe Bauanleitung).

Arduino code

#include "arduinoFFT.h"
 
#define SAMPLES 128             //Zweierpotenzen
#define ABTASTRATE 8000         //Hz

arduinoFFT FFT = arduinoFFT();
 
unsigned int zeitintervall;
unsigned long t;


//Variablen für die Sampledaten bzw. für die FFT
double vReal[SAMPLES];
double vImag[SAMPLES];

//Intensitäten der 3 Frequenzbereiche (Kanal 1 + Kanal 2)
double value1;
double value2;
double value3;
double wert1;
double wert2;
double wert3;

//pins
int kanal1=A4;
int kanal2=A6;
int pin1r=10;
int pin1g=9;
int pin1b=11;
int pin2b=A5;
int pin2g=5;
int pin2r=6;

long m1;
long M1;
long m2;
long M2;
double h;
int h1;
int h2;
int h3;
double f;
int f1;
int f2;
int f3;

int g1;
int g2;


void setup() {
    Serial.begin(9600); //Nur für Ausgabe im Seriellen Monitor nötig
    pinMode(kanal1,INPUT);
    pinMode(kanal2,INPUT);
    pinMode(pin1g,OUTPUT);
    pinMode(pin1r,OUTPUT);
    pinMode(pin1b,OUTPUT);
    pinMode(pin2b,OUTPUT);
    pinMode(pin2r,OUTPUT);
    pinMode(pin2g,OUTPUT);
    // Zeitintervall = Zeitdifferenz zwischen zwei Samples in Mikrosekunden
    zeitintervall = round(1000000*(1.0/ABTASTRATE));
    g1=round(SAMPLES*(800.0/ABTASTRATE));
    g2=round(SAMPLES*(2000.0/ABTASTRATE));
}

 
void loop() {

    //SAMPLING Kanal 1
    for(int i=0; i < SAMPLES; i++)
    {
        t = micros();
     
        vReal[i] = analogRead(kanal1);
        vImag[i] = 0;

     
        while(micros() < (t + zeitintervall)){
          //Abwarten, bis zeitintervall vorbei
        }
    }
 
    //FFT
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    value1=0;
    value2=0;
    value3=0;



    //Summen der Intensitäten für jedes Frequenzband
    for(int i=2;i < g1;i++){
      value1=value1+sqrt(sq(vReal[i])+sq(vImag[i]));
    }
    for(int i=g1;i < g2;i++){
      value2+=sqrt(sq(vReal[i])+sq(vImag[i]));
    }
    for(int i=g2;i<(SAMPLES/2);i++){
      value3+=sqrt(sq(vReal[i])+sq(vImag[i]));
    }




    //SAMPLING Kanal 2
    for(int i=0; i< SAMPLES; i++)
    {
        t = micros();
     
        vReal[i] = analogRead(kanal2);
        vImag[i] = 0;

     
        while(micros() < (t + zeitintervall)){
          //Abwarten, bis zeitintervall vorbei
        }
    }
 
    //FFT
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    wert1=0;
    wert2=0;
    wert3=0;


    //Summen der Intensitäten für jedes Frequenzband
    for(int i=2;i < g1;i++){
      wert1+=sqrt(sq(vReal[i])+sq(vImag[i]));
    }
    for(int i=g1;i < g2;i++){
      wert2+=sqrt(sq(vReal[i])+sq(vImag[i]));
    }
    for(int i=g2;i<(SAMPLES/2);i++){
      wert3+=sqrt(sq(vReal[i])+sq(vImag[i]));
    }





  m1=(value1+value2+value3)/3;
  M1=max(value1,max(value2,value3));
  m2=(wert1+wert2+wert3)/3;
  M2=max(wert1,max(wert2,wert3));
  //Serial.println(value1);
  //Serial.println(value2);
  //Serial.println(value3);

  
  value1=sq(value1/M1);
  value2=sq(value2/M1);
  value3=sq(value3/M1);
  wert1=sq(wert1/M2);
  wert2=sq(wert2/M2);
  wert3=sq(wert3/M2);

  if(m1>1500) {
    h=1;
  } else if(m1>1200) {
    h=0.7;
  } else if(m1>800) {
    h=0.3;
  }
  else if(m1>400) {
    h=0.15;
  } else {
    h=0;
  }

  if(m2>1500) {
    f=1;
  } else if(m2>1200) {
    f=0.7;
  } else if(m2>800) {
    f=0.3;
  }else if(m2>400) {
    f=0.15;
  } else {
    f=0;
  }
  
  h1=round(255*value1*h);
  h2=round(255*value2*h);
  h3=round(255*value3*h);

  f1=round(255*wert1*f);
  f2=round(255*wert2*f);
  f3=round(255*wert3*f);


  analogWrite(pin1b,h1);
  analogWrite(pin1g,h2);
  analogWrite(pin1r,h3);

  analogWrite(pin2b,f1);
  analogWrite(pin2g,f2);
  analogWrite(pin2r,f3);
}