Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 31 of 31

Thread: Teensy 3 Encoder Lib

  1. #26
    Senior Member Wozzy's Avatar
    Join Date
    Jan 2013
    Location
    Philadelphia, Pennsylvania USA
    Posts
    354
    bberger,

    Have a look at this high performance SPI Quadrature decoder chip that I used very successfully in the past.
    One advantage, is that it completely relieves the Micro-controller from monitoring the encoders. When ever you poll it, the current value is there.

    There are several variants, but here is a link to the data sheet for the one I used: http://www.lsicsi.com/pdfs/Data_Sheets/LS7366R.pdf

    The biggest problem, is that they only seem to be available direct from the manufacturer, with a minimum order of 10.

  2. #27
    Junior Member
    Join Date
    Dec 2013
    Posts
    11
    I just bought a Teensy 3.1, and I'm trying to use the interrupt-based Encoder library (with the mods supplied by Paul in post #2). I'm using this on a small robot I'm building, and hooking it up to 2 & 3. I'm using this encoder (http://www.pololu.com/product/2590) hooked up to their 100:1 gearmotor, and hooking it up to my logic analyzer and running the motor direct from a 7.4 volt battery, I'm seeing a very nice square sin wave on both A & B, at about 3.0 kHz each, offset 90 degrees.

    Click image for larger version. 

Name:	Encoder-Logic.png 
Views:	253 
Size:	150.7 KB 
ID:	1237

    I assume this is well within the capabilities of using the interrupt based encoders.

    I had to add the following to direct_pin_read.h (after making the change in post 2):

    Code:
    #if defined(__AVR__) || defined(__MK20DX128__) || defined(__MK20DX256__)
    as I assume the chip on the 3.1 is a __MK20DX256__

    I'm not getting any useful data out of the encoder. I'm using the following code:

    Code:
    /* Encoder Library - Basic Example
     * http://www.pjrc.com/teensy/td_libs_Encoder.html
     *
     * This example code is in the public domain.
     */
    
    #include <Encoder.h>
    
    const int ledPin = 13;
    
    // Change these two numbers to the pins connected to your encoder.
    //   Best Performance: both pins have interrupt capability
    //   Good Performance: only the first pin has interrupt capability
    //   Low Performance:  neither pin has interrupt capability
    Encoder myEnc(2, 3);
    //   avoid using pins with LEDs attached
    
    void setup() {
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, HIGH);   // set the LED on
      delay(1000);                  // wait for a second
      digitalWrite(ledPin, LOW);    // set the LED off
    
      Serial1.begin(57600);
      Serial1.println("Basic Encoder Test 2:");
    }
    
    long oldPosition  = -999;
    
    void loop() {
      long newPosition = myEnc.read();
      if (newPosition != oldPosition) {
        oldPosition = newPosition;
        Serial1.println(newPosition);
      }
      digitalWrite(ledPin, HIGH);   // set the LED on
      delay(100);                  // wait for a second
      digitalWrite(ledPin, LOW);    // set the LED off
      delay(900);                  // wait for a second
    }
    I added to LED blink code to make sure it was actually running (which it is). I'm using an FT232 hooked up to pins 0 & 1 for logging. I get the same non-results on the output console regardless of whether the LED code is there or not.

    I spin the motor by hand, and the encoder has a 5-spoke wheel on it, so that generates a roughly 400-500 Hz signal. I got the following output:

    Code:
    Basic Encoder Test 2:
    0
    1
    I get the same output when I turn on the motor and drive it that way.

    Does the interrupt-driven encoder code work on the Teensy 3.1 at all?

    - Jon

  3. #28
    Junior Member
    Join Date
    Dec 2013
    Posts
    11
    I figured it out - its the INPUT_PULLUP that is the issue, perhaps only with this specific encoder. I changed lines 73 and 74 from Encoder.h as follows:

    Code:
    #ifdef INPUT_PULLUP
    pinMode(pin1, INPUT);
    pinMode(pin2, INPUT);
    #else
    and now it works perfectly.

    - Jon

  4. #29
    Junior Member
    Join Date
    Dec 2013
    Location
    Pasadena, CA
    Posts
    2

    Talking Hardware encoder working ... sort of

    I'm interested in reading a fast (200 kHz, okay I guess that's not that fast) quadrature encoder (US Digital E4P) on a motor I have while doing a bunch of other stuff with the Teensy, including reading 4 much slower encoders with the software library. Cruising around the nets I found this Freescale application note that helped immensely -- I was basically able to copy their example while looking at the datasheets for microcontroller on the Teensy 3.0.
    http://cache.freescale.com/files/32b...ote/AN4381.pdf

    Here's what I came up with to test -- it seems to work when hooked up to my encoder through a level shifter, with the exception that it rolls over to 0 after 49151, whereas I would have expected it to roll over at 2^16 based on the 16-bit counter. Not sure why this is, but haven't looked too close yet. Really all I've looked at is that when I turn one way, the counter goes up, other way, goes down. Haven't yet checked for proper 1-to-1 counting.
    Code:
    #define SIM_SCGC6_FTM1_MASK    0x20000000
    #define FTM_MODE_FTMEN_MASK    0x00000001
    #define FTM_CONF_BDMMODE_3     0x000000C0
    #define FTM_QDCTRL_QUADEN_MASK 0x00000001
    #define FTM_SC_CLKS_3          0x00000018
    
    void setup() {
      // enable the clock for FTM1
      SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK;
      // enable FTM1
      FTM1_MODE |= FTM_MODE_FTMEN_MASK;
      // set the counter to run in debug mode, not really necessary
      FTM1_CONF |= FTM_CONF_BDMMODE_3;
      // set the counter initial value
      FTM1_CNTIN = 0;
      // set the FTM for quadrature mode, default options
      FTM1_QDCTRL |= FTM_QDCTRL_QUADEN_MASK;
      // start the FTM by selecting external clock
      FTM1_SC |= FTM_SC_CLKS_3;
      // configure the input pins
      PORTA_PCR12 = PORT_PCR_MUX(7);  // Teensy pin 3
      PORTA_PCR13 = PORT_PCR_MUX(7);  // Teensy pin 4
      
      // initialize serial
      Serial.begin(115200);
      Serial.println("Hardware Encoder Test");
    }
    
    void loop() {
      Serial.println(FTM1_CNT);
      delay(500);  
    }
    P.S. This is my first ever Teensy sketch! Is there any way to access the register masks referenced in the application note as opposed to defining them myself?

  5. #30
    Senior Member Jp3141's Avatar
    Join Date
    Nov 2012
    Posts
    485
    Many are in mk20dx128.h which is deep inside the Arduino directory. On a Mac, that's:
    /Applications/Arduino.app/Contents/Resources/Java/hardware/teensy/cores/teensy3

    For Teensy 3.1, it is mk20dx256.h

  6. #31
    Member geekguy's Avatar
    Join Date
    Feb 2014
    Location
    Beaverton, OR
    Posts
    66
    Quote Originally Posted by Wozzy View Post
    There are several variants, but here is a link to the data sheet for the one I used: http://www.lsicsi.com/pdfs/Data_Sheets/LS7366R.pdf
    Good find! The LS7766DO also looks very interesting - it handles dual quadrature encoders. I have requested a sample. My robot, W.A.L.T.E.R. has quadrature encoders on both motors, so I have an application for this chip.

    Update: My sample request has been accepted, and I will be getting two LS7766DO parts.

    8-Dale
    Last edited by geekguy; 03-17-2014 at 10:32 PM. Reason: Added update

Posting Permissions

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