Having Trouble reading raw midi data.

A year ago I was able to achieve reading raw MIDI data on my Attiny85. I even made a video last year showing the result. Now I am attempting to retrace my steps and can not get the same circuit to work again. Neither on Attiny85 nor Atmega328p or even an actual arduino Uno board. I've tried different 4n28 optocouplers in case one was burnt, same result.

Now the most important points are:

  • I was and still am using the software serial extension. (same thing used last time)
  • I can not use the midi.h library due to incompatibility and amout of space it takes up and instead reading the bytes manually (also same as last time).

This is a circuit I got it to work last time:

Now I don't have the project from the last time but from my memory, I used a simple instructables code and changed the serial commands to software serial alternatives This was the code, it's supposed to be a simple piece that turns the light on when a NOTE ON (0x90 or 144) byte is received:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 0); // RX, TX

byte commandByte;
byte noteByte;
byte velocityByte;

byte noteOn = 144;

#define LED_PIN 4

//light up led at pin 13 when receiving noteON message with note = 60

void setup(){
  mySerial.begin(31250);
  pinMode(LED_PIN,OUTPUT);
  digitalWrite(LED_PIN,LOW);
}

void checkMIDI(){
  do{
    if (mySerial.available()){
      commandByte = mySerial.read();//read first byte
      noteByte = mySerial.read();//read next byte
      velocityByte = mySerial.read();//read final byte
      if (commandByte == noteOn){//if note on message
          digitalWrite(LED_PIN,HIGH);//turn on led
      }
    }
  }
  while (mySerial.available() > 2);//when at least three bytes available
}
    

void loop(){
  checkMIDI();
  delay(100);
  digitalWrite(LED_PIN,LOW);//turn led off
}

Last thing I did for debugging, I moved the LED pin to turn HIGH after mySerial.available() instead of when it received a NOTE ON byte to see if it's actually receiving some sort of data and it indeed does. I also tried an Arduino Uno to send back some data from the software serial MIDI input to the IDE serial monitor to make sense of the incoming data but the numbers there don't tell me much.

See my page about a MIDI decoder - my schematic is a bit different from yours, particularly the resistor value from pin 5 of the optocoupler. Also you could try my code, see if that works.

I gotta tell you, your code is night and day compared to mine but you seem to have scavanged every inch of the midi signam where as I just needed to utilize the note on off commands. As of right now the circuit is not working (also noted that you use a 4n35, I have an 4n28. Different specs explain different resistor values?)

Actually would anyone mind checking if the code is correct because if this is correct and it works then it's a hardware issue so I can start from there.

How about running my code? It works for me, and if it works for you then you have a hardware issue. The only way I could check your code is to get the MIDI hardware out and hook it up, whereas it sounds like you are all ready to run.

That's just about it, I can't run your code because I'm working with Atmega 328 directly which does not support the native serial (since that function is operated in junction with an LM324 or another atmel chip acting as a serial to usb converter.) So I can't use your code.

The code I posted was taken from an instructables tutorial that seemed to have success with other folks but it uses a different optocoupler schematic to get midi input. However since that code works, logically to adapt it I just needed to add the software serial alternative. I have no way of confirming that though since at this point I don't know if the code is incorrect or my circuit is incorrect. So if someone could glance at the code and confirm that that indeed should work, I can then trail off to troubleshooting the circuit.

I've done a test on an UNO and it actually works. I was able to read the MIDI message just fine on the UNO connected to the RX pin.

This, however does not work on the standalone chip. The RX pin on Uno goes through the serial converter before entering the microcontroller but I thought that software serial was able to replace that exact need for the chip.

SoftwareSerial mySerial(2, 0);

I don't think you should tell SoftwareSerial to use pin 0, which is a HardwareSerial pin.

The RX pin on Uno goes through the serial converter before entering the microcontroller ...

No it doesn't. The Rx pin goes directly to pin 2 on the Atmega328P.

Uno serial Rx.png

I see. Well that crosses that possibility then. After a few more deductions:
Since the RX pin goes directly into the microcontroller input pin 2 (DP0), I've literally switched the circuit from UNO RX to the microcontroller RX since they are one and the same and I am not getting the same reaction on the controller as I do on Uno. Logically same Chips (atmega 328p) so they should have behaved the same.

Alright. To put all the current facts into perspective:

  • I'm able to read MIDI on Uno board with native serial function or with the Software serial BUT only if I use the RX pin on the UNO.
  • When I simply switch the RX pin in the software serial code, I am no longer able to read the midi messages on the Uno board.
  • The RX pin on the uno board reads MIDI but the RX pin on a controller directly does not.
  • Since I'm working with some Atmega328s and later on with ATtiny which do not have built in UART, I have to use software serial.

PS: I've set 0 in the software serial code TX when I was testing another pin for RX, I've set it to a non existing pin (40) as at the moment it's the input I'm concerned about.

I'm guessing that whatever is causing the issue is the same reason I'm unable to read the midi input on the controller directly. I figured software serial was essentially made to be able to set any other pins as rx and tx pins for data transfers.

What clock rate is your chip running at?

External 16mhz Chrystal on the Atmega 328P standalone chip.

Are you sure? I mean you have 2 x Atmega328P chips. One works, one doesn't. If the standalone one is running at 8 MHz that would explain things. Try uploading a blink sketch, and time the delay between blinks (with your watch). You may have a crystal but if the fuses are set to use the internal 8 MHz oscillator, the processor will ignore it.

Maybe run this: chip detector

I'll checked, the blink sketch, the delay(1000) is half a second instead of a full second so its running twise as fast so I'm guessing 16mhz crystal is twise as fast as the 8mhz internal. Also to note that the chip will not run the code unless the crystal is connected too.

TobiasRipper:
External 16mhz Chrystal on the Atmega 328P standalone chip.

You may have the divide-clock-by-8 fuse bit set.

TobiasRipper:
I'll checked, the blink sketch, the delay(1000) is half a second instead of a full second so its running twise as fast so I'm guessing 16mhz crystal is twise as fast as the 8mhz internal. Also to note that the chip will not run the code unless the crystal is connected too.

Well of course 16 MHz is twice as fast as 8 MHz. But your Uno will be running at 16 MHz and you said you had a 16 MHz crystal on your stand-alone board. Didn't you?

Before someone makes a funny comment, remember 16 mHz is 16 milli-Herz, which is very very slow. The abbreviation is MHz (mega-Herz).

Ah right, I wasn't paying attention to the capital M for Mega. But yes, as I said. It's running on a 16MHz crystal, the chip won't run unless it's connected along with 2 22uF ceramic caps. I can read and set fuses from within Atmel Studio as I've set it up before. I feel like we're getting somewhere with this. I'm learning a few new things about this process.

I have the AVRISP MK2 programmer, I can get information directly from Atmel studio if you need something.

PS: This was a tutorial I first sucecssfully burned the bootloader onto this blank chip:

The tutorial demonstrated on an Uno board but it worked on a standalone chip as well.

it's connected along with 2 22uF ceramic caps

I'm hoping they are 2 x 22 pF ceramic caps. That's a difference of 1000000 (multiplier).

I don't want to nit-pick, but you are our eyes and ears here. If you say you have 22 µF caps we have to believe you.

Oh my bad. picofarad - it's 22pF. Again my fault.