caramoan tour package

caramoan tour package

Author Topic: Arduino-Based Music Synchronized Light Controller  (Read 565 times)

Offline anthonydp

  • Size D Battery
  • ******
  • Posts: 320
  • Pogi/Ganda Points: 54
  • Gender: Male
    • My Empty Blog
Arduino-Based Music Synchronized Light Controller
« on: December 21, 2010, 12:59:01 PM »
Being the Christmas season, it would be nice to decorate the house for the holidays.
So, here's a project for the holidays: an arduino-controlled midi-synchronized light controller



the code was based from the Tom Scarff's MIDI Drums to LEDs, modified to respond on the DOREMI of music instead of drums and to display it on 10-LEDs for all notes on all octaves.

The controller is 10-channel only, although nothing should stop you to increase the number of channels.

enjoy.

Code: [Select]
/*
 NAME:                 MIDI Drums to 16 TTL Outputs
 WRITTEN BY:           TOM SCARFF
 DATE:                 12/1/2009
 FILE SAVED AS:        midi_drums_LEDS.pde
 FOR:                  Miduino ATmega168
 CLOCK:                16.00 MHz CRYSTAL                                       
 PROGRAMME FUNCTION:  Detect midi Drum inputs and send 16 corresponding TTL outputs.
 
 
 IMPORTANT:
 The Miduino might not start if it receives data directly after a reset,
 because the bootloader thinks you want to upload a new progam.You might
 need to unplug the MIDI IN cable until the board is running your program.
 Also when programming the Miduino disconnect the MIDI IN cable.
 
 HARDWARE NOTE:
 The Midi IN Socket is connected to the Miduino RX through an 6N139 opto-isolator
 *
 * To send MIDI, attach a MIDI out Female 180 Degree 5-Pin DIN socket to Arduino.
 * Socket is seen from solder tags at rear.
 * DIN-5 pinout is:                                         _______
 *    pin 2 - Gnd                                          /       \
 *    pin 4 - 220 ohm resistor to +5V                     | 1     3 |  MIDI jack
 *    pin 5 - Arduino Pin 1 (TX) via a 220 ohm resistor   |  4   5  |
 *    all other pins - unconnected                         \___2___/
 *
 *
 *****************************************************************************
 *
 */




// define the output pins (anthonydp: i only use 10 outputs)
#define Output0 2
#define Output1 3
#define Output2 4
#define Output3 5
#define Output4 6
#define Output5 7
#define Output6 8
#define Output7 9
#define Output8 10
#define Output9 11
//#define Output10 12



//variables setup

byte midiByte;
byte MIDIchannel = 0; //drum channel (anthonydp: channel 1, but we'll use all channels and filter channel on PC side)
byte channel;

byte status=0;
byte statusType;
byte statusTest;
byte volume_now=0;
byte volume_past=0;
byte x;
byte startTest=0;
byte runningStatus;
byte Flag;
byte LedPin = 13;   // select the pin for the LED
byte runStatusFlag=0;
byte realTimeTest;
byte count;
byte note;
byte startNoteFlag=0;


int startNote=60;
int channelTest=0;


void setup() {
  pinMode(Output0,OUTPUT);
  pinMode(Output1,OUTPUT);
  pinMode(Output2,OUTPUT);
  pinMode(Output3,OUTPUT);
  pinMode(Output4,OUTPUT);
  pinMode(Output5,OUTPUT);
  pinMode(Output6,OUTPUT);
  pinMode(Output7,OUTPUT);
  pinMode(Output8,OUTPUT);
  pinMode(Output9,OUTPUT);

  pinMode(12, INPUT);     // Program Switch
  digitalWrite(12, HIGH); // Set inputs Pull-up resistors High

  pinMode(LedPin,OUTPUT);   // declare the LED's pin as output

  for (x=1; x<=4; x++){
    digitalWrite( LedPin, HIGH );
    delay(300);
    digitalWrite( LedPin, LOW );
    delay(300);
  }


   Serial.begin(38400);  //start serial with midi baudrate 38400 Roland MIDI

  //Serial.begin(31250);  //start serial with midi baudrate 31250

    Serial.flush();


}


void loop() {




  // Midi in to out
  midiThru();



}
//_____________________________________________________________________________________________________

// Functions:




//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


void midiThru(){

  if (Serial.available() > 0){      //If MIDI available read the incoming MIDI byte and transmit it thru
    midiByte = Serial.read();
    digitalWrite(LedPin, HIGH);   // sets the LED on

    statusType= midiByte&0xF0;
    statusTest=midiByte&0x80;
    channel=midiByte&0x0F;

    if(statusTest==0x80){        // if midi status and NOT data

      if(midiByte>=0x80 && midiByte<=0xEF){ //if midi channel command
        runningStatus=midiByte;
      }
      status=midiByte;
      Serial.print(status,BYTE); // transmit midi status byte
      txMidi();                   // transmit following data bytes
    }


    if(statusTest!=0x80&&status!=0){      // if running status and NOT starting data byte

      status=runningStatus;    // insert status byte
      channel=status&0x0F;
      statusType= status&0xF0;
      Serial.print(status,BYTE); // transmit midi running status byte
      txMidi2(status);                   // transmit following data bytes
    }

  }
  digitalWrite(LedPin, LOW);    // sets the LED off
}



//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


void readMidi(){

  while (Flag==0){
    if (Serial.available() > 0) { 
      midiByte = Serial.read();         
      Flag=1;
    }
  }
  Flag=0;

}

////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void txMidi(){



  if(statusType==0xF0){

    getStatus1(status);  // complete status byte

  }

  else if(statusType!=0xF0){

    getStatus2(status); // status with channel removed
  }

}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void getStatus1(byte val){


  switch (val) {
  case 0xF0:                //Begin System Exclusive 11110000 (F0)
    while (midiByte!=0XF7){      // until End of Sysex
      if (Serial.available() > 0) { 
        midiByte = Serial.read();
        Serial.print(midiByte,BYTE);     
      }
    }
    break;

  case 0xF1:                //MIDI  Time Code 11110001 (F1)

    mididata1Tx();
    break;

  case 0xF2:             //Song Position Pointer  11110010 (F2)

    mididata2Tx();
    break;

  case 0xF3:            //Song Select  11110011 (F3)

    mididata1Tx();
    break;


  case 0xF7:           //End System Exclusive 11110111 (F7)   
    break;                // single byte data

  case 0xF8:           //Timing Clock 11111000 (F8)
    // single byte data
    break;

  case 0xFA:           //Start 11111010  (FA)
    // single byte data
    break;

  case 0xFB:          //Continue 11111011 (FB)
    // single byte data
    break;

  case 0xFC:          //Stop 11111100 (FC)
    // single byte data
    break;

  case 0xFE:          //Active Sensing  11111110 (FE)
    // single byte data
    break;

  case 0xFF:         //System Reset 11111111 (FF)
    // single byte data 
    break;




  default:
    break;
  }
}

//___________________________________________________

void getStatus2(byte val){

  val = val & 0xF0;          //remove channel info

  switch (val) {
  case 0x90:                // Note-On Event            1001bbbb (9X)

    //mididata2Tx();
    count=2;
    while (count!=0){
      readMidi();             // get midi
      realTimeTest=midiByte&0x80;   // if Real Time dont decrement count
      if (realTimeTest==0){
        //if(count==2 && channel==MIDIchannel){  //anthonydp: commented this out so we'll allow all midi channels
        if(count==2){                            //anthonydp: added this
          note=midiByte;
        }

        //else if (count==1 && channel==MIDIchannel){    //anthonydp: commented this out so we'll allow all midi channels
        else if (count==1){
          if(midiByte==0){
            getNoteOff(note);
          }
          else if(midiByte!=0){
            getNoteOn(note);
          }
        }
        count=count-1;
      }            // data byte
      Serial.print(midiByte,BYTE); // transmit midi
    }
    break;

  case 0x80:                //Note-Off  Event          1000bbbb (8X)

    //mididata2Tx();
    count=2;
    while (count!=0){
      readMidi();             // get midi
      realTimeTest=midiByte&0x80;   // if Real Time dont decrement count
      if (realTimeTest==0){
        //if (count==2 && channel==MIDIchannel){    //anthonydp: commented this out so we'll allow all midi channels
        if (count==2){                              //anthonydp: added this

          getNoteOff(midiByte);
        }
        count=count-1;


      }            // data byte
      Serial.print(midiByte,BYTE); // transmit midi
    }
    break;

  case 0xA0:                //Control Polyphonic Key Pressure  1010bbbb (AX)      0kkkkkkk  0fffffff

    mididata2Tx(); 
    break;

  case 0xB0:                //Control Change           1011bbbb (BX)

    mididata2Tx();   
    break;

  case 0xC0:                //Program Change           1100bbbb (CX)

    mididata1Tx();
    break;

  case 0xD0:                //Channel Pressure         1101bbbb (DX)

    mididata1Tx(); 
    break;

  case 0xE0:                //Pitch Bend               1110bbbb (EX)

    mididata2Tx();   
    break;


  default:
    break;
  }
}


////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

void txMidi2(byte val){      // running status mode data 1 available already in midiByte


  val = val & 0xF0;          //remove channel info

  switch (val) {
  case 0x90:                // Note-On Event            1001bbbb (9X)
    //if(channel==MIDIchannel)                 //anthonydp: commented this out so we'll allow all midi channels
    {  note=midiByte;

    }
    Serial.print(midiByte,BYTE); // transmit midi data
    // mididata1Tx();
    count=1;
    while (count!=0){
      readMidi();             // get midi
      realTimeTest=midiByte&0x80;   // if Real Time dont decrement count
      if (realTimeTest==0){
        //if (count==1 && channel==MIDIchannel){    //anthonydp: commented this out so we'll allow all midi channels
        if (count==1){
          if(midiByte==0){
            getNoteOff(note);
          }
          if(midiByte!=0){
            getNoteOn(note);
          } 
        }
        count=count-1;
      }            // data byte
      Serial.print(midiByte,BYTE); // transmit midi
    }
    break;

  case 0x80:                //Note-Off  Event          1000bbbb (8X)
    //if(channel==MIDIchannel)    //anthonydp: commented this out so we'll allow all midi channels
    {
      getNoteOff(midiByte);
    }
    Serial.print(midiByte,BYTE); // transmit midi note data
    // mididata1Tx();
    count=1;
    while (count!=0){
      readMidi();             // get midi
      realTimeTest=midiByte&0x80;   // if Real Time dont decrement count
      if (realTimeTest==0){
        count=count-1;
      }           
      Serial.print(midiByte,BYTE); // transmit midi
    }
    break;

  case 0xA0:                //Control Polyphonic Key Pressure  1010bbbb (AX)      0kkkkkkk  0fffffff

    Serial.print(midiByte,BYTE); // transmit midi Polyphonic Key Pressure  data 1
    mididata1Tx();   
    break;

  case 0xB0:                //Control Change           1011bbbb (BX)

    Serial.print(midiByte,BYTE); // transmit midi control data 1
    mididata1Tx();   
    break;

  case 0xC0:                //Program Change           1100bbbb (CX)

    Serial.print(midiByte,BYTE); // transmit midi program change data 
    break;

  case 0xD0:                //Channel Pressure         1101bbbb (DX)

    Serial.print(midiByte,BYTE); // transmit midi channel pressure data     
    break;

  case 0xE0:                //Pitch Bend               1110bbbb (EX)

    Serial.print(midiByte,BYTE); // transmit midi Pitch Bend  data 1
    mididata1Tx();   
    break;


  default:
    break;
  }
}

//---------------------------------------------------------------------------------

void mididata2Tx()

{
  count=2;
  while (count!=0){
    readMidi();             // get midi
    realTimeTest=midiByte&0x80;   // if Real Time dont decrement count
    if (realTimeTest==0){
      count=count-1;
    }            // data byte
    Serial.print(midiByte,BYTE); // transmit midi
  }

}   

//------------------------------------------------------------------------------

void mididata1Tx()

{
  count=1;
  while (count!=0){
    readMidi();             // get midi
    realTimeTest=midiByte&0x80;   // if Real Time dont decrement count
    if (realTimeTest==0){
      count=count-1;
    }            // data byte
    Serial.print(midiByte,BYTE); // transmit midi
  }

}

////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


void getNoteOn(byte var)
{
  byte i = var % 10;
  digitalWrite(2 + i,HIGH);    //anthonydp: we allow all notes on all octaves to be displayed on our 10 lights
}

//==========================================
void getNoteOff(byte var)
{
  byte i = var % 10;
  digitalWrite(2 + i,LOW);    //anthonydp: we allow all notes on all octaves
}   


//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


your question appears to be an XY Problem.

why don't you just tell us exactly what you're trying to do?

Philippine Electronics Forum

Arduino-Based Music Synchronized Light Controller
« on: December 21, 2010, 12:59:01 PM »

Offline maldihtah13

  • Technical People
  • Nuclear Reactor
  • *****
  • Posts: 4669
  • Pogi/Ganda Points: 120
  • Gender: Female
  • Everyday is a learning process so try to learn ;D
    • Blogspot
Re: Arduino-Based Music Synchronized Light Controller
« Reply #1 on: December 21, 2010, 09:49:37 PM »
Nice project huh!  ;)

Philippine Electronics Forum

Re: Arduino-Based Music Synchronized Light Controller
« Reply #1 on: December 21, 2010, 09:49:37 PM »

Offline Macgyver

  • Diesel Generator
  • *
  • Posts: 1440
  • Pogi/Ganda Points: 70
    • MakerDude
Re: Arduino-Based Music Synchronized Light Controller
« Reply #2 on: December 21, 2010, 10:11:46 PM »
ano yung nagkiklick?  parang relay ang tunog eh.
Become a Virtual Worker |  MakerDude.com Electronics Shop is now OPEN!

Philippine Electronics Forum

Re: Arduino-Based Music Synchronized Light Controller
« Reply #2 on: December 21, 2010, 10:11:46 PM »

Offline anthonydp

  • Size D Battery
  • ******
  • Posts: 320
  • Pogi/Ganda Points: 54
  • Gender: Male
    • My Empty Blog
Re: Arduino-Based Music Synchronized Light Controller
« Reply #3 on: December 21, 2010, 10:16:04 PM »
relay po yun.  i intend to use triacs and opto-triacs but budget limits me to what's on my bin.  anyway, the only disadvantage with using relays is i can't do dimming.

i used Anvil Studio on the PC side.
Follow this instruction on how to connect your USB to a MIDI interface.

For those really serious about christmas lights with music like from this video:


you may want to visit http://www.vixenlights.com/
there's lots of professional DIY stuff there, all free.
your question appears to be an XY Problem.

why don't you just tell us exactly what you're trying to do?

Philippine Electronics Forum

Re: Arduino-Based Music Synchronized Light Controller
« Reply #3 on: December 21, 2010, 10:16:04 PM »

 

Privacy Policy

Contact Us: elabph@yahoo.com