# ks0108 sample code confusion - egg incubator

Status
Not open for further replies.

#### ameal

##### New Member
hi...

i´m starting an egg incubator using a ds18b20 and a ks0108 based 128*64 dysplay.
Controling them is a PIC16F876A@20Mhz, which will do the temp reading,
dysplay refresh and control the heater dimmer throught a moc3020, using a PID loop.

Till now i´ve made and tested the zero crossing detection circuit. It uses a 6N139. Fully working in my dual trace analog scope.

Now, to start controling and viewing things happening i need the display working.
So far i´ve seen some sample code from Peter Onion here.
Also some code snippets in this forum. i've been around for some time,
but i've always found my questions already answered by someone in someone else´s thead.
So no need to bother anyone, till today.

I was able to take from that code the InitLCD and the ClearLCD routines.
I´ve run the code one routine at a time using some LED´s beeing the outputs.
It works, mainly because i use 1 second delays between instructions for my eyes to see it happen.
After debug i´ve taken the delays away.
I have yet to built and debug routines like ReadLCD, Write LCD, ReadData and WriteData.
Then i´ll take away the LED´s. The remaining code will be built on top of this.

Meanwhile, i have a doubt. The display's data sheet refers to 450ns (nanoseconds) enable time.
The code i´ve seen from Peter Onion has some time delays i find too big. Like this:

Code:
#define CNTLPORT PORTB
#define CNTLTRIS TRISB
#define DATAPORT PORTA
#define	DATATRIS TRISA
;; For 20Mhz use 12.     Can be reduced at lower clock speeds
;; For 12.288Mhz use 5   Select on test !
#define DELAY 12

;; Definitions for bits in CNTLPORT

#define CSABIT 0
#define CSBBIT 1
#define DIBIT 2
#define RWBIT  3
#define EBIT   4
#define RESETBIT 5

WSTROBE	MACRO
movlw	12
movwf	scratch3
decfsz	scratch3,F
goto	$-1 bsf CNTLPORT,EBIT ; Rising edge IF 0 movlw 1 movwf scratch3 decfsz scratch3,F goto$-1
ENDIF
bcf	CNTLPORT,EBIT		; Falling edge
;  strobes data
ENDM

In there i see him setting the enable bit for 9 clock cicles, which is correct. overkill, but correct.
since two cycles will be 400ns, for a 20MHzclock, two single instructions like the following would be enough:

Code:
movlw	12
movwf	scratch3
decfsz	scratch3,F
goto	$-1 bsf CNTLPORT,EBIT ; Rising edge goto$+1                            ;2 cycles - 400ns
nop                                   ;2 cycles - 200ns
bcf	CNTLPORT,EBIT		; Falling edge

What am i missing?My code provides for 600ns. Peter´provides for 1800ns.

And what is that delay right before that is 12 time even bigger?
Is he wasting time just because he didn´t use the method of polling the LCD and waiting for the not Busy state?

i haven't put the LCD up to speed yet but i´m afraid of missing something and losing a lot of time debugging.

Warm Regards,
Hugo Ferreira,
Portugal

#### ameal

##### New Member
Egg Incubator - Working DS1820 code with Extended Precision inside

Hi...
I´ve been working in my incubator for some days now.
I found some code samples for the DS1820 here and there, including Dallas website, but only
for the direct measurement for the units value and half degree, which is give directly in one register.
I´ve lost , well ,dedicated some time to bring those extra 1/16 resolution bits out to show in my dysplay and use in the PID routines.

So, for someone that uses the DS1820 and feel the need for those extra precision bits,hereis the code and heavy comments to explain.

Code:
processor 16f876a		;
#include p16f876a.inc

cblock 0x20
;.....
TempInt, TempBH
TempLSB, TempMSB, THReg, TLReg, Res1, Res2, CountRemain, CountPerC, CRC
;------
endc

; Define text substitution
; ........

#define	Search_ROM		0xF0	;DS1820
#define	Read_ROM		0x33
#define	Match_ROM		0x55
#define	Skip_ROM		0xCC
#define	ConvertT		0x44
#define	WrScratchPad	0x4E
#define	RdScratchPad	0xBE
#define	CpScratchPad	0x48
#define	RecallE2		0xB8
#define	RdPowerSupply	0xB4
#define AlarmSearch		0xEC

;**********************************************************************
;    	Read Temperature					      *
;**********************************************************************

DS_Temp
call	DS_Rx		; Check DS1820 status
addlw	0x01		; 255=ready, 0= ready
btfss	STATUS,Z	; Zero flag set = ready
goto	Erro
GetTemp
call	DS_Reset	; Reset chip first
btfss	STATUS,Z	; Zero flag set = OK
goto	Erro		; If not response, exit
movlw	Skip_ROM	; Skip ROM command
call	DS_Tx		; Send command
movlw	RdScratchPad; Read scratch pad command
call	DS_Tx		; Send command
call	DS_Rx		; Read 8-bit data LSB
movwf	TempLSB		; Save data to register
call	DS_Rx		; Read 8-bit data MSB
movwf	TempMSB		; Save data to register
call	DS_Rx		; Read 8-bit data MSB
movwf	THReg
call	DS_Rx		; Read 8-bit data
movwf	TLReg
call	DS_Rx		; Read 8-bit data
movwf	Res1
call	DS_Rx		; Read 8-bit data
movwf	Res2
call	DS_Rx		; Read 8-bit data
movwf	CountRemain
call	DS_Rx		; Read 8-bit data
movwf	CountPerC
;call	DS_Rx		; Read 8-bit data
;movwf	CRC
call	DS_Reset	; Restart
movlw	Skip_ROM	; Skip ROM command
call	DS_Tx		; Send command
movlw	ConvertT	; Start convert command
call	DS_Tx		; Send command

btfsc	TempMSB, 7	; TempMSB,7 is clear, then positive number
goto	Erro		; If negative, return error
Call	Compute

Erro
retlw	0x00		; Temp is negative

;*****************************************************************
;
;*****************************************************************
; According to the datasheet we lose the half degree bit and follow like this:

; Temperature = TempMSB - 0.25 + (CountPerC - Count Remain) / CountPerC
; Which is the same as...
; Temperature = TempMSB - 4/16 + (16 - Count Remain) / 16
; And the same as...
; Temperature = TempMSB + (16 - Count Remain - 4) / 16
; Please note that as the temperature rises CountRemain decreases.

;Result in TempLSB and CountPerC, atributed to TempInt and TempBH  at the end

Compute
rrf		TempLSB, f		; lose the half degree bit;
movfw	CountRemain		;										CountRemain ; = 15	; = 14	; = 13	; = 12	; = 13	; ...			; = 1	; = 0
subwf	CountPerC, f	; Subtract CountRemain from CountPerC	CountPerC	; = 1	; = 2	; = 3	; = 4	; =	5	; ...			; =15	; =16
movlw	0x04			; Subtract 0,25ºC...;
subwf	CountPerC, f	; from CountPerC						CountPerC	; = -3	; = -2	; = -1	; = 0	; = 1	; ...			; =11	; =12
btfss	STATUS, C		; test for negative result							; 0xFF	; 0xFE	; 0xFD							; this will exit with
call	Complement2		; if carry, get abs value...																		; TempLSB + 0/16 ...
movf	CountPerC, w	;																									; TempLSB + 1/16...
movwf	TempBH			; Temperature Better Half =:-)																		; TempLSB + 2/16...
movfw	TempLSB			; assign TempLSB value...
movwf	TempInt			; ... to TempInt, for PID
retlw	0x01			; If Yes, (Temp as negstive then return

;*****************************************************************

;*****************************************************************;

Complement2
decf	TempLSB, f		; At this point we have TempLSB - something, so...;
; ... might as well be TempLSB - 1 + something;
decf	CountPerC, f	; decrement										CountPerC	 ; = -4	;  = -3	 ; = -2	 ;  ...	 ;  ...	 ;  ...	 ;  ...
comf	CountPerC, w	; complement									CountPerC	 ; = 3	;  = 2	 ;  = 1	 ;  ...	 ;  ...	 ;  ...	 ;  ...
movwf	DUMMY4			; store CountPerC;
movlw	0x0f			;
movwf	CountPerC		; load CountPerC
decf	DUMMY4, w		; conditioning (necessary)						CountPerC	 ; = 2	;  = 1	 ;  = 0	 ;  ...	 ;  ...	 ;  ...	 ;  ...
movfw	DUMMY4			;
subwf	CountPerC, w	;15 - abs value									CountPerC	 ; = 13	;  = 14	 ;  = 15	 ;  ...	 ;  ...	 ;  ...	 ;  ...
movwf	CountPerC		;													; this will exit with
; TempLSB - 1 + 13/16 ...
; TempLSB - 1 + 14/16 ...
return ;

You´ll be better copying the code to the MPLAB IDE and study there, as the comments go way far to the right.

Also,here is the routine i use to make that TempBH (Better Half ) into an integer.
Mainly, my display routine converts:
- the TempInt from INT to BCD. this gives a two digit number, as this is an egg incubator, will never go (hopefully ) beyond 38ºC.
- the TempBH from half nibble (1 to 16 resolution) to an integer, that is, 1 to 0,0625ºC, 2 to 0.125ºC, and so on.
So, its half nibble to a "composed" Integer and then to BCD.
This also gives a two digit value, in my aplication, beeing the higher, the result of 0,50 + 0,25 + 0,12 + 0,06 = 0,93.

Code:
;*****************************************************************

;*****************************************************************

BH2Dig

movlw	0x00
btfsc	TempBH, 3
addlw	.50
nop
btfsc	TempBH, 2
addlw	.25
nop
btfsc	TempBH, 1
addlw	.12
nop
btfsc	TempBH, 0
addlw	.06

movwf	NumL
call	Convert

movfw	Tens
movwf	Dig2
movfw	Ones
movwf	Dig1

return

Hope it helps someone.

Warm regards,
Hugo Ferreira

Status
Not open for further replies.

Replies
24
Views
24K
Replies
42
Views
6K
Replies
1
Views
1K
Replies
6
Views
2K
Replies
3
Views
6K

Loading