# 6 digit odometer or event counter

Status
Not open for further replies.

#### fastback86

##### Member
I need to know if anyone has built or knows how to build an odometer (with memory) for a car using a 6 digit LED common anode display based on a PIC. I've looked for some examples and I don't have a very good understanding of ASM code to program a PIC or even a modify a similar circuit to do what I want. I've looked through Nigel's tutorials but there must be something basic about programming I just don't know. I have a 16F628 and a few circuits based on the chip I was hoping to be able to modify but I'll be honest...I don't have clue!

I'm building a digital dash for one of my old cars and already have designed fuel, battery, oil pressure, and water temperature around lm3914's and ICL7107's. I can get a signal from the Vehicle speed sensor which outputs 8,000 pulses per mile. I could build it using older CMOS or TTL circuitry but that would be an overly large circuit.

I want to stress I don't mean to ask anyone do to it for me, just for help or guidance as I'm not getting the gist of it.

Thanks everyone!

#### ChrisP58

##### Well-Known Member
You can also get compilers that will allow you to program in C or Basic. They might be an easier to learn.

#### crutschow

##### Well-Known Member
I recommend using a microprocessor that has a Basic language available as I believe it's the easiest for beginners to learn (that's the reason is was invented). C or Assembly are rather arcane, somewhat like learning a completely different foreign language, whereas Basic uses standard English words for the most part.

Here's a short tutorial on Basic that may be of help to get a feel for the language. A Google search will turn up others.

#### fastback86

##### Member
Do they have a compiler that turns basic into hex for programming a PIC?

#### crutschow

##### Well-Known Member
Do they have a compiler that turns basic into hex for programming a PIC?
No, but here are some references for that. Also check on the Microchip website.

#### fastback86

##### Member
No, but here are some references for that. Also check on the Microchip website.
Thanks! I'm going to check that out.

#### fastback86

##### Member
Here's something I found interesting. This is basically what I need less the 2 most significant digits. All I would need to do is write code to advance the count 1 digit every 800 pulses to indicate 0.1 miles or 1 digit for every 8000 pulse for 1 mile. Any suggestions?

What I really found interesting was the way the displays are multiplexed...

View attachment 65476

Here's the code:

Code:
; 8DGTCACC.INC: 8 digits CA or CC 7-segments LED display
; using conditional assembly

;-------------------- keywords for conditional assembly -----------------

; uncomment only one among these two directives
#define useCAdisplay		; if using Common Anode 7-segment display
;#define useCCdisplay		; if using Common Cathode 7-segment display

; uncomment only one among these five directives
;#define PORTX	5		; if using PORTA (full 8 bits, example: PIC16F628)
#define PORTX	6		; if using PORTB (any 18 pins mid-range PICmicro)
;#define PORTX	7		; if using PORTC (any 28 pins mid-range PICmicro)
;#define PORTX	8		; if using PORTD (any 40 pins mid-range PICmicro)
;#define PORTX	9		; if using PORTE (any 40 pins mid-range PICmicro)

;------------------------------------------------------------------------
; declare in the main file:
;------------------------------------------------------------------------
;	numdgt			; .128, then .64, .32, .16, .8, .4, .2, .1
;	rlfcnt			; .8, then .7, .6, .5, .4, .3, .2, .1
;	affvis			; ratio display visible
;	dgtvis			; digit currently displayed
;
;	dgtDS7			; digit #7 (left most digit)
;	dgtDS6			; digit #6
;	dgtDS5			; digit #5
;	dgtDS4			; digit #4
;	dgtDS3			; digit #3
;	dgtDS2			; digit #2
;	dgtDS1			; digit #1
;	dgtDS0			; digit #0 (right most digit)
;
;------------------------------------------------------------------------
; macro to prepare input parameters to "Disp" routine
;------------------------------------------------------------------------
DISPDGT	macro	posdgt, dgt
MOVLW	posdgt
MOVWF	rlfcnt
MOVF	dgt, w
CALL	Disp
endm

;------------------------------------------------------------------------
;config. RBx & CC as outputs, (if Common Cathode), then RBx=HIGH & CC=LOW
;Config. RBx & CA as outputs, (if Common Anode), then RBx=LOW & CA=HIGH
;------------------------------------------------------------------------
SEGx	macro REGx, RBx, jump, configRB, dgtX
BTFSC dgtX, RBx
GOTO  jump

#ifdef	useCCdisplay
BTFSS REGx, RBx		; conditional assembly
#endif

BTFSC REGx, RBx		; conditional assembly
#endif

GOTO  jump
BSF STATUS, RP0		; flip to bank1
MOVLW configRB
XORWF dgtX, w
MOVWF PORTX
BCF STATUS, RP0		; go back to bank0
MOVLW configRB

#ifdef	useCCdisplay
XORLW 0FFh		; complement W (conditional assembly)
#endif

MOVWF PORTX

MOVLW	.128		; internal delay = 0.5 ms (quartz 4 MHz)
BTFSS	STATUS, Z	; bit Z=1 (i.e. W = 0 ?)
GOTO	\$-2		; loop = 4 * 128 = 512 us

endm

;-----------------------------------------------------------------------
; Routine to display 8 digits
; (one digit at a time, segment by segment individually)
;-----------------------------------------------------------------------
Display
MOVLW	.15
MOVWF	affvis
dispdgts
DISPDGT	.8, dgtDS7
DISPDGT	.7, dgtDS6
DISPDGT	.6, dgtDS5
DISPDGT	.5, dgtDS4
DISPDGT	.4, dgtDS3
DISPDGT	.3, dgtDS2
DISPDGT	.2, dgtDS1
DISPDGT	.1, dgtDS0

DECFSZ	affvis, f
GOTO	dispdgts
RETURN

;-----------------------------------------------------------------------
; Common Cathode digit, light segment by segment
; Common Anode digit, light segment by segment
;-----------------------------------------------------------------------
Disp
MOVWF   dgtvis

MOVLW	high Tab7seg
MOVWF	PCLATH
MOVF	dgtvis, w	; (dgtvis) -> W
CALL	Tab7seg		; convert
MOVWF	dgtvis		; (dgtvis) converted to 7 segments code

COMF	dgtvis, f	; conditional assembly (for Common Anode)
#endif
CLRF	numdgt
BSF	dgtvis, 7
BSF	STATUS, C
rlfloop
RLF	numdgt, f
RLF	dgtvis, f
BTFSC	STATUS, C
GOTO	setBit0
BCF	dgtvis, 0
GOTO	rlfnext
setBit0
BSF	dgtvis, 0
rlfnext
BCF	STATUS, C
DECFSZ	rlfcnt, f
GOTO	rlfloop

DispsegA SEGx dgtvis,0,DispsegB,0FEh, numdgt ; Disp. dgtvis, bit0
DispsegB SEGx dgtvis,1,DispsegC,0FDh, numdgt ; Disp. dgtvis, bit1
DispsegC SEGx dgtvis,2,DispsegD,0FBh, numdgt ; Disp. dgtvis, bit2
DispsegD SEGx dgtvis,3,DispsegE,0F7h, numdgt ; Disp. dgtvis, bit3
DispsegE SEGx dgtvis,4,DispsegF,0EFh, numdgt ; Disp. dgtvis, bit4
DispsegF SEGx dgtvis,5,DispsegG,0DFh, numdgt ; Disp. dgtvis, bit5
DispsegG SEGx dgtvis,6,DispsegX,0BFh, numdgt ; Disp. dgtvis, bit6
DispsegX SEGx dgtvis,7,Dispoff, 07Fh, numdgt ; Disp. dgtvis, bit7

Dispoff
CLRF	PORTX		; clear portX
RETURN

; 8DGTCNT.ASM: main file to test display file "8DGTCACC.INC"

;------------------------------------------------------------------------------
list P = 16F628A
#include <p16f628a.inc>
__CONFIG _CP_OFF &_BODEN_OFF &_PWRTE_ON &_WDT_OFF &_LVP_OFF &_MCLRE_OFF &_INTRC_OSC_NOCLKOUT

;---------------------- DEFINE HARDWARE ---------------------------------------
#define	BTN	PORTA, 4	; push button connected to RA4

;--------------------- DEFINE VARIABLES ---------------------------------------
CBLOCK	0x70		; common RAM [16 bytes, 0x70 to 0x7F]
numdgt			; .128, puis .64, .32, .16, .8, .4, .2, .1
rlfcnt			; .8, puis .7, .6, .5, .4, .3, .2, .1
affvis			; ratio display visible
dgtvis			; digit currently displayed

dgtDS7			; digit #7 (left most digit)
dgtDS6, dgtDS5, dgtDS4	; digit #6, digit #5, digit #4
dgtDS3, dgtDS2, dgtDS1	; digit #3, digit #2, digit #1
dgtDS0			; digit #0 (right most digit)
ENDC

;------------------------------------------------------------------------------
; increment one digit from 0 to maxi-1 ; if maxi, then wrap to 0
;------------------------------------------------------------------------------
INC1	macro	digitX, maxi, jump
INCF	digitX, f	; increment digitX
MOVLW	maxi
XORWF	digitX, w
BTFSS	STATUS, Z	; digitX = maxi ?
GOTO	jump		; no
CLRF	digitX		; yes, then clear digitX
endm

;//////////////////////////////////////////////////////////////////////////////
ORG  0x00		; reset vector
GOTO Start
;------------------------------------------------------------------------
; L.U.T. to convert a decimal value into the corresponding 7 segment code
;------------------------------------------------------------------------
Tab7seg
ADDWF PCL, f		; display 7 segments GFEDCBA
DT 3Fh, 06h, 5Bh, 4Fh, 66h, 6Dh, 7Dh, 07h, 7Fh, 6Fh

;/////////////////////////////////////////////////////////////////////////////////
#include "8DGTCACC.INC"
;/////////////////////////////////////////////////////////////////////////////////
Start
bsf	STATUS, RP0	; flip to Bank 1
bsf	BTN		; config. BTN as input
bcf	STATUS, RP0	; back to Bank 0

clrf	dgtDS7
clrf	dgtDS6
clrf	dgtDS5
clrf	dgtDS4
clrf	dgtDS3
clrf	dgtDS2
clrf	dgtDS1
clrf	dgtDS0
tstBtn
btfsc	BTN		; BTN pushed
goto	majDisp		; no
IncDgts
INC1	dgtDS0, .10, majDisp
INC1	dgtDS1, .10, majDisp
INC1	dgtDS2, .10, majDisp
INC1	dgtDS3, .10, majDisp
INC1	dgtDS4, .10, majDisp
INC1	dgtDS5, .10, majDisp
INC1	dgtDS6, .10, majDisp
INC1	dgtDS7, .10, majDisp
majDisp
CALL    Display
GOTO	tstBtn
;------------------------------------------------------------------------
END
Here's where I found the circuit:

http://www.edn-europe.com/eightdigitcounterworkswithcommonanodeorcommoncathode+article+4329+Europe.html#ref1

Last edited:

#### OlPhart

##### Member
I'm going to espouse the draconian: Take the time to do it in assembler! A Freescale microcontroller easily tracks voltage, velocity, odometer (a sub of velo), oil temp, water temp and oil pressure. I know this because I have one I built for my K75KS. Its' first build was a Z80, but they were OTP (one time pgmable). I was turned onto Freescale, by a colleague, and its' flash aspects were worth the trade off of a less flexible instruction set.

I built a second version for my K75RS: different display, & user interface, but same core.

Your first build will be tough. I can help. but neither turnkey nor free (exc tidbits). That you derive this (ostensibly) by yourself, your grasp & ability will have made significant progress.

I would be happy to generate a descriptive schema of the programs' flow, but my time is well demanded, and I'm known for teaching how to fish.... Not providing them. <<<)))

P.S Only if you want to drink the "koolaid".... I'm Old School and don't trust many of the currently accepted methods. Season to taste...

Last edited:

#### fastback86

##### Member
I'm going to espouse the draconian:
You're going to expose what? LOL! Are you quoting something esoteric?

Take the time to do it in assembler! A Freescale microcontroller easily tracks voltage, velocity, odometer (a sub of velo), oil temp, water temp and oil pressure.
Wouldn't a microcontroller by any manufacturer do it easily?

I know this because I have one I built for my K75KS.
Sweet. You would know exactly what I'm looking for.

I built a second version for my K75RS: different display, & user interface, but same core.
Can I see a photo of either version? I love instrumentation.

Your first build will be tough. I can help. but neither turnkey nor free (exc tidbits). That you derive this (ostensibly) by yourself, your grasp & ability will have made significant progress.

I would be happy to generate a descriptive schema of the programs' flow, but my time is well demanded, and I'm known for teaching how to fish.... Not providing them. <<<)))
I agree. Only through suffering will I learn anything. That's how I learned most of what I already know. I guess my next step is to try to recode the circuit in my previous post and ask for help if I get stuck.

P.S Only if you want to drink the "koolaid".... I'm Old School and don't trust many of the currently accepted methods. Season to taste...
Actually I would like to learn how to make the koolaid. There's many flavors I would like to be able to make. I have the ingredients, I just need to figure how much to use and when to use them. Unfortunately I don't know enough about chemistry.

#### crutschow

##### Well-Known Member
My eyes tend to glaze over whenever I see an Assembly program, but if you want to go through the time consuming pain of learning it, that's your call. But unless you need to program for absolute maximum efficiency in the program execution, Assembly has no particular advantage. And it can take a dozen or more Assembly commands to do what one high level language command can do.

I guess Assembly is just too tedious for me, sorta like trying to write a large number in binary rather than decimal.

Last edited:

#### colin55

##### Well-Known Member
Do you realise how dull the display will be?

#### fastback86

##### Member
Here's a 12 digit timer,

View attachment 65494