Hi there,
I just realized that I had previously posted this thread in the wrong topic (sorry Mods!!). Hoping to get more advice here.
Original post:
Hi, I'm using an Arduino Nano to control an ALPS motorized fader.
A motorized fader consists of the following components:
- 10v DC Motor
- B10k Potentiometer
- Capacitive Touch Sensor
I have an L298N DC Motor Driver, and a pair of MIDI input/output jacks (with corresponding circuitry, i.e. a 6138N Optocoupler)
Right now, the motorized fader responds to data coming in from my DAW (Ableton Live 9 Standard) by moving up and down along with the first track's volume/automation as I change it in the DAW. It also sends MIDI data into my DAW to control the tracks volume. When I touch the fader and move it to zero, my first track in my DAW is selected.
I'd like to change the code so that when I touch the fader, the track is immediately selected, rather than only when I move the fader all the way down.
Here's the code:
#include <SoftwareSerial.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
#define rxPin 4
#define txPin 1
SoftwareSerial midiSerial (rxPin, txPin);
const byte motorDown = 5;
const byte motorUp = 6;
const byte motorPWM = 3;
const byte wiper = 7; //Position of fader relative to GND (Analog 0)
const byte touchSend = 2;//Send pin for Capacitance Sensing Circuit (Digital 7)
const byte touchReceive = 7; //Receive pin for Capacitance Sensing Circuit (Digital 8)
int incomingVelocity;
byte motorSpeed = 75; // Raise if the fader is too slow (0-255)
byte minimumCp = 75; // Raise if the fader is too sensitive (0-16383)
byte tolerance = 10; // Raise if the fader is too shaky (0-1023)
double faderMax = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
bool touched = false; //Is the fader currently being touched?
CapacitiveSensor cs_7_2 = CapacitiveSensor(touchReceive, touchSend);
MIDI_CREATE_DEFAULT_INSTANCE();
void setup() {
cs_7_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
midiSerial.begin(31250);
MIDI.begin(MIDI_CHANNEL_OMNI);
while (!Serial);
pinMode(motorDown, OUTPUT);
pinMode(motorUp, OUTPUT);
pinMode(motorPWM, OUTPUT);
pinMode(rxPin, INPUT );
pinMode(txPin, OUTPUT);
analogWrite(motorPWM, motorSpeed);
calibrateFader(); }
void calibrateFader() {
digitalWrite(motorUp, HIGH);
analogWrite(motorPWM, 100);
delay(300);
digitalWrite(motorUp, LOW);
faderMax = analogRead(wiper) - tolerance;
digitalWrite(motorDown, HIGH);
analogWrite(motorPWM, 100);
delay(300);
digitalWrite(motorDown, LOW);
faderMin = analogRead(wiper) + tolerance; }
void loop() {
int faderPos = analogRead(wiper);
int lastfaderValue;
int faderMIDI = faderPos / 8;
int faderHiResMIDI = ((faderPos *16) - 8191);
while ( midiSerial.available() > 0 ) {
int commandByte = midiSerial.read();
int noteByte = midiSerial.read();
byte velocityByte = midiSerial.read();
midiSerial.write( commandByte);
midiSerial.write( noteByte);
midiSerial.write( velocityByte);
incomingVelocity = velocityByte*8; }
{ int totalCp = cs_7_2.capacitiveSensor(30);
if (totalCp <= minimumCp) { touched = false; updateFader(incomingVelocity); }// Not Touching Fader
if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) { touched = true; // Touching Fader
MIDI.sendNoteOn(104, 127, 1);
digitalWrite(motorDown, LOW);
digitalWrite(motorUp, LOW); }
if ((faderPos != lastfaderValue) && (totalCp > minimumCp)) { touched = true; // Moving Fader
MIDI.sendPitchBend(faderHiResMIDI, 1);
digitalWrite(motorDown, LOW);
digitalWrite(motorUp, LOW); }
lastfaderValue = faderPos; } }
void updateFader(int position) { //Function to move fader to a specific position between 0-1023 if it's not already there
if (position < analogRead(wiper) - tolerance && position > faderMin && !touched) {
digitalWrite(motorDown, HIGH);
while (position < analogRead(wiper) - tolerance && !touched) {}; //Loops until motor is done moving
digitalWrite(motorDown, LOW); }
else if (position > analogRead(wiper) + tolerance && position < faderMax && !touched) {
digitalWrite(motorUp, HIGH);
while (position > analogRead(wiper) + tolerance && !touched) {}; //Loops until motor is done moving
digitalWrite(motorUp, LOW); } }
Still left to do:
- Try to get the tracks in my DAW to respond immediately after touching the sensor, rather than only when my motor is all the way down (not sure why it's doing this to begin with??)
- Try to implement PID DC Motor Control (it's easier 'said' than 'done') - I've tried for MANY hours at this point, no luck (and I'm seriously confused about the concept in general)
- Try to get the Arduino to ONLY read MIDI data from a certain command and channel (i.e. Note G#7, MIDI channel 1, which would be read by the Arduino as '104' and '1')
- Try to get the motor to respond to quick automation movements without lag/skipping
Edit 1: Fixed some typos
Edit 2: Added 'Still left to do' list
Edit 3: fixed some more typos