MOTORFADER control surface – test-

fabians diy control surface (like mackie control, steinberg cc121) for DAWs (Cubase,…) with motorfader, status leds, buttons …

arduino controlling the buttons, leds and the motorfader, pure data managing arduino/software communication

read more…this project is still work in progress…

motorfader diy

running pd+arduino

arduino pd motorfader

code is part of music controller projekt by Fabian

Motorfader controlled by IC l293d

code by our great Jakob Scheid

arduino code:

//************************* MotorFader
//Kommandos ueber die serielle Schnittstelle (serial-USB):
//a.) Kommando 255: lies die FaderPosition und sende den Wert an den PC
//b.) Kommando 160 + (0 bis 31): veraendert den Wert von Kp (Verstaerkungsfaktor)
//c.) Kommando 128 + (0 bis 31): veraendert den Wert von MinSpeed (Mindestdrehzahl des Motors)
//d.) Kommando 0 bis 127: FaderPosition veraendern. Der Motor fahrt zum Faderwert 0 bis 127

//Funktinen deklarieren:
void establishContact(void);
inline void moveMotor(byte);

//globale Konstaten deklarieren und initialisieren:
#define pwmPin 9
#define dirPin 8
#define Taste_0 2
#define Taste_1 3
#define Taste_2 4
#define Taste_12 A1

#define NullTest 8
#define MinSpeed 64
#define Kp 2

//globale Variablen deklarieren und initialisieren:

//int pwmPin = 9; // Motor-Pwm-Ausgang pin 9 -> ist am L293d-Pin Input_2 angeschlossen
//int dirPin = 8; // Motor-Drehrichtung pin8 -> ist am L293d-Pin Input_1 angeschlossen
//byte comValue; //Variable fuer die Kommandos, die ueber die serielle Schnittstelle hereinkommen
//byte MinSpeed = 64; //Voreinstellung fuer Mindestdrehzahl des Motors
//byte Kp = 2; //Voreinstellung fuer Kp (Verstaerkungsfaktor)
//byte NullTest = 50;

//Voreinstellungen fuer die verwendeten Pins des Arduinoboards:
void setup() {
pinMode(Taste_0, INPUT);
digitalWrite(Taste_0, HIGH); //interner pullup ON
pinMode(Taste_1, INPUT);
digitalWrite(Taste_1, HIGH); //interner pullup ON
pinMode(Taste_2, INPUT);
digitalWrite(Taste_2, HIGH); //interner pullup ON
pinMode(Taste_12, INPUT);
digitalWrite(Taste_12, HIGH); //interner pullup ON

pinMode(dirPin, OUTPUT); // Motor-Drehrichtung pin8 ist ein digitaler Ausgang
digitalWrite(dirPin, LOW); // Motor-Drehrichtung = LOW -> Uhrzeigersinn
analogWrite(pwmPin, 0); // Motordrehzahl = 0 -> stillstand
Serial.begin(19200); // Einstellung fuer die serielle Schnittstelle (serial-USB)
establishContact(); // Aufruf der Funktion: establishContact (siehe unten (nicht sehr wichtig))
}

//Hauptfunktion des Programms (hier beginnt das eigentliche Programm)
void loop()
{
byte comValue;
// delay(30);

if(Serial.available() > 0) //wenn ein Byte ueber die serielle Schnittstelle hereingekommen ist, mache Folgendes:
{
comValue = Serial.read(); //lies das Byte und kopiere es in die Variable comValue

if(bitRead(comValue,7)) //wenn das 7.Bit von comValue ein Einser ist (1xxxxxxx), mache Folgendes:
{
switch(comValue & B11100000) //analysiere comValue (die ersten 3 Bits bestimmen das jeweilige Kommando)
{
// //veraendert den Wert von MinSpeed (Mindestdrehzahl des Motors)
// case B10000000: //Kommando = 128
// NullTest = comValue & B00011111;
// NullTest = NullTest << 3;
// Serial.write(NullTest);
// break;
//
// //veraendert den Wert von Kp (Verstaerkungsfaktor)
// case B10100000: //Kommando = 160
// Kp = comValue & B00011111;
// Serial.write(Kp);
// break;

//schicke TastenStatus
case B11000000: //Kommando = 192
int TastStat;
TastStat = 0;
TastStat |= ((int)digitalRead(Taste_1)) << 1;
TastStat |= ((int)digitalRead(Taste_2)) << 2;
TastStat |= ((int)digitalRead(Taste_1)) << 8;
TastStat |= ((int)digitalRead(Taste_12)) << 9; Serial.write((byte)TastStat); Serial.write((byte)(TastStat >> 8));
break;

//schicke FaderPosition an PC
case B11100000: //Kommando = 224 (kann auch 224 + x sein, z.b.: 255)
Serial.write((byte)(analogRead(0) >> 3));//(umrechnen der FaderPosition von einem Wert 0 bis 1023 in einen Wert 0 bis 127)
break;
}
}
else //wenn das 7.Bit von comValue KEIN Einser ist (0xxxxxxx), mache Folgendes:
{
moveMotor(comValue); // Aufruf der Funktion: moveMotor (der Parameter comValue bestimmt die Fader-Sollposition)
}
}
}

//Der Motor stellt den Fader auf die Position, die im Parameter b_sollPos angageben ist
inline void moveMotor(byte b_sollPos) //sollPos: 0 bis 127
{
//lokale Variablen deklarieren und initialisieren (die gelten nur fuer diese Funktion):
unsigned int Speed; //MotorSpeed (bestimmt den Dutycycle (die Pwm-OutputFrequenz) am pwmPin (Pin9)
unsigned int istPos; //Variable fuer die momentane FaderPosition
byte err0Counter = 0; //Zaehlervariable (wie oft ist der Fader schon ueber die Zielposition hinausgependelt?)
unsigned int err; //Variable fuer die Differenz zwischen Sollposition und Istposition
unsigned int sollPos = b_sollPos << 3; //umrechnen der sollPosition von einem Wert 0 bis 127 in einen Wert 0 bis 1023

while(err0Counter < NullTest)//70) //wie oft ist der Fader schon ueber die Zielposition hinausgependelt? { //wenn es noch unter 70 mal sind, mache Folgendes: istPos = analogRead(0); //lies die momentane FaderPosition if(sollPos > istPos) //wenn die momentane FaderPosition unterhalb der Sollposition liegt, mache Folgendes:
{
err = sollPos – istPos; //err = die Differenz zwischen Sollposition und Istposition
digitalWrite(dirPin, LOW); // Motor-Drehrichtung = LOW -> im Uhrzeigersinn (weil die momentane FaderPosition unterhalb der Sollposition liegt)
Speed = MinSpeed + (err * Kp); //MotorSpeed: je groesser die Differenz zw. Soll- und Istposition ist, desto hoeher ist die Geschwindigkeit
if(Speed > 255) Speed = 255; //die maximal erlaubte MotorSpeed fuer die Funktion „analogWrite“ ist 255
analogWrite(pwmPin, (byte)Speed); //setze die MotorSpeed (bestimmt den Dutycycle (die Pwm-OutputFrequenz) am pwmPin (Pin9)
} //hier muss der Kehrwert von Speed verwendet werden, weil die Drehrichtung gegen den Uhrzeigersinn lauft

if(sollPos < istPos) //wenn die momentane FaderPosition oberhalb der Sollposition liegt, mache Folgendes: { err = istPos – sollPos; //err = die Differenz zwischen Sollposition und Istposition digitalWrite(dirPin, HIGH); // Motor-Drehrichtung = HIGH -> gegen den Uhrzeigersinn (weil die momentane FaderPosition oberhalb der Sollposition liegt)
Speed = MinSpeed + (err * Kp); //MotorSpeed: je groesser die Differenz zw. Soll- und Istposition ist, desto hoeher ist die Geschwindigkeit
if(Speed > 255) {Speed = 255; } //die maximal erlaubte MotorSpeed fuer die Funktion „analogWrite“ ist 255
analogWrite(pwmPin, 255 – (byte)(Speed) ); //setze die MotorSpeed (bestimmt den Dutycycle (die Pwm-OutputFrequenz) am pwmPin (Pin9)
} //hier muss der Kehrwert von Speed verwendet werden, weil die Drehrichtung gegen den Uhrzeigersinn lauft

if(sollPos == istPos) //Wenn die Differenz zw. Soll- und Istposition gleich 0 ist (Error = 0), mache Folgendes:
{ //Der Fadermotor schiesst ueber das Ziel hinaus und pendelt wieder zurueck
err0Counter++; //bei jedem Pendler wird der Ausschlag kleiner, bis der Motor einigermassen an der sollposition angekommen ist
//diese Pendler werden mit „err0Counter“ gezaehlt. Es wid angenommen, dass der Motor nach 70 Pendlern am Ziel ist
digitalWrite(dirPin, LOW); //setze MotorSpeed auf 0 (weil der Error 0 ist)
analogWrite(pwmPin, 0);
}
}
//der Motor scheint am Ziel (Sollposition) angekommen zu sein. (Er hat 70 mal die Sollpositiom ueberpendelt)
digitalWrite(dirPin, LOW); //setze MotorSpeed endgueltig auf 0
analogWrite(pwmPin, 0);
Serial.write((byte)(analogRead(0) >> 3)); //schicke die Faderposition zur Kontrolle an den PC (es sollte die Sollposition sein)
} //(umrechnen der FaderPosition von einem Wert 0 bis 1023 in einen Wert 0 bis 127)

void establishContact(void)
{
Serial.flush(); //leere den Eingangspuffer (falls da noch ungelesene Bytes herumkugeln)
// char inByte = 0;
delay(2000); //warte 2 Sekunden
// while(inByte != 5)
// {
// Serial.write(5);
// delay(2000);
// if(Serial.available() > 0){
// inByte = Serial.read();}
// }
// Serial.write(10);
Serial.flush();

}

pd Patch