6.4 Quadrature Encoder Interface (QEI) Peripheral

This section guides the users through the process of enabling the Quadrature Encoder Interface (QEI) module and developing testing code to capture motor data. A motor sensor system is presented that leverages the QEI to accurately capture motor encoder data, such as position counters and velocity metrics.

This demonstration utilizes a motor equipped with Hall Sensor A and Hall Sensor B signals, making it versatile and compatible with various motor types. For more details about the specific motor in this demo, refer to the Encoder Metal Gearmotor 12V DC High Speed 130RPM Gear Motor with Encoder for Arduino and 3D Printers in Reference Documentation from Related Links.

The BLE Transparent UART with QEI peripheral application example can also be found in wireless_apps_pic32_bz6/apps/ble/peripheral_applications/qei_peripheral_trp_uart. For more details, see BLE + QEI Transparent UART from Related Links.

Hardware Requirement

Table 6-4. Hardware Requirement
S. No. Tool Quantity
1PIC32-BZ6 Curiosity Board1
2Micro USB cable1
3Hall Encoder DC Motor1
4AC/DC Adapter1

SDK Setup

  • Refer to Getting Started with Software Development from Related Links.

Software Requirement

  • To install Tera Term tool, refer to the Tera Term web page in Reference Documentation from Related Links.

Smart Phone Application

  • Microchip Bluetooth Data (MBD)

Programming the Application using MPLAB X IDE

Using MPLAB® X IPE:
  1. Right click on the qei_testing tab in MPLABX IDE project and select Make and Program Device.
    Figure 6-2. Make and Program Device
  2. From the drop-down list, select the PIC32-BZ6 tool.

Demo Description

Once the application is programmed, PIC32-BZ6 begins capturing the motor data through the QEI. PIC32-BZ6 periodically prints the pulse counter and velocity to the terminal every second. In accordance with the QEI specification, the velocity register(VELxCNT) is read, and consequently reset, every 1 ms in the TC0 callback, however the pulse counter register (POSxCNT) is read every 1s and the information printed.

Tera Term Configuration

The user can view the terminal messages using a terminal emulator like TeraTerm.
  • Baud Rate/Speed: 115200
  • Parity: None
  • Data Bits: 8
  • Stop Bits: 1
  • Flow control: None

Testing

This section assumes that user has programmed the application example on the PIC32-BZ6 Curiosity Board.
  1. The following figure illustrates the hardware setup.
    Figure 6-3. PIC32-BZ6 Hardware Setup
  2. The following table provides details about the pin connections of the PIC32-BZ6hardware setup.
    Table 6-5. Pin Table
    Pin LocationPin on PIC32-BZ6Motor Pin
    GPIO headerPB10Encoder B Vout (white wire)
    GPIO headerPB5Encoder A Vout (yellow wire)
    Mikrobus 2+5VEncoder Vcc (blue wire)
    GPIO headerGroundEncoder Ground (green wire)
    AC/DC adapterAC/DC adapter (-)Motor (-) (black wire)
    AC/DC adapterAC/DC adapter (+)Motor (+) (red wire)
  3. Reset the PIC32-BZ6 Curiosity Board.
  4. Open a terminal emulator like Tera Term, and select the right COM port.
  5. The following are the configuration settings:
    • Speed: 115200
    • Data: 8-bit
    • Parity: none
    • stop bits: 1 bit
    • Flow control: none
    Figure 6-4. Tera Term Serial Port Setup and Connection
  6. Upon reset, the following is continuously displayed every second until the AC/DC adapter is plugged in:
    Figure 6-5. Serial Terminal Output: Pulse Counter and Velocity Readings
    Note: Upon reset, the pulse counter may be 0, 1, or -1.
  7. Supply power to the motor by plugging in the AC/DC adapter.
    1. When the motor (-) is connected to AC/DC Adapter (-) and Motor (+) is connected to AC/DC Adapter (+), the motor rotates counter-clockwise, the pulse count decreases, and the velocity will be negative.
      Figure 6-6. Serial Terminal Output: Negative Pulse Counter and Velocity Measurements
    2. The QEI provides a Velocity Counter (VELxCNT) register that increments or decrements based on the signal from the encoder. This register is reset any time it is read, and we read it every 1 ms or at a rate of 1 kHz. The pulse count is read and printed every one second. Ideally, the velocity counter specifies the distance traveled between the time interval of each sample. The velocity at time t can be calculated by subtracting the pulse count at time t by the pulse count at time t-1. For example, -10402 – (-5755) = -4647, and -15058 – (-10402) = -4656 and so on.
    3. The QEI provides an interface for capturing information about the motor direction, speed and position. The encoder sends signals which are captured and analyzed by the QEI. The two signals look like this on an oscilloscope:
      Figure 6-7. Two Signals
    4. If the QEA signal leads the QEB signal, the motor is deemed positive or forward. If QEB leads QEA, the motor is deemed negative or reverse. The yellow signal in the image is QEA and the green signal is QEB, therefore the motor is in reverse.
    5. The quadrature decoder increments a counter (POSxCNT) when QEA leads QEB and decrements the counter when QEB leads QEA, therefore the pulse counter is decreasing.
    6. Additionally, for increased resolution, the QEI provides a x4 mode which multiplies the input signals by a factor of four. This mode is evident in the pulse counter in the Tera Term output.
  8. Unplug the AC/DC adapter. Swap the Motor (-) and Motor (+) pins such that the AC/DC Adapter (-) is connected to Motor (+) and AC/DC Adapter (+) is connected to Motor (-).
  9. Supply power to the motor by plugging in the AC/DC adapter.
    1. Since the Motor (+) and (-) pins were swapped, the motor now rotates clockwise, the pulse count increases and the velocity is positive.
      Figure 6-8. Serial Output: Pulse Counter and Velocity after Motor Pin Swap
      Note: The pulse count resumes counting from where it left off, the count will not be reset unless the board is reset.
    2. Now the QEA signal (blue) is leading the QEB signal (yellow), so the motor is deemed positive or forward.
      Figure 6-9. QEA (Blue) and QEB (Yellow) Signal
  10. When the motor is spinning and the power is removed, the velocity goes to 0 and the counter stops incrementing or decrementing and remain the same.
    Figure 6-10. Power Removal

Developing the Application from Scratch using the MPLAB Code Configurator

This section explains the steps required to develop this application example from scratch using MPLABx Code Configurator.
Note: The recommendation for the new users of MPLAB Code Configurator is to go through the MPLAB® Code Configurator (MCC) User’s Guide. For more details, refer to the MPLAB® Code Configurator (MCC) User’s Guide in the Reference Documentation from Related Links.
  1. Create a new MCC Harmony Project. For more details on how to create a new MCC Harmony Project, refer to Creating a New MCC Harmony Project from Related Links.
  2. Add the “QEI” component to the project graph.
    1. In the Device Resources tab, from the “QEI” drop-down, click the green plus symbol.
    Figure 6-11. Adding QEI Component
    1. Configure the “QEI” component as follows:
      Figure 6-12. QEI Configuration
  3. Add the “TC0” component to the project graph.
    Figure 6-13. Adding TC0 Component
    1. Configure the “TC0” component as follows:
      Figure 6-14. Configuring TC0 Component
  4. Add the “SERCOM0” component to the project graph.
    Figure 6-15. Adding SERCOM0 Component
    1. Configure the “SERCOM0” component as follows:
      Figure 6-16. Configuring SERCOM0 Component
  5. From the “SERCOM0 Direct (High Speed) Pin Enable (SCOM0_HSEN)” drop-down list, select DIRECT in the system component.
    Figure 6-17. Select DIRECT in the System Component
  6. Verify if the Project Graph window has all the expected configuration.
    Figure 6-18. Project graph Window
  7. In the Project Graph tab, from the “Plugins” drop-down list, select Pin Configuration.
    Figure 6-19. Pin Configuration
    1. In the Pin Settings tab, configure the pin settings as follows:
      Figure 6-20. Pin Settings

Files and Routines Automatically generated by the MCC

After clicking Generate Code in the MCC interface for generating program source, the BLE configuration appears in the following project directories.

User Application Development

To implement the described functionality in the main.c file (without using FreeRTOS), the user must follow these steps:
  1. Include stdio.h at the top of the main.c file:
    #include <stdio.h>
  2. Start the QEI and configure the TC0 callback by adding these function calls in the main() function:
    QEI_Start();
    TC0_TimerCallbackRegister(TC0_Callback_InterruptHandler, (uintptr_t)NULL);
    TC0_TimerStart();
    Figure 6-21. main.c Source Code Window – QEI and Timer Initialization
  3. Define the TC0 callback interrupt handler. The user must call this function must be called every 1 ms (assuming TC0 is configured for a 1 ms period). This code reads the velocity every 1 ms and prints the pulse counter and velocity every 1s.
    Figure 6-22. TC0 Timer Callback Interrupt Handler