Skip to content

Commit

Permalink
MPAE-15505: Grammar edits
Browse files Browse the repository at this point in the history
  • Loading branch information
robertperkel committed Feb 15, 2023
1 parent 54636a1 commit 330de62
Showing 1 changed file with 14 additions and 14 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<a href="https://www.microchip.com" rel="nofollow"><img src="images/microchip.png" alt="MCHP" width="300"/></a>
# Quadrature Decoder with PIC18F16Q40

This code example creates a simple quadrature decoder on the PIC18F16Q40 device. It utilizes 2 of the Configurable Logic Cells (CLCs) and TMR1/2/3 to decode the quadrature output of the rotary encoder. A UART interface is also used for a serial readout.
This code example creates a simple quadrature decoder on the PIC18F16Q40 device. It utilizes two of the Configurable Logic Cells (CLCs) and TMR1/2/3 to decode the quadrature output of the rotary encoder. A UART interface is also used for a serial readout.

## Software Used

Expand Down Expand Up @@ -57,32 +57,32 @@ Depending on the encoder, the specific circuit required for proper operation wil

The encoder used is a mechanical encoder with 24 pulses-per-revolution (PPR). High PPR encoders provide more precise positioning information. However, this example uses it for user interfacing, where the precision of a higher PPR encoder was not needed.

To connect the encoder to the microcontroller, the manufacturer for this encoder (Bourns Inc.) recommends pulling up the outputs of the encoders to V<sub>DD</sub> and filtering with an RC filter, an example of which is shown in Figure 3. (See the [Manufacturer's Datasheet](https://www.bourns.com/docs/Product-Datasheets/PEC12R.pdf) for up-to date information.)
To connect the encoder to the microcontroller, the manufacturer for this encoder (Bourns Inc.) recommends pulling up the outputs of the encoders to V<sub>DD</sub> and filtering with an RC filter, an example of which is shown in Figure 3. (See the [Manufacturer's Data Sheet](https://www.bourns.com/docs/Product-Datasheets/PEC12R.pdf) for up-to date information.)

![Sample Circuit](./images/sampleCircuit.png)
*Figure 3 - Implemented Circuit*

10k resistors were added in series with the RC filter to reduce the current through the ESD diodes from the filter capacitor if power is lost while the capacitors are fully charged. Since the encoder signal is digital, the added resistance should have a minimial effect on the performance of the encoders.
If the power is lost while the filter capacitors are fully charged, the 10k resistors added in series with the RC filter will reduce the current through the ESD diodes from the filter capacitor. The added resistance should have a minimial effect on the performance of the encoders.

Note: Damage may occur if too much current is passed through the ESD diodes.

## Operation

This example has 2 outputs - a UART output and an LED bar graph display output.
This example has two outputs - a UART output and an LED bar graph display output.

The UART output prints the net change in encoder value (over a period of 1s) and the current volume of the program at 115,200 baud.
The LED graph display output uses a 10-position LED bar graph to display the current volume.

### UART Output

The UART output is connected through the programmer to the PC. [MPLAB Data Visualizer](https://www.microchip.com/mplab/mplab-data-visualizer) can be used to visualize the serial output. After plugging in the board, select the programmer's COM port, but do not connect to it. In the bottom left corner of the Data Visualizer Window/Tab, enter the following settings.
The UART output is connected through the programmer to the PC. [MPLAB Data Visualizer](https://www.microchip.com/mplab/mplab-data-visualizer) can be used to visualize the serial output. After plugging in the board, select the programmer's COM port, but do not connect to it. In the bottom left corner of the Data Visualizer Window, enter the following settings.

* Baud Rate: 115,200
* Char Length: 8 bits
* Parity: None
* Stop Bits: 1 bit

After setting these options, press apply, then connect to the COM port. In the terminal window, set the display to 8-bit ASCII, the source to the connected COM port, and wait. Within a few seconds, text should start printing to the screen.
After setting these options, press apply, then connect to the COM port. In the terminal window, set the display to 8-bit ASCII, the source to the connected COM port, and within a few seconds, text should start printing to the screen.

![Terminal Output](./images/terminalOutput.PNG)

Expand All @@ -97,17 +97,17 @@ The LED bar graph is a graphical "volume" style output. Each bar graph is worth

*Figure 5 - Demonstration of the LED Bar Graph Output*

Note: Due to differences in encoder parameters, some of the constants may have to be tweaked to find the right balance of speed and accuracy with the Volume Control.
Note: Due to differences in encoder parameters, some of the constants may have to be tweaked to find the right balance of speed and accuracy with the volume control.

#### Control options

* Linear - Each pulse from the encoder is counted as 1.
* Threshold - After exceeding a threshold, in this case 3 pulses, each pulse is worth the same as a "1 rotation pulse".
* 1 Rotation - Each pulse is worth approximately the value required for a single rotation to go from 0 to 100.
* Linear - Each pulse from the encoder is counted as one
* Threshold - After exceeding a threshold, in this case three pulses, each pulse is worth the same as a "one rotation pulse"
* One Rotation - Each pulse is worth approximately the value required for a single rotation to go from 0 to 100

## Theory of Operation

The quadrature decoder takes 2 inputs, A and B, that are out-of-phase by 90 degrees. One of the inputs is considered a reference waveform, for which the phase of the other is measured against. The other waveform determines the direction of the encoder based on if it leads or lags the reference, as shown in Figure 6.
The quadrature decoder takes two inputs, A and B, that are out-of-phase by 90 degrees. One of the inputs is considered a reference waveform, for which the phase of the other is measured against. The other waveform determines the direction of the encoder based on if it leads or lags the reference, as shown in Figure 6.

![Example Waveform](./images/exampleWaveform.png)

Expand All @@ -128,7 +128,7 @@ The reset lines in this implementation operate asynchronously - if the line is h

*Figure 7 - CLC Logic Diagram*

There are 2 CLCs used in this project, with the only difference being that A and B are swapped between the two. Swapping A and B causes one of the CLCs to see the input lag while the other sees the input lead. In a JK flip-flop, J must be high when the clock is rising in order to set the output high. The only flip-flop that will be set is the configuration where the input leads the clock signal, as shown in Figures 8 and 9.
There are two CLCs used in this project, with the only difference being that A and B are swapped. Swapping A and B causes one of the CLCs to see the input lag while the other sees the input lead. In a JK flip-flop, J must be high when the clock is rising to set the output high. The only flip-flop that will be set is the configuration where the input leads the clock signal, as shown in Figures 8 and 9.

![Waveform 1](./images/waveform1.PNG)

Expand All @@ -139,11 +139,11 @@ There are 2 CLCs used in this project, with the only difference being that A and

*Figure 9 - Output of the CLCs (with A and B switched)*

Both images were taken with a test signal of ~30Hz. Between runs, the wires to A and B were switched, causing 1 CLC to become active while the other becomes inactive. The output of the CLCs is internally routed to either TMR1 or TMR3. The rising edge of the output causes the timer to count. Normally the TMR1 or TMR3 overflow is used as an interrupt, however since the pulse count is unknown and is likely to be relatively small, it makes more sense to use a timer (such as TMR2) as an interrupt to poll the number of pulses in each.
Both images were taken with a test signal of ~30 Hz. Between runs, the wires to A and B were switched, causing one CLC to become active while the other becomes inactive. The output of the CLCs is internally routed to either TMR1 or TMR3. The rising edge of the output causes the timer to count. Normally, the TMR1 or TMR3 overflow is used as an interrupt, however since the pulse count is unknown and is likely to be relatively small, it makes more sense to use a timer (such as TMR2) as an interrupt to poll the number of pulses in each timer.

The simple way to get the number of pulses in TMR1/3 is to stop the timer, read the value, reset the counter back to 0, and start it again. However, if a pulse occurs, then it will be missed by the timer. A better approach is to use the relative difference between each polling event. If the encoder was spun in the same direction between each polling event, then the difference in values (current to old) will be 0, while the other will change. If the direction of rotation was changed between polling events, then both counters will have non-zero differences.

To prevent invalid reads, this example uses TMR1 and TMR3 in 16-bit read mode to buffer the high byte of the timer counter when the low byte is read. This mode of operation prevents an increment that could occur after reading the 1st byte from affecting the high byte, as shown in Figure 10.
To prevent invalid reads, this example uses TMR1 and TMR3 in 16-bit Read mode to buffer the high byte of the timer-counter when the low byte is read. This mode of operation prevents an increment that could occur after reading the first byte from affecting the high byte, as shown in Figure 10.

![CLC Implementation](./images/timingError.png)

Expand Down

0 comments on commit 330de62

Please sign in to comment.