Quadrature encoder interface (QEI) does exactly what is in the name - provides an interface for quadrature encoders. The used dsPIC has two such interfaces.
My encoder is Faulhaber IE2-16 and is mounted to a small DC motor. This encoder has a resolution of 16 pulses per revolution and requires a supply voltage of 4-18V. I will power the encoder with 5V, and because the logic voltage of my dsPIC is 3.3V, I have to use a logic voltage converter for the two outputs.
Since MCC does not support QEI, I will have to set all the registers myself, including setting up the Peripheral Pin Select (PPS). PPS basically allows you to select which pin will serve what purpose.
First, I connected the encoder and the logic voltage converter.
Now I need to set up the pins. Both are inputs, also need to be set to digital instead of default analog. PPS is not terribly difficult to set - simply setting the QEIA1R and QEIB1R registers to the pin number does the job.
_ANSELD10 = 0; // set pin to digital (by default analog)
_ANSELD11 = 0; // set pin to digital (by default analog)
_TRISD10 = 1; // set pin to input
_TRISD11 = 1; // set pin to input
__builtin_write_RPCON(0x0000); // Unlock
_QEIA1R = 75; // assign pin to QEI
_QEIB1R = 74; // assign pin to QEI
__builtin_write_RPCON(0x0800); // Lock
QEI1CONbits.QEIEN = 1; //Enable Module
Now it's simply the matter of reading the POS1CNT register and displaying it on the display.
And after a few hours of debugging, only to discover bad contact on the breadboard, it works!
Bubble displays are characterized by their clever magnification technique. Nothing but power-hungry LEDs await under the smart glasses - they draw up to 90 mA.
Not much is needed to extend the blink program to drive the HPDL-1414 bubble display.
There are 12 pins, two of which are used for power and one for a write signal. The remaining 9 pins transmit the data - two to select the digit and the rest to select the character from a set of 64. The display has volatile memory, so it will remember the previously displayed character as long as it is powered.
Character is made out of 16 individual segments.
I will power the display with 5V. Since the display is smart, it integrates all the necessary things to drive the LEDs, and I can control it with the 3.3V logic from dsPIC.
Looking at the timing characteristics, only minimum timing is specified. Since I'm using an 8MHz internal oscillator, the dsPIC will execute one instruction per 250ns. Therefore, I don't have to use a timer and rely on my setup's relatively low MIPs.
This time, I don't use the custom name from MCC and write directly to the register.
To program the dsPIC, I use the MPLAB X IDE from Microchip.
The initial setup is fairly straightforward. After selecting the device and programming tool, it creates an empty project.
To save some time perusing through the datasheet, I use the MPLAB Code Configurator (MCC). This tool allows setting some of the most used registers through a GUI and even visualizes the package's pin assignment.
For this blink test, I set pin 15 as output and assigned a custom name LEDOUT. On the breadboard, I added a small LED to pin 15 with a current limiting resistor - all in a way such that the microcontroller acts as a sink and the absolute maximum current rating of the IO pin is satisfied.
Back in the IDE, I used the main.c file created by MCC and included some of the generated files.
Next, the instruction cycle clock (FCY) needs to be defined for the wait function to work. The frequency of the selected internal oscillator (FOSC) is 8MHz, and the datasheet states that the FCY is half that of FOSC.
#define FCY 4000000UL //UL suffix sets the data type to be unsigned long
Now I add the blink loop, which uses the custom name from MCC:
// initialize the device