Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 20 of 20

Thread: Teensy 3.6 controlled motorfader panel

  1. #1
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84

    Teensy 3.6 controlled motorfader panel

    Using a Teensy 3.6 to control 8 ALPS motorfaders:



    L293B H-bridges are used to drive the motors. The fader wipers and touchtracks are connected directly to the Teensy. Each faders has it's own PID control using 12 bit PWM at 14648.437 Hz. The ResponsiveAnalogRead library is used for the analog inputs, notice how stable the values are. Separate timers are used for the analogRead and touchRead:
    Code:
    elapsedMicros sinceFaderRead;                         // timer for fader check
    unsigned int  faderReadInterval=500;                  // interval in microseconds for checking fader position(update)
    elapsedMicros sinceTouchRead;                         // timer for touch read
    unsigned int  touchReadInterval=5000;                 // interval in microseconds for reading fader touch
    A second Teensy is reading the values from the faders via I2C and shows the raw values on the LED displays using the LedDisplay library.

    Fader panel bottom view:

    Click image for larger version. 

Name:	Zeus-SPS-8-fader-panel.jpg 
Views:	245 
Size:	164.8 KB 
ID:	9884

    The plan is to create a MIDI step & pattern sequencer with presets and this is an important first step. The code will of course be available when finished, in the meantime I'll be happy to provide snippets if somebody is interested.
    A very big Thank You to everybody involved with the Teensy, Arduino and the great libraries that are available!

    Kind regards,

    Gerrit

  2. #2
    Junior Member
    Join Date
    Jan 2017
    Posts
    7
    Hello,

    can you give us the complete Sketch? I need this functions for my project... Thanks

  3. #3
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by uezi View Post
    Hello,

    can you give us the complete Sketch? I need this functions for my project... Thanks
    As I said, the code is not finished. It is full of debugging stuff, parts of examples and half-baked ideas so I'd rather not publish it as is.

    What functions do you need and what is the context? Maybe I can provide pieces of code or functions. I'm currently working on controlling the panel via I2C commands, I still need to figure out want kind of little protocol I need (I'm using the advanced examples from the new I2C lib as a starting point) to be able to implement the functionality I want.
    What you see in the video is what I call 'link mode', all untouched faders follow the one that is touched. This now works only for this panel but should work for multiple panels. The other function would be a simple preset recall. Based on my experiments it seems like a good idea to implement variable PID tuning for supporting these two different operating modes. As soon as I have figured this out and got it working I will publish the code.

    Kind regards,

    Gerrit

  4. #4
    Junior Member
    Join Date
    Jan 2017
    Posts
    7
    Thanks for your quick reply.

    I search a solution to controll my fader like this Youtube Video



    Later, I would like to replace the potentiometer with a readout value of 0-1023. But first I need it like this video.

    I have the same H-Bridge like you.

    I have connect it like this picture:
    Click image for larger version. 

Name:	Motorfader-Arduino-Schaltung.jpg 
Views:	168 
Size:	79.5 KB 
ID:	9889

    And I used this sketch...

    Code:
    
    // pins
    int motorA = 5;
    int motorB = 6;
    int enablePin = 3;
    int button = 8;
    int poti = 0;
    
    // config
    int target[] = {800, 100, 1000, 0, 500};
    int targetsTotal = 5;
    int theThreshold = 30;
    int movingTimeout = 300;
    long myTime = 0;
    
    // programming stuff
    int buttonState = 0;         // current state of the button
    int lastButtonState = 0;     // previous state of the button
    int currentTarget = 0;
    
    void setup() {
      pinMode(enablePin, OUTPUT);
      pinMode(button, INPUT_PULLUP);
    }
    
    void loop() {
      buttonState = digitalRead(button);
    
      if (buttonState != lastButtonState) {
        if (buttonState == HIGH) {
          currentTarget++;
          if (currentTarget > targetsTotal - 1) currentTarget = 0;
          myTime = millis();      
        }
      }
    
      if (myTime + movingTimeout > millis()) {
        digitalWrite(enablePin, HIGH);
        if (analogRead(poti) > (target[currentTarget] + theThreshold) ) {
          analogWrite(motorA, 255);
          analogWrite(motorB, 0);
        } else if (analogRead(poti) < (target[currentTarget] - theThreshold) ) {
          analogWrite(motorA, 0);
          analogWrite(motorB, 255);
        } else {
          analogWrite(motorA, 0);
          analogWrite(motorB, 0);
        }
      } else {
        digitalWrite(enablePin, LOW);
      }
    
      lastButtonState = buttonState;
    }
    When I Push the button the Fader runs..

    Video to this project:

    https://www.youtube.com/watch?v=GCttn3wnz-Q

    Do you have any ideas how i can do it?

  5. #5
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    I don't understand what your problem is. You say the fader runs, is the issue that it doesn't stop? What Teensy do you use? How many faders do you need to control and what else do you expect it to do?

    I the first video it is explicitly mentioned that no PID control and no PWM were used. It does look a bit jittery to me and I would like to see what happens if the fader has to hit a target at near maximum distance.

    The second video uses a simple approach but the movement is too slow, faders can move much faster but then you run into problems with simple control. Also notice how when the fader is pulled from its positions it flips back with overshoot.

    I based my controller on the code in the article PID without a PhD. In stead of structs I used arrays for the implementation:
    Code:
    // PID arrays
    double dState[8];
    double iState[8];
    double iMin[8];
    double iMax[8];
    double pGain[8];
    double iGain[8];
    double dGain[8];
    double minUpPWM[8];
    double minDownPWM[8];
    double plantDrive[8];
    double maxD=0.00;       // maximum derivative value for debugging purposes
    
    void UpdatePID(int faderIndex, double faderError, double faderPosition)
    {
      double pTerm, dTerm, iTerm, plantDriveInput;
      // calculate the proportional term
      pTerm = pGain[faderIndex] * faderError;   
      // calculate the integral state with appropriate limiting
      iState[faderIndex] += faderError;
      if (iState[faderIndex] > iMax[faderIndex]){
        iState[faderIndex] = iMax[faderIndex];
        }
      else if (iState[faderIndex] < iMin[faderIndex]){
        iState[faderIndex] = iMin[faderIndex];
      }
      iTerm = iGain[faderIndex] * iState[faderIndex];  // calculate the integral term
      dTerm = dGain[faderIndex] * (faderPosition - dState[faderIndex]);
      if (abs(faderPosition - dState[faderIndex]) > maxD){
        maxD=abs(faderPosition - dState[faderIndex]);
      }
      dState[faderIndex] = faderPosition;
    
      plantDriveInput = pTerm + iTerm - dTerm;
      if (plantDriveInput > 4096) {
        plantDriveInput=4096;
      }
        if (plantDriveInput < -4096) {
        plantDriveInput=-4096;
      }
      if (plantDriveInput > 0 && plantDriveInput < minUpPWM[faderIndex]){
        plantDriveInput=0;
      }
      if (plantDriveInput < 0 && -plantDriveInput < minDownPWM[faderIndex]){
        plantDriveInput=0;
      }
      plantDrive[faderIndex]=plantDriveInput;
    }
    The code allows for individual tuning of the PID parameters for each fader. To make use of this I would have to figure out some kind of calibration procedure. The PID parameters are set in the setup routine:
    Code:
      // set PID tuning parameters
      for (int i=0;i<8;i++){
        pGain[i]=20.00;
        iGain[i]=0.5;
        dGain[i]=40.00;
        iMin[i]=-4000;
        iMax[i]=4000;
        minUpPWM[i]=100;
        minDownPWM[i]=100;
      }
    In the main loop the elepasedMicros timer updates the PIDs:

    Code:
      // check elapsedMicros and millis timers
      // faders
      if (sinceFaderRead >=faderReadInterval) {
        sinceFaderRead = sinceFaderRead-faderReadInterval;
        readFaders();
        if (linkMode && faderTouchCount==1) {
          // first set linkValue
          for (int i=0;i<8;i++){
            if (faderTouched[i]){
              linkValue=faderValue[i];
            }
          }
          for (int i=0;i<8;i++){
            UpdatePID(i,linkValue-faderValue[i],faderValue[i]);
          }
          for (int i=0;i<8;i++){
            if (!faderTouched[i]){
              if(plantDrive[i]>0){
                analogWrite(faderMotorDownPin[i],0);
                analogWrite(faderMotorUpPin[i],plantDrive[i]);
              } else if (plantDrive[i] <=0){
                analogWrite(faderMotorUpPin[i],0);
                analogWrite(faderMotorDownPin[i],-plantDrive[i]);
              }
            } 
          }
        } else if(linkMode && faderTouchCount==0){
          for (int i=0;i<8;i++){
            analogWrite(faderMotorDownPin[i],0);
            analogWrite(faderMotorUpPin[i],0);
          }
        }
      }
    Please beware that programming in C is new to me so there's always the chance I made some rookie mistake somewhere and I'm certain the code can be optimised. I also tried the PID library but wasn't able to achieve control. By creating my own implementation based on aforementioned article I got a much better understanding of what PID is about and why/when you need it. The speed and capabilities of the Teensy 3.6 allow for the implementation of sophisticated control so why not do it? Motorfaders are expensive parts so the cost of a Teensy 3.6 is not an issue, at least not in the context of DIY.

    Kind regards,

    Gerrit

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,014
    On Teensy 3.6 only float is done by hardware. Unless you absolutely need the higher precision of double, you can run this code much faster if you change all the double variables to float.

  7. #7
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by PaulStoffregen View Post
    On Teensy 3.6 only float is done by hardware. Unless you absolutely need the higher precision of double, you can run this code much faster if you change all the double variables to float.
    Thanks for the tip, I'll change the code. It could be that even int is sufficient for this purpose, I'd have to try that as I do not have the experience to judge this up front. The setup is almost ready for testing the full I2C communication. After I have this up and running I planned on further tuning the PID parameters.

    Kind regards,

    Gerrit

  8. #8
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    I've got the I2C communication working, here's a video showing the cycling through several preset values. The target values for the faders are 10, 1000, 500 and 550. Large and small steps were deliberately chosen to show the response.



    I think the performance is pretty good, if I dare say so myself, the faders can move very fast and there's practically no overshoot even at high speed. To improve on this I think it will be necessary to come up with a calibration function to adjust the PID tuning for each fader individually.

    On button click a single message of 18 bytes is sent from the master to the panel:

    Code:
    void sendFaderCommand(byte mode){
      size_t idx;
      faderTargetData[16]=0;
      for (int i=0;i<8;i++){
        // split Target integers over two bytes in array
        faderTargetData[(i*2)]=(faderTarget[i] >> 8) & 0xFF;
        faderTargetData[(i*2)+1]=faderTarget[i] & 0xFF;
        // fill last byte in array with faderMove boolean array
        faderTargetData[16] |= faderMove[i] << i;
      }
      // Transmit to Slave
      Wire.beginTransmission(PANEL_ADDR);   // Slave address
      // Send mode
      Wire.write(mode);
      // Send target data
      for(idx = 0; idx <= MESSAGE_LEN; idx++) // Write data to I2C Tx buffer
          Wire.write(faderTargetData[idx]);
      Wire.endTransmission();           // Transmit to Slave
    }
    The first byte sets the operating mode: TARGET or FOLLOW. The intention is to allow for separate PID parameter tuning, now the difference is that with TARGET mode the PID state (integral & derivative) is cleared with each command. The PID control will time-out after the last command.
    I removed the PWM threshold from the PID controller function , introducing a threshold in the control actually interferes with the PID algorithm.

    Here's the complete code for the panel:
    Code:
    /* 
      Zeus Commander Controller Series
      I2C controlled motorfader octet
    
      Full PID motor control supporting two operating modes:
      TARGET  for fast preset recall
      FOLLOW  for slow to fast following of values 
    
      This code expands on the examples provided with the i2c_t3 library for the I2Ccommunication
      
      This code is in the public domain.
    */
    #include <i2c_t3.h>
    #include <ResponsiveAnalogRead.h>
    
    // PID arrays
    float dState[8];
    float iState[8];
    float iMin[8];
    float iMax[8];
    float pGain[8];
    float iGain[8];
    float dGain[8];
    float plantDrive[8];
    float maxD=0.00;       // maximum derivative value for debugging purposes
    
    void UpdatePID(int faderIndex, float faderError, float faderPosition)
    {
      float pTerm, dTerm, iTerm, plantDriveInput;
      // calculate the proportional term
      pTerm = pGain[faderIndex] * faderError;   
      // calculate the integral state with appropriate limiting
      iState[faderIndex] += faderError;
      if (iState[faderIndex] > iMax[faderIndex]){
        iState[faderIndex] = iMax[faderIndex];
        }
      else if (iState[faderIndex] < iMin[faderIndex]){
        iState[faderIndex] = iMin[faderIndex];
      }
      iTerm = iGain[faderIndex] * iState[faderIndex];  // calculate the integral term
      dTerm = dGain[faderIndex] * (faderPosition - dState[faderIndex]);
      if (abs(faderPosition - dState[faderIndex]) > maxD){
        maxD=abs(faderPosition - dState[faderIndex]);
      }
      dState[faderIndex] = faderPosition;
    
      plantDriveInput = pTerm + iTerm - dTerm;
      if (plantDriveInput > 4096) {
        plantDriveInput=4096;
      }
        if (plantDriveInput < -4096) {
        plantDriveInput=-4096;
      }
      plantDrive[faderIndex]=plantDriveInput;
    }
    
    elapsedMicros sinceFaderRead;                         // timer for fader check
    unsigned int  faderReadInterval=1000;                 // interval in microseconds for checking fader position(update)
    elapsedMicros sinceTouchRead;                         // timer for touch read
    unsigned int  touchReadInterval=5000;                 // interval in microseconds for reading fader touch
    elapsedMillis sinceLastCommand;                       // timer for time-out of PIF after last command
    unsigned int  commandTimeOutInterval=500;             // interval for PID time-out in milliseconds
    int     faderWiperPin[8]={32,31,39,20,21,15,65,64};   // analog in pin for fader wipers
    int     faderTouchPin[8]={1,0,16,17,18,19,22,23};     // touchRead pins for fader touch
    int     faderMotorUpPin[8]={29,9,7,5,3,14,36,38};     // motor up PWM pin
    int     faderMotorDownPin[8]={30,10,8,6,4,2,35,37};   // motor down PWM pin
    int     faderValue[8];                                // fader value ranging 0 to 1023
    int     faderTarget[8];                               // fader target value ranging 0 to 1023
    int     faderTouch[8];                                // fader touch reading
    boolean faderPidOn[8];                                // status of PID
    int     faderTouchThreshold=3000;                     // threshold value for touchRead
    boolean faderTouched[8];                              // boolean indicating if fader is touched
    
    ResponsiveAnalogRead analog[8]{ResponsiveAnalogRead(32, true),ResponsiveAnalogRead(31, true),
                                   ResponsiveAnalogRead(39, true),ResponsiveAnalogRead(20, true),
                                   ResponsiveAnalogRead(21, true),ResponsiveAnalogRead(15, true),
                                   ResponsiveAnalogRead(65, true),ResponsiveAnalogRead(64, true)};
    
    // I2C communication
    // Command definitions
    #define TARGET    0x10              // All faders to target value as fast as possible. PID state is cleared with each command.
    #define FOLLOW    0x20              // Faders follow value, last byte in message is used to determine which motors should move.
                                        // PIDs will time-out after last command.
    
    // Function prototypes
    void receiveEvent(size_t count);
    void requestEvent(void);
    #define PANEL_ADDR 0x66              // I2C address, should be selectable by jumper using leftover pins.
    #define MESSAGE_LEN 17
    byte faderValueData[MESSAGE_LEN];    // 16 bytes for values, 1 byte for touch
    byte faderTargetData[MESSAGE_LEN];   // 16 for target values, 1 byte for indicating which faders should be moved.
    volatile uint8_t received;
    volatile uint8_t cmd;
    byte operatingMode = TARGET;
    
    
    void setup()
    {  
      
      //initialize faders and analog reference 
      analogReference(EXTERNAL);
      analogWriteResolution(12);
      for (int i=0; i<8; i++){
        pinMode(faderMotorUpPin[i], OUTPUT);
        pinMode(faderMotorDownPin[i], OUTPUT);
        analogWriteFrequency(faderMotorUpPin[i],14648.437);  // 14648.437 ideal frequency for 180MHz 12bit PWM
        analogWriteFrequency(faderMotorDownPin[i],14648.437);  //14648.437 ideal frequency for 180MHz 12bit PWM
        faderTouched[i]=false;
        faderValueData[i]=0;
        faderTarget[i]=500;
        faderPidOn[i]=false;
      }    
           
      readFaders();
      // set PID tuning parameters
      for (int i=0;i<8;i++){
        pGain[i]=10;
        iGain[i]=1;
        dGain[i]=50.00;
        iMin[i]=-1500;
        iMax[i]=1500;
      }
      
      // Setup for Slave mode pins 33/34, external pullups, 400kHz
      Wire.begin(I2C_SLAVE, PANEL_ADDR, I2C_PINS_33_34, I2C_PULLUP_EXT, 400000);
      // register events
      Wire.onReceive(receiveEvent);
      Wire.onRequest(requestEvent);
      cmd = 0;    // incoming command operating mode
    }
    
    void loop()                     
    {
      // check elapsedMicros and millis timers
      // faders
      if (sinceFaderRead >=faderReadInterval) {
        sinceFaderRead = sinceFaderRead-faderReadInterval;
        readFaders();
        
        // always update PID for timing consistency
        for (int i=0;i<8;i++){
            UpdatePID(i,faderTarget[i]-faderValue[i],faderValue[i]);
          }
          
        // loop through faders and move where necessary
        for (int i=0;i<8;i++){
          if (!faderTouched[i] && faderPidOn[i]){
            if(plantDrive[i]>0 && faderValue[i] <=1022){
              analogWrite(faderMotorDownPin[i],0);
              analogWrite(faderMotorUpPin[i],plantDrive[i]);
            } else if (plantDrive[i] <=0 && faderValue[i] >=1){
              analogWrite(faderMotorUpPin[i],0);
              analogWrite(faderMotorDownPin[i],-plantDrive[i]);
            }
          } 
          else if(!faderPidOn[i]){
              analogWrite(faderMotorDownPin[i],0);
              analogWrite(faderMotorUpPin[i],0);
            }
        }
      }
      
      //  separate touchRead timer 
      if (sinceTouchRead >= touchReadInterval){
        sinceTouchRead = sinceTouchRead - touchReadInterval;
        readTouch();
      }
      
      // command time-out  
      if (sinceLastCommand >= commandTimeOutInterval){
        for (int i=0;i<8;i++){
          faderPidOn[i]=false;
        }
        sinceLastCommand = 0;
      }
      
    }
    
    // read fader analog values and update faderValue array
    void readFaders() {
      for (int i=0; i<8; i++) {
        analog[i].update();
        faderValue[i] = analog[i].getValue();
      } 
    }
    
    // read fader touch
    void readTouch() {
      for (int i=0; i<8; i++) {
        faderTouch[i]= touchRead(faderTouchPin[i]);
        if (faderTouch[i]>faderTouchThreshold){
          faderTouched[i]=true;
        } else if (faderTouch[i]<=faderTouchThreshold){
          faderTouched[i]=false;
        }
      } 
    }
    
    // handle Rx Event (incoming I2C data)
    void receiveEvent(size_t count) {
      size_t idx;
      int incomingTargetValue[8];
      boolean incomingFaderMove[8];
      if(count)
      {
        // grab command
        cmd = Wire.readByte();
        switch(cmd)
        {
        case TARGET:
          if (operatingMode==FOLLOW){
            // set PID tuning parameters
    //        for (int i=0;i<8;i++){
    //          pGain[i]=20.00;
    //          iGain[i]=0.5;
    //          dGain[i]=40.00;
    //        }
            operatingMode=TARGET;
          }
          break;
        case FOLLOW:
          if (operatingMode==TARGET){
            // set PID tuning parameters
    //        for (int i=0;i<8;i++){
    //          pGain[i]=20.00;
    //          iGain[i]=0.5;
    //          dGain[i]=40.00;
    //        }
            operatingMode=FOLLOW;
          }
          break;
        }
        idx = 0;
        while(Wire.available()) faderTargetData[idx++] = Wire.readByte();
              
        // Process data
        for (int i=0;i<8;i++){
          // combine bytes back to integers and put in temporary array
          incomingTargetValue[i]= faderTargetData[(i*2)];
          incomingTargetValue[i]= incomingTargetValue[i] << 8 | faderTargetData[(i*2)+1];
          // fill faderPidOn boolean array with last byte
          incomingFaderMove[i] = 1 & faderTargetData[16] >> i;
          // clear PID states if PID is switched on or if mode is TARGET
          if ((incomingFaderMove[i] && faderPidOn[i]!=incomingFaderMove[i]) || operatingMode==TARGET){
            dState[i]=faderValue[i]; 
            iState[i]=0; 
          }
          faderPidOn[i]=  incomingFaderMove[i];
          // update fader target
          faderTarget[i]=incomingTargetValue[i];
        }
        // reset timer
        sinceLastCommand=0;
      }
    }
    
    // handle Tx Event (outgoing I2C data)
    void requestEvent(void)
    {
      faderValueData[16]=0;
      for (int i=0;i<8;i++){
        // split value integers over two bytes in array
        faderValueData[(i*2)]=(faderValue[i] >> 8) & 0xFF;
        faderValueData[(i*2)+1]=faderValue[i] & 0xFF;
        // fill last byte in array with touch boolean array
        faderValueData[16] |= faderTouched[i] << i;
      }
      Wire.write(faderValueData, MESSAGE_LEN); // fill Tx buffer (send full mem)
    }
    Next up is the implementation of FOLLOW mode over I2C, this should not require any changes to the panel code other than PID tuning.

    Any suggestions for improvements are very much appreciated.

    Kind regards,

    Gerrit

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    17,014
    Quote Originally Posted by Gerrit View Post
    Thanks for the tip, I'll change the code. It could be that even int is sufficient for this purpose, I'd have to try that as I do not have the experience to judge this up front.
    On Teensy 3.5 & 3.6, float and integers are approximately the same speed. Only double is slow.

    There are some ways for integer math to be significantly faster, but they involve extremely difficult optimization techniques. Usually that level of effort isn't worthwhile except for special signal processing libraries.

  10. #10
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by PaulStoffregen View Post
    On Teensy 3.5 & 3.6, float and integers are approximately the same speed. Only double is slow.

    There are some ways for integer math to be significantly faster, but they involve extremely difficult optimization techniques. Usually that level of effort isn't worthwhile except for special signal processing libraries.
    Thank you, good to know.

    King regards,

    Gerrit

  11. #11
    Junior Member
    Join Date
    Mar 2017
    Posts
    3
    Hello,
    I try to build a surface contrôle with motorfader.
    Can you post the schematic of your circuit, it will help me.
    Thanks

  12. #12
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by Dreuf View Post
    Hello,
    I try to build a surface contrôle with motorfader.
    Can you post the schematic of your circuit, it will help me.
    Thanks
    To drive the motors I used a L293B chip and implemented the schematic in the datasheet:

    Click image for larger version. 

Name:	L293B-schematic.png 
Views:	76 
Size:	83.9 KB 
ID:	9924

    You have to copy the schematic on the left side to the right. I used 1N4007 diodes, which probably overkill, which I had a bunch of. As you can see in an earlier post everything is build on stripboard so there is no schematic of the whole thing. The connection are shown in this pinout diagram:

    Click image for larger version. 

Name:	MotorfaderPanelTeensy.jpg 
Views:	143 
Size:	144.3 KB 
ID:	9925

    As an external voltage reference I used an AD780, this is definitely overkill but it was the only one I could find that would put out 3V, work with 5V and was through hole. The external reference may not be necessary but I thought it was better to be safe than sorry. The AD780 is connected as shown in the datasheet:

    Click image for larger version. 

Name:	AD780-schematic.png 
Views:	106 
Size:	35.5 KB 
ID:	9926

    I build this panel for use in a, yet to develop, midi sequencer because as far as I know such a device does not exist. If you're building a standard DAW controller surface, I would think twice before starting such a project. It will be next to impossible to build something for less than what is commercially available.

    Kind regards,

    Gerrit

  13. #13
    Junior Member
    Join Date
    Mar 2017
    Posts
    3
    Thank you for the quick reply.
    I dont want to make a complete DAW, just motorfaders and some buttons, just for fun.
    I never used external voltage reference before, you connect the AD780's Vout to Teensy AREF and to the + pin of the fader ?
    Do you connect AGND to GND ?
    Last question :
    What power supply do you use ? for motors and Teensy ?

    Thank you !

  14. #14
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by Dreuf View Post
    Thank you for the quick reply.
    I dont want to make a complete DAW, just motorfaders and some buttons, just for fun.
    I never used external voltage reference before, you connect the AD780's Vout to Teensy AREF and to the + pin of the fader ?
    Do you connect AGND to GND ?
    Last question :
    What power supply do you use ? for motors and Teensy ?

    Thank you !
    Just for fun is a perfectly valid reason as far as I'm concerned

    As for your questions:

    Yes, the AD780 out is connected to the Teensy AREF and + pin of the fader. Remember to first set the reference to external in your code before connecting the external reference.
    Yes, AGND is connected to GND

    I use a 10V 50W supply for the faders and a 5V supply for the Teensy (DC-DC converter of the 10V supply). I did not yet check the power supply lines with a scope to see if there's any interference, it could be a good idea to use a completely separate 5V supply for the Teensy. I measured a peak current of just under 4A when all 8 faders start moving at full speed.

    Kind regards,

    Gerrit

  15. #15
    Junior Member
    Join Date
    Mar 2017
    Posts
    3
    Thank you very much !

    Fred

  16. #16
    Junior Member
    Join Date
    Nov 2017
    Posts
    4
    I am working on a similar project and this is very helpful. I am fairly new to Arduino and have yet to use teensy and have extensive C/C++ experience. But in reading the code listed above I understand it pretty well but am confused by the analog input pins used. The code indicates fader 5 wiper is pin 21 , fader 6 wiper is 15 OK. But fader 7 is pin 65 and fader 8 is pin 64. The pin diagram shows fader 7 on pin 21 which is also fader 5. Fader wiper 8 is pin 64 but the diagrams says fader 8 is pin 22 which is touch 7.

    It looks to me like pin 22 and 23 are dual use but you do not specify any external logic to manage this. How can you connect 2 faders to the same pin or a touch and fader to one pin?

    Maybe this is me being a teensy newbe, but how does software pin 64 and 65 map to physical pin 22 and 21?

    Thanks,
    Mark

  17. #17
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by mark.winger View Post
    I am working on a similar project and this is very helpful. I am fairly new to Arduino and have yet to use teensy and have extensive C/C++ experience. But in reading the code listed above I understand it pretty well but am confused by the analog input pins used. The code indicates fader 5 wiper is pin 21 , fader 6 wiper is 15 OK. But fader 7 is pin 65 and fader 8 is pin 64. The pin diagram shows fader 7 on pin 21 which is also fader 5. Fader wiper 8 is pin 64 but the diagrams says fader 8 is pin 22 which is touch 7.

    It looks to me like pin 22 and 23 are dual use but you do not specify any external logic to manage this. How can you connect 2 faders to the same pin or a touch and fader to one pin?

    Maybe this is me being a teensy newbe, but how does software pin 64 and 65 map to physical pin 22 and 21?

    Thanks,
    Mark
    Fader 7 and 8 in the diagram refer to the inner pins on the teensy next to the ones on the edge (22 and 21), these inner pins have number 65 and 64.

    Kind regards,

    Gerrit

  18. #18
    Junior Member
    Join Date
    Nov 2017
    Posts
    4
    Quote Originally Posted by Gerrit View Post
    Fader 7 and 8 in the diagram refer to the inner pins on the teensy next to the ones on the edge (22 and 21), these inner pins have number 65 and 64.

    Kind regards,

    Gerrit
    Thanks Gerrit. Been away for a while and am not working on this again. I am using motorized faders removed from a tascam dm-24. Not sure what they are. I decided to us a teensy 3.5 but I want to control more faders so I am using a PCA9685 pulse with modulator board running on the i2s bus. Each board controls 16 pwm pins. I plan on controlling 20 faders on a single teensy(without touch) with 3 of these boards daisy chained . Initial testing and initial pid tuning looks good - sending midi over usb both ways with 1 fader.

    My final project I plan on having 34 faders with 4 buttons with leds on each (total of 128 buttons and 128 leds) using 2 teensies. I will update occasionally as I make progress.

    Mark

  19. #19
    Member
    Join Date
    Jan 2017
    Location
    Maastricht
    Posts
    84
    Quote Originally Posted by mark.winger View Post
    Thanks Gerrit. Been away for a while and am not working on this again. I am using motorized faders removed from a tascam dm-24. Not sure what they are. I decided to us a teensy 3.5 but I want to control more faders so I am using a PCA9685 pulse with modulator board running on the i2s bus. Each board controls 16 pwm pins. I plan on controlling 20 faders on a single teensy(without touch) with 3 of these boards daisy chained . Initial testing and initial pid tuning looks good - sending midi over usb both ways with 1 fader.

    My final project I plan on having 34 faders with 4 buttons with leds on each (total of 128 buttons and 128 leds) using 2 teensies. I will update occasionally as I make progress.

    Mark
    That's an elaborate setup. Are you sure you can do without touch sensing? How are you going to prevent the fader working against the user? Also I find it important to be able to set a value without moving the fader.

    I'm currently working on my DAW plugin controller. The motor faders are on the back-burner for now, I will get back to that when my I finished the controller.

    Kind regards,

    Gerrit

  20. #20
    Junior Member
    Join Date
    Nov 2017
    Posts
    4
    I may add touch in the future. But I will be using the this for live mixing console that does not need automation. Motor faders will be used for total recall of snap shots and for switching between fader layers. I have used Tascam DM-24 (touch sensitive), Yamaha Promix-01(not touch sensitive) and Behringer BCF2000(not touch sensitive) as control surfaces for this and touch sensitivity was never an issue either way. Now if I decide to use time code synchronization for complex shows or use it as a DAW I will definitely need it. But for now it does not matter.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •