Serial.write problem

Hi there, i compiled this code
Basically, it modifes incoming messages and transmite them on tx port.
Problem is i can't get any data on output port though the code seems to be ok!...

#include <MIDI.h>

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( channel, note+transpose, velocity );
}

void noteoff(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOff( channel, note+transpose, velocity );
}

void setup() {
  
       MIDI.begin();      
        MIDI.setHandleNoteOn(noteon);
        MIDI.setHandleNoteOff(noteoff);
}

void loop() {
        MIDI.read();
}?

I never used the Midi library but looking to your code you are just reading the incoming messages I believe.

Incoming unread bytes/messages are kept in the Arduino serial buffer, in order not to flood it, check regularily with MIDI.read. See the reference for Thru explanations.

In your loop() you are just doing that.
How can you send something if you are not doing it?

i tried to write a serial.write function in void setup, but it didn't work..

Ok, i see what you mean..

i should place a recursive function in void loop to write modified messages.

Wich would the best way to do this?

i should place a recursive function in void loop to write modified messages.

Probably not. Unless you know what you're doing, recursion is way to dig your self a huge hole quickly.

Wich would the best way to do this?

That would depend on a number of factors. The primary ones are what your definition of best is, and what "this" is that you want to do the best way.

Well, basically i'd just like to get the modified data on the tx port

Problem is i cannot understand how to use the Serial.write function in order to transmit them..
i'm working on it since a couple of weeks, i read the manual and googled but i didn't get it.

#include <MIDI.h>

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( channel, note+transpose, velocity );
}

void noteoff(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOff( channel, note+transpose, velocity );
}

void setup() {
  
       MIDI.begin();      
        MIDI.setHandleNoteOn(noteon);
        MIDI.setHandleNoteOff(noteoff);
}

void loop() {
        MIDI.read();
}?

Well, basically i'd just like to get the modified data on the tx port

First, you have to get some data. What kind of data is it?

Second, you need to modify that data. What modifications do you want to perform?

Third, you have to send that modified data out. You need to define what you are sending that data to.

If, as I suspect, you want to use the Arduino between two MIDI devices, getting data from one, modifying that somehow, and then sending it to another device, you have some challenges ahead of you. The way you are going now, you are getting data from one source, and sending data back to that source.

midi deviceA transmit data to -> arduino transmit modified data to -> midi deviceB

All hardware connections are made and tested.

midi deviceA send note on and note off messages (made of three byte each).

first byte is the data type (note on or note off)
second byte is pitch (the note)
third byte is velocity (the volume)

i want to modify the note.

So, i wrote a code where:

-i have a transpose variable (wich modify the pitch). This variable is summed to the pitch of the incoming messages. This operation is performed each time a message is received.
I think the code i posted is pretty good and i presume that should work until this point.
-my problem is that i don't understand how to write those messages (note on or note off) (of three byte each) on output port

#include <MIDI.h>

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( channel, note+transpose, velocity );
}

void noteoff(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOff( channel, note+transpose, velocity );
}

void setup() {
  
       MIDI.begin();      
        MIDI.setHandleNoteOn(noteon);
        MIDI.setHandleNoteOff(noteoff);
}

void loop() {
        MIDI.read();
}?

All hardware connections are made and tested.

I guess it's not necessary to know what that hardware is, what the connections are, and how you tested anything.

midi deviceA send note on and note off messages (made of three byte each).

first byte is the data type (note on or note off)
second byte is pitch (the note)
third byte is velocity (the volume)

i want to modify the note.

Modify it how?

So, i wrote a code where:

-i have a transpose variable (wich modify the pitch). This variable is summed to the pitch of the incoming messages. This operation is performed each time a message is received.

So, where IS that code?

I think the code i posted is pretty good and i presume that should work until this point.

The only code that you have posted so far is rubbish.

The MIDI.read() function returns some data, which you discard, or modifies some global data. The only global data you have is a byte variable, transpose, which the MIDI class is not even aware of.

In setup(), you define some functions for the MIDI class to call when some events occur. I see no proof that there is anything that causes those events to occur.

Also, you need one instance of the MIDI class for the input and one for the output, IF you have two MIDI ports. Once instance can't handle both ports. At least, I don't think that that is possible.

All of the details:

HARDWARE:

  • i have a midi keyboard
  • i send a note on message and a note off message to the midi out port
  • The messages travel through a midi cable to the midi in port connected to Arduino

Hardware input connections are shown at the link below:

LINK http://www.instructables.com/files/deriv/FHN/J43V/H6MEVNIE/FHNJ43VH6MEVNIE.LARGE.jpg

  • The messages are received on the rx pin on Arduino.
  • They're modified and then they're sent to the tx port.
  • The tx port transmit data to the midi out plug

Hardware output connections are shown at the link below:

LINK http://www.instructables.com/files/deriv/FAV/6Y9L/H337KSBC/FAV6Y9LH337KSBC.LARGE.jpg

I tested the connections with a simple code that took the messages on the rx port and transmit them on the tx port.
Messages sent by the keyboard were displayed on the midi monitor application.

SOFTWARE: i'll try to explain why i wrote the code in that way.

I declared a variable:
tybe: byte
name: transpose
value: 7

then i wrote two callback functions (one for note off message and one for note on message)

So each time that Arduino receive a note on or a note off message the function is called back and the variable is summed to the second byte of the messages (that's how i modify the second byte)

Then i put in void setup:

void setup() {

MIDI.begin();
MIDI.setHandleNoteOn(noteon);
MIDI.setHandleNoteOff(noteoff);
}

so that the callback functions are connected to the library.

Of course there's something in my logic that doesn't work at all.

PaulS :

Unfortunately i didn' t understand yours suggestions.. sorry for that.
Could you please have a look at this new post and hit me back again with your opinions? thanks..

CODE

#include <MIDI.h>

byte transpose = 7;

void noteon(byte channel, byte note, byte velocity) {
MIDI.sendNoteOn( note+transpose, velocity, channel );
}

void noteoff(byte channel, byte note, byte velocity) {
MIDI.sendNoteOff( note + transpose, velocity, channel );
}

void setup() {

MIDI.begin();
MIDI.setHandleNoteOn(noteon);
MIDI.setHandleNoteOff(noteoff);
}

void loop() {
MIDI.read();
}?

Code tags.

How to use this forum

I looked at the MIDI library. I expected MIDI.read() to return something other that true or false. It doesn't. It populates a structure somewhere.

Since this now seems to be strictly a MIDI issue, and I know next to nothing about MIDI, I can't help you.

There is a note in the read() method documentation that if passthru mode is enabled, and the message is of the correct type, it will be automatically rerouted. I don't see that you are setting anything like that.

problem was that MIDI library has parameters in different orders for different functions:

void noteon(byte channel, byte note, byte velocity) {
    MIDI.sendNoteOn( note + transpose, velocity, channel );
}

So, i wrote this code and it works. BUT got a new problem..

I added a midi panic button (that works preety well) and a "push button switch" for real time transposition.
When i press the button: messages are transposed
Problem is that if i press the button during a note off message, transposition starts from that message and the previous note on message keeps playing.

Example

Time note message
00 C1 ON
01 C1 OFF
02 C1 ON
03 D1 OFF <----- transpose button is pressed. Note off message for C1 is transposed. C1 keeps playing.
04 D1 ON C1 still ON
05 D1 OFF C1 still ON
... .. .... C1 still ON

So, i though that i should insert in void loop() a code like:

when the button state is HIGH
if the current message is a note off
don't traspose it
if the current message is a note on
transpose it
do this instruction just one time

when the button state is LOW
if the current message is a note off
don't transpose it
if the current message is a note on
transpose it
do this instruction just one time

What do you think about it? would it be the right way?

thanks for your attention..

#include <MIDI.h>

const int InputTriggerTranspose = 7; // port for the push button transpose switch
byte transpose = 0;  

byte last_type, last_ch, last_note, last_vel;

const int InputTriggerPanic = 2; // port for the working midi panic button
int Panic = 0;


void noteon(byte channel, byte note, byte velocity) {
    digitalWrite( 13, HIGH );         
    last_type = 1;
    last_ch = channel;
    last_note = note;
    last_vel = velocity;

}

void noteoff(byte channel, byte note, byte velocity) {
    digitalWrite( 13, LOW );         
    last_type = 2;
    last_ch = channel;
    last_note = note;
    last_vel = velocity;
}

void setup() {
          
        pinMode (2, INPUT);  
        pinMode (7, INPUT);    
        pinMode( 13, OUTPUT );
 
        MIDI.begin();      
        MIDI.setInputChannel( MIDI_CHANNEL_OMNI );      // listen to all channels
        MIDI.turnThruOff();                                                 // turn off thru mode
        MIDI.setHandleNoteOn(noteon);                             // call noteon when a note on message is received
        MIDI.setHandleNoteOff(noteoff);                            // call noteoff when a note off message is received
 
        last_type = 0;
}

void loop() {
    
        Panic = digitalRead(InputTriggerPanic); 
        if (Panic == HIGH) {
        MIDI.sendControlChange(120, 0, last_ch);  // midi panic message
}

        transpose = digitalRead(InputTriggerTranspose);
        if (transpose == HIGH) {
          transpose = 7;}