Displaying the temperature from DS18B20 on Hitachi 2x16 LCD

Lobobo

Member
Hi. I believe that there is answer for my question somewhere in the forum, but I could not find it.
So I am trying to make some temperature display where I am using DS18B20 sensor and Hitachi 16x2 LCD display conected like it's shown in mannual 2 page 36. It displays a message from eeprom like in the example from the manuals, but when I try to display read data from DS18B20, it gives me a mess symbols. I understand that there is a problam in variable type, but I cannot figure it out how to make it work. Please have a look into my code. Most of it is copied from book and my not working part is to display the variables tents and singles. Please help.

#Picaxe 28x1

symbol button1 = pin1
symbol button2 = pin2
symbol temperature = b0
symbol system_var = b1
symbol system_var2 = b2
symbol system_var3 = b3
symbol system_var4 = b4
symbol hundreds = b5
symbol tents = b6
symbol singles = b7
symbol temp_var = b8

gosub init
pause 500

main:

pause 500
readtemp 0, temperature
bintoascii temperature, hundreds, tents, singles
gosub show_temp
debug
goto main


show_temp:

temp_var = 12 'hide cursor
gosub wrins
pause 10
temp_var = 1 'clear screen
gosub wrins
pause 10
temp_var = 128 'move to first line
gosub wrins
pause 10
temp_var = hundreds 'display hundreds on the screen
gosub wrcht
pause 15
temp_var = tents 'display tents
gosub wrcht
pause 15
temp_var = singles 'display singles
gosub wrcht
pause 15
return

wrcht: 'prints char on the screen (temp_var)
pins = temp_var & %11110000 | system_var3
pulsout 3, 1
pins = temp_var * %00010000 | system_var3
pulsout 3, 1
system_var3 = %00000100
return

wrins: 'LCD listens specific comands stored in temp_var
pins = temp_var & 240 'Mask the high nibble of system_var into b2.
pulsout 3,1 'Pulse the enable pin to send data.
system_var2 = temp_var * 16 'Put low nibble of system_var into b2.
pins = system_var2 & 240 'Mask the high nibble of b2
pulsout 3,1 'Pulse enable pin to send data.
high 2 'Back to character mode
return

init: 'resets and restores LCD screen
let pins = 0 'Clear all output lines
let system_var4 = 0 'Reset variable b4
pause 200 'Wait 200 ms for LCD to reset.
let pins = 48 'Set to 8-bit operation.
pulsout 3,1 'Send data by pulsing ‘enable’
pause 10 'Wait 10 ms
pulsout 3,1 'Send data again
pulsout 3,1 'Send data again
let pins = 32 'Set to 4-bit operation.
pulsout 3,1 'Send data.
pulsout 3,1 'Send data again.
let pins = 128 'Set multiple line operation
pulsout 3,1 'Send data.
let system_var = 14 'Screen on, cursor on instruction
gosub wrins 'Write instruction to LCD
return
Thank you.
 

Lobobo

Member
Actualy I had a surprise. After I posted my issue (above), I have tried to display some text what I had saved in EEPROM and the same temperature variable after it, same coding what wasn't working. And surprisingly it started displaying everything perfectly. I don't understand what it was, but I have it working now...
Anyway if someone sees how the code could be optimised, please let me know as I in general don't understand these init, wrins, wrchr subs. Thank you.
 

Haku

Senior Member
Something I've noticed from directly controlling alphanumeric LCD screens without a serial backpack is that after programming the Picaxe the screen display can become garbled and the Picaxe+LCD need power cycling at the same time to get things running smoothly on the display.
 

marks

Senior Member
1602 display 4 bit

a few people seem to want 4 bit mode
so i thought i,d have a crack tonight
hopefully the pinouts are correct can easily be changed at the top
it was tested on my 20x2 so hoping its been ported correcty for 28x1 use
ah well you can only try it lol.

Code:
'            DB7     = 7	
'            DB6     = 6	
'            DB5     = 5	
'            DB4     = 4	        	
      SYMBOL E       = 3
'            RS      = 2				                  
      SYMBOL DS18B20 = 0
     				                  
	SYMBOL senddata    = W0  :  SYMBOL senddataMSB  = b1  : SYMBOL senddataLSB  = b0
	SYMBOL Temperature = W1		
	SYMBOL index       = b4
	SYMBOL RS          = b5
	
	SYMBOL Sign        = b10
	SYMBOL T1          = b11 
	SYMBOL T2          = b12 
	SYMBOL T3          = b13 
	SYMBOL T4          = b14 
	SYMBOL T5          = b15 
	
	
	TABLE	  0, ($30,$30,$30,$20,$20,$80,$0,$C0,$0,$10)  '(4Bit)(Function 8bit/2line/5x8)(Display On)(Clear Display)	
	TABLE  10, ("marks")
	TABLE  16, (" THE HEAT IS ON ")
	
 				
IntialiseLCD: 
      FOR  index = 0 to 9                                               
 READTABLE index, senddata : outpins = senddata  :  PULSOUT E,1 ' Initialise LCD
 	NEXT index  :  PAUSE 10	 	
						

Celsius:
Readtemp12 b.0,Temperature                          'read in result ds18b20

 Convert:                                           
  let Sign =" "                                     'Display + 
IF Temperature > 64655 THEN                         '  info     - 55 degrees          = 64656
  let Sign ="-"                                     'Display - 
   Temperature = - Temperature                      '  info   if - ie w1=1000   display   - 10.00 C
ENDIF                                
Temperature = Temperature * 25 / 4                  '  info      + ie w1=8500   display     85.00 C
                                          
BINTOASCII Temperature,T1,T2,T3,T4,T5 
  IF T1 = "0" THEN  : T1 = " "                      ' zero blanking T1
     IF T2 = "0" THEN  : T2 = " "  :ENDIF           ' zero blanking T2
  ENDIF  

                       
LCDdisplay:
       
          senddata = $80 : GOSUB Command	        '(128-147)  Line 1 Cursor Position ($80 + 1 to 19)
        
      FOR index = 10 TO 14                 
 	  READTABLE index, senddata : GOSUB Display ' sending characters to line one      
 	NEXT index    
         
 	FOR  index = 0 TO 8
 	  LOOKUP index,(Sign,T1,T2,T3,".",T4,T5,223,"C"),senddata 
 	                              GOSUB Display ' sending characters to line one       
 	NEXT index
 	  
        senddata = 192 : GOSUB Command	        '(192-211)  Line 2 Cursor Position ($C0 + 1 to 19)	
     								
  	FOR index = 16 TO 30                 
 	  READTABLE index, senddata : GOSUB Display ' sending characters to line two      
 	NEXT index
 	  
GOTO Celsius


Command:  RS = 0  :  GOTO Send           ' > RSlow  send command to LCD 
Display:  RS = 4	                       ' > RShigh send character to LCD                          	
   Send:  senddata = senddata * 16       ' > send 4Bit Mode
	  outpins = senddataMsb * 16 + RS			        
	    PULSOUT E,1                     ' \ valid data falling edge 
	       outpins = senddataLsb + RS			        
	    PULSOUT E,1                     ' \ valid data falling edge 
	                     RETURN
 

hippy

Ex-Staff (retired)
Anyway if someone sees how the code could be optimised, please let me know as I in general don't understand these init, wrins, wrchr subs.
Me neither.

They are familiar but different to what I'm familiar with and I don't really follow the changes which have been made nor understand why. For example the use of 'system_var3' in 'wrcht' and particularly the 'let system_var=14' and 'gosub wrins' at the end of the 'init:' routine.
 

jtcurneal

Senior Member
As far as using 8 bit v. 4 bit mode on displays,

I set up a device that displays time, hydraulic pressure, and tons force on a 4x20 oled
and also logs data on a micro SD card ( http://www.sparkfun.com/products/9530 )
using a Picaxe 20M2 running at 16 MHz.

My tests showed that sending the data to the display in 8 bit mode showed that the
time for a complete update of all the data ( updating the display and sending the data to the openlog ) to be about 15% faster
than sending the data using 4 bit mode.

I did not think that I wanted to lose 4 I/O pins for a 15% increase in thru-put.

Joel
 

g6ejd

Senior Member
Here's my temperature display routine:-

display_temp:
readtemp12 7,temp_word
SignBit = temp_word / 256 / 128
If SignBit = 0 Then Positive
' its negative
temp_word = temp_word ^ $ffff + 1 ' take twos comp

Positive:
TempC = temp_word * 6 ' TC = value * 0.0625
temp_word = temp_word * 25 / 100
TempC = TempC + temp_word
Htemp = TempC / 100
Ltemp = TempC % 100
If SignBit = 0 Then SerOut LCD, BAUD,(254,Line1,"+",#Htemp,".") ELSE SerOut LCD, BAUD,(254,Line1,"-",#Htemp,".") ENDIF
' be sure the fractional is two digits
Ltemp = Ltemp / 10
SerOut LCD, BAUD,(#Ltemp,223,"C") ' For the 20x4 LCD 223 is the degree symbol
Return


Where LCD = 6 and BAUD = N2400
 

Lobobo

Member
I carefully studied yor responces to my thread subject, tried to play with Marks code (works probably a little better than mine) and have to say it's not very efficient to use 4 bit display for the project and where also it needs to use control buttons on single chip. If to display things and constantly check the input status (buttons) the reaction time to button press is way to slow and project looks not professional (input read command within main program body). If to read button inputs via interupt command, after it's done the program jumps back from interupt where it was before and sometimes prints few weird symbols on the screen (as screen gets half of the commands) and this does not look professional again. If to go from interupt sub to different part of the program, it doesn't reenables interupt as it thinks interupt sub not finished yet. Unless I am wrong somewhere and you can fix me. I make the decission to use a AXE033 kit or to use 2 chips, where one of them is just to print messages on the screen.
Thanks everyone.
 

saunj

Senior Member
Here's my temperature display routine:-

display_temp:
readtemp12 7,temp_word
SignBit = temp_word / 256 / 128
If SignBit = 0 Then Positive
' its negative
temp_word = temp_word ^ $ffff + 1 ' take twos comp

Positive:
TempC = temp_word * 6 ' TC = value * 0.0625
temp_word = temp_word * 25 / 100
TempC = TempC + temp_word
Htemp = TempC / 100
Ltemp = TempC % 100
If SignBit = 0 Then SerOut LCD, BAUD,(254,Line1,"+",#Htemp,".") ELSE SerOut LCD, BAUD,(254,Line1,"-",#Htemp,".") ENDIF
' be sure the fractional is two digits
Ltemp = Ltemp / 10
SerOut LCD, BAUD,(#Ltemp,223,"C") ' For the 20x4 LCD 223 is the degree symbol
Return


Where LCD = 6 and BAUD = N2400
For us backwards Americans, just temp_word*9/8 and add or subtract from 320 depending on sign to get deg F in tenths. Hope it never gets into negative Deg F territory!
 

saunj

Senior Member
Deg F code

Here's my temperature display routine:-

display_temp:
readtemp12 7,temp_word
SignBit = temp_word / 256 / 128
If SignBit = 0 Then Positive
' its negative
temp_word = temp_word ^ $ffff + 1 ' take twos comp

Positive:
TempC = temp_word * 6 ' TC = value * 0.0625
temp_word = temp_word * 25 / 100
TempC = TempC + temp_word
Htemp = TempC / 100
Ltemp = TempC % 100
If SignBit = 0 Then SerOut LCD, BAUD,(254,Line1,"+",#Htemp,".") ELSE SerOut LCD, BAUD,(254,Line1,"-",#Htemp,".") ENDIF
' be sure the fractional is two digits
Ltemp = Ltemp / 10
SerOut LCD, BAUD,(#Ltemp,223,"C") ' For the 20x4 LCD 223 is the degree symbol
Return


Where LCD = 6 and BAUD = N2400
For us backwards Americans, just temp_word*9/8 and add or subtract from 320 depending on sign to get deg F in tenths. Hope it never gets into negative Deg F territory!
 

westaust55

Moderator
The code:
Code:
If SignBit = 0 Then Positive
' its negative
temp_word = temp_word ^ $ffff + 1 ' take twos comp
can be changed to:
Code:
If SignBit = 0 Then Positive
' its negative
temp_word = [B][COLOR="#FF0000"]-[/COLOR][/B] temp_word  ' take twos comp
which will save a few bytes should the need arise.
 
Top