Using serial from Pi to Arduino to Midi Library

A bit obscure but I've reached a wall.
I am trying to send data from a Raspberry pi across a serial connection to an Arduino uno. For the simple test I am sending a random integer on the pi to play a midi note on the Arduino. I set up a simple random python script to test. I managed to encode and send bytes across the serial with this helpful tutorial with newline breaks successfully at 9600 baud. Serial.read and Arduino: Here's the advanced stuff you should know
All this looks fine in the serial monitor. Each number displays on a new line clearly.

Now the issue is some kind of conflict with the Midi library. (#include <MIDI.h)MIDI Library - Arduino Reference

It seems to change the baud rate to 31250 automatically although you can’t see it.
I am able to convert the data over the serial to an integer (thisPitch) to put in MIDI.sendNoteOn(thisPitch,127,1);
but the midi library seems to corrupt the data coming across the serial.

I’ve tried to update the python script and the Arduino to 31250 baud but still no luck. It all seems simple in theory, but maybe I can’t use the midi library with other serial communications. Are there other ones people have tried this?

Does anyone know of any way to monitor output at 31250 baud on an Arduino uno
The serial monitor doesn’t have that preset.

I monitor the breadboard 8 pin midi output to USB using Ableton live. Other note outputs from the midi library work fine.

Here is the python code on the Pi which simply sends a random number across the serial connection.

import random
import threading
import time

import serial


def infiniteloop1():
    while True:
        pnote = (random.randint(0,255))
        print(pnote)
        ser = serial.Serial('/dev/ttyACM0',9600, timeout=1)
        ser.flush()
        ser.write(b"pnote\n")
        print('pnote sent')
        time.sleep(5)
                

thread1 = threading.Thread(target=infiniteloop1)
thread1.start()

Here is the Code on the Arduino that takes the random number via serial and converts it to midi using the library and turns on a light when looping:

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
#define blueLed 10

void setup() {
  // put your setup code here, to run once:
  //Serial.begin(9600);
  MIDI.begin();
  pinMode(blueLed, OUTPUT);
}

void loop() {
  // read serial
  int sensorReading = analogRead(A0);
  Serial.println(sensorReading);
  int thisPitch = map(sensorReading, 400,1000,120,1500);
  tone(9, thisPitch, 10);
  digitalWrite(blueLed, HIGH);
  // send midi
  MIDI.sendNoteOn(thisPitch,127,1); //turn midi note on variable, velocity 127, midi channel 1.
  delay(1000);
  MIDI.sendNoteOff(thisPitch,127,1); //turn midi note off variable, velocity 127, midi channel 1.
  digitalWrite(blueLed, LOW);
  delay(100 );
  //delay(1);
}

Welcome to the forum

I am not familiar with the MIDI library. Which pins does it use for its serial communication ?

The Arduino reads analogRead(A0) for serial.
In my Ardunio circuit the midi data sends out on the TX to the 8 pin connector.

As I said, I am not familiar with the library but that sounds very odd

If you can read the data then you are probably sending ASCII text rather than a MIDI message. The MIDI message is not in text form, just a sequence of bytes.

Just try and receive the data at the Arduino and print it out to the serial monitor to see what you are getting at that end of the link. You will need to write a simple sketch to echo the characters from the receiving MIDI serial port to the standard Tx/Rx pair for Serial.

The MIDI library uses the UNO usb port to communicate with with the PC and should generally be 31250 baud rate. Because the hardware port is being used by the MIDI connection you can't use the serial monitor.

The GitHub documentation gives an example of PC input which use switch/case to identify the Status Byte and if there is a match it blinks the on board LED to the count of the Data1 value.

I modified the GitHub example to look for note on in the switch case and included a Python example. It is working on my PC so hopefully it will work for you.

Arduino

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  MIDI.begin(MIDI_CHANNEL_OMNI);
}

void blinks(int val) {
  for(int i=0;i<val;i++)
  {
   digitalWrite(LED_BUILTIN,HIGH);
        delay(300);
        digitalWrite(LED_BUILTIN,LOW);
        delay(300); 
  }
        
}

void loop()
{
    if (MIDI.read())     
              
    {
     
        switch(MIDI.getType())     
        {
            case midi::NoteOn:  
                blinks(MIDI.getData1());           
                break;
            
            default:
            break;
        }
    }
}

Python

import time
import serial

ser = serial.Serial('/dev/ttyACM0',31250)


while True:
		cmd=0x90
		pitch=0x06
		velocity=0x01

		mylist=[cmd,pitch,velocity]
		
		ser.write(mylist)

		while ser.in_waiting >0:
				try:
					val=ser.read()
					int_val = int.from_bytes(val, "big")
					print(hex(int_val))
				except:
					pass

		time.sleep(10)

BTW MIDI appears to echo its commands and errors back to the PC so I included a read in the Python code

Thanks for the input. I'll try this out with the switch/case.
The serial code works and the midi library works but when you put them together it seems to not mix. LOL.

Yes I got the serial to work with line breaks that you can see in the monitor. This tutorial is really good to learn about serial communications. Serial.read and Arduino: Here's the advanced stuff you should know
Prob is when you implement the midi library. It corrupts the data.

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