PDA

View Full Version : How to write/read strings EEPROM/LCD



g-hoot
- 27th January 2007, 16:50
Hello,
Im using a 16F648A and my program has a bunch of LCDOUT commands so that the user can select different settings. Well, I am adding new features, and am out of space. I saw Melanies post "Making Program Code Space your playground" for program space, but this chip won't allow that, so I'm thinking EEPROM is the Solution?

Here's part of the code I cut out to give a better idea of what I'm doing. Each time a certain button is pushed, it loops back through this part of the code:

Case 2
Refresh = Refresh + 1
IF Refresh = 9 Then Refresh = 1
ref:
Select Case Refresh
GoSub lcdone ' Position cursor at home
LCDOut "Refresh"
GoSub lcdsec
Case 1
LCDOut "None"
RefTime = 0
Case 2
LCDOut "30 Sec"
RefTime = 30 ' Move to 2nd line on LCD
Case 3
LCDOut "2.5 Min"
RefTime = 140
Case 4
LCDOut "7 Min"
RefTime = 400
Case 5
LCDOut "15 Min"
RefTime = 900
Case 6
LCDOut "30 Min"
RefTime = 1700
Case 7
LCDOut "1 Hour"
RefTime = 3500
Case 8
LCDOut "2 Hour"
RefTime = 7000

End Select
Pause 400

I have several of these menus throughout the program and the strings for most LCDOUT commands are different. I have played a little with EEPROM, but am not sure the easiest way to us it. Here's the only thing that I've gotten to work, but I'm afraid in may take more space (and a ton of work). I'm using values 0-15 for other stuff, so "A" is at 16. The code below displays "BAD" on the LCD.

EEPROM 0, [1,1,10,0,0,0,24,1,1,150,0,250,0,1,1,0,"A","B","C","D","E","F","G","H","I","J","K","L","M"]

testmem VAR BYTE[8]

Read 17, testmem[0]
Read 16, testmem[1]
Read 19, testmem[2]
testmem[3] = " "
testmem[4] = " "
testmem[5] = " "
testmem[6] = " "
testmem[7] = " "

LCDOut STR testmem

I had to add all of the blank spaces in the last 5 spots of the array to keep "wierd" characters from being displayed. In the manual where it talks about strings in EEPROM, it says "No lenghth or terminator is automatically added", so I assume that's the reaon for the wierch characters, but don't really know how to fix it. I'm using the array of 8 since the LCD is a 2x8 display. Anyway, am I wasting my time here? Would I be better off just saying:

LCDOUT "BAD"

Sure could use some ideas on how to free up some space. Thanks,
Gary

Archangel
- 28th January 2007, 08:56
Greetings g-hoot,
I never tried this but here is my idea.
StringVar var byte

Stringvar = testmem[3]
gosub string

Stringvar = testmem[4]
gosub string

Stringvar = testmem[5]
gosub string

Stringvar = testmem[6]
gosub string

String:
LCDOUT stringvar
return

What I am thinking is the lcdout commands are using up your codespace, so put them into a loop and make the string a variable, give the variable the value you wish to display and then call the display subroutine. Also see select case instructions in the manual.
JS

Archilochus
- 28th January 2007, 18:05
Hi ghoot,
Not sure if it would save any code space overall, but you might want to look into the "LOOKUP" command too.

Also, in your code where you limit "Refresh" to 8...


Refresh = Refresh + 1
IF Refresh = 9 Then Refresh = 1

You might want to do this instead...


Refresh = Refresh + 1
IF Refresh > 8 Then Refresh = 1

That way if the Pic ever has some glitch and makes "Refresh" any value greater than 8, the code will revert back to "Refresh=1"

Arch

mister_e
- 28th January 2007, 21:36
Different ways... use an external EEPROM to store your strings and some variable values (reftime etc etc) Or work around something like
http://www.picbasic.co.uk/forum/showthread.php?t=1999&highlight=embedded+strings

it's up to you!

g-hoot
- 29th January 2007, 04:26
Joe,
I got "rid" of all of the LCD out commands with a sub and sure thought that would do the trick, but my program only went from 3934 to 3931. Here's what I did:


IF Refresh > 8 Then Refresh = 1
ref:
Select Case Refresh
GoSub lcdone ' Position cursor at home
T[0]="R":T[1]="e":T[2]="f":T[3]="r":T[4]="e":T[5]="s":T[6]="h":T[7]=" "
GoSub LCDout1
GoSub lcdsec
Case 1
T[0]="N":T[1]="o":T[2]="n":T[3]="e":T[4]=" ":T[5]=" ":T[6]=" ":T[7]=" "
GoSub LCDout1
RefTime = 0
Case 2
T[0]="3":T[1]="0":T[2]=" ":T[3]="S":T[4]="e":T[5]="c":T[6]=" ":T[7]=" "
GoSub LCDout1
RefTime = 30

etc........

LCDout1:
LCDOut STR T
Return


What did you mean by "Also see select case instructions in the manual."...am I missing something there?

Arch,
I fixed the "IF Refresh > 8 " problem. Thanks for that. I've looked at the LOOKUP command, but really don't don't understand it. I guess if I set up the alphabet as constants, that won't use any space, but once I use lookup to read them into an array, woukldn't that take up the same space as above?

mister_e,
This board design has been done for a while, so I can't use external on this one, but if I do it on another design, when I retrieve the strings to go into the LCDOUT command, won't that put me in the same boat? As you can see, I'm quite a rookie at this. :-) I don't think I can do the embedded strings either since this chip won't let me use program space. "Flash Program Write" is disabled when I select that chip in the EPIC Programmer.
Gary

mister_e
- 29th January 2007, 04:36
Ah crap! So the RTFM of the day goes to me :D

Using an external EEPROM solve the problem, the only thing you have to keep in your PIC is the EEPROM start address of your string. From there, you just call and display routine.

Anyways, i'm pretty sure there's something to do around this without changing your actual stuff... let me sleep on this. If you want, you can post your whole code here or, if you can't for some privacy and/or commercial reason, send it on my e-mail.

Archangel
- 29th January 2007, 05:29
Joe,



What did you mean by "Also see select case instructions in the manual."...am I missing something there?


Dohe!
Well it's like this, these coke bottle thick glasses . . . I didn't see you had used select case already, Just ignorant of me, sorry.
JS
EDIT: You might check with Darrel, I think he has something that measures the code size for each bit of code, but understand this, my memory isn't worth much.

g-hoot
- 29th January 2007, 16:01
"the only thing you have to keep in your PIC is the EEPROM start address of your string"

Ahh, I think it's starting to sink in to my thick melon. What I was trying to do was set up the alphabet in upper and lower case, and numbers and a few other characters in eeprom, and then call each one individually. I noticed in many places that people were looping through like this:
for i = 0 to 7
read i, LCDtext(i)
next i

but that wouldn't work with the alphabet deal since I had to jump around to different, non-sequential eeprom locations.
So, what you are saying is that I would save each actual string in eeprom and then just give the loop the starting location of the string. I'm only using about 16 locations of eeprom right now, and this chip has 256, so that leaves me enough room for about thirty 8 character strings, so that should help a bunch. I'll give that a shot tonight.
Thanks all,
Gary

mister_e
- 29th January 2007, 16:04
can you post your text string here?

maybe there's some word you can use from one and merge into another... but will this worth?

g-hoot
- 29th January 2007, 16:29
can you post your text string here?

maybe there's some word you can use from one and merge into another... but will this worth?


Hey Steve,
I think you have got me thinking enough that I can get enough space free to add what I need. The code is pretty long so I just emailed you the code also, just to take a quick look at it if you want. Please don't spend too much time on it. Thank you very much for taking the valuable time to look at it.
Gary

mister_e
- 29th January 2007, 21:16
You might check with Darrel, I think he has something that measures the code size for each bit of code, but understand this, my memory isn't worth much.

I think you talk about...


How much code would a code hog hog
http://www.picbasic.co.uk/forum/showthread.php?t=2418

Archangel
- 29th January 2007, 22:07
I think you talk about...


How much code would a code hog hog
http://www.picbasic.co.uk/forum/showthread.php?t=2418

Yes Sir, Mister_e !
That was what I saw!

g-hoot
- 30th January 2007, 00:32
Man, this thing is a pain in the booty. Using eeprom works great until i get more that about 30 characters saven in it. Then my LCD just displays black rectangles/blanks. If I delete all of the charcters from eeprom and just leave about 50, it works fine? I dunno, maybe the pic nees a pause somewhere at startup to read the eeprom? Here's the sub:

EEtext:
LCDtextNm = 0
For EEnum = EEnum TO EEnum+7
Read EEnum, LCDtext[LCDtextNm]
LCDtextNm=LCDtextNm+1
Next EEnum
LCDOut STR LCDtext
Return

mister_e
- 30th January 2007, 03:45
this one is dangerous and you trick the compiler

For EEnum = EEnum TO EEnum+7

doing that you'll jump in an endless loop. i don't know what's around your sub but i think this one make much sense



EEtext:
For CharAddress = EEnum TO EEnum+7
Read CharAddress, Char
LCDOUT Char
Next

Return

g-hoot
- 30th January 2007, 04:54
This is getting plain silly. If I have this:
EEPROM 30,["R","e","a","d","y"," "," "," "]
EEPROM 38,["D","e","l","a","y"," "," "," "]
EEPROM 46,["1","5"," ","S","e","c"," "," "]
EEPROM 54,["2","0"," ","S","e","c"," "," "]

The run through the sub:

EEtext:
LCDtextNm = 0
EnumC = EEnum
For EEnum = EnumC TO EnumC+7
Read EEnum, LCDtext[LCDtextNm]
LCDtextNm=LCDtextNm+1
Next
LCDOut STR LCDtext
Return

Ready will display, but the other 3 strings produce a blank screen. If I replace the "e" in ready with a space " " then it works fine, except for the fact that it now says "R ady". ;-) I have had lots of strange happenings with the LCD, like for instance, I can't display a number ending in "0". Also can't display the name "MCKELLOP". Who knows?....
Gary

g-hoot
- 30th January 2007, 05:01
Hold the phone! I added a Pause 10 right after the Read statement and it seems to be working now.

Archangel
- 30th January 2007, 05:06
G-HOOT!
I like that handle, sounds very celtic, anyway on to business . . .
I was curious, about the quantity of text strings you are attempting to store and recall, and how you intend to call them up, also curious what chip you chose to use. I made up a device which does essentialy this and I stored all my strings in codespace, using a 16f648A. In fact I still have not used eprom in a project yet. Still mastering the basics.
JS

g-hoot
- 30th January 2007, 06:16
G-HOOT!
I like that handle, sounds very celtic, anyway on to business . . .
I was curious, about the quantity of text strings you are attempting to store and recall, and how you intend to call them up, also curious what chip you chose to use. I made up a device which does essentialy this and I stored all my strings in codespace, using a 16f648A. In fact I still have not used eprom in a project yet. Still mastering the basics.
JS

Hmm, the 16f648A is what I'm using too, since that's as much memory as I can find in an 18 pin chip, but I read that to do the code space thing, that you have to enable "Flash Program Write", but that option is disabled when I choose that chip? Maybe I got that mixed up with something else I was reading about. If I do another board layout, I'm going with probably the 16f916. It has more pins and I think it was 8K of memory. Also, there are several others that I can swap out with it to get a ton of memory if needed....Live and learn. Let me show you what you guys have helped me do though. I have went from way out of space down to 3344 words.

Here's the EEPROM statements:

EEPROM 0, [1,1,10,0,0,0,24,1,1,150,0,250,0,1,1,0]
EEPROM 30,["R","e","a","d","y",0]
EEPROM 36,["D","e","l","a","y",0]
EEPROM 42,["1","5"," ","S","e","c",0]
EEPROM 49,["2","0"," ","S","e","c",0]
EEPROM 57,["1"," ","M","i","n","u","t","e"]
EEPROM 65,["2"," ","M","i","n","u","t","e"]
EEPROM 73,["5"," ","M","i","n","u","t","e"]
EEPROM 81,["E","n","t","e","r",0]
EEPROM 87,["A","c","t","i","v","i","t","y"]
EEPROM 95,["D","b","l","e"," ","P","i","c"]
EEPROM 103,["S","e","n","s","t","v","t","y"]
EEPROM 111,["H","i","g","h",0]
EEPROM 116,["M","e","d","i","u","m",0]
EEPROM 123,["L","o","w",0]
EEPROM 127,["D","a","y","N","i","g","h","t"]
EEPROM 135,["2","4"," ","H","o","u","r"," "]
EEPROM 143,["D","a","y"," ","O","n","l","y"]
EEPROM 151,["D","a","r","k","O","n","l","y"]
EEPROM 159,["W","a","l","k","T","e","s","t"]
EEPROM 167,["S","t","r","t","W","a","l","k"]
EEPROM 175,["E","x","i","t",0]
EEPROM 180,["C","a","m"," ","T","y","p","e"]
EEPROM 188,["O","N","/","O","F","F","-","1"]
EEPROM 196,["O","N","/","O","F","F","-","2"]
EEPROM 204,["A","l","w","a","y","s","O","n"]
EEPROM 212,["R","e","f","r","e","s","h"," "]
EEPROM 220,["S","h","u","t","t","e","r"," "]
EEPROM 228,["S","l","v","R","f","r","s","h"]
EEPROM 236,["S","l","v","O","n","T","m","e"]
EEPROM 244,["3","0"," ","S","e","c",0]
EEPROM 251,["7"," ","M","i","n"]

'The vars:
LCDtext VAR BYTE[8]
EEnum VAR BYTE
LCDtextNm VAR BYTE
LCDtemp VAR BYTE
LCDnum VAR BYTE
EnumC VAR BYTE

'Some of the code:
Select Case Mode
Case 1
Delay = Delay + 1
IF Delay > 7 Then Delay = 1
delmode:
Select Case Delay
GoSub lcdone ' Position cursor at home
EEnum = 36
GoSub EEtext
' LCDOut "Delay"
GoSub lcdsec ' Move to 2nd line on LCD
Case 1
GoSub TENsec
' LCDOut "10 Sec"
TimeDely = 10
Case 2
EEnum = 42
GoSub EEtext
' GoSub fteenSec
' LCDOut "15 Sec"
TimeDely = 15
Case 3
EEnum = 49
GoSub EEtext
' LCDOut "20 Sec"
TimeDely = 20
Case 4
EEnum = 57
GoSub EEtext
'LCDOut "1 Minute"
TimeDely = 60
Case 5
EEnum = 65
GoSub EEtext
'LCDOut "2 Minute"
TimeDely = 120
Case 6
EEnum = 73
GoSub EEtext
'LCDOut "5 Minute"
TimeDely = 300
Case 7
GoSub TenMin
'LCDOut "10 Min"
TimeDely = 600
End Select
Pause 400


'The SUB:

EEtext: LCDtextNm = 0
Pause 10
LCDnum = 0
EnumC = EEnum
For EEnum = EnumC TO EnumC+7
Read EEnum, LCDtext[LCDtextNm]
Read EEnum, LCDtemp
Pause 10
IF LCDtemp = 0 Then
LCDnum = 1
EndIF
IF LCDnum = 1 Then
LCDtext[LCDtextNm] = " "
EndIF
LCDtextNm=LCDtextNm+1
Next
LCDOut STR LCDtext
Return

Thank you all for the help! This will get me down the road a ways.
Gary

g-hoot
- 9th February 2007, 04:44
Well, I thought this was gonna work, and I'll bet it will, but it's giving me fits. It looks like it may have something to do with using the "0" to know where the end of my string is in EEPROM. My screen goes blank (most of the time), when the program try to display one of those on the 2nd line of the display. Since I've never been able to get the display to show a number ending in "0" (zero), I thought maybey that had something to do with it, so I cahnged it to "99". With "99" in there, now it won't display a string that has a "c" in it past the string. For examle "Activity" is displayed ad "A"..."PicPrEvt" is displayed as "Pi". So I changed it to "1" and then "Ready" was displayed as "eady", so I just shut it off without going further through the menu.

I'm using portB interrupts to detect when i push a couple of push buttons to set it up. This has never been a problem in the past since I haven't been sing EEPROM to store the strings, but i wonder if that could have something to do with it?

Here's the subs that I call before doing an LCDOUT for line one and two:
lcdone: LCDOut $fe, 1 : LCDOut $fe, 2 ' Position cursor at home
Return
lcdsec: LCDOut $fe, $C0 ' Move to 2nd line on LCD
Return

Again, this has always worked fine too before using the EEPROM, so not sure that it has anything to do with it either. Do I need to somehow check and see if the EEPROM actually go read before placing the results in the LCDOUT command? If so, how would I do that without having to compare it to a string and then end up using all of that space again? Any help would be much apreciated..it's driving me wacky. ;-)

g-hoot
- 10th February 2007, 17:34
Thought I would keep adding info to my post as I progress in case there are other "programming challenged" readers trying to do what I'm trying to do. ;-) All of the strings that I'm storing that have a space at the end like this:

EEPROM 212,["R","e","f","r","e","s","h"," "]
EEPROM 220,["S","h","u","t","t","e","r"," "]

"seem" to be the problem, even though they're not any where near the strings that were having problems like:

EEPROM 103,["S","e","n","s","t","v","t","y"]

I replaced the spaces with 0 and that so far has been working. Since I've seen several posts wanting to do this, once my other changes are complete, and if it still works, then I'm going to do a new post for wanna be's like me to have an "easy" starting place for storing strings to be displayed on an LCD. Also, I guess it's common knowledge, but with the 0 in there on shorter strings, you don't have to keep looping through to fill the rest of the strings with spaces. I guess that's what is meant by a "terminator" that I've read about in a few places.
Gary

Archangel
- 10th February 2007, 22:00
Hmm, the 16f648A is what I'm using too, since that's as much memory as I can find in an 18 pin chip, but I read that to do the code space thing, that you have to enable "Flash Program Write", but that option is disabled when I choose that chip?
Flash Program Write?
I just do it this way:


LCDOUT 254,1 ' Clears Display
LCDOUT 254,128,"Here's how to output"
LCDOUT 254,192,"Strings from code"
LCDOUT 254,148,"space easily !"
LCDOUT 254,212,"Where you put it"

g-hoot
- 10th February 2007, 23:35
Joe,
Here's a post taliking about the "Flash Program Write". It's disabled when I select 16F648A I the EPIC Programmer, and the setting is completley taken away when I select this chip in Melabs Programmer 3.31, but maybe I don't really need it.

http://www.picbasic.co.uk/forum/showthread.php?t=1076

I've read some about using code space, but don't really understand. So is that part of the 4k space that is used when programing the chip? If so, then I would start storing strings at say space 3500 and then just have to make sure that the program doesn't get any bigger than 3499?

I don't unserstand this:

LCDOUT 254,1 ' Clears Display
LCDOUT 254,128,"Here's how to output"
LCDOUT 254,192,"Strings from code"
LCDOUT 254,148,"space easily !"
LCDOUT 254,212,"Where you put it"

Isn't that just standard LCDOUT commands in decimal rather than hex? Sorry for all of the questions...this stuff is confusing since I don't know assembly language, and most of the examples use it.

Archangel
- 11th February 2007, 06:26
Joe,

Isn't that just standard LCDOUT commands in decimal rather than hex? Sorry for all of the questions...this stuff is confusing since I don't know assembly language, and most of the examples use it.

Yes that's all it is, but you are using codespace and not eprom. It executes fast and if you lack the knowledge to use eprom, well it works.