MIDI in, read noteByte - if comparisson worked but no math...

Hey there,
I have something strange is going on with my bytes when i read the second byte from MIDI inputs. When I set noteByte to a specific Number like

byte noteByte = 62;

the frequency is played but when i do this with hairless midi or a midi in over tx rx i can't multply the NoteByte. It just gave me the major C frequencies:

byte commandByte;
byte noteByte;
byte velocityByte;
long freq;

long tuning = 440.0; // Equal Tuning A4=a'=440.0Hz n = Midi Note Number
const PROGMEM byte noteOn = 144; // 1001 & 0000 = 8 bytes = 144
const PROGMEM byte noteOff = 128; // 1000 & 0000 = 8 bytes = 128

void checkMIDI(){
  do {
    if(Serial.available() > 2) {
      commandByte = Serial.read(); //read first byte
      noteByte = Serial.read(); //read next byte
      velocityByte = Serial.read(); //read final byte
      //if note on message (Key Pressed)
      if (commandByte == noteOn){
        if (velocityByte > 0 && noteByte > 0) {
          //Formula to connect MIDI-Note Number with Base Frequency (Tuning also possible) Midi Tuning standard
          // Equal Tuning t=A4=a'=440Hz n = Midi Note Number
          // f = t * 2 ^ ((n - 69) / 12)
          freq = tuning * pow(2,(noteByte - 69) / 12);
          tone(11,freq);    
        }
      }
      
      //if note off message
      if (commandByte == noteOff) {
        noTone(11);
      }
    }
  } while (Serial.available() >= 2); //when at least three bytes available
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  checkMIDI();
  delay(100);
}

But if If you do a check with if like this:

if (noteByte == 60) {
or like:
if (noteByte == 53) {

the noteByte gets read correctly in an if comparrison. But when you want to multiply it like:

freq = tuning * pow(2,(noteByte - 69) / 12);

It just doesn't get right. I have tried to change the variable type convert it and so on but every time couldn't multiply it to get the right frequency on the right noteByte when played...
To check against you could try to set the noteByte manually:

noteByte = 53; // 0-127

And in this case it works and play every tone pre entered but not when it read the Byte from Midi.
If there was a problem with the midi connection it wouldn't have worked when you compare it in an if clause...
Does someone know how or why this strange behaviour happens? :frowning:

Have found something... and I could fix it :slight_smile:

float an = pow(SEMITONE, (float)(noteByte - MIDI_NOTE_CONCERT_A));
float fn = PITCH_CONCERT_A * an;
setFrequency(wave1,fn);

So I just mixed up longs bytes and floats :sweat_smile: ... which is not desired

Your fault is using integer arithmetic for this:

          freq = tuning * pow(2,(noteByte - 69) / 12);

You need to use floating point, since integer division truncates.

          freq = tuning * pow(2,(noteByte - 69) / 12.0);

The floating point constant 12.0 will force the division to use floating point. The fact that
pow() takes floating point arguments doesn't have any influence I'm afraid, you have to
explicitly force the division itself to use floating point, otherwise the conversion from int
to float happens too late.