MIDin: a trasmitter/receiver sytem for MIDI messages using XBee and Arduino

Hi hi-tech friends (…with a prominent geek attitude 🙂 )!

This time I would like to talk about…MUSIC! Ta-daaaa!!

As you know I am also a musician, and I produce freely downloadable music from my music website www.marcolastri.net (only italian language, sorry!  ).

I have a large set of keyboards and synthesizers in my studio, and I have also a Roland AX-7, a “wearable” MIDI controller keyboard similar to a guitar (today these instruments are called “keytars” 😉 ). This keytar is used also by the mighty Herbie Hancock…. 😉

This keytar has also a great feature: it can be power by 6 AA batteries….but you will have always the midi cable in order to command your sound generator or expander (or software synth etc.). The midi cable is a limitation to your performance freedom on stage…so I want to cut it! 😉

There are some good wireless solution off-the-shelf, for example the Mid-Air product from M-Audio….and the price is not so low. 😦

…So I want to realize a DIY solution, using two Arduinos UNO, two XBee Shields and two XBee modules: this is the Garretlabs MIDin project! Ta-daaaa!

I bought from my preferred store (www.robot-italy.com) the following components:

Then I connected these components to two Arduino UNO boards in order to realize: one component working as MIDI Receiver-XBee Sender and one component working as MIDI Sender-XBee Receiver.

Thi is the system overview…design handmade by ML! 😉

20140711_093503

First step: program the XBee modules

This is the more complex step…I don’t love it but (unfortunately) it is necessary.

We must to setup the Series 2 modules in order to enable the “AT mode” communication (the Series 2 chips support also another -more complicated- configuration, in order to realize very complex networks of XBee modules). In other words, we must to program the devices in order to simulate a point-to-point-connection, a true serial wireless connection.

The best tutorial I’ve found on the internet is the following: http://tutorial.cytron.com.my/2012/03/08/xbee-series-2-point-to-point-communication/comment-page-1/. I used it step-by-step in order to configure my XBee modules…and it worked great! 😉

Firstly I downloaded  and installed the X-CTU utility (only for Windows… 😦 ) from Digi site.

After this, I attached a wire to the RESET pin of the Arduino and I connected it to GND. Then I connected the XBee Shield with the XBee module onboard (remember to set his jumper on “USB”): this is the way to directly access the XBee modules for programming them using Arduino board USB connection. In other words, to program the XBee modules it’necessary to disable the ATMEGA chip, so…or you remove it, or you connect to GND the RST Arduino pin. 😉

So, I used as network ID the suggested number (1234), then I configured one module as Coordinator AT (setting in the values SH/SL of  serial number of Router module), and I configured the other module as Router AT (setting in the values SH/SL of Serial Number of Coordinator module).

Well, once configured, the two modules start to “talk” each other, and the leds on shields start to blink. To test the correct configuration you can use the procedure well explained in the  http://tutorial.cytron.com.my/2012/03/08/xbee-series-2-point-to-point-communication/comment-page-1/.

IMPORTANT NOTE: I used the default speed of serial connection (9600 bps) for XBee modules, since I noticed that if I change the data speed, the USB connection from Arduino IDE to Arduino in order to download applications should fatally fail.

 

Second step: the MIDI receiver-XBee sender

The difficult step is passed…so, one moment of relax now! 😉

Ok, let’s start with the secdond step.

This MIDI receiver/XBee Sender has one MIDI connector in order to receive MIDI signals from a synthesizer, the software collect them, then it uses the XBee serial link to send MIDI signals to the other system component (see the third step).

The circuit is very simple…. and it is based on the standard MIDI-IN circuit. See http://www.midi.org/techspecs/electrispec.php to see the details. I modified it a little (especially the optocoupler)…in order to match the parts I had in the “Garret” at the moment 😉 !

The components are:

  • 1x Optocoupler 4N35
  • 1x Diode 4148
  • 1x 100KOhm resistor
  • 1x 220Ohm resistor
  • 1x 3.3KOhm resistor

Note that in the schema I added the XBee module and the XBee shield on the right side of Arduino, in order to better explain the connections, but OBVIOUSLY their must be mounted ON the Arduino! 🙂

XBEE_sender+MIDI_receiver_Garretlabs_bb

The software is simply a MIDI messages collector and re-sender.

Note that I used a buffer to memorize a certain number of MIDI message before to send them, because if wen I receive a message I resend it immediately, I could loose another MIDI message incoming in the meantime. So, I used a “buffering approach”. I verified -as musician 🙂 – that the latency due to buffering is very (very) low, so this approach is acceptable. 😉

Note also that I use the Software Serial (the RX is on pin 10)  to receive MIDI messages, because XBee must use the Serial port.

 #include <SoftwareSerial.h>

SoftwareSerial MidiSerial(10, 11); // RX, TX

byte in_buffer[1024]; //maximum number of bytes arrived in one cpu cycle
unsigned int received_bytes;

void setup()
{
  Serial.begin(9600); //XBEE transmission
  MidiSerial.begin (31250); //MIDI transmission
  
  //led 13 used for debug
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  
  received_bytes=0;

}

void loop()
{
  if(MidiSerial.available()>0)
  {
      received_bytes=MidiSerial.available();
      for (int i=0;i<received_bytes;i++)
        in_buffer[i]=MidiSerial.read();  //save in the buffer all bytes arrived from MIDI port
      
      //write all bytes arrived in the present cycle (so, the input is decoupled from the output)
      digitalWrite(13, HIGH);
      for (int i=0;i<received_bytes;i++)
      {
        Serial.write(in_buffer[i]);
      }
      digitalWrite(13, LOW);
      
      //reset the counter of received bytes in the cycle
      received_bytes=0;
  }
}

In order to write the program on Arduino, you must set the XBee jumper on “USB” position (and obviously you must to remove the cable to ground connected to the RST pin…see step one!). After programming, you should set the jumper on “XBee” position.

 

Third step: the MIDI sender-XBee receiver

Well, this component is more simple than the previous: it receives the MIDI messages from Xbee serial wireless link and it resend them to the MIDI Out port, in order to command a sound generator, a expander or another synth.

Only one component in this case:

  • 1x 220Ohm resistor

This is the (simple) circuit. As you can note, the MIDI In and Out circuits are NOT mirrored (this is the standard)! ….What a strange design choice!!! 🙂

XBEE_receiver+MIDI_sender_Garretlabs_bb

 

And this is the Arduino software (the MIDI management functions are taken from http://arduino.cc/en/Tutorial/Midi?from=Tutorial.MIDI):

#include <SoftwareSerial.h>

SoftwareSerial MidiSerial(10, 11); // RX, TX

void setup()
{
  Serial.begin(9600); //XBEE transmission
  MidiSerial.begin (31250); //MIDI transmission
  
  //led 13 used for debug
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

}

void loop()
{
  
  if(Serial.available() > 0)
  {
    digitalWrite(13, HIGH);
    MidiSerial.write(Serial.read()); //receives the midi messages via XBEE...and send it to Synth
    digitalWrite(13, LOW);
  }
  //Test function
  //SendAllNotes();
}
////////////////////////////////////////////////////////////////////////////////////////////
//
// MIDI HELPER FUNCTIONS (taken from http://arduino.cc/en/Tutorial/Midi?from=Tutorial.MIDI)
//
////////////////////////////////////////////////////////////////////////////////////////////

void SendAllNotes() {
  // play notes from F#-0 (0x1E) to F#-5 (0x5A):
  for (int note = 0x1E; note < 0x5A; note ++) {
    //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
    digitalWrite(13, HIGH);
    MIDICommand(0x90, note, 0x45);
    delay(100);
    digitalWrite(13, LOW);
    //Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
    MIDICommand(0x90, note, 0x00);   
    delay(100);
    
  }
}

//  Send a midi command.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void MIDICommand(int cmd, int pitch, int velocity) {
  MidiSerial.write(cmd);
  MidiSerial.write(pitch);
  MidiSerial.write(velocity);
}

Now you can write the software on Arduino,

And…well… that’s done! 🙂

To test the system you can connect a master keyboard (better if it is a keytar! 😉 ) to Midi Receiver-XBee Sender and a sound generator to Xbee Receiver-Midi Sender…. and you can try to emulate Sandy Marton’s (one of my 80’s Italo Disco heroes) performances with their faboulous keytars!

This is the mighty Sandy in one of his mighty performances:

sandy_marton

Well… it seems a DIY keytar!

 

Bye bye people, now I go to play some note with my AX7…I need a music overdose (I think today I will write an italo-disco song)! 😉

And…remember tio visit my music site www.marcolastri.net!

 

Advertisements

Intel Galileo: I can’t live without a shell…

Hi ,

as promised in my last post, it’s time to write some code and to create some solded part! 🙂 So…let’s start.

An embedded Linux board without a shell has no sense in my opinion. I think this after many, many, toooooo many experience with embedded boards, so similar to black boxes! 😦

You know, I prefer the old style serial shell (the original RS-232 one!), but since Intel Galileo has a fast ethernet plug one can use also a telnet or ssh connection.

So, if you prefer the RS-232 shell, you must build a simple cable in the following way:

Material:

  • One jack 3.5” stereo male connector (you can reuse it form an old pair of earphones!)
  • One DE-9 pin standard female connector for RS-232
  • Three not too long wires
  • Some basic soldering skill 🙂

Schema (drawn by myself ):

serial Galileo

The cable will be connected to the Galileo using a devoted female jack 3.5” connector (right, you can’t use it to plug in your earphones! ^__^) and to the host pc via a native RS-232 male connector or (more probably) using a ten-euros Usb-to-Serial converter.

At this point you will connect to the Galileo using a shell program (in Linux and Mac I use Minicom, on Windows I use PuTTY) with the following (I know, you know… they are always the same) parameters:

  • Serial Port: the identifier of the connected port on the host pc (i.e. COMxx, /dev/ttyUsbx etc. depending on your operating system)
  • Speed: 115200 bps
  • Flow Control: None
  • Parity: None
  • Stop bits: 1
  • Data bits: 8

If you prefere a more “network oriented” solutyion, you can use a telnet shell.

In order to do this, you must download a particular sketch via Arduino IDE for Intel Galileo. This sketch will call some Linux system shell commands (yes, you can launch Linux shell scripts using the Arduino skecth programming…it’s very interesting and it is one of the more celebrated features of Intel Galileo!!!).

You can connect the host pc and the Galileo board via cross-patch network cable or using a Fast Ethernet switch between the host pc and the board.

This is the sketch I used . You can copy/paste it on the Arduino IDE then you will download it on Galileo after his boot, lastly open the IDE serial terminal to see the output of linux commands.

//Sketch to connect a PC host to Linux Galileo via telnet 
// Written by M. Lastri fo garretlabs.wordpress.com
//The sketch will:
//1. set the Galileo IP to 169.254.1.1 
//2. start telnet server
//------>>>>>After this the user can:
//3. From the pc host (i.e. with IP =169.254.1.2) send ping 169.254.1.1 and verify the answer
//4. From the host send the famous command "telnet 169.254.1.1"...and the Linux Galileo shell should appear (user: root, no password)!
//5. Enjoy!
void setup() 
{
  system("ifconfig > /dev/ttyGS0");
  system("ifconfig eth0 169.254.1.1 netmask 255.255.0.0 up");
  system("ifconfig > /dev/ttyGS0");
  system("telnetd -l /bin/sh");
}
void loop() 
{
  //nothing here 
}

Important note: someone on internet verified that if Galileo starts without the ethernet cable connected, the telnet server will not start properly, so, ensure that you will power on the Galileo board with the ethernet link connected (directy to the host pc or to the switch).

Another important thing: if using for Galileo and for host pc the well known LAN addresses 192.168.1.x with mask 255.255.255.0, the connection between pc and Galileo doesn’t seem to work in my setup. It is a very strange behavior in my opinion…so we should investigate on it! 😉

In the next post dedicated to Galileo I will start to play with porting sketches (and their problems) from Arduino UNO/Mega ADK  to the Intel platform. Well’ verify that it’s no so simple… or, better,as we say in Italy, “It isn’t all gold which is brilliant” ! 🙂

…Bye (male & female) geeks!