optical tachometer to MIDI help

hi

I am working on a device that will be able to measure the speed of a rotating object (in this case a bicycle wheel) and control the pitch of an audio file (in ableton) I have go the optical tachometer working accuratly enough (although the incrementations by which it goes up and down need a bit of tweaking), I have managed to also get it to control the brightness of an LED according to the RPM. The next hurdle is to get the arduino to output the RPM as a midi cc message.
I have wired into the arduino a MIDI out port and have attempted to hack together some code I had from previous projects but so far with so success.
The arduino is outputting midi values but its jibbirish. I just want the RPM to be a cc value so that when it is at its fastest speed it is reading the highest midi value of 127 and when it is still it reads a midi value of 0.
below is the code I have so far - does anyone have any suggestions how to improve it?

/*
 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually. A status LED is connected
 * to pin 12. Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * 
 */
 
int ledPin = 13;                // IR LED connected to digital pin 13
int statusPin = 12;
int lightPin = 11;// LED connected to digital pin 12
int brightness = 0;
int delay_time = 40; // delay for this amount each write cycle.
byte MIDI_channel = 1;
byte cc_number = 127;
byte printing_byte = 0;
int baud_rate = 32500;
int Value = 0;

volatile byte rpmcount;
volatile int status;

unsigned int rpm;

unsigned long timeold;

 void rpm_fun()
 {
   //Each rotation, this interrupt function is run twice, so take that into consideration for 
   //calculating RPM
   //Update count
      rpmcount++;
      
   //Toggle status LED   
   if (status == LOW) {
     status = HIGH;
   } else {
     status = LOW;
   }
   digitalWrite(statusPin, status);
 }

void setup()
 {
   Serial.begin(baud_rate);
   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);
   
   //Turn on IR LED
   pinMode(ledPin, OUTPUT); 
   digitalWrite(ledPin, HIGH);
   
   //Use statusPin to flash along with interrupts
   pinMode(statusPin, OUTPUT);
   pinMode(lightPin, OUTPUT);
   rpmcount = 0;
   rpm = 0;
   timeold = 0;
   status = LOW;
   MIDI_channel = MIDI_channel - 1;
 }

 void loop()
 {
   //Update RPM every second
   delay(500);
   //Don't process interrupts during calculations
   detachInterrupt(0);
   //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
   //happened once per revolution instead of twice. Other multiples could be used
   //for multi-bladed propellers or fans
   rpm = 3*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;
   
  brightness = (4 * rpm);
  analogWrite(lightPin, brightness);
  printing_byte = rpmcount;

  
  Serial.print(B10110000 + MIDI_channel,BYTE);
  Serial.print(cc_number,BYTE);
  Serial.print(127-printing_byte,BYTE);
   //Write it out to serial port
   Serial.println(rpm,DEC);
   
   //Restart the interrupt processing
   attachInterrupt(0, rpm_fun, FALLING);

  }

any help would be greatly appreciated

you might benefit (and, I should say, your code would also) from a peek at the map() function.

map(inLow,inHigh,outLow,outHigh);

[this is from memory, so no slings and arrows, please!!]

for instance: map(0,4095,1,127) will map input values of 0-4095 into output values of 1-127

also, you probably don't want to swamp the MIDI bus with THOUSANDS of CC messages per second, so you'll want to determine a way to scale that back a bit (perhaps only output an averaged value every so often, for example

hey

thanks for your reply - the map function is next on my list.
For now, I have managed to get the MIDI working pretty well - just need to tidy up the maths regarding the rpm readout as it jumps around a bit.
here is the code I have used:

/*
 * Optical Tachometer
 *
 * Uses an IR LED and IR phototransistor to implement an optical tachometer.
 * The IR LED is connected to pin 13 and ran continually. A status LED is connected
 * to pin 12. Pin 2 (interrupt 0) is connected across the IR detector.
 *
 * 
 */
//#define DEBUG      
 
int ledPin = 13;                // IR LED connected to digital pin 13
int statusPin = 12;
int lightPin = 11;// LED connected to digital pin 12
int brightness = 0;
int delay_time = 40; // delay for this amount each write cycle.
byte MIDI_channel = 0;
byte cc_number = 0;
byte printing_byte = 0;
int Value = 0;
int midi_pitch = 0;
#ifdef DEBUG
const int DEBUG_RATE = 9600;        // Serial debugging communicates at 9600 baud
const int SERIAL_PORT_RATE = DEBUG_RATE;
#else
const int MIDI_BAUD_RATE = 31250;   // MIDI communicates at 31250 baud
const int SERIAL_PORT_RATE = MIDI_BAUD_RATE;
#endif



volatile byte rpmcount;
volatile int status;

unsigned int rpm;

unsigned long timeold;

 void rpm_fun()
 {
   //Each rotation, this interrupt function is run twice, so take that into consideration for 
   //calculating RPM
   //Update count
      rpmcount++;
      
   //Toggle status LED   
   if (status == LOW) {
     status = HIGH;
   } else {
     status = LOW;
   }
   digitalWrite(statusPin, status);
 }

void setup()
 {
   Serial.begin(SERIAL_PORT_RATE);
   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
   //Triggers on FALLING (change from HIGH to LOW)
   attachInterrupt(0, rpm_fun, FALLING);
   
   //Turn on IR LED
   pinMode(ledPin, OUTPUT); 
   digitalWrite(ledPin, HIGH);
   
   //Use statusPin to flash along with interrupts
   pinMode(statusPin, OUTPUT);

   rpmcount = 0;
   rpm = 0;
   timeold = 0;
   status = LOW;

 }

 void loop()
 {
   //Update RPM every second
   delay(500);
   //Don't process interrupts during calculations
   detachInterrupt(0);
   //Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
   //happened once per revolution instead of twice. Other multiples could be used
   //for multi-bladed propellers or fans
   rpm = 3*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;
  brightness = (4 * rpm);
  analogWrite(lightPin, brightness);
 
   if(rpm > 127) {
    printing_byte = 127;
  
   }
  

else {
  
  printing_byte = rpm ;
  }
  #ifdef DEBUG
    Serial.println(rpm, DEC);
  #else
  Serial.print(B10110000 + MIDI_channel,BYTE);
  Serial.print(cc_number,BYTE);
  Serial.print(printing_byte,BYTE);
  #endif

  
     
   //Write it out to serial port
 
   
   //Restart the interrupt processing
   attachInterrupt(0, rpm_fun, FALLING);
   
 
  

  }

You are are measuring the time while you write the MIDI output and the pulse counting is inactive.
Maybe you should move the

   timeold = millis();

to just before you reenable the interrupts and restart the counting.