Need some help getting a DC Motorized Fader to be more responsive with MIDI

Hi there,

I've got a DC motor that's going back and forth depending on data coming in from Serial Monitor. I'm using a musical keyboard and MIDI to send data into the Serial Monitor, which then transmits the values ranging from 0-127.

My motor could be more responsive to the data coming in. I notice that there's a bit of a lag. I do have the delay function in my code, so I'm sure that this must be causing an issue. I did try adding the "BlinkwithoutDelay" method to my code, but with no luck.

Anybody see something I'm missing?
Thanks for the help!

#include <AltSoftSerial.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
AltSoftSerial midiSerial;

#define RXPIN 8
#define TXPIN 1
const int dir1PinA = 5;
const int dir2PinA = 6;
int faderValue = analogRead(A0);
int velnew;

CapacitiveSensor cs_7_2 = CapacitiveSensor(7, 2);

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  cs_7_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  analogRead(faderValue);
  analogWrite(3, 255);
  MIDI.begin(MIDI_CHANNEL_OMNI); }

void loop() {
  int touchSensorLow = digitalRead(7);
  int touchSensorHigh = digitalRead(2);

  while ( midiSerial.available() > 2 ) {
    int commandByte = midiSerial.read();
    int noteByte = midiSerial.read();
    int velocityByte = midiSerial.read();
    midiSerial.write( commandByte);
    midiSerial.write( noteByte);
    midiSerial.write( velocityByte);
    velnew = velocityByte * 8; }

  {  long total =  cs_7_2.capacitiveSensor(30);

    if (total <= 74) {
      motorControl(); }

    else {
      stopMotor(); } } }

void motorControl() {
  int sensorValue = analogRead(A0);

  if (sensorValue <= velnew - 5) {
    moveMotorUp(); }
    
  if (sensorValue >= velnew + 5) {
    moveMotorDown();}
    
  if (sensorValue == velnew) {
    stopMotor(); } }

void moveMotorUp() {
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, HIGH);
  delay(1);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
  delay(1); }

void moveMotorDown() {
  digitalWrite(dir1PinA, HIGH);
  digitalWrite(dir2PinA, LOW);
  delay(1);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
  delay(1); }

void stopMotor() {
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW); }```

Is there another method of replacing delay in this code?

Hi,
I don't see any delay in the loop in your code. There is only delays in your motor driving functions which I would assume need to be there?

Scroll to the bottom

Hi,
Oh, I see what you are saying. Instead of putting delays in those functions, I would use a sort of counter.

When I take out the delay function from that portion of the code, my motor doesn't move at all, so It seems that it does need to have a bit of delay.

Whether the timing has to be done with delay or not though is what I'm mainly wondering

Hi,
Try this. I added a counter. Change the question marks to the delay you need. I only added it to the movemotorup() function.

#include <AltSoftSerial.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
AltSoftSerial midiSerial;

#define RXPIN 8
#define TXPIN 1
const int dir1PinA = 5;
const int dir2PinA = 6;
int faderValue = analogRead(A0);
int velnew;
int counter=0;

CapacitiveSensor cs_7_2 = CapacitiveSensor(7, 2);

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  cs_7_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  analogRead(faderValue);
  analogWrite(3, 255);
  MIDI.begin(MIDI_CHANNEL_OMNI); }

void loop() {
counter++;
  if (counter == ?){
    counter = 0;
  }
  int touchSensorLow = digitalRead(7);
  int touchSensorHigh = digitalRead(2);

  while ( midiSerial.available() > 2 ) {
    int commandByte = midiSerial.read();
    int noteByte = midiSerial.read();
    int velocityByte = midiSerial.read();
    midiSerial.write( commandByte);
    midiSerial.write( noteByte);
    midiSerial.write( velocityByte);
    velnew = velocityByte * 8; }

  {  long total =  cs_7_2.capacitiveSensor(30);

    if (total <= 74) {
      motorControl(); }

    else {
      stopMotor(); } } }

void motorControl() {
  int sensorValue = analogRead(A0);

  if (sensorValue <= velnew - 5) {
    moveMotorUp(); }
    
  if (sensorValue >= velnew + 5) {
    moveMotorDown();}
    
  if (sensorValue == velnew) {
    stopMotor(); } }

void moveMotorUp() {
  while (counter != ?){
    digitalWrite(dir1PinA, LOW);
    digitalWrite(dir2PinA, HIGH);
  }
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
  delay(1); }

void moveMotorDown() {
  digitalWrite(dir1PinA, HIGH);
  digitalWrite(dir2PinA, LOW);
  delay(1);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
  delay(1); }

void stopMotor() {
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW); }

Thanks for that - It seems that this makes the motor turn in one direction constantly (up).

I'll try adding that to the rest of the code to see what happens though

No luck there either. adding that same 'while' line to the "moveMotorDown" section of the code simply makes the motor stop moving altogether

Hi,
Try changing all those while loops to if loops. That might work.

Hi,
What model Arduino are you using.

#define RXPIN 8
#define TXPIN 1

You are using pin1, in some Arduino models pin1 and pin0 are the UART programming pins and for the IDE serial monitor.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Hi, I'm using an UNO.

I'll try reworking it a bit based on your replies.

Thanks!

Hi again,

I switched TXPIN to Arduino pin 9. I didn't notice any performance difference, but with this Arduino it's probably better this way.

I switched to 'if' but I found that the motor still only moves in one direction with that code as is.

Thanks for the info!

Hi,
Maybe try this:

#include <AltSoftSerial.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
AltSoftSerial midiSerial;

#define RXPIN 8
#define TXPIN 9
const int dir1PinA = 5;
const int dir2PinA = 6;
int faderValue = analogRead(A0);
int velnew;
int counter=0;

CapacitiveSensor cs_7_2 = CapacitiveSensor(7, 2);

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  cs_7_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  analogRead(faderValue);
  analogWrite(3, 255);
  MIDI.begin(MIDI_CHANNEL_OMNI); }

void loop() {
  counter++;
  
  int touchSensorLow = digitalRead(7);
  int touchSensorHigh = digitalRead(2);

  while ( midiSerial.available() > 2 ) {
    int commandByte = midiSerial.read();
    int noteByte = midiSerial.read();
    int velocityByte = midiSerial.read();
    midiSerial.write( commandByte);
    midiSerial.write( noteByte);
    midiSerial.write( velocityByte);
    velnew = velocityByte * 8; }

  {  long total =  cs_7_2.capacitiveSensor(30);

    if (total <= 74) {
      motorControl(); }

    else {
      stopMotor(); } } }

void motorControl() {
  int sensorValue = analogRead(A0);

  if (sensorValue <= velnew - 5) {
    moveMotorUp(); }
    
  if (sensorValue >= velnew + 5) {
    moveMotorDown();}
    
  if (sensorValue == velnew) {
    stopMotor(); } }

void moveMotorUp() {
  if (counter <= ?){
    digitalWrite(dir1PinA, LOW);
    digitalWrite(dir2PinA, HIGH);
    if (counter > ?){
      counter=0;
    }
  }
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
}

void moveMotorDown() {
  if (counter <= ?){
    digitalWrite(dir1PinA, HIGH);
    digitalWrite(dir2PinA, LOW);
    if (counter > ?){
      counter=0;
    }
  }
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW);
}

void stopMotor() {
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW); }

what type of DC motor?.... amps, voltage, drivers? hardware image?

It's a Motorized Fader by Alps. B10k, 500mA (I believe), 10V.

I'm using a L298N motor driver for this.

Here's an image of the fader I'm using:

This thread is a good example of why you should never make assumptions and then act upon them. It’s unclear what your project is intended to do but one thing is very clear, you cannot solve a problem that has not been defined.

What is apparent from your (original) code is that you turn on a motor, in a given direction for 0.001 seconds and then turn it off. If some analog value is less than or equal to some unexplained magic number with a value of 74, you repeat the process. A motor simply cannot work well with that scheme.

Recently, you’ve edited your original code posting, removing any continuity in the thread and now making things even harder for people to understand and help.

You need to follow the best practices thread that is a sticky post at the top of every forum category that explains how to get the best help possible. This involves explaining in detail what your project is supposed to do and what it doesn’t do. Also required is a proper schematic so we can see what and how parts are connected together. This would include links to the motor(s) used and their drivers.

As things currently stand, no one can help you solve your problem because the problem is not understood, only vaguely described. The attempts to resolve the problem so far amount to nothing more than to throw crap at a wall in the hope that some of it may stick. It’s a waste of everyone’s time and will just frustrate you in the end.

Please take a step back and document your project. An explanation, a schematic and your code are required. So far, we’ve got about 1.5 out of 3. Halfway there. It’s a good start.

Hardware:

The MIDI In/Out each have a bit of circuitry to get them connected, those have been tested and are working fine.

I'm using a MIDI cable to connect my keyboard to my Arduino, and my Arduino to a Focusrite Scarlett interface, which is then connected to my laptop.

At the moment, I don't have a schematic, but my Arduino is hooked up according to the fritzing diagrams I found online. Mainly, it's just a couple of resistors (220 ohm) on the output MIDI jack, a 6N138 optocoupler IC chip, and 2 more 220 ohm resistors.

The motorized fader has the following components:

  • B10k Potentiometer (connected to A0 on my Arduino)
  • 10v DC Motor (connected to digital pins 5 and 6 on my Arduino)
  • Capacitive Touch Sensor (connected to pins 7 and 2 via a 1M resistor)
  • MIDI to USB cable (miO)

The 'Magic Number' you referred to is the level of total capacitance that is idling in my circuit. While hardly being magical as you've described it, this value is important because I'm using a capacitive touch sensor on the fader. When I measure the amount that is going into my variable named 'total', I get a number between 1 and 74, ergo when I'm NOT touching my fader, the number for 'total' will be below 74. When I am touching it, the total capacitance goes above 74, and my motor stops trying to adjust itself back to the position set by any incoming MIDI data.

Hope this helps with the documentation!

If I can provide any more info (other than a schematic) please let me know.

Still looking for a way to replace the delay in my code. I'll try adding a timer again today.

Also, I promise not to edit my posts so substantially as to remove continuity. I do often make edits to reword things so they're slightly easier to understand, or to fix the occasional typo, my apologies for the inconvenience.

Thanks again for your responses! Looking forward to getting this thing up and running. It's so close!

Edit 1 - Added links
Edit 2 - Added paragraph regarding post editing
Edit 3 - Added this list of edits
*Edit 4 - Added resistance/voltage information and info on MIDI cables

I started with this tutorial to get my MIDI Input/Output up and running:
https://www.limulo.net/website/coding/physical-computing/midi-interface.html

Here are images of the fritzing diagram as well as a schematic of my MIDI connections. Note, that this does NOT represent my Motorized Fader. I'll make a diagram for that as well.


I also used this tutorial to get my motorized fader up and running, though I used digital pins 5 and 6 in my code, rather than 6 and 7 as shown in this diagram:
https://hhayley.com/2018/02/25/timotorized-potentiometer-h-bridgel293le/

Fritzing Diagram - Motorized Fader

Edit 1: Fixed spelling on the word "Fritzing"
Edit 2: added text ", though I used digital pins 5 and 6 in my code, rather than 6 and 7 as shown in this diagram"

I've reworked the code a bit today - Here's the latest revision. I've taken out the delay entirely, but my motor is still a bit buggy. I was able to get it to move around with my DAW though (Ableton 9 Standard), so I was pretty happy about that.

#include <AltSoftSerial.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
AltSoftSerial midiSerial;

#define RXPIN 8
#define TXPIN 1
const int dir1PinA = 5;
const int dir2PinA = 6;
int faderValue = analogRead(A0);
int velnew;
byte motorSpeed = 100; // Raise if the fader is too slow (0-255)
byte minimumCp = 205; // Raise if the fader is too sensitive (0-1023)
byte tolerance = 10; // Raise if the fader is too shaky (0-1023)

CapacitiveSensor cs_7_2 = CapacitiveSensor(7, 2);

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  cs_7_2.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  while (!Serial);
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  analogRead(faderValue);
  analogWrite(3, motorSpeed);
  MIDI.begin(MIDI_CHANNEL_OMNI); }

void loop() {
  int faderPos = analogRead(A0);
  int faderMIDI = faderPos / 8;

  while ( midiSerial.available() > 0 ) {
    int commandByte = midiSerial.read();
    int noteByte = midiSerial.read();
    int velocityByte = midiSerial.read();
    midiSerial.write( commandByte);
    midiSerial.write( noteByte);
    midiSerial.write( velocityByte);
    velnew = velocityByte * 8; }

  { long totalCp =  cs_7_2.capacitiveSensor(30);
  
    if (totalCp <= minimumCp) {
      motorControl(); }
    else {
      MIDI.sendControlChange(36, faderMIDI, 16); // Pitch: 36, Data: Controlled by fader Channel: 16)
      stopMotor(); } } }

void motorControl() {
  int sensorValue = analogRead(A0);
  
  if (sensorValue <= velnew - tolerance) {
    moveMotorUp(); }
  if (sensorValue >= velnew + tolerance) {
    moveMotorDown(); }
  if (sensorValue == velnew) {
    stopMotor(); } }

void moveMotorUp() {
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, HIGH); }

void moveMotorDown() {
  digitalWrite(dir1PinA, HIGH);
  digitalWrite(dir2PinA, LOW); }

void stopMotor() {
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, LOW); }