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

Thread: Encoder Simulator

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

    Encoder Simulator

    A friend asked for my help to create an emulator for an old shaft encoder.
    Of course I answered "No problem... A Teensy 3.0 can do that."
    But now I'm struggling with the best way to go about it.
    While I was finally able to understand the PIC product spec sheets, the Freescale documentation still spins my head around.

    The encoder is mounted on a shaft that varies in RPM from 10 to 3000 RPM.
    It has 4 outputs which vary in frequency proportional to the shaft RPM.

    1) 60/Rev - a 50% square wave with 60 cycles per revolution.
    2) 1/Rev - 1 single pulse the same width as 60/rev, and aligned to one of the 60/Rev Cycles.
    3) Flip Flop - a square wave that toggles each revolution aligned with the rising edge of the 1/Rev
    4) Ramp - and analog sawtooth wave from -10V to +10V that resets on the rising edge of the 1/Rev

    See the attached image
    Click image for larger version. 

Name:	Encoder.jpg 
Views:	366 
Size:	35.2 KB 
ID:	302

    He really didn't need the the ramp, but I took the challenge to try and include it... But I'll probably end up using an external function generator chip.
    So I've set up an input encoder knob as the RPM adjust, and tried Interval Timer, and assorted PWM functions, but each runs into limitations with range, or resolution.
    I looking into using one output to drive a base frequency, then reading it back into other pins as timer/counters, then triggering yet other pins set as outputs.
    I'm also considering that I may need to use multiple Teensy 3.0s, or a possibly a different model.

    I was hoping you guys could steer me in the right direction so I can save face with my friend.

    I promise to share whatever I learn.
    Thanks
    Last edited by Wozzy; 03-05-2013 at 06:08 PM. Reason: grammer correction

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,929
    When I wrote the Encoder library, I make a little encoder emulator circuit to test the maximum speed. It's built with a 555 timer and CD4013 dual flip-flop. Details are on the encoder page:

    http://www.pjrc.com/teensy/td_libs_Encoder.html

    Scroll down to the section "Emulating Quadrature Encoded Signals".

    That circuit outputs 2 logic level signals. If you wanted open collector style like most mechanical encoders have, you'd need to add something like 4066 switched or NPN or N-channel transistors.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,929
    Oh.... looking at those waveforms, it's not a quadrature encoder at all. Opps.

    3000 RPM and 60/rev is only a max 3000 pulses per second. That's slow enough to just emulate with software.

    I'd just build this with some simplistic code code using digitalWrite and an elapsedMicros variable.

    Code:
    elapsedMicros us = 0;  // increments automatically at a rate of 1000000/sec
    int period = 333;
    int pinstate = LOW;
    int count = 0;
    
    void loop() {
      if (us >= period) {
        us = us - period;
        if (pinstate == LOW) {
          digitalWrite(pin, HIGH);
          pinstate = HIGH;
        } else {
          digitalWrite(pin, LOW);
          pinstate = LOW;
        }
        count = count + 1;
        if (count >= 60) {
           // do similar stuff to update the other 2 pins
        }
        
        // check for input to modify the period variable
      }
    This isn't a complete or tested example. In fact, I just made it up for this message and never tried verifying in any way. It's only meant to explain the idea.

    333 us is such a long time for Teensy 3.0, or even Teensy 2.0, that you can just create the waveforms the easy way with digitalWrite.
    Last edited by PaulStoffregen; 03-05-2013 at 07:01 PM.

  4. #4
    Senior Member Wozzy's Avatar
    Join Date
    Jan 2013
    Location
    Philadelphia, Pennsylvania USA
    Posts
    341
    Quote Originally Posted by PaulStoffregen View Post
    Oh.... looking at those waveforms, it's not a quadrature encoder at all...
    That's slow enough to just emulate with software... you can just create the waveforms the easy way with digitalWrite.
    Thanks Paul for getting me going...
    I have it pretty much working except for the Ramp - for me, not bad for a few hours.

    The Teensy is so much faster than what I'm used to working with this was completely doable in software.
    I'll clean it up, comment and post the code tomorrow.
    It still needs a few tweaks, and perhaps a correction factor.

    Here's a photo of the Hardware:
    It has a 24 pulse encoder for input and a four digit serial seven segment display for RPM indication.
    The 3 LEDs are hooked up to the outputs for now.
    Click image for larger version. 

Name:	Encoder Emulator.jpg 
Views:	507 
Size:	145.9 KB 
ID:	304


    Here's an Image of the output wave forms from my el-cheapo logic analyser.
    Click image for larger version. 

Name:	Encoder DLA.jpg 
Views:	255 
Size:	109.8 KB 
ID:	303
    Last edited by Wozzy; 03-06-2013 at 04:23 AM.

  5. #5
    Senior Member Jp3141's Avatar
    Join Date
    Nov 2012
    Posts
    458
    Wozzy -- won't this have a glitch when us wraps ?

    [CODE] if (us >= period) {
    us = us - period;[CODE]

  6. #6
    The ramp should be doable by PWMing a pair of transistors across +/- 10V rails with a non-polarized cap smooth the output would it not? Pretty much half of an H-bridge.
    Last edited by Qumefox; 03-06-2013 at 06:22 PM.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,929
    Quote Originally Posted by Jp3141 View Post
    Wozzy -- won't this have a glitch when us wraps ?

    [CODE] if (us >= period) {
    us = us - period;[CODE]
    No, it will not. You're thinking of micros(), which hits 32 bit rollover approx every 1.2 hours.

    elapsedMicros is a special variable type which increments like micros(), but it's writable. Since the period is subtracted each time, it will always remain between 0 to 333, or perhaps slightly over 333 occasionally if there is some software latency (eg, from interrupts). It will never get anywhere near 32 bit rollover.

    Internally, elapsedMicros is implemented with C++ operator overloading, using functions that call micros() and properly handle the 32 bit rollover. That's why I created elapsedMicros and elapsedMillis, to make these types of use much simpler and without having to think carefully about 32 bit rollover every time. There's more documentation here:

    http://www.pjrc.com/teensy/td_timing.html

Posting Permissions

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