Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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. :rolleyes:

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. :D

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.

EE World Online Articles

Loading
Top