Sending MIDI notes from a Raspberry Pi to an Arduino Uno using Serial Ports in C

Hello, I'm working with a Raspberry Pi 2 (Raspbian) and an Arduino Uno.

I've made some researches about MIDI and I've found many things about MIDI Arduino -> PC, unlike MIDI PC -> Arduino.

I already have the code on the arduino. It puts on the led on the pin 13 when the note = 60.

*Receive MIDI and check if note = 60
By Amanda Ghassaei
July 2012
http://www.instructables.com/id/Send-and-Receive-MIDI-with-Arduino/

 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.

*/

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
  Serial.begin(31250);
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void checkMIDI(){
  do{
    if (Serial.available()){
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      if (commandByte == noteOn){//if note on message
        //check if note == 60 and velocity > 0
        if (noteByte == 60 && velocityByte > 0){
          digitalWrite(13,HIGH);//turn on led
        }
      }
    }
  }
  while (Serial.available() > 2);//when at least three bytes available
}
    

void loop(){
  checkMIDI();
  delay(100);
  digitalWrite(13,LOW);//turn led off
}

I've tested many things like https://ccrma.stanford.edu/~craig/articles/linuxmidi/output/method1.c, using or not the WiringSerial Library.

But each time, the led was lightened up 4 times because of the serial connection(weird :o , i didn't expect that) and then nothing.

I've tested several baudrates (the same on each side of course) but it still doesn't work.

Right now, I'm quite lost. :sob:

A do/while statement is probably the dumbest thing ever invented. It executes the body of the statement, and then checks to see if it should have. Useless for your purposes.

Inside the body. you check for there being at least one byte to read. If there is, you proceed to read three bytes, two of which haven't arrived yet. Oops.

As you can see this code is not mine, it's just an example to test the midi transmission. It works with Garage Band which sends midi notes to the arduino for example.

But you suggest to replace the do if while with a simple if (Serial.available() > 2)? I'll check it later. Thanks

Hello, I’ve made my own USB->MIDI->TX cable with this tutorial. With that, the RPI recognizes a MIDI device.

I’ve modified the Arduino code as you suggested.

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  digitalWrite(13,LOW);
}

void checkMIDI(){
    if (Serial.available()>2){
      commandByte = Serial.read();//read first byte
      noteByte = Serial.read();//read next byte
      velocityByte = Serial.read();//read final byte
      if (commandByte == noteOn){//if note on message
        //check if note == 60 and velocity > 0
        if (noteByte == 60 && velocityByte > 0){
          digitalWrite(13,HIGH);//turn on led
        }
      }
    }
}
    

void loop(){
  checkMIDI();
  delay(100);
  digitalWrite(13,LOW);//turn led off
}

And, here is my C code on the RPI 2. The LED is turned on, turn off and then turned on.

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<linux/soundcard.h>
#include <wiringSerial.h>

int main(){

   // usb to midi cable
   char* device = "/dev/midi";

   //note 60 on
   char data[3] = {0x90, 60, 127};
   //note 60 off
   char data2[3] = {0x80, 60, 0};

   //open a serial connection
   int fd = serialOpen(device,9600);

   if(fd<0){
      printf("Connection error\n");          
      return 1;
   }
   
   //send the note on signal
   fflush(stdout);
   serialPutchar(fd,data[0]);
   serialPutchar(fd,data[1]);
   serialPutchar(fd,data[2]);
  
  //send the note off signal
   serialPutchar(fd,data2[0]);
   serialPutchar(fd,data2[1]);
   serialPutchar(fd,data2[2]);
   
   //send the note on signal
   serialPutchar(fd,data[0]);
   serialPutchar(fd,data[1]);
   serialPutchar(fd,data[2]);   


   serialClose(fd);
   return 0;
}

The led lights up 2 times :slight_smile:

Now, I’d like to know if it is possible with an I2C connection between the Arduino Uno and the RPI2 to do the same thing.
With an I2C connection, there is no more USB->MIDI cable.