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
S. No. | Tool | Quantity |
---|---|---|
1 | PIC32-BZ6 Curiosity Board | 1 |
2 | Micro USB cable | 1 |
3 | Hall Encoder DC Motor | 1 |
4 | AC/DC Adapter | 1 |
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
- Right click on the qei_testing tab in MPLABX IDE project and select Make and
Program Device.
Figure 6-2. Make and Program Device - 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
- Baud Rate/Speed: 115200
- Parity: None
- Data Bits: 8
- Stop Bits: 1
- Flow control: None
Testing
- The following figure illustrates the hardware setup.
Figure 6-3. PIC32-BZ6 Hardware Setup - The following table provides details about the pin connections of the PIC32-BZ6hardware setup.
Table 6-5. Pin Table Pin Location Pin on PIC32-BZ6 Motor Pin GPIO header PB10 Encoder B Vout (white wire) GPIO header PB5 Encoder A Vout (yellow wire) Mikrobus 2 +5V Encoder Vcc (blue wire) GPIO header Ground Encoder Ground (green wire) AC/DC adapter AC/DC adapter (-) Motor (-) (black wire) AC/DC adapter AC/DC adapter (+) Motor (+) (red wire) - Reset the PIC32-BZ6 Curiosity Board.
- Open a terminal emulator like Tera Term, and select the right COM port.
- 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 - 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. - Supply power to the motor by plugging
in the AC/DC adapter.
- 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 - 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.
- 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 - 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.
- 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.
- 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.
- 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.
- 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 (-).
- Supply power to the motor by plugging in the AC/DC adapter.
- 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. -
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
- Since the Motor (+) and (-) pins were swapped, the motor now rotates clockwise,
the pulse count increases and the velocity is positive.
- 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
- 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.
- Add the “QEI” component to the project graph.
- In the Device Resources tab, from the “QEI” drop-down, click the green plus symbol.
Figure 6-11. Adding QEI Component - Configure the “QEI” component as follows:
Figure 6-12. QEI Configuration
- Add the “TC0” component to the project graph.
Figure 6-13. Adding TC0 Component - Configure the “TC0” component as follows:
Figure 6-14. Configuring TC0 Component
- Configure the “TC0” component as follows:
- Add the “SERCOM0” component to the project graph.
Figure 6-15. Adding SERCOM0 Component - Configure the “SERCOM0” component as follows:
Figure 6-16. Configuring SERCOM0 Component
- Configure the “SERCOM0” component as follows:
- 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 - Verify if the Project Graph window has all the expected configuration.
Figure 6-18. Project graph Window - In the Project Graph tab, from the “Plugins” drop-down list, select Pin
Configuration.
Figure 6-19. Pin Configuration - In the Pin Settings tab, configure the pin settings as follows:
Figure 6-20. Pin Settings
- In the Pin Settings tab, configure the pin settings as follows:
Generating Code
For instructions on generating a code, refer to the MPLAB Code Configurator(MCC) Code Generation from Related Links.
Files and Routines Automatically generated by the MCC
User Application Development
main.c
file (without using
FreeRTOS), the user must follow these steps:- Include
stdio.h
at the top of themain.c
file:#include <stdio.h>
- 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 - 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