HomeArticlesProjectsBlogContact
Articles
PIC LAB 1 Extra Page 9
Colin Mitchell
Colin Mitchell
Make sure to subscribe to our newsletter and be the first to know the news.

Table Of Contents

01
THREE DIGIT COUNTER and A-to-D CONVERTER
02
THE PROGRAM
03
ANALOGUE TO DIGITAL (A-to-D)
04
HOW CAN THE READING BE ALTERED?
05
ALTERNATIVE DETECTION METHOD

THREE DIGIT COUNTER and A-to-D CONVERTER


Even though the PIC LAB-1 board has only a single display, a 3-digit counter can be displayed by flashing the 3 digits then pausing before displaying again. Ws have produced up to 5 digits in this manner and the counter is fairly easy to read once you realize how the digits are displayed.
The 3-digit counter serves to show how the limitations of a single display can be overcome.
We have produced another project 5x7 Display, using a single display to produce a 3 and 5-digit counter. It uses a matrix of LEDs to produce a single digit and the same principle of “flashing” has been used.
Multiple-digit counters can be called “tally counters” for recording the total production of a particular item. Some items can be weighed to get a quantity but this takes time and expense.
The simplest is to have a detector (plus electronics) record each item as it is being produced and keep track of the total. This can be used to “back up” the values obtained from individually weighed amounts.
A tally counter will only need to be read once a day and the single digit can be a low-cost way of showing this value.
The program can be designed to accept a code from a set of buttons so that operators cannot access the data. It’s a security measure to avoid theft and fraud.

THE PROGRAM

A 3-digit counter requires three files to hold the “tally.” Each digit is held in the lower “nibble” (a nibble is 4 bits).
These files are initially cleared so the readout is “000.”
The first digit (actually the hundreds) is displayed then the display is cleared for a short time. This is repeated for the second and third digit.
The display is then cleared for a longer period of time to indicate the end of the number.
The routine is then repeated.
Throughout the program, the input must be poled at (looked at) regular intervals. The most difficult part of the program is to place the button-instruction where it can be constantly executed by the micro.
The only place is within the display routine.
The program takes about 1 second to display the three digits and in this time the button can be pressed 10 or more times.
By placing the button instruction (BTFSS 05,0) in the display routine it is accessed every 2mS.
You can press the button while the display is flashing and the program will increment the tally in the background. The result is very impressive. It appear that the program is down two things at the same time. The circuit for the counter:

Here is the complete program:

      ;3digit.asm
      ;Project: 3 Digit Counter
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

            ORG 0             ;This is the start of memory for the program.
SetUp       BSF 03,5          ;Go to Bank 1
            CLRF 06           ;Make all port B output
            MOVLW 01          ;Load W with 0000 0001
            MOVWF 05          ;Make RA0 input
            BCF 03,5          ;Go to Bank 0 - the program memory area.
            CLRF 05           ;Clear portA
            CLRF 1F           ;Clear the button-press file
            CLRF 11h          ;Clear 'units' file
            CLRF 12h          ;Clear 'tens' file
            CLRF 13h          ;Clear 'hundreds' file
            GOTO Main

Table       ADDWF 02h,1       ;Add W to the Program Counter to create a jump.
            RETLW 3Fh         ;0 format= gfedcba
            RETLW 06h         ;1 If any table value has a leading letter, it must be
            RETLW 5Bh         ;2  preceded with a "0."  E.g: 0A3h, 0FFh, 0CCh
            RETLW 4Fh         ;3
            RETLW 66h         ;4
            RETLW 6Dh         ;5
            RETLW 7Dh         ;6
            RETLW 07h         ;7
            RETLW 7Fh         ;8
            RETLW 6Fh         ;9

Clear       MOVLW 20h
            MOVWF 0D
            CLRF 06           ;Clear the display
            CALL Disp1
            RETURN

Display     MOVLW 80h
            MOVWF 0Ch
Disp1       BTFSS 05,0        ;Test the input line on port A
            GOTO Disp2        ;Button not pressed
            BTFSC 1F,0        ;Button pressed first time?
            GOTO DelA         ;Button already pressed
            BSF 1F,0          ;Set button-press flag
            CALL Inc          ;Button pressed. Increment count
            GOTO DelA
Disp2       BCF 1F,0
DelA        NOP
            DECFSZ 1A,1
            GOTO DelA
            DECFSZ 0C,1
            GOTO Disp1
            RETURN

Inc         INCF 11h,1        ;Increment units.
            MOVLW 0A          ;Has count reached ten?
            XORWF 11h,0       ;Compare file 11h with ten
            BTFSS 03,2        ;Check the zero flag in Status file
            RETURN            ;Count has not reached ten
            CLRF 11h          ;Zero the units file
            INCF 12h,1        ;Increment tens.
            MOVLW 0A          ;Has count reached ten?
            XORWF 12h,0       ;Compare file 12h with ten
            BTFSS 03,2        ;Check the zero flag in Status file
            RETURN            ;Count has not reached ten
            CLRF 12h          ;Zero the tens file
            INCF 13h,1        ;Increment hundreds.
            MOVLW 0A          ;Has count reached ten?
            XORWF 13h,0       ;Compare file 13h with ten
            BTFSS 03,2        ;Check the zero flag in Status file
            RETURN            ;Count has not reached ten
            CLRF 13h          ;Zero the hundreds
            RETURN

Main        MOVF 13h,0        ;Copy 'hundreds' into W
            CALL Table
            MOVWF 06          ;Display the number
            CALL Display
            CALL Clear
            MOVF 12h,0        ;Copy 'tens' into W
            CALL Table
            MOVWF 06          ;Display the number
            CALL Display
            CALL Clear
            MOVF 11h,0        ;Copy 'units' into W
            CALL Table
            MOVWF 06          ;Display the number
            CALL Display
            CLRF 06           ;Blank the display
            CALL Clear
            CALL Clear
            CALL Clear
            GOTO Main

            END               ;Tells assembler end of program

It is very easy to change the program to create a 4 or 5 digit display. A new file (say 14h) must be added. It is cleared in SetUp and added to Inc sub-routine (by copying instructions) to produce thousands. It is then added to Main by copying a small block of instructions in Main and changing the values as needed.

ANALOGUE TO DIGITAL (A-to-D)

The analogue input on the PIC LAB-1 reads a value of resistance connected to the “pot” terminals.


Connecting a potentiometer to the PIC LAB-1

The value of resistance can be almost any value from 10 ohms to 1M (and higher).
But it’s a little bit more complex than simply fitting an unknown value of resistance and showing the value on the display.
The program has to be “set up.”
It works like this:
The first step is to decide on the maximum resistance you wish to measure. Suppose it is 1,000 ohms.
The input line is capable of dividing this value into 256 parts (say 250 parts). This means the resolution is 1,000/250 = 4 ohms
If the maximum value is 10,000 ohms, the resolution is 40 ohms.
If the maximum resistance is 100,000 ohms, the resolution is 400 ohms and for 1M it is 4k.
This is the resolution if we use a single file to hold the result. We can get a better resolution if two files are used (256 x 256 = 65,535 parts) and this will be a future experiment.
For now, we will keep it simple and use a single file.
In the first case, a filled count-file (containing 250) must indicate 1,000 on the display. To perform the conversion, the transfer from the count-file to the display files (files 11h, 12h and 13h) is carried out 4 times. In other words the 250 is multiplied by 4 to get 1,000.
The pot included in the kit is 10,000 ohms. To convert 1,000 to 10,000 a zero is added to the display.
Connect the pot to the project, burn the following program into the PIC chip and rotate the pot. You will be able to read the value on the display (from nearly zero ohms to about 10k).
The lowest digit (“0”) is added to the 3-digit counter (shown above) to get 4 digits.

      ;Pot1.asm
      ;Project: Potentiometer to PIC LAB-1
List P = 16F84
#include <p16F84.inc>
__CONFIG 1Bh ;_CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC

      ORG 0             ;This is the start of memory for the program.
SetUp BSF 03,5          ;Go to Bank 1
      CLRF 06           ;Make all Port B output
      MOVLW 10h         ;Load W with 0001 0000
      MOVWF 05          ;Make RA4 input
      BCF 03,5          ;Go to Bank 0 - the program memory area.
      CLRF 05           ;Clear PortA
      GOTO Main1

Table ADDWF 02h,1       ;Add W to the Program Counter to create a jump.
      RETLW 3Fh         ;0    format= gfedcba
      RETLW 06h         ;1    If any table value has a leading letter, it must be
      RETLW 5Bh         ;2  preceded with a "0." E.g: 0A3h, 0FFh, 0CCh
      RETLW 4Fh         ;3
      RETLW 66h         ;4
      RETLW 6Dh         ;5
      RETLW 7Dh         ;6
      RETLW 07h         ;7
      RETLW 7Fh         ;8
      RETLW 6Fh         ;9

Clear MOVLW 80h
      MOVWF 1B
      CLRF 06           ;Clear the display
      CALL Delay
      RETURN

Delay NOP               ;Create 300mS delay
      NOP
      DECFSZ 1A,1
      GOTO Delay
      DECFSZ 1B,1
      GOTO Delay
      RETURN

Inc   INCF 11h,1        ;Increment units.
      MOVLW 0A          ;Has count reached ten?
      XORWF 11h,0       ;Compare file 11h with ten
      BTFSS 03,2        ;Check the zero flag in Status file
      RETURN            ;Count has not reached ten
      CLRF 11h          ;Zero the units file
      INCF 12h,1        ;Increment tens.
      MOVLW 0A          ;Has count reached ten?
      XORWF 12h,0       ;Compare file 12h with ten
      BTFSS 03,2        ;Check the zero flag in Status file
      RETURN            ;Count has not reached ten
      CLRF 12h          ;Zero the tens file
      INCF 13h,1        ;Increment hundreds.
      MOVLW 0A          ;Has count reached ten? ;Compare file 13h with ten
      XORWF 13h,0       ;Check the zero flag in Status file
      BTFSS 03,2        ;Count has not reached ten
      RETURN            ;Zero the hundreds
      CLRF 13h
      RETURN

Look  CLRF 0C           ;Count-down file
      BSF 06,7          ;Take cap HIGH
Look2 NOP
      INCF 0C,1
      BTFSC 05,4        ;Is input LOW?
      GOTO Look2
      BCF 06,7          ;Take cap low
      RETURN

Main  MOVF 13h,0        ;Copy 'hundreds' into W
      CALL Table
      MOVWF 06          ;Display the number
      CALL Delay
      CALL Clear
      MOVF 12h,0        ;Copy 'tens' into W
      CALL Table
      MOVWF 06          ;Display the number
      CALL Delay
      CALL Clear
      MOVF 11h,0        ;Copy 'units' into W
      CALL Table
      MOVWF 06          ;Display the number
      CALL Delay
      CALL Clear
      MOVLW 3Fh
      MOVWF 06          ;Output "0"
      CALL Delay
      CALL Clear        ;Blank display
      CALL Delay
      CALL Delay
Main1 CLRF 11h          ;Clear 'units' file
      CLRF 12h          ;Clear 'tens' file
      CLRF 13h          ;Clear 'hundreds' file
      CALL Look
      MOVLW 04          ;Four loops of "Count to display"
      MOVWF 0F
Main2 MOVF 0C,0         ;Copy 0C to W
      MOVWF 0E          ;Move W to 0E
Main3 DECFSZ 0E,1       ;Move count-down file to display-value
      GOTO Main4
      DECFSZ 0F,1
      GOTO Main2
      GOTO Main
Main4 CALL Inc          ;Create display value
      GOTO Main3

      END               ;Tells assembler end of program

You will find the readout starts at 0000 and goes as high as approx 8760. It does not show 9999.
What is the problem?
This is where the answer gets technical, but very interesting.
The time-delay circuit made up of the 100n and 10k resistor in series, has a time-constant of approx 1,100mS to charge the 100n when the resistance is 10k. This is not the normal “time-constant” covered in a normal RC or time-delay circuit, where the capacitor charges to approx 66% of its maximum value. In our case the capacitor charges until the lower threshold of the input to the PIC detects a LOW. You can select any “cut-off point” or “trigger point” for any determination, providing the value can be repeated.
The “Look” circuit, looks at the input for the 4 instructions between “Look2” and GOTO Look2. These instructions take 5uS. 256 loops of 5uS = 1280uS. At a time-interval of 1,100uS the loop counter is 220. The program multiplies this by 4 to get 8800.

HOW CAN THE READING BE ALTERED?

This highlights two factors.
At an execution speed of one million instructions per second, the instruction-speed is not high enough to allow the programmer to adjust the length of the loop. In other words, instructions cannot be added or deleted to make minor increments or decrements. If we remove the NOP in the loop, the counter will reach 256 when the resistance is about 8 or 9k and this will produce a false reading on the other side of the range.
The only thing we can do is match the circuit to the program.
If the capacitor is increased in value by about 10 times (to 1u), the charge-time will increase and this will give the programmer the ability to adjust the length of the loop.

ALTERNATIVE DETECTION METHOD

There is another method of detecting the value of resistance using only a single input/output line. The circuit is shown below. It does not matter if the pot is above or below the capacitor.


Measuring resistance with a single in/out line

The program is not as fast as the method above and will result in a slower “up-date.” To achieve the same resolution as above, the charging capacitor will have to be a large value (1u or higher) to allow the loop-counter to fill completely.
The program starts with an uncharged capacitor and the “drive-line” goes high for a short period of time. The line is then changed to an input (a sense-line) and the voltage measured. The input line can only detect a change from a LOW to a HIGH. If it does not detect a HIGH, the line is changed back to an output (“drive-line”) and the cycle is repeated. In this way the capacitor is gradually charged. The line reversal takes a few microseconds and a delay (a NOP) should be placed in the program to allow the line to settle from one state to the other before a reading is made.
The program for the “look” section is as follows. To take advantage of the TRIS function, you must know the state of the other lines on Port B, if you don’t want them to change state during this operation.

LookB CLRF 0C           ;Count-down file
LookC MOVLW 00h
      TRIS 06           ;Make the top line an output. (0000 0000)
      BSF 06,7          ;Take cap HIGH
      INCF 0C,1
      MOVLW 80h
      TRIS 06           ;Make the top line an input. (1000 0000)
      NOP               ;Create a delay before reading input
      BTFSS 06,7        ;Is input HIGH?
      GOTO LookC        ;No
      RETURN            ;Yes.

This method takes 10uS per loop and our previous method takes 5uS.
This is not a problem with our simple experiments. It simply means the update time is longer.
To get the count-file to completely fill using the 10uS loop, the capacitor will have to be larger and this will also increase the update time.


Colin Mitchell

Colin Mitchell

Expertise

electronics
writing
PIC-Chips

Social Media

instagramtwitterwebsite

Related Posts

TODO
Transistor Test
© 2021, All Rights Reserved.

Quick Links

Advertise with usAbout UsContact Us

Social Media