Arduino Frequency to MIDI

Hi, I'm struggling with getting my code to work, I'm using the circuit from the arduino frequency detection instructable and I have managed to get it to pick up frequencies fine but what I was hoping to do was get the arduino to detect the frequency and then send a MIDI message so the note would play.

Any help would be greatly appreciated as I'm a bit stumped.

Here is the code I'm using:





//clipping indicator variables
boolean clipping = 0;

//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//keeps time and sends vales to store in timer[] occasionally
int timer[10];//sstorage for timing of events
int slope[10];//storage fro slope of events
unsigned int totalTimer;//used to calculate period
unsigned int period;//storage for period of wave
byte index = 0;//current storage index
float frequency;//storage for frequency calculations
int maxSlope = 0;//used to calculate max slope as trigger point
int newSlope;//storage for incoming slope data

//variables for decided whether you have a match
byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long
byte slopeTol = 3;//slope tolerance- adjust this if you need
int timerTol = 10;//timer tolerance- adjust this if you need

//for MIDI instructions
int noteON = 144;//144 = 10010000 in binary, note on command
int noteOFF = 128;//128 = 10000000 in binary, note off command

int velocity = 100;




void setup(){
  
  Serial.begin(9600);
  
  pinMode(13,OUTPUT);//led indicator pin
  pinMode(12,OUTPUT);//output pin
  
  cli();//diable interrupts
  
  //set up continuous sampling of analog pin 0 at 38.5kHz
 
  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;
  
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
  
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE); //enabble auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements
  
  sei();//enable interrupts
}

ISR(ADC_vect) {//when new ADC value ready
  
  PORTB &= B11101111;//set pin 12 low
  prevData = newData;//store previous value
  newData = ADCH;//get value from A0
  if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
    newSlope = newData - prevData;//calculate slope
    if (abs(newSlope-maxSlope)<slopeTol){//if slopes are ==
      //record new data and reset time
      slope[index] = newSlope;
      timer[index] = time;
      time = 0;
      if (index == 0){//new max slope just reset
        PORTB |= B00010000;//set pin 12 high
        noMatch = 0;
        index++;//increment index
      }
      else if (abs(timer[0]-timer[index])<timerTol && abs(slope[0]-newSlope)<slopeTol){//if timer duration and slopes match
        //sum timer values
        totalTimer = 0;
        for (byte i=0;i<index;i++){
          totalTimer+=timer[i];
        }
        period = totalTimer;//set period
        //reset new zero index values to compare with
        timer[0] = timer[index];
        slope[0] = slope[index];
        index = 1;//set index to 1
        PORTB |= B00010000;//set pin 12 high
        noMatch = 0;
      }
      else{//crossing midpoint but not match
        index++;//increment index
        if (index > 9){
          reset();
        }
      }
    }
    else if (newSlope>maxSlope){//if new slope is much larger than max slope
      maxSlope = newSlope;
      time = 0;//reset clock
      noMatch = 0;
      index = 0;//reset index
    }
    else{//slope not steep enough
      noMatch++;//increment no match counter
      if (noMatch>9){
        reset();
      }
    }
  }
    
  if (newData == 0 || newData == 1023){//if clipping
    PORTB |= B00100000;//set pin 13 high- turn on clipping indicator led
    clipping = 1;//currently clipping
  }
  
  time++;//increment timer at rate of 38.5kHz
}

void reset(){//clea out some variables
  index = 0;//reset index
  noMatch = 0;//reset match couner
  maxSlope = 0;//reset slope
}


void checkClipping(){//manage clipping indicator LED
  if (clipping){//if currently clipping
    PORTB &= B11011111;//turn off clipping indicator led
    clipping = 0;
  }
}





void loop(){
  
  checkClipping();
  
  frequency = 38462/float(period);//calculate frequency timer rate/period
  
  //print results
  Serial.print(frequency);
  Serial.println(" hz");
  

  //MIDI notes

  int Enote = 40;
  int Fnote = 41;
  int Fsnote = 42;
  int Gnote= 43;

  
    if (frequency>79&frequency<84.5) {
      MIDImessage(noteON, Enote, velocity);
     
    }
    else {
      MIDImessage(noteOFF, Enote, velocity);
      
    }
    

  

  
    if (frequency>84.6&frequency<89.5) {
      MIDImessage(noteON, Fnote, velocity);
    }
    else {
      MIDImessage(noteOFF, Fnote, velocity);
    }
    

  

 
    if (frequency>89.6&frequency<95) {
      MIDImessage(noteON, Fsnote, velocity);
    }
    else {
      MIDImessage(noteOFF, Fsnote, velocity);
    }
    

  

  
    if (frequency>95.1&frequency<101) {
      MIDImessage(noteON, Gnote, velocity);
     
    }
    else {
      MIDImessage(noteOFF, Gnote, velocity);
      
    }


  }
  
     //send MIDI message
void MIDImessage(int command, int MIDInote, int MIDIvelocity) {
  Serial.write(command);//send note on or note off command 
  Serial.write(MIDInote);//send pitch data
  Serial.write(MIDIvelocity);//send velocity data
}



If you are connecting your serial output to a MIDI instrument you should be using the MIDI baud rate: 31250

Ive got the baud rate set to 9600 because I'm using the arduino through hairless MIDI and loop MIDI when connecting it to the music DAW

Doesn't "hairless MIDI" get confused when you send this non-MIDI data?

I'm not too sure, I've only got the serial print code in to test in the arduino IDE if the frequency its detecting is correct. I will try test it without the serial print code soon, hopefully it will solve the issue thanks!

Ive tried removing the serial monitor code and tested it but it didnt change anything unfortunately

Try this sketch with just the "MIDImessage()" function and some calls to play several notes. Make sure that the Hairless MIDI setup is working correctly.

//for MIDI instructions
const int noteON = 144;   //144 = 10010000 in binary, note on command
const int noteOFF = 128;  //128 = 10000000 in binary, note off command

//MIDI notes

const int Enote = 40;
const int Fnote = 41;
const int Fsnote = 42;
const int Gnote = 43;

const int velocity = 100;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  MIDImessage(noteON, Enote, velocity);
  delay(500);
  MIDImessage(noteOFF, Enote, velocity);

  delay(500);

  MIDImessage(noteON, Fnote, velocity);
  delay(500);
  MIDImessage(noteOFF, Fnote, velocity);

  delay(500);

  MIDImessage(noteON, Fsnote, velocity);
  delay(500);
  MIDImessage(noteOFF, Fsnote, velocity);

  delay(500);

  MIDImessage(noteON, Gnote, velocity);
  delay(500);
  MIDImessage(noteOFF, Gnote, velocity);
  
  delay(500);
}

//send MIDI message
void MIDImessage(int command, int MIDInote, int MIDIvelocity)
{
  Serial.write(command);       //send note on or note off command
  Serial.write(MIDInote);      //send pitch data
  Serial.write(MIDIvelocity);  //send velocity data
}

Hi, thanks for your help again, I tried the code you gave me and it works through the hairless MIDI. I tried it in the music DAW and it was playing the right notes so there must be something wrong in my original code. Ive ordered an arduino leonardo so i can just use the MIDI usb library and connect it without the need for the hairless MIDI but i think if it isnt working in the hairless midi program then it won't work without it but i thought it might be worth a try

You now know that the MIDI part isn't the problem. Try changing MIDImessage() to do serial output instead so you can see if the rest of your code works to call MIDImessage():

void MIDImessage(int command, int MIDInote, int MIDIvelocity)
{
  Serial.print(command);       //send note on or note off command
  Serial.print(", ");
  Serial.print(MIDInote);      //send pitch data
  Serial.print(", ");
  Serial.println(MIDIvelocity);  //send velocity data
}

You can also put back in the:

  Serial.print(frequency);
  Serial.println(" hz");

To make sure the frequencies are being detected correctly.

When i add that code it seems to just loop through the notes and the frequency doesnt affect which note it does, i dont know if that explains it well but ive shown the serial monitor in the attached image
image

Please don't use images of text. Copy the text from Serial Monitor and paste it into your reply as if it were code.

The four "noteOFF" (128) messages mean that none of the four 'if' statements are matching and the 'else' is selected each time.

if (frequency > 79   & frequency < 84.5)
if (frequency > 84.6 & frequency < 89.5) 
if (frequency > 89.6 & frequency < 95) 
if (frequency > 95.1 & frequency < 101)

You're only looking for frequencies between 79 and 101 Hz. That doesn't match 117.98 or 6410.33 Hz. That's why you got no 'noteON' messages.

Rather than one 'if' per note you could use an array of frequencies for all MIDI notes from 0 to 127 and scan through the list looking for the closest match to the frequency.

const float MIDI_FREQUENCY[]
{
//	C			C-sharp		D			D-sharp		E			F			F-sharp		G			G-sharp		A			A-sharp		B			
    8.18,		8.66,		9.18,		9.73,		10.30,		10.92,		11.56,		12.25,		12.98,		13.75,		14.57,		15.44,		// Octave -1
    16.35,		17.32,		18.35,		19.45,		20.60,		21.83,		23.12,		24.50,		25.96,		27.50,		29.14,		30.87,		// Octave 0
    32.70,		34.65,		36.71,		38.89,		41.20,		43.65,		46.25,		49.00,		51.91,		55.00,		58.27,		61.74,		// Octave 1
    65.41,		69.30,		73.42,		77.78,		82.41,		87.31,		92.50,		98.00,		103.83,		110.00,		116.54,		123.47,		// Octave 2
    130.81,	 	138.59,		146.83,		155.56,		164.81,		174.61,		185.00,		196.00,		207.65,		220.00,		233.08,		246.94,		// Octave 3
    261.63,		277.18,		293.66,		311.13,		329.63,		349.23,		369.99,		392.00,		415.30,		440.00,		466.16,		493.88,		// Octave 4
    523.25,		554.37,		587.33,		622.25,		659.25,		698.46,		739.99,		783.99,		830.61,		880.00,		932.33,		987.77,		// Octave 5
    1046.50,	1108.73,	1174.66,	1244.51,	1318.51,	1396.91,	1479.98,	1567.98,	1661.22,	1760.00,	1864.66,	1975.53,	// Octave 6
    2093.00,	2217.46,	2349.32,	2489.02,	2637.02,	2793.83,	2959.96,	3135.96,	3322.44,	3520.00,	3729.31,	3951.07,	// Octave 7
    4186.01,	4434.92,	4698.63,	4978.03,	5274.04,	5587.65,	5919.91,	6271.93,	6644.88,	7040.00,	7458.62,	7902.13,	// Octave 8
    8372.02,	8869.84,	9397.26,	9956.06,	10548.08,	11175.30,	11839.82,	12543.86	// Octave 9 (partial)
    };

const uint8_t MIDI_NOTE_C0	= 12;
const uint8_t MIDI_NOTE_C9	= 120;
static byte LastNote = 0;

  for (byte note = MIDI_NOTE_C0; note < MIDI_NOTE_C9; note++)
  {
    if (frequency < (MIDI_FREQUENCY[note] + MIDI_FREQUENCY[note+1]) / 2)
    {
      // Matching note!
      if (note != LastNote)
      {
        // The note has changed so turn off the previous note
        MIDImessage(noteOFF, LastNote, velocity);
      }
      MIDImessage(noteON, note, velocity);
      LastNote = note;
      break;  // No need to look for more matches.
    }
  }

I added the code you sent and it seems to be picking up the correct notes to frequency but it still isnt being picked up through hairless MIDI

heres what i got from the serial monitor

00

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

122.88 hz

144, 47, 100

81.14 hz

128, 47, 100

144, 40, 100

81.14 hz

144, 40, 100

81.14 hz

144, 40, 100

81.14 hz

144, 40, 100

81.14 hz

144, 40, 100

189.47 hz

128, 40, 100

144, 54, 100

961.55 hz

128, 54, 100

144, 83, 100

81.83 hz

128, 83, 100

144, 40, 100

83.07 hz

144, 40, 100

82.18 hz

144, 40, 100

48.14 hz

128, 40, 100

144, 31, 100

302.85 hz

128, 31, 100

144, 63, 100

80.30 hz

128, 63, 100

144, 40, 100

7692.40 hz

128, 40, 100

144, 119, 100

1748.27 hz

128, 119, 100

144, 93, 100

1479.31 hz

128, 93, 100

144, 90, 100

97.37 hz

128, 90, 100

144, 43, 100

82.71 hz

128, 43, 100

144, 40, 100

78.33 hz

128, 40, 100

144, 39, 100

836.13 hz

128, 39, 100

144, 80, 100

452.49 hz

128, 80, 100

144, 69, 100

452.49 hz

144, 69, 100

2403.87 hz

128, 69, 100

144, 98, 100

2136.78 hz

128, 98, 100

144, 96, 100

1131.24 hz

128, 96, 100

144, 85, 100

725.70 hz

128, 85, 100

144, 78, 100

115.85 hz

128, 78, 100

144, 46, 100

874.14 hz

128, 46, 100

144, 81, 100

82.18 hz

128, 81, 100

144, 40, 100

82.01 hz

144, 40, 100

81.66 hz

144, 40, 100

81.83 hz

144, 40, 100

81.32 hz

144, 40, 100

82.01 hz

144, 40, 100

82.18 hz

144, 40, 100

81.14 hz

144, 40, 100

81.83 hz

144, 40, 100

40.92 hz

128, 40, 100

144, 28, 100

128.21 hz

128, 28, 100

144, 48, 100

107.74 hz

128, 48, 100

1326.28 hz

128, 45, 100

144, 88, 100

82.01 hz

128, 88, 100

144, 40, 100

81.83 hz

144, 40, 100

97.87 hz

128, 40, 100

144, 43, 100

1831.52 hz

128, 43, 100

144, 94, 100

4273.56 hz

128, 94, 100

144, 108, 100

1672.26 hz

128, 108, 100

144, 92, 100

413.57 hz

128, 92, 100

144, 68, 100

1424.52 hz

128, 68, 100

144, 89, 100

310.18 hz

128, 89, 100

144, 63, 100

818.34 hz

128, 63, 100

144, 80, 100

82.01 hz

128, 80, 100

144, 40, 100

82.89 hz

144, 40, 100

557.42 hz

128, 40, 100

144, 73, 100

80.97 hz

128, 73, 100

144, 40, 100

99.39 hz

128, 40, 100

144, 43, 100


If it's showing up as text in Serial Monitor it certainly isn't being sent as binary to hairless MIDI. You have to put MIDImessage() back the way it was. You should probably, again, take out the lines that print the frequency.

Here is a version with DEBUG_MODE defined at the top. Set it to 0 for hairless MIDI or set it to 1 for text output.

#define DEBUG_MODE 0  // 1 = text output to Serial Monitor, 0 = binary to Hairless MIDI

//clipping indicator variables
boolean clipping = 0;

//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;    //keeps time and sends vales to store in timer[] occasionally
int timer[10];            //sstorage for timing of events
int slope[10];            //storage fro slope of events
unsigned int totalTimer;  //used to calculate period
unsigned int period;      //storage for period of wave
byte index = 0;           //current storage index
float frequency;          //storage for frequency calculations
int maxSlope = 0;         //used to calculate max slope as trigger point
int newSlope;             //storage for incoming slope data

//variables for decided whether you have a match
byte noMatch = 0;   //counts how many non-matches you've received to reset variables if it's been too long
byte slopeTol = 3;  //slope tolerance- adjust this if you need
int timerTol = 10;  //timer tolerance- adjust this if you need

//for MIDI instructions
constexpr int noteON = 144;   //144 = 10010000 in binary, note on command
constexpr int noteOFF = 128;  //128 = 10000000 in binary, note off command

int velocity = 100;

const float MIDI_FREQUENCY[]{
  //	C			C-sharp		D			D-sharp		E			F			F-sharp		G			G-sharp		A			A-sharp		B
  8.18, 8.66, 9.18, 9.73, 10.30, 10.92, 11.56, 12.25, 12.98, 13.75, 14.57, 15.44,                              // Octave -1
  16.35, 17.32, 18.35, 19.45, 20.60, 21.83, 23.12, 24.50, 25.96, 27.50, 29.14, 30.87,                          // Octave 0
  32.70, 34.65, 36.71, 38.89, 41.20, 43.65, 46.25, 49.00, 51.91, 55.00, 58.27, 61.74,                          // Octave 1
  65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.83, 110.00, 116.54, 123.47,                      // Octave 2
  130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.00, 196.00, 207.65, 220.00, 233.08, 246.94,              // Octave 3
  261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392.00, 415.30, 440.00, 466.16, 493.88,              // Octave 4
  523.25, 554.37, 587.33, 622.25, 659.25, 698.46, 739.99, 783.99, 830.61, 880.00, 932.33, 987.77,              // Octave 5
  1046.50, 1108.73, 1174.66, 1244.51, 1318.51, 1396.91, 1479.98, 1567.98, 1661.22, 1760.00, 1864.66, 1975.53,  // Octave 6
  2093.00, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520.00, 3729.31, 3951.07,  // Octave 7
  4186.01, 4434.92, 4698.63, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040.00, 7458.62, 7902.13,  // Octave 8
  8372.02, 8869.84, 9397.26, 9956.06, 10548.08, 11175.30, 11839.82, 12543.86                                   // Octave 9 (partial)
};

const uint8_t MIDI_NOTE_C0 = 12;
const uint8_t MIDI_NOTE_C9 = 120;
static byte LastNote = 0;




void setup()
{
  Serial.begin(9600);

  pinMode(13, OUTPUT);  //led indicator pin
  pinMode(12, OUTPUT);  //output pin

  cli();  //diable interrupts

  //set up continuous sampling of analog pin 0 at 38.5kHz

  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;

  ADMUX |= (1 << REFS0);  //set reference voltage
  ADMUX |= (1 << ADLAR);  //left align the ADC value- so we can read highest 8 bits from ADCH register only

  ADCSRA |= (1 << ADPS2) | (1 << ADPS0);  //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE);                 //enabble auto trigger
  ADCSRA |= (1 << ADIE);                  //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN);                  //enable ADC
  ADCSRA |= (1 << ADSC);                  //start ADC measurements

  sei();  //enable interrupts
}

ISR(ADC_vect)
{  //when new ADC value ready

  PORTB &= B11101111;  //set pin 12 low
  prevData = newData;  //store previous value
  newData = ADCH;      //get value from A0
  if (prevData < 127 && newData >= 127)
  {                                 //if increasing and crossing midpoint
    newSlope = newData - prevData;  //calculate slope
    if (abs(newSlope - maxSlope) < slopeTol)
    {  //if slopes are ==
      //record new data and reset time
      slope[index] = newSlope;
      timer[index] = time;
      time = 0;
      if (index == 0)
      {                      //new max slope just reset
        PORTB |= B00010000;  //set pin 12 high
        noMatch = 0;
        index++;  //increment index
      }
      else if (abs(timer[0] - timer[index]) < timerTol && abs(slope[0] - newSlope) < slopeTol)
      {  //if timer duration and slopes match
        //sum timer values
        totalTimer = 0;
        for (byte i = 0; i < index; i++)
        {
          totalTimer += timer[i];
        }
        period = totalTimer;  //set period
        //reset new zero index values to compare with
        timer[0] = timer[index];
        slope[0] = slope[index];
        index = 1;           //set index to 1
        PORTB |= B00010000;  //set pin 12 high
        noMatch = 0;
      }
      else
      {           //crossing midpoint but not match
        index++;  //increment index
        if (index > 9)
        {
          reset();
        }
      }
    }
    else if (newSlope > maxSlope)
    {  //if new slope is much larger than max slope
      maxSlope = newSlope;
      time = 0;  //reset clock
      noMatch = 0;
      index = 0;  //reset index
    }
    else
    {             //slope not steep enough
      noMatch++;  //increment no match counter
      if (noMatch > 9)
      {
        reset();
      }
    }
  }

  if (newData == 0x00 || newData == 0xFF)
  {                      //if clipping
    PORTB |= B00100000;  //set pin 13 high- turn on clipping indicator led
    clipping = 1;        //currently clipping
  }

  time++;  //increment timer at rate of 38.5kHz
}

void reset()
{                //clea out some variables
  index = 0;     //reset index
  noMatch = 0;   //reset match couner
  maxSlope = 0;  //reset slope
}

void checkClipping()
{  //manage clipping indicator LED
  if (clipping)
  {                      //if currently clipping
    PORTB &= B11011111;  //turn off clipping indicator led
    clipping = 0;
  }
}

void loop()
{
  checkClipping();

  frequency = 38462 / float(period);  //calculate frequency timer rate/period

#if DEBUG_MODE
  //print results
  Serial.print(frequency);
  Serial.println(" hz");
#endif


  //MIDI notes

  for (byte note = MIDI_NOTE_C0; note < MIDI_NOTE_C9; note++)
  {
    if (frequency < (MIDI_FREQUENCY[note] + MIDI_FREQUENCY[note + 1]) / 2)
    {
      // Matching note!
      if (note != LastNote)
      {
        // The note has changed so turn off the previous note
        MIDImessage(noteOFF, LastNote, velocity);
        MIDImessage(noteON, note, velocity);
      }

      LastNote = note;
      break;  // No need to look for more matches.
    }
  }
}

//send MIDI message
void MIDImessage(byte command, byte MIDInote, byte MIDIvelocity)
{
#if DEBUG_MODE
  // Display each MIDI message as text for debugging
  switch (command)
  {
    case noteON: Serial.print("noteON"); break;
    case noteOFF: Serial.print("noteOFF"); break;
    default:
      Serial.print(command);  // show note on or note off command
      break;
  }
  Serial.print(", ");
  Serial.print(MIDInote);  // show pitch data
  Serial.print(", ");
  Serial.println(MIDIvelocity);  // send velocity data
#else
  // Send each MIDI message to Hairless MIDI as three binary bytes
  Serial.write(command);       //send note on or note off command
  Serial.write(MIDInote);      //send pitch data
  Serial.write(MIDIvelocity);  //send velocity data
#endif
}

Unfortunately still getting nothing from the hairless MIDI.

Also im getting this error message when i set debug mode to 1

Using board 'uno' from platform in folder: C:\Users\belar\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6
Using core 'arduino' from platform in folder: C:\Users\belar\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6
Detecting libraries used...
"C:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IC:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "C:\\Users\\belar\\AppData\\Local\\Temp\\arduino\\sketches\\E4809B33DAE00DE3AF0412340864651A\\sketch\\sketch_mar7a.ino.cpp" -o nul
Generating function prototypes...
"C:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IC:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "C:\\Users\\belar\\AppData\\Local\\Temp\\arduino\\sketches\\E4809B33DAE00DE3AF0412340864651A\\sketch\\sketch_mar7a.ino.cpp" -o "C:\\Users\\belar\\AppData\\Local\\Temp\\arduino\\sketches\\E4809B33DAE00DE3AF0412340864651A\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"C:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\builtin\\tools\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\belar\\AppData\\Local\\Temp\\arduino\\sketches\\E4809B33DAE00DE3AF0412340864651A\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IC:\\Users\\belar\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "C:\\Users\\belar\\AppData\\Local\\Temp\\arduino\\sketches\\E4809B33DAE00DE3AF0412340864651A\\sketch\\sketch_mar7a.ino.cpp" -o "C:\\Users\\belar\\AppData\\Local\\Temp\\arduino\\sketches\\E4809B33DAE00DE3AF0412340864651A\\sketch\\sketch_mar7a.ino.cpp.o"
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino: In function 'void MIDImessage(byte, byte, byte)':
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:207:10: error: the value of 'noteON' is not usable in a constant expression
     case noteON: Serial.print("noteON"); break;
          ^~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:25:5: note: 'int noteON' is not const
 int noteON = 144;   //144 = 10010000 in binary, note on command
     ^~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:207:10: error: the value of 'noteON' is not usable in a constant expression
     case noteON: Serial.print("noteON"); break;
          ^~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:25:5: note: 'int noteON' is not const
 int noteON = 144;   //144 = 10010000 in binary, note on command
     ^~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:208:10: error: the value of 'noteOFF' is not usable in a constant expression
     case noteOFF: Serial.print("noteOFF"); break;
          ^~~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:26:5: note: 'int noteOFF' is not const
 int noteOFF = 128;  //128 = 10000000 in binary, note off command
     ^~~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:208:10: error: the value of 'noteOFF' is not usable in a constant expression
     case noteOFF: Serial.print("noteOFF"); break;
          ^~~~~~~
C:\Users\belar\AppData\Local\Temp\.arduinoIDE-unsaved202327-13800-1o3xnr3.xew8\sketch_mar7a\sketch_mar7a.ino:26:5: note: 'int noteOFF' is not const
 int noteOFF = 128;  //128 = 10000000 in binary, note off command
     ^~~~~~~

exit status 1

Compilation error: the value of 'noteON' is not usable in a constant expression

Sorry. Change those to constants:

//for MIDI instructions
constexpr int noteON = 144;   //144 = 10010000 in binary, note on command
constexpr int noteOFF = 128;  //128 = 10000000 in binary, note off command

(Corrected in Reply 13)

Thank you the debug mode is working now, it shows in the serial monitor that its still picking out the right MIDI notes from the frequencies but still nothing from the hairless MIDI.
Here is what the serial monitor is showing:

17.27 hz
17.27 hz
82.54 hz
noteOFF, 13, 100
noteON, 40, 100
80.63 hz
82.01 hz
82.54 hz
82.54 hz
82.18 hz
167.96 hz
noteOFF, 40, 100
noteON, 52, 100
81.32 hz
noteOFF, 52, 100
noteON, 40, 100
81.32 hz
82.01 hz
81.49 hz
81.49 hz
81.49 hz
81.49 hz
81.49 hz
81.49 hz
81.49 hz
80.97 hz
80.97 hz
80.97 hz
80.97 hz
80.97 hz
20.50 hz
noteOFF, 40, 100
noteON, 16, 100

Is hairless MIDI connected to the right serial port?

Yeah, i double checked it was connected to the arduino and tried changing it around in case it was just being glitchy but still got nothing unfortunately

Ive managed to get it working now, I think the problem was with the arduino IDE using the COM port as well so once i uploaded the code I restarted my computer and it started to be picked up in the hairless MIDI and the music DAW.

Thank you so much for your help and patience, so glad its finally working!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.