QuadEncoder Component questions

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 8.

Moderator: Benj

Post Reply
zumpitu
Posts: 22
Joined: Tue Jul 03, 2018 12:21 pm
Location: Southam UK
Has thanked: 4 times
Been thanked: 2 times
Contact:

QuadEncoder Component questions

Post by zumpitu »

Hi All !

I have some question about the QuadEncoder Component macro.

I'm using a Nucleo 64 board and I need to implement on my project 2 quadrature encoder and 1 (3) hall sensor (for BLDC motor) .

I know that the STMF4 Chip have implemented this feature on the timers , so is possible to have 2 32Bit quadrature encoder and 1 hall sensor.

The question is, is the rotatory encoder Macro using that feature or use is own specific code ? Because I think is quite a big difference.



Here I have the code that I use from Mbed that activate that feature. I still have problem to implement it from the "supplementary code".

I downloaded the specific mbed.h for my Nucleo board but when I compile the file I have error:

from Encoder_mbed.c:71:
platform/platform.h:22:19: fatal error: cstddef: No such file or directory



Anyway I would much prefer to have the ability to use all the hardware feature of the timers directly inside Flowcode without additional code.



Thank you

Sacha

Code: Select all

#include "mbed.h"
 
// Hardware Quadrature Encoder ABZ for Nucleo F401RE
// Output on debug port to host PC @ 9600 baud
// 
// By Nigel Webb, November 2014
 
/* Connections
   PA_0 = Encoder A
   PA_1 = Encoder B
   PA_4 = Encoder Z 
*/
 
InterruptIn ZPulse(PA_4) ; // Setup Interrupt for Z Pulse
 
void EncoderInitialise(void) {
    // configure GPIO PA0 & PA1 as inputs for Encoder
    RCC->AHB1ENR |= 0x00000001;  // Enable clock for GPIOA
 
    GPIOA->MODER   |= GPIO_MODER_MODER0_1 | GPIO_MODER_MODER1_1 ;           //PA0 & PA1 as Alternate Function   /*!< GPIO port mode register,               Address offset: 0x00      */
    GPIOA->OTYPER  |= GPIO_OTYPER_OT_0 | GPIO_OTYPER_OT_1 ;                 //PA0 & PA1 as Inputs               /*!< GPIO port output type register,        Address offset: 0x04      */
    GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0 | GPIO_OSPEEDER_OSPEEDR1 ;     // Low speed                        /*!< GPIO port output speed register,       Address offset: 0x08      */
    GPIOA->PUPDR   |= GPIO_PUPDR_PUPDR0_1 | GPIO_PUPDR_PUPDR1_1 ;           // Pull Down                        /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
    GPIOA->AFR[0]  |= 0x00000011 ;                                          //  AF01 for PA0 & PA1              /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
    GPIOA->AFR[1]  |= 0x00000000 ;                                          //                                  /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
   
    // configure TIM2 as Encoder input
    RCC->APB1ENR |= 0x00000001;  // Enable clock for TIM2
 
    TIM2->CR1   = 0x0001;     // CEN(Counter ENable)='1'     < TIM control register 1
    TIM2->SMCR  = 0x0003;     // SMS='011' (Encoder mode 3)  < TIM slave mode control register
    TIM2->CCMR1 = 0xF1F1;     // CC1S='01' CC2S='01'         < TIM capture/compare mode register 1
    TIM2->CCMR2 = 0x0000;     //                             < TIM capture/compare mode register 2
    TIM2->CCER  = 0x0011;     // CC1P CC2P                   < TIM capture/compare enable register
    TIM2->PSC   = 0x0000;     // Prescaler = (0+1)           < TIM prescaler
    TIM2->ARR   = 0xffffffff; // reload at 0xfffffff         < TIM auto-reload register
  
    TIM2->CNT = 0x0000;  //reset the counter before we use it  
}
 
// Z Pulse routine
void ZeroEncoderCount() {
    TIM2->CNT=0 ; //reset count to zero
}
 
int main() {
    EncoderInitialise() ;
    
    ZPulse.rise(&ZeroEncoderCount) ; //Setup Interrupt for rising edge of Z pulse 
    ZPulse.mode(PullDown) ; // Set input as pull down
     
    unsigned int EncoderPosition ;
    
    while (true) {
        // Print Encoder Quadrature count to debug port every 0.5 seconds
        EncoderPosition = TIM2->CNT ; // Get current position from Encoder
        printf("%i\n", EncoderPosition); 
        wait(0.2);
    }
   
       
}
    


User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: QuadEncoder Component questions

Post by LeighM »

Hi
The easiest way to do this is to use the Flowcode Rotary Encoder component, and yes it uses its own code.

It is best to create a timer interrupt to call the component CheckForChanges(),
just ensure that the interrupt rate is at least twice the frequency of the fastest encoder rate.

You can then use ReadCounter() to get the value, please note that the component has a 16 bit counter, hope that is sufficient for you.
Last edited by LeighM on Mon Jul 23, 2018 10:14 am, edited 1 time in total.

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: QuadEncoder Component questions

Post by medelec35 »

LeighM wrote:It is best to create a timer interrupt to call the component CheckForChanges(),
just ensure that the interrupt rate is at least twice the frequency of the fastest encoder rate.
Hi Leigh, would you recommend timer interrupt over IOC?
Martin

User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: QuadEncoder Component questions

Post by LeighM »

Hi Martin,
Yes, IOC is better, if you have nice clean signals from say an opto-coupler or well filtered (debounced) switch.
otherwise In practice I've found the timer solution to be more stable.

zumpitu
Posts: 22
Joined: Tue Jul 03, 2018 12:21 pm
Location: Southam UK
Has thanked: 4 times
Been thanked: 2 times
Contact:

Re: QuadEncoder Component questions

Post by zumpitu »

Hi guys

Thank you for your support.

UmMm.. so In this sense I need a 32 Bit encoder at least for one of my 2 encoder.

Actually the first reason why I chose the STMF4 platform is because it have is own hardware quadrature code feature that is exactly what I need.

Can you give me any advice or documentation on how I can implement that code inside Flowcode ?

I can also generate code to activate all the feature I need from CubeMX .

As I can see I need to include the necessary library on "Definitions and function declarations:" of the the supplementary code and than Add the code on the "Function implementations:"

Since I decided to go on with Flowcode ( Just got the license ! ) I really want to learn and understand how the software work

Post Reply