Pages: 1 [2] 3   Go Down
Author Topic: Arduino dropping midi signals  (Read 6911 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah, after I posted I found a link to the beta code.   However, the problem with it is it doesn't allow you to independently adjust the TX buffer sizes, and on the Mega with 4 USARTS, only needing one buffered transmitter but potentially needing a large buffer, using the beta code would be costly.

What I'm thinking of doing instead is modifying the 0022 HardwareSerial to add a new function, writeavailable that returns the TX data empty bit--  that way I can implement a non-interrupt based TX ring buffer that should be able to meet my needs.    I don't care if it's interrupt driven (though that'd be nice), what I care about is that I can buffer a single TX and control the size of the buffer...


--

Zinc
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Welp, my computer bit the big one (or close enough to it that it might as well be the case for a while) so this project is getting back burnered indefinitely. Thanks for your suggestions and help, RuggedCircuits. I appreciate it.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, my computer is back, so this project is back on. Still having the same trouble as before. No idea what the heck is going on here.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

Sorry to dig up this thread.

Just a bit of info which I picked up from the same place you got your original schematic ( http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1187962258 )

People discovered that the circuit worked better without the 100K resistor (or any thing for that matter) connected to pin 6 of the opto-coupler.

I tried the same circuit with and without.  The circuit didn't work with the resistor but worked perfectly without.

So just to reiterate, leave both pin3 and pin6 open.

Let us know how the project is going.

Cheers,
Col
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, back so soon!!

I forgot to mention, I also had issues reading MIDI while I still had a USB cable plugged in to the Arduino I guess because it was conflicting with the Rx pin.

So I'd definitely recommend you try running your Arduino from a battery or another PSU, not USB.

Cheers,
Col
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm having the same problem.  Completely new to this platform (though I did MIDI as a senior project about, oh, 25 years ago :-) ), and if I go slowly (a little faster than the 4s cited by OP) it behaves as expected, but otherwise I lose note offs.

My keyboard only sends note + Velocity of 0 for off, doesn't send 0x80 (an old Yamaha PSR-262).

I don't have the MIDI out hooked up; I don't have the FTDI connected when I'm doing MIDI stuff; but it still is too slow.

The circuit I'm using is a fair bit different, if there's interest / attention to this thread I can upload a schematic.  I basically ripped the circuitry out of an old Game Port -> MIDI adapter I had... never going to have another system with a Game Port on it, and it was an easy way to come up with the optocoupler...  Which in this case is a 6N136, not one of the 4N series.  The pull up on the signal out pin is a 5.6K, which makes me wonder given the other statements that 3.3K was too much.

I haven't been able to find the right diagram/table to explain the relationship between that pull up (RsubL in the datasheet for the chip) and the timing.  It may just be that it's been toooo long since I read these sorts of things and I'm missing it.

The other thing I'm wondering about is whether I can improve the bias of the output transistor...there's a pin to the  base of the collector, but I am not finding enough details to get a good idea what I should set the output to...and I don't have an oscilloscope to be able to do input/output tweaking with a pot in that spot.
Logged

Austin, TX
Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you have another MIDI keyboard to try? I mention it because I was building a MIDI circuit too, and with a Yamaha PSR keyboard it would always seem to drop notes, and even add notes!! And I must have gone through my schematic and circuits a hundred times.
But then I plugged into my Kurzweil piano and it worked flawlessly... and just to be sure I have a Rockband controller which has MIDI out, and it works fine as well... So I believe these Yamaha PSR keyboards don't follow the standards too well.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Replying to Reply #20 on

I also use the 6N136.

You need at least 4.7k from the pin 6. The 6n138 used in Tom Igoe's http://www.tigoe.net/pcomp/code/communication/midi
uses a Darlington Pair, so much smaller resistor (270 R) is used.

I have same problem that most folks have with midi.

That is ... I used a mega1280 and avoid RX/TX (favour using 1, 2 or 3) else flashing the beast becomes tiresome.

The read is fast enough.

The write seems to lag.

I have modified HardwareSerial to have a 512 byte buffer, and used the & 511 instead of %.

This allows me to read upto 512 bytes without loss.

The first 64 bytes read/write seem near instantaneous:
  • [1]PC ->
  • [2]midi ox monitor ->
  • [3]USB ->
  • [4]RX1 ->
  • [5]my sketch ->
  • [6]TX1 ->
  • [7]USB ->
  • [8] midi ox monitor.
But once I go past 64 bytes the lag is evident.

It appears to be in stages [3]-[8]. At the moment I dont know how to home in on the issue.
But as my SysEx message gets longer (16, 32, 64, 128, 256, 512), the >64 lag is "linear" ie few seconds for 128.
About twice as long for next etc.

For my purposes, I am decoding NRPNs, and need to read in a patch (434 bytes) before processing and updating internal state.
So I can live with the lag.
I also intend to throw to /dev/null any sysex that doesnt fit the pattern I am looking for (determined by examining first 9 bytes).

I am also wanting to make a merge unit.
Then I commit to protoboard/project box.

But basic midi is fine. I dont see the issues other report "provided" you dont read junk data (you do check SerialAvailable() before reading right?).
Even then, I have on rare occaisions need 255 (-1 as an unsigned) read in ... and this is Midi for System Reset ... since I have no equipment sending this I ignore it.
You are handling running status (if your synth sends it)?

Not sure how to uploaded sketches to the forum. You can find a photo of my test rig on my http://sourceforge.net/projects/miniaktools/ website (4th or 5th screen shot picture). If there is a way to upload Fritzing sketches or photos here, I can do that.

Regards

Steve H

PS I was probably playing with the same midi hardware 25 years ago too :-)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Unfortunately I don't have another kbd to try.

I've tried the schematic from here as well: http://arduino.cc/forum/index.php/topic,22447.0.html

(but using 4N25...well, actually an NTE3040... instead of 4N28) and got the same results. 

In the original circuit, my pull up on pin 6 is 5.6k, the resistor on the input loop (pin 4 of the MIDI to pin 2 of the 6N136) was 270.

I tried adding the 100k and various others up to 1M to the base (pin 7) but didn't get any improvement.

I also tried tweaking that resistor in the other version of the circuit.

I have found that I'm getting a lot of Active Sensing messages (0xFE), and that seems to pause if I start playing at any speed.  But I don't see anything in the manual for the kbd or online about turning that off.  The MIDI Implementation Chart in the manual doesn't imply anything there either, just notes that it recognizes active sensing on input and sends it on output.

I'm starting to think I really need to get a scope if I'm going to get anywhere with this, or else buy a different input device to try.

In case anyone's interested, here's the code I'm using, it's also based on that thread above, but I tried a few tricks to see if it could run faster, and there are some dead subroutines that I was using when i was identifying the Active Sensing stuff.

Hm.... having reviewed this again I think I need to verify whether or not I'm getting multiple bytes each loop and ignoring part of the buffer....  The other possibility that occurs to me is maybe the Active Sensing stuff is burning up my buffer and I'm having overruns.  But it's nearly 1am so work for another day.  smiley-mr-green

I'm using a Mintduino for this (uses ATMega328), and I'm also wondering if maybe I could do better using the Arduino Mega I got more recently...haven't checked whether the serial buffer is bigger, or clock is faster.


Code:

//variables setup

int incoming;      // number of incoming bytes
byte incomingByte;
byte note;
byte vel;
int led;

  byte note2pins[] = {
    2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8
  };

  int vel2val[] = {
    LOW, LOW, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH
  };
 
  int toggles[] = {
    LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW
  };

int statusLed = 13;   // select the pin for the LED
int action=2; //0 =note off ; 1=note on ; 2= nada


//setup: declaring iputs and outputs and begin serial
void setup() {
  pinMode(statusLed,OUTPUT);   // declare the LED's pin as output
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
 
  //start serial with midi baudrate 31250 or 38400 for debugging
  Serial.begin(31250);       
  // digitalWrite(statusLed,HIGH); 
}

//loop: wait for serial data, and interpret the message
void loop () {
  while ((incoming = Serial.available()) > 0) {
    digitalWrite(statusLed, HIGH);
    // read the incoming byte:
    incomingByte = Serial.read();
   
    // wait for as status-byte, channel 1, note on or off
    if (incomingByte == 0x90){ // note on message starting starting
      //showByte(0);
      while ((note = Serial.read()) == 0xFF) {
        // just wait until next byte is available; -1 shows up as FF in a byte
      }
      // showByte(note);
      while ((vel = Serial.read()) == 0xFF) {
        // just wait until the next byte is available; -1 shows up as FF in a byte
      }
      digitalWrite(note2pins[(note - 36) % 12], vel2val[int(vel/10)]);
    }
    digitalWrite(statusLed, LOW);
  }
}
   
void showByte(byte incomingByte) {
  for (int i=0; i<8; i++) {
    if (incomingByte & (1 << i)) {
      digitalWrite(i+2, HIGH);
    } else {
      digitalWrite(i+2, LOW);
    }
  }
}

// probably should check for a valid place and led value
void toggle(int place, int led) {
  if (toggles[place] == LOW) {
    digitalWrite(led, HIGH);
    toggles[place] = HIGH;
  } else {
    digitalWrite(led, LOW);
    toggles[place] = LOW;
  }
}

void trackBytes(int incoming) {
  // track number of bytes coming in
    led = (incoming - 1) % 8;
    if (toggles[led] == LOW) {
      digitalWrite(led+2, HIGH);
      toggles[led] = HIGH;
    } else {
      digitalWrite(led+2, LOW);
      toggles[led] = LOW;
    }
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

------

I +1 the mega, but not because its faster or what not.

Midi works nicely with Mega 1280 (I am guessing these went out of production since EBay was selling them cheap and now the mega is a 2560).

Simply it has much more memory, and 4 UARTs, of which if you ignore Serial this leaves 3.
I say ignore Serial ... the 1/2/3 dont get interfered with during program upload etc.

I am using 1/2 for IN, merging the streams and spitting out on 1's TX then reading in on 3 and spitting out on 3 a transformed stream of midi.

I _dont_ like the duplicity of pins in Arduino ... ie if you use an interrupt, it seems to share pins you want to use for UART say.

------

Before you get a scope, what happens when you send test data from midi OX say?

Does you code work as expected?

It seems you are wanting to write out a series of LEDs to visualize the midi bytes right?

If you cut and paste your code, modify it to work with C++ or java and debug it with "pretend" steam, is it working properly? I need to get into this avr-g++ env so I can use debugger etc. The number of hours I have wasted because I "know" my code is correct ... oh wait ... errmm nope it isnt ... phew project works now.

So you have checked your algorithm right. You have test data ... how to generate this in the outside world and push it thru your circuit.

Have you tried the MidiLibrary to read the bytes, and then take the content and use that to display?

IE (and not trying to be patronising here), if you systematically take your project apart and test each part independently, do they all work? If no ... fix that ... if yes ... which sub-component breaks ... and why.

Good luck with your project.

Regards

Steve H

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Before you get a scope, what happens when you send test data from midi OX say?

Does you code work as expected?

Not familiar with MIDI OX, I will check and see if that helps me.

Quote
It seems you are wanting to write out a series of LEDs to visualize the midi bytes right?

That's just an intermediate step to make sure I'm getting the data I think I should be.  Ultimately I want to use the MIDI In for either a simple sequencer, or an analog CV converter (and yeah, I know there's a lot more circuitry involved with that :-) )

Quote
So you have checked your algorithm right. You have test data ... how to generate this in the outside world and push it thru your circuit.

I'm using a very slight variation on code that many people have posted as how they're doing it...

Quote
Have you tried the MidiLibrary to read the bytes, and then take the content and use that to display?

the MidiLibrary is probably another good thing to go along with the OX :-)


Quote
IE (and not trying to be patronising here), if you systematically take your project apart and test each part independently, do they all work? If no ... fix that ... if yes ... which sub-component breaks ... and why.

No offense taken :-)

I'm down to a fairly basic part of the project though; all I'm really doing is making sure I'm getting midi in bytes.  You've given me some pointers to other ways to test that let me break it down further, I'll pursue those (probably after I get my friend's RB3 keyboard and confirm that it's not the PSR issue mentioned above).

Thanks!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Progress:  Got the RB3 keyboard from a friend today.  After figuring out how to make it actually be a MIDI keyboard (press and hold start...) I found that my 4N25 circuit did not work with it at all (though it still works with the PSR-262).  Reverting back to the 6N136 circuit, I found that this one does use note offs so I put that back into my code.  At which point the D key worked flawlessly, and all the others still aren't getting note off.  So obviously problems in my code somewhere too, I expect.  I'm going to switch to the Mega 2560 and use the serial monitor to see what it actually thinks is coming in.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Should have used the Mega a long time ago, it's much easier to monitor what's coming in if you can write it out to a different serial port to see it.  So yes, the PSR-262 MIDI-out is dropping bytes if I get over a certain speed.  I can tell because I'll see things like:

90 2B 1C
90 2B 0
90 2B 41
2B
0
90 2D 41
2D
0
90 2F 36
2F
0

Which is clearly dropping the 90 that would go with 90 2F 00, or the note off for key 2F.  Faster gets even more garbled.  I half think that they are trying to chain strings of notes, and I may try to see if it will make sense if I interpret it that way.  In other words, once they send a note on, they just send additional note and velocity values without resending the initial command byte.  Horrible abuse of the protocol, but if I can make it work I dont' have to buy a new keyboard/controller....

The RB3 keyboard follows the protocol exactly.

Hooking up the RB3 kbd to IN and the PSR-262 to OUT, I can play the yamaha with the smaller keyboard, through my Mega, in real time.  Onward and upward to my expansions of the project :-).  Thanks to folks for the pointers here, particularly the information about how broken the yamaha keyboards are.  If anyone's interested, I can post my "pass through" code, but since it's only slightly different from what I had before, not sure if it's worth the storage space.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One final comment: I rescind my statement about "abuse of the protocol"...

"To further optimize the data stream, "Running status", a convention that allows the status byte to be omitted if it would be the same as that of the previous message, helps to mitigate bandwidth issues somewhat."

http://home.roadrunner.com/~jgglatt/tech/midispec/run.htm

So basically the simple code doesn't deal with running status types of keyboards.

And brief investigation shows that the Midi Library does handle Running status, at least if you define it in.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry I have been busy as of late. Not sure how to setup this tool to inform when a new post is made on a topic.

Yup running status is what you were seeing.

As you said, the MidiLibrary understands this.

Not all midi interpreters respect this. But you have to be able to deal with it.

Similar things happen with sysex.
0xF0 indicated start of the sentence.
0xF7 and/or ANY hit status bit indicates EOM.
But like "i before e except after c", IIRC the system realtime messages are "exceptional".

I am writing a merge at the moment (when I make the time ... algorithms written but not coded into arduino yet).
So I have two inputs, which will "thru" for bypass incase of issues (using the 7404's to not not as per the standard).
These will be merged to one output.
The inputs will be fed from Miniak OUT and from MasterKeyboard OUT.
This will go into BCR2000, and the merge out goes into my "input transform" -> to thru box.
And suddenly I can deal with Controller, feedback and transform.

Like you found ... the devil is in the detail.
Debugging can be such fun.

The tricky part here is understanding which messages to "ignore"/filter etc.

Regards

Steve H
Logged

Pages: 1 [2] 3   Go Up
Jump to: