Sparkfun's musical instruament shield program for Arduino to work with ESP32

This minimal program works with an Arduino Uno:

/*
 
 This code works with the VS1053 Breakout Board and controls the VS1053 in what is called Real Time MIDI mode. 
 
 https://www.sparkfun.com/products/10587

 5V : VS1053 VCC
 GND : VS1053 GND
 D3 (SoftSerial TX) : VS1053 RX
 D4 : VS1053 RESET
 
 Attach a headphone breakout board to the VS1053:
 VS1053 LEFT : TSH
 VS1053 RIGHT : RSH
 VS1053 GBUF : GND
 
 When in the drum bank (0x78), there are not different instruments, only different notes.
 To play the different sounds, select an instrument # like 5, then play notes 27 to 87.
 
 To play "Sticks" (31):
 talkMIDI(0xB0, 0, 0x78); //Bank select: drums
 talkMIDI(0xC0, 5, 0); //Set instrument number
 //Play note on channel 1 (0x90), some note value (note), middle velocity (60):
 noteOn(0, 31, 60);
 
 */
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

byte note = 0; //The MIDI note value to be played
byte resetMIDI = 4; //Tied to VS1053 Reset line
byte ledPin = 13; //MIDI traffic inidicator
int  instrument = 0;


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

  //Setup soft serial for MIDI control
  mySerial.begin(31250);

  //Reset the VS1053
  pinMode(resetMIDI, OUTPUT);
  digitalWrite(resetMIDI, LOW);
  delay(100);
  digitalWrite(resetMIDI, HIGH);
  delay(100);
  talkMIDI(0xB0, 0x07, 120); //0xB0 is channel message, set channel volume to near max (127)
}

void loop() 
{

  talkMIDI(0xB0, 0, 0x00); //Default bank GM1
  talkMIDI(0xC0, 98, 0);   //Set instrument number. 0xC0 is a 1 data byte command
  
      //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
      noteOn(0, 98, 60);
      delay(50);

      //Turn off the note with a given off/release velocity
      noteOff(0, 98, 15000);

  delay(2000);

}



//Send a MIDI note-on message.  Like pressing a piano key
//channel ranges from 0-15
void noteOn(byte channel, byte note, byte attack_velocity) {
  talkMIDI( (0x90 | channel), note, attack_velocity);
}

//Send a MIDI note-off message.  Like releasing a piano key
void noteOff(byte channel, byte note, byte release_velocity) {
  talkMIDI( (0x80 | channel), note, release_velocity);
}

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
  digitalWrite(ledPin, HIGH);
  mySerial.write(cmd);
  mySerial.write(data1);

  //Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes 
  //(sort of: http://253.ccarh.org/handout/midiprotocol/)
  if( (cmd & 0xF0) <= 0xB0)
    mySerial.write(data2);

  digitalWrite(ledPin, LOW);
}

However, I try to change the pins to an ESP32, and just get a fuzzy sound:

/*
 
 ESP32 code

  https://www.mouser.com/ProductDetail/Espressif-Systems/ESP32-DevKitC-32D
 
 Pinout

  ESP   SparkFun Shield
  GND   GND
  16    2
  17    3
  4     4
  RX    RX
  TX    TX

  5V    +5V
  3V3   3.3V
 
 */
#define RXD2 16 // was 2 
#define TXD2 17 // was 3


byte note = 0; //The MIDI note value to be played
byte resetMIDI = 4; //Reset line
int  instrument = 0;


void setup()
{
  Serial.begin(57600);
  
  //Setup soft serial for MIDI control
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);

  //Reset
  pinMode(resetMIDI, OUTPUT);
  digitalWrite(resetMIDI, LOW);
  delay(100);
  digitalWrite(resetMIDI, HIGH);
  delay(100);
  talkMIDI(0xB0, 0x07, 120); //0xB0 is channel message, set channel volume to near max (127)
}

void loop() 
{

  talkMIDI(0xB0, 0, 0x00); //Default bank GM1
  talkMIDI(0xC0, 98, 0);   //Set instrument number. 0xC0 is a 1 data byte command
  
      //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
      noteOn(0, 98, 60);
      delay(50);

      //Turn off the note with a given off/release velocity
      noteOff(0, 98, 15000);

  delay(3000);

}



//Send a MIDI note-on message.  Like pressing a piano key
//channel ranges from 0-15
void noteOn(byte channel, byte note, byte attack_velocity) {
  talkMIDI( (0x90 | channel), note, attack_velocity);
}

//Send a MIDI note-off message.  Like releasing a piano key
void noteOff(byte channel, byte note, byte release_velocity) {
  talkMIDI( (0x80 | channel), note, release_velocity);
}

//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
  Serial2.write(cmd);
  Serial2.write(data1);

  //Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes 
  //(sort of: http://253.ccarh.org/handout/midiprotocol/)
  if( (cmd & 0xF0) <= 0xB0)
    Serial2.write(data2);

}

enter image description here

I did notice that the baud for serial2 is different to the baud you set for the UNO (31250)

Your ESP32 is a 3.3V device. Those pins are NOT 5V tolerant but you are connecting them to the shield which is designed for a Uno (5V device)

It still should work. I changed the baud rate to 31250 now.

Oh and why is that? Do you have some sort of secret knowledge, please tell us.

Because it works with the Uno. It's just serial data.

The IC on the SparkFun shield (VS1053B) operates at 3v3.

I tried again with a 3rd ESP32, except this time I externally connected all the grounds of the shield together. It works!

Happyness :slight_smile:

Until you learn a bit more about electronics and voltage levels.

Within tolerance of the datasheet and used USB which is 5V. Be less grumpy.

So your are happy in this delusion then.

For others following this thread in the future, this is simply not true.

"you're". Contraction for "you are"

1 Like

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