Go Down

Topic: Arduino Playing Glockenspiel (Read 1 time) previous topic - next topic


I have a Glockenspiel I have been driving with hardware and thought it would be fun to play with an Arduino.  Here's what I did.  MIDI data comes from Power Tracks Pro Audio (or a keyboard) into a opto circuit.  Output from the opto goes to a Software Serial port on the Arduino.  This allows using the serial port for the Serial Monitor to debug this mess.  I only look for MIDI commands to turn notes on or off and just ignore the rest.  If I get a MIDI on, I read the note and the velocity, and convert the velocity to either on or off.  There are only 24 notes, so I need three bytes of data sent to two 4x4 Logos Driver Shields.  The driver shields powers the door bell magnets that are mounted on top of the bells.  I don't use any librarys other than for the software serial port and the turnaround time to ring a bell is in the order of 2 milliseconds.  I'm not a programmer but rather in the spirit of all of this, stole most of the code in the sketch below.  A video off the glock is at this link
Code: [Select]

  #include <SoftwareSerial.h>
  SoftwareSerial mySerial(5,6); // RX, TX
  int value;
  byte incomingByte;
  byte note;
  byte notes[24];
  byte notetoplaynow;
  byte velocity; 
  byte highByte;
  byte lowByte;
  byte lastByte;
  unsigned long lasttimenotesent;
  byte channel = 3;     //set the MIDI channel here
  void setup() {
    pinMode(6,OUTPUT);  //MIDI out not used
    pinMode(7,OUTPUT);  //Register Latch
    pinMode(8,OUTPUT);  //Register Latch
    pinMode(9,OUTPUT);  //Middle C light
    pinMode(11,OUTPUT); //Register Input
    pinMode(13,OUTPUT);} //Clock Pin for 4x4

   void loop (){  //This only looks for on or off messages and the note and velocity  MIDI 0 files do not work
      incomingByte = mySerial.read();
      //If the incomming byte just read was a command byte to turn a note on or off, read the next two bytes.  Ignore everything else.
      //1001nnnn (144=channel) is a turn on command byte.  1000nnnn (128) is a note off command where nnnn is the channel.
      if (incomingByte== (127+16+channel) || incomingByte== (127+channel)){
        note = mySerial.read();
        velocity = mySerial.read();
        if (note>=57 && note<=80)playNote(note, velocity); }  // Only play with useful notes
      else if((millis()-lasttimenotesent)>1000)  SendNotes(0, 0, 0); }//Don't leave notes stuck on 
   void playNote(byte note, byte velocity) {
    value=LOW;   //Set the note to either on or off regardless of velocity
    if (velocity >10) value=HIGH; 
    notetoplaynow=note-57;  //convert notetoplaynow to the right output register
    if (value==HIGH) notes[notetoplaynow]=1;  //notes[turn notetoplaynow] on
    else if (value==LOW) notes[notetoplaynow]=0; //turn notes[notetoplaynow] off
    byte lowByte = 0;
    byte highByte = 0;
    for ( byte i=0; i < 8; ++i )
     lowByte |= (notes[i] << i );  //shift each note one register and keep oring them
     highByte |= (notes[8+i] << i );
     lastByte |= (notes[16+i] << i );
   SendNotes(highByte, lowByte, lastByte);   //go play the note
  void SendNotes(byte highByte, byte lowByte, byte lastByte){
   digitalWrite(7, LOW); // Prepares latch
   digitalWrite(8, HIGH); // Deactivates master reset
   shiftOut(11, 13, MSBFIRST, 0);
   shiftOut(11, 13, MSBFIRST, lastByte);   
   shiftOut(11, 13, MSBFIRST, highByte); // shift data for OUT8-OUT15
   shiftOut(11, 13, MSBFIRST, lowByte);  // shift data for OUT0-OUT7
   digitalWrite(7, HIGH);}

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131