Writing Variable Contents to Parallel LCD

reywas

Member
Here's my working code:

Code:
[color=Black]LCD_write:  [/color][color=Green];write inch and fraction to LCD 

 
      
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Navy]1                  [/color][color=Green]; set b1 to "clear display" instruction
      [/color][color=Blue]gosub [/color][color=Black]wrins             [/color][color=Green]' send instruction to LCD

      [/color][color=Blue]bintoascii [/color][color=Purple]inches[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b2    [/color][color=Green];inches range: 0-36
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b3
      [/color][color=Blue]gosub [/color][color=Black]wrchr
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b2
      [/color][color=Blue]gosub [/color][color=Black]wrchr
      
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Red]"-"
      [/color][color=Blue]gosub [/color][color=Black]wrchr

      [/color][color=Blue]bintoascii [/color][color=Purple]numer[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b2     [/color][color=Green];numerator range: 0-32
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b3
      [/color][color=Blue]gosub [/color][color=Black]wrchr
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b2
      [/color][color=Blue]gosub [/color][color=Black]wrchr

      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Red]"/"
      [/color][color=Blue]gosub [/color][color=Black]wrchr

      [/color][color=Blue]bintoascii [/color][color=Purple]denom[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b3[/color][color=Black],[/color][color=Purple]b2     [/color][color=Green];denominator values: 2,4,8,16,32
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b3
      [/color][color=Blue]gosub [/color][color=Black]wrchr
      [/color][color=Purple]b1 [/color][color=DarkCyan]= [/color][color=Purple]b2
      [/color][color=Blue]gosub [/color][color=Black]wrchr
      
      [/color][color=Blue]return[/color]
The code is designed to simply write an inch and fraction to an LCD. It works well but I'm sure there must be a more elegant way to do this. Execution speed is top priority. Also, I could use some help figuring out a good way to strip the leading zeros. And on a completely unrelated topic: Is it OK to use a goto to exit a subroutine and go back to the top of the main routine?

Paul
 
Last edited:

premelec

Senior Member
On the leaving subroutine RETURN is the way to go and cleans up the held return address... EXIT might work - check the BASIC commands - Best not to leave in the middle of something but it's possible to write code differently so you don't need to do that. For instance don't call the GOSUB if you don't want to execute there - in short put a conditional that you'd use to exit GOSUB even before you GO...
 

inglewoodpete

Senior Member
I wrote some code for handling Leading Zero Blanking (LZB) for parallel interfaced LCDs here. This was written for a 28X2 but can be rewritten for an M2-series PICAXE.

In principle, first you write the digits to an area of RAM and then search for the first non-zero digit before outputting the remaining digits to the LCD. Of course, if the value is actually zero, you still have to send one zero character.
 

hippy

Technical Support
Staff member
The code is designed to simply write an inch and fraction to an LCD. It works well but I'm sure there must be a more elegant way to do this. Execution speed is top priority.
It is pretty much what I would write. There isn't any more elegant way to code it other than to perhaps hide code within #MACRO definitions to make it more readable. It would be possible to improve speed but speed optimisations usually make code look less elegant, for example -

Code:
bintoascii denom,b3,b3,b2     ;denominator values: 2,4,8,16,32
b1 = b3
gosub wrchr
b1 = b2
gosub wrchr
Could become -

Code:
b1 = denom / 10 + "0"
gosub wrchr
b1 = denom // 10 + "0"
gosub wrchr
Leading zero blanking can be added with ...

Code:
b1 = denom / 10 + "0"
if b1 = "0" then
  b1 = " "
end if
gosub wrchr
b1 = denom // 10 + "0"
gosub wrchr
Where there is a GOSUB followed by a RETURN, that can be optimised to just a GOTO, for example -

Code:
gosub wrchr
return
Can become ...

Code:
goto wrchr
In most cases speed can be best increased simply by running the PICAXE faster with SETFREQ. That may require adjustment to PAUSE times so it's often best to increase speed incrementally rather than jump to fastest, though trying fastest and then dropping back until it does work is an equally valid approach.

For maximum speed, copying the code which is in the 'wrins' and 'wrchr' routines to where the 'gosub' calls to those are used will make things faster. For readability it is best to use #MACRO for those. Note however that program memory used will increase.

Note that maximum speed isn't always as desirable as it may first seem. For a fast moving input which is being displayed; going faster can simply cause the reading to change so fast that it is impossible to read.

Jumping out of subroutines to the start of a program is not a good idea, though it can work if the circumstances are right. It will likely fail under Simulation though as the eventual return stack overflow will be detected as an error.

If you are wanting a 'GOTO main' in a subroutine, the question must be why you are using a GOSUB to that subroutine rather than a GOTO to that section of code in the first place. That may be an indicator that the code is not as well structured as it could be.
 

reywas

Member
Thanks for the help guys. I'll post the revised code when I'm finished working through all the ideas you gave me.

If you are wanting a 'GOTO main' in a subroutine, the question must be why you are using a GOSUB to that subroutine rather than a GOTO to that section of code in the first place. That may be an indicator that the code is not as well structured as it could be.
I was searching through previous threads for LCD information and ran across a code snippet that combined the wrins and wrchr into one routine but I failed to bookmark it. It was something like:

wrins:
low RS
goto doit
wrchr:
high RS
doit:
write data to LCD
return

I don't think that will work, at least not as a subroutine, but I can't recall exactly how it was written. I guess what I'm asking is...How are the subroutine labels and returns matched up? Can a subroutine be entered at a label other than the subroutine's naming label?
 
Last edited:

hippy

Technical Support
Staff member
The above example works because 'wrins' and 'wrchr' are both subroutines which, ultimately, terminate with a RETURN statement.

It's basically an optimisation to remove common code, for example ...

Code:
SubA:
  b0 = "A"
  b1 = b0 + 1
  Return

SubB:
  b0 = "B"
  b1 = b0 + 1
  Return
Code:
SubA:
  b0 = "A"
  Gosub CommonCode
  Return

SubB:
  b0 = "B"
  Gosub CommonCode
  Return

CommonCode:
  b1 = b0 + 1
  Return
Code:
SubA:
  b0 = "A"
  Goto CommonCode

SubB:
  b0 = "B"
  Goto CommonCode

CommonCode:
  b1 = b0 + 1
  Return
Code:
SubA:
  b0 = "A"
  Goto CommonCode

SubB:
  b0 = "B"
 
CommonCode:
  b1 = b0 + 1
  Return
 
Top