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…
running pd+arduino

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();
}

