Go Down

Topic: No MIDI from arduino [SOLVED] (Read 878 times) previous topic - next topic

Jul 10, 2013, 01:09 am Last Edit: Jul 13, 2013, 04:11 pm by Stroboscapes Reason: 1
Alright, so I've managed to get my DIY arduino board to work, with all the basic example sketches working. However, then I tried to write this example on it: http://arduino.cc/en/Tutorial/Midi
The IDE says it passed, but none of my MIDI monitors show any activity. I've tried changing it from various channels and various notes, and even trying to send note on values to a device for which I know the note values should trigger something. I've also tried various MIDI cables, still nothing. I have everything wired as it is in the schematic. I've also tried disconnecting the programmer from the TX pin on the chip, still nothing. I'm kind of at a dead end here, can anyone help me?

Thanks in advance.

johnwasser

What 'programmer' was connected to the TX pin?

Have you tried the MIDI example on a regular Arduino board to se if that sends correctly?
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Ok, I've solved it, it was the stupidest mistake possible. The jumper wire that I used to connect the TX pin to the MIDI jack didn't flow current through it. I feel kind of ridiculous now.

However I do have another question now. I've written and programmed the code below:

Code: [Select]
#include <MIDI.h>

const int RecButtonPin = 7;
const int StopButtonPin = 8; //Init button pins
const int RecLedPin = 13;
const int StopLedPin = 12;

int RecLedState = LOW;
int RecButtonState;
int lastRecButtonState = LOW;


int StopLedState = LOW;
int StopButtonState;
int lastStopButtonState = LOW;

void setup() {
   //  Set MIDI baud rate:
   pinMode(RecButtonPin, INPUT);
   pinMode(StopButtonPin, OUTPUT);
   pinMode(RecLedPin, OUTPUT);
   pinMode(StopLedPin, OUTPUT);
   
   digitalWrite(RecLedPin, RecLedState);
   digitalWrite(StopLedPin, StopLedState);
   Serial.begin(31250);
}

void loop() {

  int previousRecState;
  int previousStopState;
   
   // check if the pushbutton is pressed.
   // if it is, the buttonState is HIGH:
  RecButtonState = digitalRead(RecButtonPin);
   StopButtonState = digitalRead(StopButtonPin);
   if (RecButtonState != previousRecState){
    if (RecButtonState = HIGH){
       //Note on channel 1 (0x90), value 0, middle velocity (0x45):
    MIDI.sendNoteOn(0, 64, 1);
    }
  }
  if (StopButtonState != previousStopState){
    if (StopButtonState = HIGH){
    //Note on channel 1 (0x90), value 4, middle velocity (0x45):
    MIDI.sendNoteOn(4, 64, 1); 
    }
  }
  previousRecState = RecButtonState;
  previousStopState = StopButtonState;
   
}


Disregarding the LED parts for now, this code sends continuous MIDI messages all the time, but what I'd like it to do is just send a noteOn command when a button is pressed. In the Serial Monitor I get a constant blank value being sent, and I don't know what that means. Hardware is all connected properly.

Any help is appreciated!

boguz

i am not sure what the problem is.  :smiley-red:
what do you get on the console when you are not pressing any button?
If you have the baud rate of the console = to what you defined on your sketch, then you shouldn't get anything.

One thing i noticed, you have your StopButtonPin set to OUTPUT, but i guess you mean to set it to INPUT.
Code: [Select]

   pinMode(StopButtonPin, INPUT);


How are you connecting your buttons? are you using pull-up or pull-down resistors (i guess from your code you might be using pull-down)? If not, maybe your signal is kind of floating around and giving you strange readings. You might want to take a look at that...

Yes, thanks, I was using pull-downs, and that was the error. I couldn't see the tree for the forest. I should really sit down and think about what I can do before posting here.

But not this time, so I have another question. I've added a debounce procedure adapted from the examples debounce code, and I'd like to add a function for the button hold. Here's the code snippet, it all works as it should within the main loop.
Quote
void StopPlaying(int StopReading){
   // If the switch state changed, reset the debounce timer
  if (ButtonStopState != LastStopState){
    StopDebounceTime = millis();
  }
  // If the reading has been active for more than the DebounceDelay time,
  // it is the new state
  if ((millis() - StopDebounceTime) > DebounceDelay){
      //if the button state has changed
    if (StopReading != ButtonStopState){
      ButtonStopState = StopReading;
      // only send MIDI if the new state is HIGH
      if(ButtonStopState == HIGH){
         MIDI.sendControlChange(85,64,1); // Send MIDI CC #85 value 64 channel 1
        changeLoopMode(3);
      }   
    }
  }
  // Save the reading
  LastStopState = StopReading;   
}


I've tried adding a "if ((millis() - StopDebounceTime) > 2000)" condition before the DebounceDelay condition, and the DebounceDelay in the else of that condition but it didn't work.
As always any help would be greatly appreciated.

boguz

i think probably someone else will be able to help better than me.

to you know the ClickButton library?
https://code.google.com/p/clickbutton/
It is very easy to use and it gives you simple clicks, double and triple click, simple hold and double and triple click+hold.
I have used it in the past and it worked great.


I my latest project i also used a click and click+hold function (without the library) and i had some trouble doing it (i'm not so experienced!!).
The way i got it working was to always send the message on button release, instead of button push!

i made something like this:
Code: [Select]

// this is not code, more like pseudo-code to give you an idea...  ;)

When a buttonState != lastButtonState and the button is pressed {
   reset button's counter and start counting.
}
when a buttonState != lastButtonState and the button is released {
   //check the button's counter:
   if button's counter is smaller than holdInterval {  // so this is a simple click
      do this...
   }
   if button's counter is bigger than holdInterval {   // so this is a button hold
      do that...
   }
}

so, this was my idea. than i adapted it to my needs, but it seems to be working fine.


Here's the code snippet, it all works as it should within the main loop.

Do you really need it outside the main loop?

why are you using like this:
Code: [Select]

   void StopPlaying(int StopReading)


or this:
Code: [Select]

    ButtonStopState = StopReading;

('im not saying it is wrong. i don't know so much code and i'm trying to understand so i can help you).

Do you need to "report" the button state and use it also somewhere else in the code, or do you just need it to send that midi command  and change the loopMode? Maybe you can make the bit of code more simple...

Quote
to you know the ClickButton library?
https://code.google.com/p/clickbutton/
It is very easy to use and it gives you simple clicks, double and triple click, simple hold and double and triple click+hold.
I have used it in the past and it worked great.


I didn't know about that, I'll check it out, thanks!

Quote
I my latest project i also used a click and click+hold function (without the library) and i had some trouble doing it (i'm not so experienced!!).
The way i got it working was to always send the message on button release, instead of button push!

i made something like this:


I've tried something similar but it didn't work. But I have to send the message on button press, not release, so that's not an option for me.

Quote
Do you really need it outside the main loop?


In theory no, but I have 3 more just like it currently and am going to add another 6 or so once I get the hold function solved, so I prefer to keep them separate for neatness.

Quote
why are you using like this:
Code:
   void StopPlaying(int StopReading)

or this:
Code:
    ButtonStopState = StopReading;
('im not saying it is wrong. i don't know so much code and i'm trying to understand so i can help you).

Do you need to "report" the button state and use it also somewhere else in the code, or do you just need it to send that midi command  and change the loopMode? Maybe you can make the bit of code more simple...


The "StopReading" variable is used in the main loop and then sent to one of three different functions, so it's read in the main loop and depending on the function I need sent to one of three different functions, which is why I have only 1 digitalRead(StopReading) in the main loop. I should have mentioned this too, I apologize.

Thank you for the help!

boguz


I've tried something similar but it didn't work. But I have to send the message on button press, not release, so that's not an option for me.

How will you then do the hold? You cannot send that on click.
You could make something like you have done, on click record the millis at that point into a variable.
Then maybe you can always check how much time as passed. If passed time is equal to hold time (let's say 2000ms), send midi message.
Maybe that would work...

something i just though...
here:
Code: [Select]

  ButtonStopState = StopReading;

wouldn't it be better
Code: [Select]

  StopReading = ButtonStopState;


or is it the same?

#8
Jul 11, 2013, 02:43 pm Last Edit: Jul 11, 2013, 09:12 pm by Stroboscapes Reason: 1
Quote
How will you then do the hold? You cannot send that on click.
You could make something like you have done, on click record the millis at that point into a variable.
Then maybe you can always check how much time as passed. If passed time is equal to hold time (let's say 2000ms), send midi message.
Maybe that would work...


Oh, sorry, I misunderstood, I thought you meant trigger the debounce on release. Which now in my head makes no sense.
I have a debounce procedure that checks for 50ms after the button has changed state from low to high, and if it's still pressed then the function gets executed. I've tried putting another condition to check for 2000ms after the button has been pressed and ignore the condition that would normally occur after 50ms but apparently not very good because it didn't work.

Quote
something i just though...
here:
Code:
 ButtonStopState = StopReading;
wouldn't it be better
Code:
 StopReading = ButtonStopState;

or is it the same?


I'm not sure, but I believe that in that case the ButtonStopState would never change, and the procedure wouldn't be properly triggered. Anyway, that isn't the problem, this part works just fine, the problem is adding another function for checking the holddown time.

Thanks for the help!

Go Up