Now I am trying to get the MIDI notes to work with velocity. The way the code was posted runs the solenoids at full velocity.
Please see attached pics. In the first pic you can see jason's notes about how to get velocity turned on.
In the 2nd pic... I don't get what to change from his comments (circled in blue).
The "analogWrite" circled in red is a change I made, it had been "digitalWrite" like below circled in green. I'm hoping that is what you'd change to get the kick drum solenoid (kickMidi) to change to velocity. ,
The other instructions where it says "just be sure to double to value because midi is 0-127"... I'm not sure if that's a typo and should read "double the value" or if I'm supposed to enter those specific words somewhere in the sketch? Maybe he means to just compress the MIDI velocities so they are using a range, say of 100 to 127 instead of 000 to 127 because solenoids draw a lot of juice at startup.
I'm using Cubase to output notes to the card and it works fine. On my MIDI track you can't double the values and get anything to be over 127. Or does it mean that I'm supposed to do something in the sketch so the velocity is doubled there?
Try posting text as text not as pictures. And post the complete program. It's a lot more likely that people will help if you make it easy for them.
With what little you have posted I have no idea where 'velocity' comes from or what values it might. So I can't tell if you might want to double it or not. But I can guess that you'll probably want to remove the if statement and the "velocity = HIGH;" line.
Thanks slipstik, I'll try and delete the if statement. When I change the digitalWrite to analogWrite on the snare there was no solenoid movement on that pin (pin 1).
Here is the complete program:
#include <MIDIUSB.h>
// these are the arduino pins that the solenoids are hooked up to
enum drumPins {kickPin = 0, snarePin = 1, hhPin = 2, crashPin = 3, cowbellPin = 4 , openhatPin = 5};
// these are the midi notes that each solenoid triggers on, as well as an alternate for each
enum midiNotes {kickMidi = 36, snareMidi = 38, hhMidi = 42, crashMidi = 49, cowbellMidi = 39, openhatMidi = 46};
enum midiNoteAlts {kickMidiAlt = 44, snareMidiAlt = 48, hhMidiAlt = 45, crashMidiAlt = 149, cowbellMidiAlt = 47, openhatMidiAlt = 146};
void setup() {
// the serial port is just used as a monitor for debugging
// it is not needed for midi
Serial.begin(115200);
// setup all output pins
for(int i=0; i<=8; i++) {
pinMode(i, OUTPUT);
}
}
void loop() {
//listen for new MIDI messages
midiEventPacket_t rx = MidiUSB.read();
processMidi(rx);
}
void processMidi(midiEventPacket_t rx) {
switch (rx.header) {
case 0x0:
// do nothing
break;
// note on
case 0x9:
handleNoteOn(rx.byte1 & 0xF, rx.byte2, rx.byte3);
break;
// note off
case 0x8:
handleNoteOn(rx.byte1 & 0xF, rx.byte2, 0);
break;
// control change
case 11:
Serial.print("CC: ");
Serial.print(rx.byte2);
Serial.print(":");
Serial.print(rx.byte3);
Serial.print("\n");
break;
default:
Serial.println(rx.header);
break;
}
}
void handleNoteOn(byte channel, byte pitch, byte velocity) {
// it is possible to use the actual midi velocity here, just be sure to
// double to value because midi is 0-127
// and then change digitalWrite to analogWrite
if(velocity > 0) {
velocity = HIGH;
}
switch (pitch) {
case kickMidi:
case kickMidiAlt:
Serial.print("Kick: ");
digitalWrite(kickPin, velocity);
break;
case snareMidi:
case snareMidiAlt:
Serial.print("Snare: ");
digitalWrite(snarePin, velocity);
break;
case hhMidi:
case hhMidiAlt:
Serial.print("HH: ");
digitalWrite(hhPin, velocity);
break;
case crashMidi:
case crashMidiAlt:
Serial.print("Crash: ");
digitalWrite(crashPin, velocity);
break;
case cowbellMidi:
case cowbellMidiAlt:
Serial.print("Cowbell: ");
digitalWrite(cowbellPin, velocity);
break;
case openhatMidi:
case openhatMidiAlt:
Serial.print("Open hat: ");
digitalWrite(openhatPin, velocity);
break;
default:
// print the midi note value, handy for adding new notes
Serial.print("Note(");
Serial.print(pitch);
Serial.print("): ");
break;
}
if(velocity == 0) {
Serial.println("off");
} else {
Serial.println("on");
}
}
It says on my Leonardo card only pins 3, 5, 6, 9, 10, 11, 13 are capable of using analogWrite.
So pins 0,1,2,4,7,8 and 12 cannot be used with velocity with MIDI. I hope I have that right.
I reloaded the original code (post#2 above) and changed pin 3 (crash note number 49) to analogWrite and it appears to work but the signal is too weak to move the solenoid. The if statement discussed above is still there.
I am powering a 12V solenoid with a mosfet card which has an led that is indicating it is getting a signal from pin 3, but the led is much dimmer than with the other digitalWrite pins. I am sending a MIDI velocity of 127 to pin 3 just like the other pins that work but it appears that because they are set to digitalWrite they are getting a much hotter signal.
It feels like I need to increase the MIDI velocity as was described earlier in order to increase the PWN signal to a useable level. Is there a way to do that in MidiUsb?
Can you supply a link to this card please, the MOSFET might not be a logic level one.
Using a digital write results in no PWM at all, it gives a full logic output for any number above zero.
To increase the velocity signal simply multiply it by two.
Please read the how to use this forum sticky post, it tells you how to post code here. Go back and edit your posts with code in them so that it is posted correctly.
So pins 0,1,2,4,7,8 and 12 cannot be used with velocity with MIDI. I hope I have that right
That is correct.
Only use analogWrite on pins capable of PWM operation. Applying PWM to a solenoid has only a very limited effect on the pull in time. You might want to use a map function to compress the range of velocities you get into a range that actually works for the solenoids you have.
And yes, as far as compressing the velocities into a range that works i am familiar with doing that on Cubase. The problem is though that when using analogWrite and the max velocity is 127 that only gives me what seems like 50% of what using digitalWrite gives to the solenoid, not enough to move the solenoid at all.
So I think I need to do what you mentioned with the velocity = velocity * 2; code but I don't know where to put it in the sketch.
After I do that I can fine tune the MIDI velocities in Cubase.
Then use PWM capable pins along with analogWrite for the solenoids you want to use proportionally.
The problem is though that when using analogWrite and the max velocity is 127 that only gives me what seems like 50% of what using digitalWrite gives to the solenoid, not enough to move the solenoid at all.
I was able to only get a narrow range of volume, the solenoid didn't hit the cowbell until a velocity of 124. But it does give you some variation in tone, the 124 hits sound less bright.
Good idea about making the notes longer, will try that.
I'm trying to decide which pins I should use for which solenoids. I am using velocity, so I need to use the pins that work with analogWrite, the PWM pins.
I know that the PWM frequency for pins 3 & 11 is 980 Hz, and the rest use 490 Hz, and have read the warning that pins 5 and 6 will have higher-than-expected duty cycles. I see where it says it may result in a value of 0 not fully turning off the output on pins 5 and 6. I understand that you wouldn't want the solenoid to not turn off. I'm trying to determine if any of these factors should affect my pin choices.
I might be adding some servo motors to the project at some point if that matters.
My Leonardo card has a ≈ symbol next to pins 3,5,6,9,10 and 11 and designates them as PWM. It says "DIGITAL (PWM ≈). But there's no ≈ symbol next to pin 13 but the analogWrite page says pin 13 is PWM capable.
As far as my project, can I just use pins 3,5,6,9,10,11 and 13 as if they are identical?
You can you any of the PWM pins. As for your driver modules, the IRF520 is not a logic level mosfet. Are you using them directly or is there other circuitry to drive the gate at voltages above 5V?
And do I need to be concerned about the warning that pins 5 and 6 can act oddly with a value of zero?
I don't understand that warning.
analogWrite(pin, 0) is executed as digitalWrite(pin, LOW)
From wiring_analog.c
void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
else
{
where at the bottom under "Notes and Warnings" is says:
"The PWM outputs generated on pins 5 and 6 will have higher-than-expected duty cycles. This is because of interactions with the millis() and delay() functions, which share the same internal timer used to generate those PWM outputs. This will be noticed mostly on low duty-cycle settings (e.g. 0 - 10) and may result in a value of 0 not fully turning off the output on pins 5 and 6."
It probably (hopefully) isn't important but the fact that pin 13 doesn't, when viewing the Leonardo card from the side, have the "≈" near it like the other PWM pins made me wonder if there was something particular about that pin. My "≈" symbol is as close to the actual symbol I can find on my Mac.
Paul thanks and I'll do my power calculations and look at IRL's if I exceed what the IRF520's can provide. The ones I bought say they are 24V <5a which is probably optimistic but they are only on for a very short amount of time and don't get hot.