Author Topic: Reading speed and direction from 2 channel incremental rotary encoder  (Read 5199 times)

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
If anyone has done it and would not mind sharing, it would be appreciated  :)

I am thinking to follow this application note http://www.tufts.edu/programs/mma/emid/RotaryEncoder.pdf

Thanks,

netcruze

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #1 on: October 25, 2013, 01:51:59 PM »
Hi, do you want to implement the 7 segment display AND encoder, or just the encoder? Writing code for the encoder should be very simple, and I can create a library for you if you want. I will just have to get one for testing.

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #2 on: November 03, 2013, 03:12:06 AM »
Netcruzer,

I just need to read the encoder, find out speed (and acceleration maybe) and direction.  If you can write a Library, that would be great  :)

To sent the encoder to you would be a troublesome because it is in the machine, if you sent me a code, I can test (or probably fix) it for you.  Then I will post it back here for other people to use.  What do you think?

Thanks,
Bua
« Last Edit: November 03, 2013, 03:17:00 AM by Bua »

netcruze

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #3 on: November 05, 2013, 03:06:56 AM »
OK, I will write a library that can be configured any two inputs, and provides some functions for determining if it was tired,  and in what direction. Do you have any sbc66 boards?

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #4 on: November 05, 2013, 12:08:53 PM »
Yes, I am using SBC66EC.

netcruze

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #5 on: November 06, 2013, 04:39:43 PM »
I will need a sample though. Could you order one from http://australia.rs-online.com or somewhere else in Australia, and have it shipped to me? Or give me the digikey part number, and I can order it with my next order.

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #6 on: November 07, 2013, 01:59:02 AM »
My encoder is a bit pricey though.   It is a HENGSTLER RI58-O/1000AK.42KB; 5VDC=/0.1A.  If you really need it for testing, I can lend you my one.  I will ship it to you as soon as I can confirm your address (at Modtronix address?). 

I also attached the datasheet and recommended input circuit documents.  It is a push-pull output.

netcruze

  • Jr. Member
  • **
  • Posts: 63
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #7 on: November 07, 2013, 04:54:12 PM »
Will send you a message via email with requested details.

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #8 on: November 10, 2013, 05:49:11 PM »
That is OK. Thanks.

modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #9 on: February 02, 2014, 04:39:48 PM »
I have added initial support for rotary encoders to the "Netcruzer Library". It is contained in the nz_encIncRot.h and nz_encIncRot.c files. Have included a demo with current beta download. I placed the current beta code with your demo project on the web. Please download it from here:
www.netcruzer.com/nz/netcruzer_v203beta140203.zip

The rotary encoder demo project is located in "../src/demos/io/rotary_encoder". For this demo I used the SBC66 plugged into the PT66DIN6. On iMod port 1 I used a im5P iMod module for connecting the wires of the rotary encoder.

Click for larger image!



Open this project in MPLAB, and configure the inputs of your A and B port. I used X8 for A, and X7 for my B port. Change all references to X7 and X8 in main.c to the Netcruzer Ports you are using. When running, this demo will output values to the Netcruzer USB Terminal.

In addition you need to configure the A port to trigger on an interrupt. I used the interrupt on change feature of the PIC24 CPU. You will see the interrupt gets configured in the main code for Netcruzer Port X8:
Code: [Select]
    //Configure the interrupt on change for encoder channel A (X8) only!
    configIntOnChange(INT_ENABLE|INT_PRI_4);    //Enable Interrupt on chagne at Int Priority level 4
    clearIntOnChangeIF();                       //Clear "interrupt on change" IF (interrupt flag)
    enableIntOnChangeForPort(SBCPORT_ID_X8);    //Enable "interrupt on change" for Channel A = X8

And, in the interrupt handler, you have to call the main nz_encIncRot.c task rotinc_task():
Code: [Select]
/**
 * Interrupt on change ISR, called if any of the configured ports change value
 */
void __attribute__((interrupt,no_auto_psv)) _CNInterrupt(void)
{
    clearIntOnChangeIF();   //Clear "interrupt on change" IF (interrupt flag)
    rotinc_task(&objEncRot);
}

The main.c file contains:
Code: [Select]
// Includes /////////////////////////////////////
#include "HardwareProfile.h"    //Required for all Netcruzer projects
#include "nz_encIncRot.h"       //Rotary Encoder driver

//Add debugging, and define debugging level. Is a DEBUG_LEVEL_xx define. Set to DEBUG_LEVEL_OFF to disable.
#define MY_DEBUG_LEVEL   DEBUG_LEVEL_INFO
#include "nz_debug.h"

// Variables ////////////////////////////////////
static WORD tmrFlashLed = 0;        //Timer for flashing system LED
ENCROT_INFO objEncRot;              //Rotary Encoder object
BYTE        bufGet;                 //Pointer to last value read from encoder buffer


/**
 * Interrupt on change ISR, called if any of the configured ports change value
 */
void __attribute__((interrupt,no_auto_psv)) _CNInterrupt(void)
{
    clearIntOnChangeIF();   //Clear "interrupt on change" IF (interrupt flag)
    rotinc_task(&objEncRot);
}


/**
* Main application entry point.
*/
int main(void) {
    WORD encVal;

    //Default initialization. All ports inputs. All analog features disabled. Tick 1ms
    nzsysInitDefault();

    debugPutString("\nThis is a test debug message from rotary_encoder.c demo");

    bufGet = 0;

    //Initialize rotary encoder for using X8 as channel A, and X7 as channel B
    rotinc_init(&objEncRot, SBCPORT_ID_X8, SBCPORT_ID_X7);

    //Configure the interrupt on change for encoder channel A (X8) only!
    configIntOnChange(INT_ENABLE|INT_PRI_4);    //Enable Interrupt on chagne at Int Priority level 4
    clearIntOnChangeIF();                       //Clear "interrupt on change" IF (interrupt flag)
    enableIntOnChangeForPort(SBCPORT_ID_X8);    //Enable "interrupt on change" for Channel A = X8

    //Main loop
    while(1)
    {
        nzsysTaskDefault();     //Main netcruzer task, call in main loop.

        //Print out last values read by encoder. The times are in multiples of ENC_INC_ROT_RESOLUTION.
        //The default ENC_INC_ROT_RESOLUTION is 16us, so a value of 10 will be 10x16=160us
        while (bufGet != objEncRot.put) {
            //Get next encoder value, and update the last value we read from the buffer
            encVal = objEncRot.buf[bufGet];
            bufGet++;
            if (bufGet >= ENC_INC_ROT_BUFSIZE)
                bufGet = 0;

            //Encoder is being turned forward (Clock Wise)
            if (encVal & 0x8000) {
                debugPutString("\nF = ");
            }
            //Encoder is being turned backwards (Counter Clock Wise)
            else {
                debugPutString("\nB = ");
            }
            debugPutWord(encVal & 0x7fff);  //Print lower 15-bits. Bit 16 contains direction!
        }
    }//end while
}



« Last Edit: February 02, 2014, 05:10:50 PM by modtro2 »

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #10 on: February 06, 2014, 02:24:23 AM »
Thank you, modtro2   :-)

I only need to add "nz_encIncRot.h" and "nz_encIncRot.c" in my webserver project, right? 
You mentioned about modifying the tick resolution, do I need to update any file in the library?
My project is netcruzer_v202. 

I haven't try to run it, yet.  I will try over the weekend, and will let you know how it go.

Cheers,
Bua

Bua

  • Sr. Member
  • ****
  • Posts: 34
    • View Profile
Re: Reading speed and direction from 2 channel incremental rotary encoder
« Reply #11 on: February 08, 2014, 10:07:35 PM »
Hi,

I ran the code and see the encoder values, but the numbers did not make sense to me.

It looked like speed, more than distance or revolution.

Can you explain a bit more about the printed encoder values?

Thanks,