Converting RFID signal to MIDI

I am successfully able to have a Parallax RFID reader print the tags in the serial monitor. Now I am trying to find a way to assign these ID tags to MIDI note values. Is there a way to assign a tag that is read to a MIDI value in a sketch for the arduino board or does one need a software application to take the RFID serial data and convert it to a MIDI message? Any ideas or any examples to make this work would be appreciated. I suppose the next step would also get this constructed hardware to be noticed as a MIDI controller by a Digital Audio Workstation.

Is there a way to assign a tag that is read to a MIDI value in a sketch for the arduino board

I think you mean write it to a MIDI value.

Yes it is very simple, just associate a tag with a number and use that number in a Serial.print statement to send it to the MIDI device.
Suppose you have a list of recognised tags in an array, you get a tag number read in and search the array until you find a match lets say at tag number 12. Now you have an array with the notes you want to produce, use that number 12 in that array to find the note you have mapped it to and then send out a note on message with that note number.
It sounds a lot more complex than it is when written down like this.

The only slight snag is have you used up the serial port in reading the RFID tag? If you will have to use either a Mega with its extra serial ports or the New software serial library to bit bang another output.

Thank you for the reply! Do you know of any sample code I could look at for a frame of reference? Thanks.

You can look at how to generate a MIDI signal from a switch contact in this project:-
http://www.thebox.myzen.co.uk/Hardware/Pendulum.html
There is a bit of other stuff going on as well but pick the simplest un expanded version of the software.

When you say: "Yes it is very simple, just associate a tag with a number and use that number in a Serial.print statement to send it to the MIDI device," I understand the theory behind it, but with very little programming experience, are there any sketch examples close to or similar to what I am trying to do that I could employ? Thanks for your assistance!

Not that I have seen but it rearly is simple if you put a very small effort into it.

I am starting to think I might need a MIDI shield. Is that correct or am I over thinking this? LOL!

You are over thinking it.
You can build a simple
MiDI interface, or get a shield, or use the serial port an an application at the PC end to generate your MIDI signal.

I would prefer not to use Processing to send MIDI data. So here is what I am thinking. How would I modify the following code for creating a drum controller to use RFID tags instead of piezo sensors? You mentioned associating a tag with a number and use that number in a Serial.print statement to send it to the MIDI device. Any chance you could show me how you would do that?

/*

  • MIDI Drum Kit

  • Convert Arduino to a MIDI controller using various inputs and
  • the serial port as a MIDI output.
  • This sketch is set up to send General MIDI (GM) drum notes
  • on MIDI channel 1, but it can be easily reconfigured for other
  • notes and channels
  • It uses switch inputs to send MIDI notes of a fixed velocity with
  • note on time determined by duration of keypress and it uses
  • piezo buzzer elements as inputs to send MIDI notes of a varying velocity
  • & duration, depending on forced of impulse imparted to piezo sensor.
  • To send MIDI, attach a MIDI out jack (female DIN-5) to Arduino.
  • DIN-5 pinout is: _____
  • pin 2 - Gnd / \
  • pin 4 - 220 ohm resistor to +5V | 3 1 | MIDI jack
  • pin 5 - Arduino D1 (TX) | 5 4 |
  • all other pins - unconnected _2_/
  • On my midi jack, the color of the wires for the pins are:
  • 3 = n/c
  • 5 = black (blue)
  • 2 = red (red)
  • 4 = orange (yellow)
  • 1 = brown
  • Based off of Tom Igoe’s work at:
  • http://itp.nyu.edu/physcomp/Labs/MIDIOutput
  • Created 25 October 2006
  • copyleft 2006 Tod E. Kurt <tod@todbot.com
  • http://todbot.com/
  • Updates:
    • 2 May 2009 - fixed noteOn() and noteOff()

*/

// what midi channel we’re sending on
// ranges from 0-15
#define drumchan 1

// general midi drum notes
#define note_bassdrum 35
#define note_snaredrum 38
#define note_hihatclosed 42
#define note_hihatopen 44
#define note_crash 49

// define the pins we use
#define switchAPin 7
#define switchBPin 6
#define switchCPin 5
#define piezoAPin 0
#define piezoBPin 1
#define ledPin 13 // for midi out status

// analog threshold for piezo sensing
#define PIEZOTHRESHOLD 100

int switchAState = LOW;
int switchBState = LOW;
int switchCState = LOW;
int currentSwitchState = LOW;

int val,t;

void setup() {
pinMode(switchAPin, INPUT);
pinMode(switchBPin, INPUT);
pinMode(switchCPin, INPUT);
digitalWrite(switchAPin, HIGH); // turn on internal pullup
digitalWrite(switchBPin, HIGH); // turn on internal pullup
digitalWrite(switchCPin, HIGH); // turn on internal pullup

pinMode(ledPin, OUTPUT);
Serial.begin(31250); // set MIDI baud rate
}

void loop() {
// deal with switchA
currentSwitchState = digitalRead(switchAPin);
if( currentSwitchState == LOW && switchAState == HIGH ) // push
noteOn(drumchan, note_bassdrum, 100);
if( currentSwitchState == HIGH && switchAState == LOW ) // release
noteOff(drumchan, note_bassdrum, 0);
switchAState = currentSwitchState;

// deal with switchB
currentSwitchState = digitalRead(switchBPin);
if( currentSwitchState == LOW && switchBState == HIGH ) // push
noteOn(drumchan, note_snaredrum, 100);
if( currentSwitchState == HIGH && switchBState == LOW ) // release
noteOff(drumchan, note_snaredrum, 0);
switchBState = currentSwitchState;

// deal with switchC
currentSwitchState = digitalRead(switchCPin);
if( currentSwitchState == LOW && switchCState == HIGH ) // push
noteOn(drumchan, note_hihatclosed, 100);
if( currentSwitchState == HIGH && switchCState == LOW ) // release
noteOff(drumchan, note_hihatclosed, 0);
switchCState = currentSwitchState;

// deal with first piezo, this is kind of a hack
val = analogRead(piezoAPin);
if( val >= PIEZOTHRESHOLD ) {
t=0;
while(analogRead(piezoAPin) >= PIEZOTHRESHOLD/2) {
t++;
}
noteOn(drumchan,note_hihatopen, t*2);
delay(t);
noteOff(drumchan,note_hihatopen,0);
}

// deal with second piezos, this is kind of a hack
val = analogRead(piezoBPin);
if( val >= PIEZOTHRESHOLD ) {
t=0;
while(analogRead(piezoBPin) >= PIEZOTHRESHOLD/2) {
t++;
}
noteOn(drumchan,note_crash, t*2);
delay(t);
noteOff(drumchan,note_crash,0);
}
}

// Send a MIDI note-on message. Like pressing a piano key
// channel ranges from 0-15
void noteOn(byte channel, byte note, byte velocity) {
midiMsg( (0x90 | channel), note, velocity);
}

// Send a MIDI note-off message. Like releasing a piano key
void noteOff(byte channel, byte note, byte velocity) {
midiMsg( (0x80 | channel), note, velocity);
}

// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin,HIGH); // indicate we’re sending MIDI data
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
digitalWrite(ledPin,LOW);
}

So here is what I am thinking. How would I modify the following code for creating a drum controller to use RFID tags instead of piezo sensors?

This code sends some message when a particular switch is pressed, and another message when the switch is released.

You could send some message when a particular tag is read. You'd need to figure out when to send the corresponding note off message, though. Have you thought of how to do that?

I was thinking I could use a Master tag that turns MIDI notes off. Is that possible?

Anything is possible it is up to your code. However would that be the way you wanted it to work?
I would have thought that you might want to send the note off a fixed time after the note on.

Good point, Mike. What might you suggest?

Well I don't know what your application is trying to achieve. However given that you have only one RFID reader and that an RFID reader can only read one tag at a time, after the note on I would use a delay() for some time and then send a note off. While delay() is blocking nothing much is going to happen during it.

I would use a delay() for some time and then send a note off.

Well, I wouldn’t.

With absolutely no disrespect intended to Grumpy_Mike, I’d record when the note was sent. On each pass through loop, see if another tag has been presented. If so, send a note off command, a new note on command, and set the time again.

If no new tag was presented, see if it is time to shut off the previous note. If so, send the note off command.

But, it all depends on what you want the code to do and how fast the tags will be presented.

Eventually, I would like to create a musical instrument with RFID tags, but for now, I'd be happy sending MIDI notes one at a time to trigger sound samples and audio loops (the MIDI notes that are being sent would be mapped within Ableton Live, by the way). Would I include definitions for the tags as in the above code that uses piezo sensors or is there a better way to code this? Thanks!

Would I include definitions for the tags as in the above code that uses piezo sensors

Yes.

With absolutely no disrespect intended to Grumpy_Mike,

Yes that is the way I would normally do it myself for switches, keys or magnetic sensors.

But this is an RFID tag and I have worked quite a bit with those. It takes about quarter to a half a second to respond to the presence / absence of a tag and I am guessing that this is longer than you would want a note to be on. That is why I think a delay might just be simpler because there is nothing going on that you have to respond to in that time.

Also it depends on the reader some give only one code when the tag is first presented where others continually send the code for as long as it is in the RF field, other have a separate card present / card absent signal that could be used. However I don't know the specifics of the OPs reader.

As far as I can tell, the Parallax reader I am using continually sends the tag ID when present in the field. Though, I wonder if that is really the case or just how I have it set up in the void loop statement. I have a feeling the delay() might be the way to go. I will try both out and see what happens. I think I may be on the right track, although, I still am not clear on setting up the definitions for the RFID tags so that it correlates to the MIDI notes I intend to assign. Guess it will take some trial and error. LOL! Thanks for the help guys! Any other advice or suggestions is most appreciated.

As far as I can tell, the Parallax reader I am using continually sends the tag ID when present in the field.

Well, this would be ideal then. Send a note on message when the tag is presented. Send a note off message when the tag is removed.