The circuit builds on the one in my previous post in which a pushbutton causes a MIDI note on value to be sent. To this I added a potentiometer. One side goes to +5V, the other side to ground, and the wiper to analog input #2 on the Arduino. In the photo, the pot is on the small breadboard to the right.
The code is below. There are two slightly interesting things:
- The analogRead() method will report values in the range 0-1023, but MIDI continuous controller values must be in the range 0 to 127. The Arduino library has a convenient map() method which handles this.
- If you simply read the pot and send a volume change message every time through the loop() method, you'll produce a lot of data. The code includes a check so that we only send a volume control message every VOLUME_SEND_INTERVAL milliseconds. I experimented a bit with the value, and 100 milliseconds is too coarse - on fast volume control changes you can hear "graininess."
#include "MIDI.h"
/*
Demonstrate how to read an analog input (a potentiometer in this case) and
use that data to send MIDI volume controller information.
Every time the pushbotton is pressed, a MIDI note on will be sent with
a noteOn velocity of 127, Then, as long as the button is held, volume
controller information will be sent - the value depends on the value
read from the pot.
As a visual aid, an LED connected to digital port 13 will light whenever
the pushbutton is pressed.
Circuit:
MIDI OUT to Arduino Serial pin 1
MIDI IN from Arduino Serial pin 0
Potentiometer: Vin, gnd to each side, wiper to analog pin 2
Digital pin 2 to a pushbutton switch, and to 5v through a 10k resistor
other leg of switch to 5v
*/
#define LED 13
#define BUTTON 2
#define VOLUME_POT 2 // Analog input 2 for volume pot
int MIDI_VOLUME_CONTROLLER = 7; // MIDI controller 7 = Volume
int VOLUME_SEND_INTERVAL = 10; // Only send volume data this often (in ms).
int buttonState = LOW;
int prevButtonState = LOW;
int note = 55;
int potVal = 0;
int lastVolumeSendTime = 0; // Last time we sent volume data
void setup() {
MIDI.begin(1);
pinMode(LED, OUTPUT);
pinMode(BUTTON, INPUT);
}
void loop() {
buttonState = digitalRead(BUTTON);
if (buttonState == HIGH) {
if (prevButtonState == LOW) {
prevButtonState = HIGH;
digitalWrite(LED, HIGH);
MIDI.sendNoteOn(note, 127, 1);
} else {
// Button still pressed - send volume controller info, but
// only sample it every VOLUME_SEND_INTERVAL milliseconds so
// we don't flood the MIDI bus.
if (millis() - lastVolumeSendTime > VOLUME_SEND_INTERVAL) {
lastVolumeSendTime = millis();
potVal = map(analogRead(VOLUME_POT), 0, 1023, 0, 127);
MIDI.sendControlChange(MIDI_VOLUME_CONTROLLER, potVal, 1);
}
}
} else if (buttonState == LOW) {
if (prevButtonState == HIGH) {
prevButtonState = LOW;
MIDI.sendNoteOff(note, 0, 1);
}
digitalWrite(LED, LOW);
}
}
No comments:
Post a Comment