BasicMicro - Forums

www.basicmicro.com
It is currently Sat Feb 04, 2012 7:02 pm

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: displaying different languages on LCD
PostPosted: Mon Aug 09, 2010 8:51 am 
Offline
Citizen

Joined: Fri Jul 16, 2010 11:13 am
Posts: 7
Hi all,

I'm using a serial lcd with the pro 40m.
my machine needs to display different screens depending on the operating mode and in different languages.

On the BS2p40 I used each memory slot as a different language and the operator could set which language to use eg. 1= english, 2=french, 3=german etc. then using the store command i could select which language and then use a variable called addr to select which message to use. eg

lang=1 ' English
addr=ready2run ' select message to display
GOSUB displayit ' go to the routine to display message

displayit: ' ROUTINE TO SEND MESSAGES TO LCD
STORE lang ' change storage area to required language
get_data:
READ addr, char ' read address and message contents
IF char=0 THEN printitdone ' if character=0 then end of message
MAINIO: SEROUT 0,N9600,[char] ' send to LCD message 1 char @ a time
addr=addr+1 ' add 1 to memory position
GOTO get_data ' carry on
printitdone:
STORE 7 ' go back to looking at storage bank 7
RETURN

then in memory slot 1

ready2run DATA @2*msglen,cursor_pos,80,"READY ",0
running DATA @3*msglen,cursor_pos,80,"RUNNING ",0
stand_by DATA @4*msglen,cursor_pos,64," STANDBY",cursor_pos,80,"Press START ",0

The message contains both the commands to move the cursor etc on the screen and the message itself.

I need to find a way of doing something similar on the Pro 40m

Any ideas??????????

thanks

Jon


Top
 Profile  
 
 Post subject: Re: displaying different languages on LCD
PostPosted: Mon Aug 09, 2010 9:43 am 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 500
There are a variety of ways to do this. I have experimented with similar things in the past... You could use a bytetable to hold the characters for the messages. You could do one for all languages or one for each language.

Method 1. Put all of the messages in one bytetable. At the start of each message put a character count for how big the message is. Then in the display function. You pass in an index number for which message you wish to output. The display function simply walks through the messages by using the count until it gets to the start of the message you wish to output. If all of the languages are stored in one bytetable you could calculate the index number by lang*<Cnt per lang>+msg_num. For example in my phoenix program I had a bytetable that looked like:
Code:
_GATENAMES         bytetable   8,    "Ripple 6",|
                        9,    "Ripple 12",|
                        12,   "Quadripple 9",|
                        8,    "Tripod 4",|
                        8,    "Tripod 6",|
                        8,    "Tripod 8",|
                        7,    "Wave 12",|
                        7,    "Wave 18"

The code to walk the list is not difficult. I usually end up writing it in assembly language, because I enjoy that. But in basic it might look something like:
Code:
index var word

index = 0
while msg_num > 0
    index = index + _GATENAMES(index) + 1    '  point to the next item
    msg_num = msg_num - 1
wend
' now output the message
serout 0, N9600, [str _GATENAMES(index+1)\_GATENAMES(index)]
...

Note: I have not tried or compiled this. Normally I would use the pointer class and generate a pointer in asm... but trying to keep it simple.

Next option would be store each of the messages separately and use a pointer table. Problem is that basic does not allow me to generate a table using pointers at compile time. I have hacked this in by tricking out compiler, but requires assembly language... Could build double indirection. That is you have all of the English messages. Then have a table with the addresses of the English messages. Likewise you could have a table of German messages. Then you could have a table with a pointer to the tables for each language... Easy in C but...

Another option, store each of the messages in EEPROM. Then you could store each message at a know offset in the EEPROM and write the code similar to what you have. Instead of choosing a page number you simple generate an offset per language into the EEPROM. Problem is no easy way to have compiler save these message out into the EEPROM. Probably need simple program the outputs them first...

Hopefully someone else will have a simpler solution for you.

Good Luck
Kurt


Top
 Profile  
 
 Post subject: Re: displaying different languages on LCD
PostPosted: Mon Aug 09, 2010 11:34 am 
Offline
Citizen

Joined: Fri Jul 16, 2010 11:13 am
Posts: 7
Hi Kurt, thanks for the idea.

I think this ones going to be a bit of a pain.

If I used 1 table it would be huge!! I need 7 or 8 screens, with 5 or 6 other warning messages in 10 different languages!! Ohh and the screens are made up of 4 lines of 20 characters!!

I thought about using BRANCH and defining the screens using a series of SEROUT's, but it would be a very large program and would need a GOTO back to the line following the BRANCH call.

I'd have 3 variables:

lang, screen_no and message

value of lang would be set to :0 for English, 10 for French, 20 for German etc.
then I could BRANCH (lang+screen_no) to get the correct screen up so screen 0 in English would be the same as screen 10 in French and 20 in German etc.

There must be a better way, why isn't there a DATA command!!!!! or at worst a SELECT CASE which at least would allow us to jump back easily. :cry:

Jon


Top
 Profile  
 
 Post subject: Re: displaying different languages on LCD
PostPosted: Mon Aug 09, 2010 4:35 pm 
Offline
Master

Joined: Sun Aug 17, 2008 5:26 pm
Posts: 798
Location: CA bay Area
Somebody didn't get their nap today! :lol:
So, you want to store a mere 38,400 characters? Sounds like you need a 64K serial EEPROM to me. Just so happens there is an app note at
http://forums.basicmicro.net/atomnano-f485/app-note-using-a-64k-i2c-eeprom-with-an-atom-microprocessor-t9235.html
that tells you how to use I2C commands to use a 64K EEPROM. Yes, it's under Nano, but it applies to Pros as well. Now you determine how you want to divvy up your messages by addresses and write a single program that programs all these messages into a single 64K EEPROM. Then you write your main program to take advantage of these stored messages.
Yes, it's cumbersome, but it IS doable!
later.
kenjj

_________________
kenjj
http://blog.basicmicro.com/
http://kjennejohn.wordpress.com/


Top
 Profile  
 
 Post subject: Re: displaying different languages on LCD
PostPosted: Tue Aug 10, 2010 1:00 am 
Offline
Citizen

Joined: Fri Jul 16, 2010 11:13 am
Posts: 7
Hi guys,

thanks for the tips, they're really appreciated!!

Jon


Top
 Profile  
 
 Post subject: Re: displaying different languages on LCD
PostPosted: Tue Aug 10, 2010 8:52 am 
Offline
Site Admin
User avatar

Joined: Thu Mar 01, 2001 11:00 am
Posts: 784
Location: Temecula, CA
Since you need 38k of code space just for the strings you either need to use external eeprom like Ken pointed out(I'm not sure how this was even possible on a BS2P, they don't have enough space for that much data) or you may want to use an AtomPro40 which has 56k of code space.

There isn't a DATA command because the eeprom isn't used for code space like on the BS2 so the eeprom can't be written at the same time as programing the code. However there are bytetables which act just like yuou want the DATA command to work on the BS2. You are using the eeprom data just to store constant strings which is what bytetables are made for.

A more specific description of exactly how much string space you need would be usefull in giving a more detailed answer. I came up with much the same method as Kurt did except I used a subroutine to display any message. The subroutine would be something like displaymsg[lang,msg] where lang is the language number and msg is the msg in that language you want displayed.

I don't see why having a big table is any different from have lots of little strings but you can go either way. Here is an example using multiple bytetables with individual strings.

Code:
lang0msg0 bytetable "msg0",0
lang0msg1 bytetable "msg1",0
lang0msg2 bytetable "msg2",0
lang0msg3 bytetable "msg3",0
lang1msg0 bytetable "msg4",0
lang1msg1 bytetable "msg5",0
lang1msg2 bytetable "msg6",0
lang1msg3 bytetable "msg7",0

lang var byte
msg var byte
displaymsg [lang,msg]
if lang=0 then
   if msg=0 then
      hserout [str lang0msg0\16\0]
   elseif msg=1 then
      hserout [str lang0msg1\16\0]
   elseif msg=2 then
      hserout [str lang0msg2\16\0]
   elseif msg=3 then
      hserout [str lang0msg3\16\0]
   endif
else
   elseif msg=0 then
      hserout [str lang1msg0\16\0]
   elseif msg=1 then
      hserout [str lang1msg1\16\0]
   elseif msg=2 then
      hserout [str lang1msg2\16\0]
   elseif msg=3 then
      hserout [str lang1msg3\16\0]
endif
   return

As you can see using individual bytetabels per string takes a fair bit of code. If you used one byte table:

Code:
lang0msgs bytetable 4,msg0, |
                            4,msg1, |
                            4,msg2, |
                            4,msg3

You could use a for next loop to get and display the message instead of all the if,elseif code.

_________________
Nathan Scherdin
Basic Micro - Robotic Technology Evolved


Top
 Profile  
 
 Post subject: Re: displaying different languages on LCD
PostPosted: Tue Aug 10, 2010 9:23 am 
Offline
Master

Joined: Tue Nov 21, 2006 9:34 am
Posts: 500
Acidtech wrote:
A more specific description of exactly how much string space you need would be useful in giving a more detailed answer. I came up with much the same method as Kurt did except I used a subroutine to display any message. The subroutine would be something like displaymsg[lang,msg] where lang is the language number and msg is the msg in that language you want displayed.

I totally agree with Nathan, that I would put it into a subroutine as I normally do :)

As I mentioned, I have also done it with pointers, I wish the compiler had support for something like:
x longtable @MSG1, @MSG2, @MSG3...
or better yet
x pointertable @MSG1, ...

But in one case I played around with this, by using in-line assembly. It is faster than walking the lists but takes extra room. What my code looked like:
Code:
; define messages
_TT1         bytetable    "RR Hip Hor", 0
_TT2         bytetable   "RR Hip Vert",0
_TT3         bytetable   "RR Knee", 0
_TT4         bytetable   "MR Hip Hor", 0
_TT5         bytetable   "MR Hip Vert",0
;... define table.  Note jump around.  System thinks there is code in there...
goto AfterTable
BEGINASMSUB
ASM{
TT_TABLE:
   .long (_TT1 + 0x20000)      ; Note 0x20000 is hack to let compiler know it is byte pointer.
   .long (_TT2 + 0x20000)
   .long (_TT3 + 0x20000)
...}
ENDASMSUB
AfterTable:

; Then function to display the message:
msg var byte
ptext var pointer
DisplayMsg [msg]:
; - Wish Basic knew about our pointer table...
   xor.l   er0, er0   ; zero out the whole thing
   mov.b   @MSG, r0l
   shal.l   er0
   shal.l   er0            ; multiply by 4 bytes per...
   mov.l   #TT_TABLE:24, er1
   add.l   er0, er1         ; should have the address now
   mov.l   @er1, er0
   mov.l   er0, @PTEXT
; PTEXT has pointer to our string so now output it.  Strings are 0 terminated so use that fact
   hserout [str @ptext\20\0]
   return

Note: I believe with Basic the earlier way that I mentioned and Nathan also did may be easier to read...

Edit: Note to self. Could change assembly language to store word instead of long per pointer, would reduce the table size in half. Would simply need to change table index code to multiply by 2 instead of 4 and set the high word of the pointer to 2...

Kurt


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: Bing [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group

phpBB SEO