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

Thread: Teensy 3.2 joystick with rotary encoders

  1. #1
    Member
    Join Date
    Mar 2014
    Location
    Valencia
    Posts
    58

    Teensy 3.2 joystick with rotary encoders

    Hello everybody

    I am using a rotary encoder ( http://www.ebay.es/itm/172178149195 )

    And i have some questions for my sketch (I use Joystick button usb - USB TYPE Serial/Keyb/Mouse/Joystick).

    I would like that each clockwise turn, activate the button 5, and each counterclockwise, button 6.

    But not always works.

    Which would be better way?

    Thanks in advance.

    Code:
    #include <Encoder.h>
    
    
    void setup() {
      Serial.begin(9600);
    }
    
    long oldPosition  = -999;
    
    void loop() {
      long newPosition = myEnc.read();
    
      if (newPosition != oldPosition) {
    
              if( newPosition % 4 == 0) {     //for each 4 positions of encoder)
    
                    if (newPosition > oldPosition){
                         Serial.print(newPosition);
                         Serial.println(" - Left");
                         Joystick.Button(5,1);
                         Joystick.Button(6,0);
                     } 
    
                     else {
                          Serial.print(newPosition);
                          Serial.println(" - Right");
                         Joystick.Button(5,0);
                         Joystick.Button(6,1);
                     }
               }
               oldPosition = newPosition;
               
      } else {   //encoder same position
               Joystick.Button(5,0);
               Joystick.Button(6,0);
       }
    
    Joystick.send_now();
    delay(4);
    
    
    }
    Last edited by carcaes1; 08-29-2016 at 05:33 PM.

  2. #2
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,932
    Check your actual encoder position values but first guess is that sometimes the encoder is skipping very quickly across two values and your code will miss checks if the encoder crosses through a %4 position in the 4ms wait time.

  3. #3
    Member
    Join Date
    Mar 2014
    Location
    Valencia
    Posts
    58
    Quote Originally Posted by GremlinWrangler View Post
    Check your actual encoder position values but first guess is that sometimes the encoder is skipping very quickly across two values and your code will miss checks if the encoder crosses through a %4 position in the 4ms wait time.
    Thanks

    I have tried without delay(4 ms) and still fails sometimes.


    Code:
    #include <Encoder.h>
    
    
    void setup() {
      Serial.begin(9600);
    }
    
    long oldPosition  = -999;
    
    void loop() {
      long newPosition = myEnc.read();
    
      if (newPosition != oldPosition) {
    
              if( newPosition % 4 == 0) {     //for each 4 positions of encoder)
    
                    if (newPosition > oldPosition){
                         Serial.print(newPosition);
                         Serial.println(" - Left");
                         Joystick.Button(5,1);
                         Joystick.Button(6,0);
                     } 
    
                     else {
                          Serial.print(newPosition);
                          Serial.println(" - Right");
                         Joystick.Button(5,0);
                         Joystick.Button(6,1);
                     }
               }
               oldPosition = newPosition;
               
      } else {   //encoder same position
               Joystick.Button(5,0);
               Joystick.Button(6,0);
       }
    
    Joystick.send_now();
    
    
    
    }

  4. #4
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,932
    Stripping the delay may still allow double counts if your encoder has detents that do not match the actual contacts internally. Problem remains that your code will not trigger unless you exactly hit a multiple of four.
    Try
    if (newPosition-oldPosition>1) Serial.println("double Count"
    after the newpos!=oldpos line, will only trigger in + direction of rotation but will tell you if things are amiss.

    If this is what is happening then the fix needs to be some slightly more complex math detecting when you are more than 4 from the value you last toggled the button at, or having interupt driven code that tries to catch high speed transitions reliably.

    If you aren't getting double counts then things are more mysterious but not seeing anything wrong with your code.

  5. #5
    Member
    Join Date
    Mar 2014
    Location
    Valencia
    Posts
    58
    Thanks!!! I will test it.

  6. #6
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    What are your actual symptoms of "not always works"?

    What kind of code did you post? It can't be your real test code, "myEnc" is not declared and Joystick.Button() is a non-existing function, only Joystick.button() exists.

    Your code doesn't account for contact bouncing, multiple button presses may be triggered or the direction may be wrong.

    E.g. a test sketch:
    Code:
    #include <Encoder.h>
    
    Encoder enc(6, 7);
    uint32_t enc_prev_change_time = 0;
    
    void setup() {
      Serial.begin(9600);
    }
    
    int32_t old_pos  = 0;
    
    void loop() {
      int32_t new_pos = enc.read();
      if (new_pos != old_pos) {
        uint32_t enc_change_time = millis();
        if(abs(new_pos - old_pos) > 1) Serial.print("ERROR: large encoder change. ");
        Serial.print(millis());
        Serial.print(": ");
        Serial.print(new_pos);
        if(enc_change_time - enc_prev_change_time <= 3) Serial.println("   Encoder bouncing!");
        else Serial.println("");
        enc_prev_change_time = enc_change_time;
        old_pos = new_pos;
      }
    }
    Slowly rotating the encoder, output (output is [time in milliseconds, encoder value, possible bounce warning]):
    [...]
    12639: 15
    12659: 16
    13002: 17
    13003: 16 Encoder bouncing!
    13003: 17 Encoder bouncing!
    13003: 16 Encoder bouncing!
    13004: 17 Encoder bouncing!
    13004: 16 Encoder bouncing!
    13004: 17 Encoder bouncing!
    13004: 16 Encoder bouncing!
    13004: 17 Encoder bouncing!
    13020: 18
    13709: 19

  7. #7
    Member
    Join Date
    Mar 2014
    Location
    Valencia
    Posts
    58
    Hi tni

    Yes, you are right. In my code i have these changes

    Encoder myEnc(5, 6);

    And Joystick.button()

    Sorry, but i had to write it in that post.

    The fail is that sometimes, when i move clockwise the encoder, the position (number) is the same. Maybe in 10 movements, 2 mistakes. And similar in counterclockwise.

    I will test your code. Thanks a lot.


    Code:
    #include <Encoder.h>
    
    Encoder myEnc(5, 6);
    
    void setup() {
      Serial.begin(9600);
    }
    
    long oldPosition  = -999;
    
    void loop() {
      long newPosition = myEnc.read();
    
      if (newPosition != oldPosition) {
    
              if( newPosition % 4 == 0) {     //for each 4 positions of encoder)
    
                    if (newPosition > oldPosition){
                         Serial.print(newPosition);
                         Serial.println(" - Left");
                         Joystick.button(5,1);
                         Joystick.button(6,0);
                     } 
    
                     else {
                          Serial.print(newPosition);
                          Serial.println(" - Right");
                          Joystick.button(5,0);
                          Joystick.button(6,1);
                     }
               }
               oldPosition = newPosition;
               
      } else {   //encoder same position
               Joystick.button(5,0);
               Joystick.button(6,0);
       }
    
    Joystick.send_now();
    
    
    
    }
    Last edited by carcaes1; 08-30-2016 at 09:49 PM.

  8. #8
    Member
    Join Date
    Mar 2014
    Location
    Valencia
    Posts
    58
    Hi again

    Finally, i bought this rotary

    http://www.leobodnar.com/shop/index....roducts_id=242

    and works perfectly with some changes in code!!!!

    But with other rotaries cheaper, fails. So it depends of the rotary.

    Regards

    Regards

Posting Permissions

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