Having trouble with numbers?

I am having trouble representing numbers (decimal, integers). For example, I am using some older code by Hippy to bit-bang data to an LCD. The code is:

Code:


Symbol bitRS = bit8
Symbol bitWR = bit9
Symbol bitE = bit10
Symbol bitD4 = bit12
Symbol bitD5 = bit13
Symbol bitD6 = bit14
Symbol bitD7 = bit15

symbol bit_light=bit11 ; transistor that controls LCD backlight:

Pause 2000

Initialisation:

HI2cSetup I2CMASTER, $4E, I2CSLOW, I2CBYTE

b0 = $33 : Gosub SendB0AsInitByte
b0 = $33 : Gosub SendB0AsInitByte
b0 = $32 : Gosub SendB0AsInitByte
b0 = $28 : Gosub SendB0AsCommandByte
b0 = $0C : Gosub SendB0AsCommandByte
b0 = $06 : Gosub SendB0AsCommandByte
b0 = $01 : Gosub SendB0AsCommandByte

Pause 2

SendLCD:

b0 = $80 : Gosub SendB0AsCommandByte
b0 = "M" : Gosub SendB0AsDataByte
b0 = "o" : Gosub SendB0AsDataByte
b0 = "n" : Gosub SendB0AsDataByte
b0 = "i" : Gosub SendB0AsDataByte
b0 = "t" : Gosub SendB0AsDataByte
b0 = "o" : Gosub SendB0AsDataByte
b0 = "r" : Gosub SendB0AsDataByte
b0 = " " : Gosub SendB0AsDataByte
b0 = "O" : Gosub SendB0AsDataByte
b0 = "N" : Gosub SendB0AsDataByte

Send_Count:

b0 = $01 : Gosub SendB0AsCommandByte ;go home
counter=0
do while counter<9
pause 500
b0 = $counter : Gosub SendB0AsDataByte
inc counter
loop


SendB0AsInitByte:

Pause 15
bitWR = 0 ; Keep WR signal low

SendB0AsCommandByte:

bitRS = 0 ; Send byte as a command

SendB0AsDataByte:

bitD4 = bit4 ; Send msb first
bitD5 = bit5
bitD6 = bit6
bitD7 = bit7

bit_light=1 ;LCD backlight on
bitE = 1
b2 = b1 ; b2 holds msb with E set
bitE = 0 ; b1 holds msb with E clear

HI2cOut b1, ( b2, b1 )

bitD4 = bit0 ; Send lsb second
bitD5 = bit1
bitD6 = bit2
bitD7 = bit3

bitE = 1
b2 = b1 ; b2 holds lsb with E set
bitE = 0 ; b1 holds lsb with E clear

HI2cOut b1, ( b2, b1 )

bitRS = 1 ; Send data byte next time

Return

End Code

So, I want to calculate a number and display it on the LCD. The problem is in the "Send_Count" segment. I tried setting several formats, just squares on the LCD.

Thanks
 

hex

Active member
LCD expects ASCII characters, not raw numbers
Check the datasheet for your LCD module, by most commonly, sending 0 to 9 will cause custom characters to be displayed
If you have not set any custom characters, then what is display will be undefined.

I see no obvious way to display a simple number in the above code.

Try changing:

C:
counter=0
do while counter<9
To:
C:
counter=48                       ; ASCII zero
do while counter<57         ; ASCII nine
Not tried it myself - could be wrong
 

hex

Active member
If you tell me exactly which PICAXE chip you are using, then I may be able to help further.

but...........

I highly recommend using a serial LCD, such as AXE133Y.
PICAXE systems are well suited to serial LCD. Badly suited to parallel LCD
 

erco

Senior Member
You just taught this old dog a new trick... I thought bit- stopped at bit7! But according to PE5 syntax checker it goes up to bit31. Nice.
 

tmfkam

Senior Member
The code being shown is for an ic2 LCD I think?

Are you sure the connected LCD is ic2?
Does it definitely have the same ic2 address?

Squares on the LCD usually mean the LCD has power, but has not been initialised by the processor. Before that has been done, no characters will be displayed, however they are (or are not) sent.
 

cpedw

Senior Member
A simple dodge to avoid remembering that 48 is the magic to convert a digit to its ASCII version for printing:

PrintNumber = "0" + Number
 

Flenser

Senior Member
I tried setting several formats, just squares on the LCD.
When you connect just 5V & GND to an LCD you should see a line of white blocks. This indicates that the LCD is working (because it does display these block characters). It also indicates that the LCD has not been initialized because when the LCD is initialized the display is cleared (i.e. the blocks are removed).

I recognize the code in your post #1. It is Hippy's LCD-I2C.txt program from here for driving a character LCD with one of the I2C backpacks.

So the questions that tmfkam has asked are all important for you to answer.

Squares on the LCD usually mean the LCD has power, but has not been initialised by the processor. Before that has been done, no characters will be displayed, however they are (or are not) sent.
and
The code being shown is for an ic2 LCD I think?

This first section of Hippy's program is the code thatt does the intialization of an LCD that is conennected usign an I2C backpack.
Code:
Initialisation:

  HI2cSetup I2CMASTER, $4E, I2CSLOW, I2CBYTE

  b0 = $33 : Gosub SendB0AsInitByte
  b0 = $33 : Gosub SendB0AsInitByte
  b0 = $32 : Gosub SendB0AsInitByte
  b0 = $28 : Gosub SendB0AsCommandByte
  b0 = $0C : Gosub SendB0AsCommandByte
  b0 = $06 : Gosub SendB0AsCommandByte
  b0 = $01 : Gosub SendB0AsCommandByte

  Pause 2
After this initialization code runs you should see the blocks removed. The fact that you still see the blocks means that the initialization has not worked. If the initialization is not successfully completed then nothing else you send to the LCD will work.

The first things you need to do to debug your issue is to answer these next two questions.
Are you sure the connected LCD is ic2?
Does it definitely have the same ic2 address?
If you can post a picture showing how the PICAXE chip is connected to the LCD.
You should show the back of the LCD so that we can see the wires connecting the PICAXE pins to the LCD pins.
 
Last edited:

lbenson

Senior Member
Note that for @hex's alteration to output the ASCII numerals "0"-"8", instead of using the ASCII numbers which represent those numerals, you can use the numerals themselves:

counter="0"
do while counter<"9"

(Note: to preserve the indentation in Hippy's code, enclose the code in the tags "[ code]" and "[ /code]" (without the space following "[").)
 
If you tell me exactly which PICAXE chip you are using, then I may be able to help further.

but...........

I highly recommend using a serial LCD, such as AXE133Y.
PICAXE systems are well suited to serial LCD. Badly suited to parallel LCD
I agree, but I need to understand the conversion of variables to output. I am having the same problem with "sertxd" commands.
 
When you connect just 5V & GND to an LCD you should see a line of white blocks. This indicates that the LCD is working (because it does display these block characters). It also indicates that the LCD has not been initialized because when the LCD is initialized the display is cleared (i.e. the blocks are removed).

I recognize the code in your post #1. It is Hippy's LCD-I2C.txt program from here for driving a character LCD with one of the I2C backpacks.

So the questions that tmfkam has asked are all important for you to answer.


and



This first section of Hippy's program is the code thatt does the intialization of an LCD that is conennected usign an I2C backpack.
Code:
Initialisation:

  HI2cSetup I2CMASTER, $4E, I2CSLOW, I2CBYTE

  b0 = $33 : Gosub SendB0AsInitByte
  b0 = $33 : Gosub SendB0AsInitByte
  b0 = $32 : Gosub SendB0AsInitByte
  b0 = $28 : Gosub SendB0AsCommandByte
  b0 = $0C : Gosub SendB0AsCommandByte
  b0 = $06 : Gosub SendB0AsCommandByte
  b0 = $01 : Gosub SendB0AsCommandByte

  Pause 2
After this initialization code runs you should see the blocks removed. The fact that you still see the blocks means that the initialization has not worked. If the initialization is not successfully completed then nothing else you send to the LCD will work.

The first things you need to do to debug your issue is to answer these next two questions.


If you can post a picture showing how the PICAXE chip is connected to the LCD.
You should show the back of the LCD so that we can see the wires connecting the PICAXE pins to the LCD pins.
I was not clear enough. The LCD works fine, and I can send output in "qoutes" that displays exactly what is in the quotes. I just can't figure out how to calculate a number, say 7, and then have the LCD display 7
 
More Info: I am using a 28x2 communicating via I2c bus with a PCF8574T expander to an HD44780 LCD, a 24LC128 EEPROM, a DS3231 RTC, and an MC23008 expander (reading a keypad). All the electronics are working (meaning I managed to find the right addresses and get the hi2cin commands formatted right (the 28x2 makes that easier since I don't have to issue setup commands before each different device). I just have problems formatting the results from the chips. I get good data from the clock, but can't display it, good data from the keypad but can't display, etc. It may be something like not having a "$" or "%" in front of the variables. I can't seem to find a listing in the manual about how to prefix hex, decimal, etc, just references here and there. I am using Editor 6.2.0 (the latest one). Appreciate all the help. Thanks.
 

AllyCat

Senior Member
Hi,

The $ and % determine how constants are interpreted but for variables (e.g. b1 or w1) the # symbol can sometimes control how a variable is displayed. But first, if the Byte or Word variable can be displayed as a single digit then it can be converted to an ASCII character simply by adding "0" , or 48 (decimal) or $30 or %110000 (which all represent exactly the same numerical value). For the "Hex" values between 10 and 15 you can also add another 7 (i.e. 55 in total) to create the capital letters A to F (ASCII 65 to 70).

Using a normal SEROUT or SERTXD command you can convert any byte or word variable to directly send the appropriate number of digits (e.g. SERTXD (#w1) ) but when writing to most types of I2C display you may need to send the individual digits (in ASCII format), or you might want a fixed-width format (i.e. number of digits) to display in columns. One way to do this is the BINTOASCII or BCDTOASCII commands, e.g. BINTOASCII w1 , b4 , b5 , b6 , b7 , b8 .
Code:
w1=12345
sertxd(#w1,cr,lf)
BINTOASCII w1,b4,b5,b6,b7,b8
sertxd (b4,b5,b6,b7,b8,cr,lf)
Cheers, Alan.
 

AllyCat

Senior Member
Hi,

Yes, strictly it should be 4 arguments for a Byte variable and 6 for a Word (or 3 and 5 for the BCD version). However, if you know that a Word value will never exceed 3 digits, for example, you can use BINTOASCII w1 , b4 , b4 , b4 , b5 , b6 to save a few byte variables. But you can't overlay the source and destination bytes (e.g. BCDTOASCII w1 , b2 , b3 , b4 , b5 ), so sometimes I write my own routine (for example using repeated modulus/division by 10), which may also save a few program bytes.
Code:
#picaxe 28x2
w1 = 987    ; Maximum 999 for this example
BINTOASCII w1,b4,b4,b4,b5,b6  ; This line = 45 Program bytes
sertxd (b4,b5,b6)
b1 = w1 / 10          ; ) 
b3 = w1 // 10 + 48    ; )
b2 = b1 // 10 + 48    ; }  These lines = 25 Program bytes
b1 = b1 / 10 + 48     ; )
sertxd (b1,b2,b3)
; Note that W1 is destroyed, but (since 4800 + 480 + 48 = 5328) :
w1 = b1 * 10 + b2 * 10 + b3 - 5328  ;  This line = 14 Program bytes
sertxd(#w1)
Incidentally, single Hex characters can be converted using a simple "One Liner" : PrintHEX = Number / 10 * 7 + Number + "0" :
Code:
for b0 = 0 to 15
  b1 = b0 / 10 * 7 + b0 + "0"    ; Because 7 = "A" - ("9" + 1) = 65 - 57 - 1 or $41 - $39 - 1
  sertxd(b1)
next
Cheers, Alan.
 

Flenser

Senior Member
Bayside888,

When I want to write digits to an LCD is almost always because I want to display the contents of a variable as a set of digits.
I have posted a code snippet here that converts the contents of a word variable to a set of 5 digits using just 37 bytes of program code.
 
Top