MIDI in on UNO R4 WIFI

I Couldn't get MIDI in using the MIDI Library on the UNO R4 WIFI....
after exhausting searching around I realized the MIDI library needed to include the R4 WIFI in the boards that use Serial1 for the TX and RX pins...
adding that in the SerialMIDI.h file did the trick....

#if defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_SAM_DUE) || defined(USBCON) || defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__)
    // Leonardo, Due and other USB boards use Serial1 by default.
    #define MIDI_CREATE_DEFAULT_INSTANCE()                                      \
        MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
1 Like

Have you got a basic example of where this works?
I made the change to the SerialMIDI.h file and the Basic_IO doesn't seem to be any better and still doesn't work on the R4 Wi-Fi.

I am working on a project where I take in MIDI from a Piano and then light some leds based on that input, the change that I made to the library allowed the midi library to create my MIDI instance on the correct pins in the UNO R4 WIFI which is RX0 and TX0 on the board which is created on the Serial1 port of the board instead of the Serial0 which shares the connection with the USB port.
I am able to both receive and send MIDI over this pins after the change was made and not before.

Thanks for the response. I am not sure about

I am not sure how it is possible to both send and receive MIDI on the same pin. That would require a pin to be both an input and output at the same time, which is not possible.

As I said the modifications you suggested stopped the operation of reception of a MIDI input, not only on an R4 but on any type of Arduino, even a Uno when run with hairless.

EDIT:-
When you said

Did you actually mean
I am able to both receive and send MIDI over these pins ?

Sorry, I know very little about MIDI. And I am really rusty on the UNO R4 Serial stuff.

But could the MIDI be talking to the R4 using Serial Half Duplex? If so it could communicate just using the TX pin of the UART...

I don't think so, because nothing in the MIDI specifications mentions this possibility. Both sides of a half duplex system would have to know about when to switch.

Yes, I am sorry about the typo....
I am receiving through the RX0 pin and sending over the TX0 pins....

So can you show the code where you are getting this to work please.

Yes.... here it is...
the midi notes trigger a fill animation on a segment from my LED strip.
I am using a regular 5 Pin MIDI In circuit, and its going to pin RX0 on my UNO R4 WIFI.
before the modification to the library I would not get any MIDI data in...
LED 13 is triggered with the MIDI NoteOn to check that the MIDI is coming in.

#include <FastLED.h>
#include <MIDI.h>

#define LED_PIN     7   // Define the pin where your LED strip is connected
#define NUM_LEDS    300  // Define the number of LEDs in your strip
#define BRIGHTNESS  200 // Set the initial brightness
#define LED 13

CRGB leds[NUM_LEDS];

// Define the MIDI interface
MIDI_CREATE_DEFAULT_INSTANCE();

// Struct to hold animation state for each note
struct NoteAnimation {
  int startLed;
  int endLed;
  uint8_t colorIndex;
  bool active;
  int currentLed; // Track the currently lit LED
  unsigned long lastUpdateTime; // Track the time of the last LED update
  int animationSpeed; // Speed of the animation
};

const int numNotes = 12; // Set the number of notes/animations you want to handle
NoteAnimation noteAnimations[numNotes];

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  pinMode(LED, OUTPUT);

  // Start the MIDI interface
  MIDI.begin(MIDI_CHANNEL_OMNI);
  
  // Assign note on and off message handlers
  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.setHandleNoteOff(handleNoteOff);

  // Initialize noteAnimations array
  for (int i = 0; i < numNotes; i++) {
    noteAnimations[i].active = false;
    noteAnimations[i].currentLed = 0;
    noteAnimations[i].lastUpdateTime = 0; // Initialize lastUpdateTime
    noteAnimations[i].animationSpeed = 50; // Default animation speed
  }
  FastLED.clear(1);
}

void loop() {
  MIDI.read(); // Read incoming MIDI messages
  
  // Update active animations
  for (int i = 0; i < numNotes; i++) {
    if (noteAnimations[i].active) {
      animateLEDs(i);
    }
  }
}

void handleNoteOn(byte channel, byte pitch, byte velocity) {
  digitalWrite(LED, HIGH);

  // Ensure the pitch is within the specified range
  if (pitch >= 62 && pitch <= 73) {
    // Calculate the note index within the fixed range
    int noteIndex = pitch - 62;

    // Find an available slot for a new note animation
    for (int i = 0; i < numNotes; i++) {
      if (!noteAnimations[i].active) {
        // Set the parameters for the new note animation
        noteAnimations[i].startLed = noteIndex * (NUM_LEDS / numNotes);
        noteAnimations[i].endLed = (noteIndex + 1) * (NUM_LEDS / numNotes) - 1;
        noteAnimations[i].colorIndex = map(pitch, 62, 73, 0, 255);
        noteAnimations[i].active = true;
        noteAnimations[i].currentLed = noteAnimations[i].startLed;
        
        // Adjust animation speed based on velocity
        int velocityFactor = map(velocity, 0, 127, 1, 10); // Adjust the factor as needed
        noteAnimations[i].animationSpeed = 120 / velocityFactor; // Adjust the base speed as needed
        
        noteAnimations[i].lastUpdateTime = millis(); // Initialize lastUpdateTime
        break;
      }
    }
  }
}

void handleNoteOff(byte channel, byte pitch, byte velocity) {
  digitalWrite(LED, LOW);

  // Turn off the animation corresponding to the note that was turned off
  for (int i = 0; i < numNotes; i++) {
    int noteIndex = pitch - 62;
    int noteStartLed = noteIndex * (NUM_LEDS / numNotes);
    int noteEndLed = (noteIndex + 1) * (NUM_LEDS / numNotes) - 1;

    if (noteAnimations[i].active && noteAnimations[i].startLed == noteStartLed && noteAnimations[i].endLed == noteEndLed) {
      noteAnimations[i].active = false;
      clearLEDs(noteAnimations[i].startLed, noteAnimations[i].endLed);
      break;
    }
  }
}

void animateLEDs(int noteIndex) {
  if (noteAnimations[noteIndex].endLed > NUM_LEDS) {
    noteAnimations[noteIndex].endLed = NUM_LEDS;
  }

  // Check if animation is still in progress
  if (noteAnimations[noteIndex].currentLed <= noteAnimations[noteIndex].endLed) {
    // Calculate time since last update
    unsigned long currentTime = millis();
    unsigned long deltaTime = currentTime - noteAnimations[noteIndex].lastUpdateTime;

    // If enough time has passed, update the LED
    if (deltaTime >= noteAnimations[noteIndex].animationSpeed) {
      leds[noteAnimations[noteIndex].currentLed] = CHSV(noteAnimations[noteIndex].colorIndex, 255, 255);
      FastLED.show();
      noteAnimations[noteIndex].currentLed++;
      noteAnimations[noteIndex].lastUpdateTime = currentTime;
    }
  }
}

void clearLEDs(int start, int end) {
  for (int i = start; i <= end; i++) {
    leds[i] = CRGB::Black; // Turn off LEDs after the animation
  }
  FastLED.show();
}

Thanks for that.
I can't get the FastLED library to compile. On checking the compatibility at R4 compatability library I find it needs to

Use fork by @facchinm

So over to the FastLED library and search for facchinm, and I come up with this pull request
Pull 1523
First off it says it was incorporated into the system, and then there are a lot of comments saying it doesn't work. Finally there was a comment

It is working fine for me with R4 minima and FastLED 3.6.0 (branch master).

So can you please tell me how to get at this FastLED 3.6.0 (branch master).
This compilation message

Using library FastLED at version 3.6.0 in folder:

is telling me that I am using what I think is the correct file. But It also says

#error "This platform isn't recognized by FastLED... yet. See comments in FastLED/led_sysdefs.h for options."
^~~~~

I have looked into the library downloaded to my Arduino and I can't find this file.

Any further ideas to get it running, or should I just hack the FastLED part out as it is only actually the MIDI I am interested in?

I am using IDE 1.8.19 and R4 board manager 1.0.5

Thanks

Yes, apparently the FastLED library hasnt been fully ported to the R4, what i did was to download the FastLED library directly from the Github and installed it to the IDE via the .zip file.
this allowed the library to "compile" on the UNO R4.... and the code i sent works fine on the board.

I have moved to a different board as I was trying to use parallel output from the FastLED library and apparently that hasn't been fully ported for the R4 yet....

as of now I have moved my project to an Arduino Due, I wanted to use the GIGA but i couldnt find a library that is currently working on said board for addressable led strips...

I am using IDE 2.3.0

if you dont need the FastLED at all you can get rid of that part and the code I sent should flash your LED on pin 13 when a MIDI note comes in....

Thanks for that.

Yes I did strip out all the FastLed stuff from your code and it did compile. I am waiting for some more board mounting 5 pin DIN sockets to arrive, before I can try it out.

I think we are at cross purposes here. Yes when doing that modification, the R4 WiFi will send and receive MIDI on Serial1 TX & RX pins.

But as I said in post#2, it also breaks the ability of the MIDI messages being sent to the USB port. Therefore the R4 WiFi still can't be used with the MIDI.h library to send MIDI messages into the system, like the R4 minima can do. Or could do before that modification.

Sorry for wasting your time.