PDA

View Full Version : EEPROM Variables (EE_Vars.pbp)



Darrel Taylor
- 22nd September 2005, 07:27
Hi everybody,

First, I'd like to say that, I've gone overboard on the documentation here. It might look like a monstrous program that you'll never figure out, but really, it's very easy to use. I just tried to answer all the questions ahead of time, and I'm hoping it doesn't cause confusion instead.

This program is intended to be a demonstration of what you can do with Macro's and Include file's.
It was not meant to be the most efficient way of doing things..., just the easiest.

Hope you can use it.

Darrel Taylor
- 22nd September 2005, 07:27
<a name="EE_index"></a>
EEPROM Variables (EE_Vars.pbp)


<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_Intro">Introduction</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_Linked">Linked Variables</a>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_Var">EE_var</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_read_var">EE_read_var</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_write_var">EE_write_var</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_write_default">EE_write_default</a>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_UnLinked">Unlinked Variables</a>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_byte">EE_byte</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_word">EE_word</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_read">EE_read</a>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_write">EE_write</a>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_start">EE_start</a>
<!-- <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_Res">Resources Used by EE_Var</a> -->
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_Samples">Example Programs</a>

Darrel Taylor
- 22nd September 2005, 07:30
<a name="EE_Intro"></a>
&nbsp;Introduction

EE_Vars.pbp is an INCLUDE file that takes a lot of the "Hassle" out of working with EEPROM data. It has several advantages over PicBasic's EEPROM, DATA, READ and WRITE statements.

EEPROM and DATA are ok for setting default values in EEPROM, but it only does it when the chip is programmed. After that, all those default values are gone. They aren't stored anywhere in the program. So there's no way to go back to the default values without re-programming the chip again. Plus, it's all just a bunch of numbers, one after another. You can't give them variable names, or sizes. All of that has to be handled manually (by you).

Read and write can be difficult to work with as well. You have to do everything 1 byte at a time. You have to keep track of what EEPROM locations have what data in them. And then, figure out how to get the data from the right place when you need it. And, with the *2 problem on the 18F EEPROM locations, sometimes it's just not worth the "hassle".

Enter EE_Vars.pbp

This program does all of that for you, and much more.&nbsp; It assigns locations in EEPROM for "Persistant" variables.&nbsp; Maintains "default" values for each EE_Var.&nbsp; And, creates easy to use commands for accessing those variables in EEPROM.&nbsp; It can "Link" the EE variables with your PBP variables, so that they automatically have the correct value on Power-up", or it can work with "Un-Linked" EE variables that can be easily Read or Written to/from any PBP variable.

It also protects against WRITE errors caused by an interrupt in the middle of a write sequence by verifying the data, after a WRITE. If it doesn't match, it goes back and tries again. After a predetermined number of tries (10 default), if it's still unsuccessfull, it will Disable Global interrupts and WRITE it one more time.

The program will work on any PIC chip that has Internal EEPROM space (NOT internal I2C EEPROM). But, it requires MPASM as the assembler. It won't work with PM.


<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>

Darrel Taylor
- 22nd September 2005, 07:36
<!-- --------------------------------- -->
<a name="EE_Linked"></a>
&nbsp;Linked Variables

Here is an example of a "Linked" EE/PBP variable.
<font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;EE_Vars.PBP&quot;

</font><b>Days </b><font color="#008000"><b>VAR WORD </b></font><font color="#0000FF"><b><i>; Create your variable like normal
</i></b></font><font color="#000080">@ EE_var _Days, WORD, 365 </font><font color="#0000FF"><b><i>; Link an EE variable to it.</i></b></font>With 3 simple lines, you now have a PBP variable that is initialized from EEPROM on Power-UP. It's has a "default" value of 365 that will be initialized in EEPROM on the first "RUN" after programming, and can be restored to the default value at any time you need. The PBP variable can be used just like normal throughout your program. Then, anytime you want to permenantly save the value to EEPROM, you simply call the EE_write_var routine. On the next Reset of the processor, the PBP variable will automatically have the new value.

These are the commands for "Linked" variables.

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_Var">EE_var</a>&nbsp;&nbsp;-&nbsp;&nbsp;Associate(link) PBP/EE_Vars
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_read_var">EE_read_var</a>&nbsp;&nbsp;-&nbsp;&nbsp;Read a Linked variable from EEPROM
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_write_var">EE_write_var</a>&nbsp;&nbsp;-&nbsp;&nbsp;Write a Linked variable to EEPROM
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_write_default">EE_write_default</a>&nbsp;&nbsp;-&nbsp;&nbsp;Write the default value to EEPROM


<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_Var"></a>
&nbsp;EE_Var&nbsp;&nbsp;&nbsp;(EE_variable)

<pre>@ EE_var Variable, Size, Value</pre>

Variable - The <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#notes">PBP variable</a> that will be Linked to an EEPROM location. The variable name must be preceeded by an Underscore "_", unless the variable was declared as a SYSTEM variable. The "case" must match exatcly with the original declaration of the PBP variable.

Size - The size of the variable. Either BYTE or WORD. (case sensitive)

Value - The "default" value associated with this variable. This constant will be initialized in EEPROM on the first "RUN" after programming. It can also be restored at any time with the <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_write_default">EE_write_default</a> command.

EE_Var will probably be the most used macro in this collection. In fact, many programs will only need this, and the EE_write_var macro to do everything required to maintain all your values in EEPROM.

It's purpose is to create a location in EEPROM that is "Linked" with a previously declared PBP variable. It also handles the "First RUN" initialization.

Example:

<pre>Setpoint VAR BYTE<br>@ EE_var _Setpoint, BYTE, 150
RunTime VAR WORD<br>@ EE_var _RunTime, WORD, 1200</pre>

For easier readability, both statements can be placed on the same line, with a colon ":" in-between.

Setpoint VAR BYTE : @ EE_var _Setpoint, BYTE, 150
RunTime VAR WORD : @ EE_var _RunTime, WORD, 1200

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_read_var"></a>
&nbsp;EE_read_var

<pre>@ EE_read_var Variable </pre>

Variable - The <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#notes">PBP variable</a> name that you want to read from EEPROM.

EE_read_var will read the EEPROM value that has been Linked to a PBP variable with the EE_var command. &nbsp; It can only be used with Linked variables.

On Power-up the variable will already be set to the value in EEPROM. So, the only time you would need to use this command is if you have used the variable for other puposes, and want to restore it to the "Power-up" state.

Example:

<pre>@ EE_read_var _Setpoint
@ EE_read_var _RunTime</pre>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_write_var"></a>
&nbsp;EE_write_var

<pre>@ EE_write_var Variable </pre>

Variable - The <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#notes">PBP variable</a> name that you want to write to EEPROM.

After you have changed the value of a variable in your program, you can save it to EEPROM by using the EE_write_var command. Once written, the PBP variable will automatically contain the new value on the next "Power-up".

Example:

<pre>@ EE_write_var _Setpoint
@ EE_write_var _RunTime</pre>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_write_default"></a>
&nbsp;EE_write_default

<pre>@ EE_write_default Variable </pre>

Variable - The <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#notes">PBP variable</a> name that you want to restore the default for.

EE_write_default will restore the default value that was defined with an EE_var statement. That value will be written to EEPROM, and it will also be placed in the Linked PBP variable.

Example:

<pre>@ EE_write_default _Setpoint
@ EE_write_default _RunTime</pre>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>

Darrel Taylor
- 22nd September 2005, 07:39
<!-- --------------------------------- -->
<a name="EE_UnLinked"></a>
&nbsp;UnLinked Variables

Unlinked EE variables, are not linked to any PBP variables, but can allow greater freedom in how you handle them.

They allow you to create meaningfull names to represent EEPROM locations. &nbsp;And, those locations can have default values, just like the Linked EE_Vars.

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_byte"></a>&nbsp;EE_byte

<pre>@ EE_byte Name, Value</pre>Define a BYTE sized location in EEPROM, with a Unique name, and default value.

Name - A unique Name to identify this EE variable.

Value - The "default" value associated with this variable. This constant will be initialized in EEPROM on the first "RUN" after programming. It can also be restored at any time with the <pre>@ EE_write Name, default</pre> command.

Example:

<pre>@ EE_byte Version, 1<br>@ EE_byte VersionMinor, 0</pre>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_word"></a>&nbsp;EE_word

<pre>@ EE_word Name, Value</pre>Define a WORD sized location in EEPROM, with a Unique name, and default value.

Name - A unique Name to identify this EE variable.

Value - The "default" value associated with this variable. This constant will be initialized in EEPROM on the first "RUN" after programming. It can also be restored at any time with the "@&nbsp; EE_write&nbsp;&nbsp; Name, default" command.

Example:

<pre>@ EE_word Speed, 1100<br>@ EE_word PWMfreq, 20000</pre>
<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_read"></a>&nbsp;EE_read

<pre>@ EE_read Name, Variable</pre>

Name - A Name that was previously defined using either EE_byte or EE_word.

Variable - The <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#notes">PBP variable</a> that will receive the value from EEPROM.

Note: The variable must be the same size as the EE Variable you are using. If it was defined with EE_word, and you supply EE_read with a byte sized variable, another variable will be overwritten with the High byte of the word.

Example:

<pre>Mspeed VAR WORD
@ EE_read Speed, _Mspeed

Version VAR BYTE
@ EE_read Version, _Version</pre>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>
_________________________________
<a name="EE_write"></a>&nbsp;EE_write

<pre>@ EE_write Name, Variable</pre>


Name - A Name that was previously defined using either EE_byte or EE_word.

Variable - The <a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#notes">PBP variable</a> that holds the value to be written to EEPROM. OR, the word "default"

Note: The variable must be the same size as the EE Variable you are using. If it was defined with EE_word, and you supply EE_write with a byte sized variable, 1 garbage byte from another variable will be written to EEPROM.

Example:

<pre>Mspeed = 2000<br>@ EE_write Speed, _Mspeed
Version = 2<br>@ EE_write Version, _Version</pre>

<a href="http://www.picbasic.co.uk/forum/showthread.php?t=2444#EE_index">up to index</a>

Darrel Taylor
- 22nd September 2005, 07:41
<a name="notes"></a>Notes:

PBP variables - The PBP variable name must be preceeded by an Underscore "_", unless the variable was declared as a SYSTEM variable. The "case" must match exatcly with the original declaration of the PBP variable.
<br>
<br>

Darrel Taylor
- 22nd September 2005, 08:47
<a name="EE_Samples"></a>This example program creates 4 Linked EE variables.

Days and cats will always remain the same value, which is the default value that is Initialized on the "First Run". &nbsp; Mice will create a new value on each power-up, and PowerOn will keep track of how many times to circuit has been powered up.

<font color="#0000FF"><b><i>; Initialize the hardware and LCD first

</i></b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;EE_Vars.PBP&quot; </font><font color="#0000FF"><b><i>; Include the EE_var routines

</i></b></font><b>Days </b><font color="#008000"><b>VAR WORD </b></font>: @ <b>EE_var _Days</b>, <font color="#008000"><b>WORD</b></font>, <b>365
Cats </b><font color="#008000"><b>VAR WORD </b></font>: @ <b>EE_var _Cats</b>, <font color="#008000"><b>WORD</b></font>, <b>1024
Mice </b><font color="#008000"><b>VAR WORD </b></font>: @ <b>EE_var _Mice</b>, <font color="#008000"><b>WORD</b></font>, <b>10000
PowerOn </b><font color="#008000"><b>VAR BYTE </b></font>: @ <b>EE_var _PowerOn</b>, <font color="#008000"><b>BYTE</b></font>, <b>0

PowerOn </b>= <b>PowerOn </b>+ <b>1 </b><font color="#0000FF"><b><i>; Increment number of Power-On cycles
</i></b></font><font color="#000080">@ EE_write_var _PowerOn </font><font color="#0000FF"><b><i>; save the new number to EEPROM

</i></b></font><font color="#008000"><b>LCDOUT </b></font><b>$FE</b>,<b>$80</b>,<font color="#FF0000">&quot;Days= &quot;</font>, <font color="#008000"><b>DEC </b></font><b>Days
</b><font color="#008000"><b>LCDOUT </b></font><b>$FE</b>,<b>$C0</b>,<font color="#FF0000">&quot;Cats= &quot;</font>, <font color="#008000"><b>DEC </b></font><b>Cats
</b><font color="#008000"><b>LCDOUT </b></font><b>$FE</b>,<b>$90</b>,<font color="#FF0000">&quot;Mice= &quot;</font>, <font color="#008000"><b>DEC </b></font><b>Mice
</b><font color="#008000"><b>LCDOUT </b></font><b>$FE</b>,<b>$D0</b>,<font color="#FF0000">&quot;PowOn= &quot;</font>, <font color="#008000"><b>DEC </b></font><b>PowerOn

</b><font color="#008000"><b>RANDOM </b></font><b>Mice </b><font color="#0000FF"><b><i>; get a new value for Mice
</i></b></font><font color="#000080">@ EE_write_var _Mice </font><font color="#0000FF"><b><i>; save it to EEPROM

</i></b></font><font color="#008000"><b>STOP
</b></font>

brittons
- 1st October 2008, 18:53
Hello Darrel, I see this line in the include file.

EE_start CON 0 ; Starting address for EE_Vars

Is this the starting address for your EEprom storage? I use the beginning addresses for specific things that may not be able to use your EE_Vars method. I actually want that area blocked out.

Can I mix and match your method with generic PBP read and write if I set the EE_Start address up higher. Say for an 18F part if I set it to 512 that would leave the bottom half for me to do what I want with and the top to experiment with your method.

Is this correct?

Thanks, Bob

skimask
- 1st October 2008, 18:57
Is this the starting address for your EEprom storage? I use the beginning addresses for specific things that may not be able to use your EE_Vars method. I actually want that area blocked out.
That's the way I read it.


Can I mix and match your method with generic PBP read and write if I set the EE_Start address up higher. Say for an 18F part if I set it to 512 that would leave the bottom half for me to do what I want with and the top to experiment with your method.
I don't see why not. Just be careful you don't start overwriting what you don't want to start overwriting...

brittons
- 2nd October 2008, 17:18
Yes, I tried setting the starting address to 511 and the variables get stored there.

I haven't been able to get the variables to start out in the 'First Run' or default value unless I execute the EE_write_default command. Is there a way to create the 'First Run' sate of the vars without doing this? It seems when you create the var using EE_var the first time it creates the default value but I was only able to do it for the first var I experimented with. Subsequent attempts seemed to come up with 'FFFF' as the default value.

I have been reading through the EE_Var.pbp code but I have to admint my knowledge of macros is limited. Any recomendations on where I can get up to speed on macros?

skimask
- 2nd October 2008, 17:55
Reinitialize the first run? You mean program a set of initial values into the eeprom?

brittons
- 2nd October 2008, 18:14
Yes, I've been trying this:

Setpoint VAR BYTE
@ EE_var _Setpoint, BYTE, 150

RunTime VAR WORD
@ EE_var _RunTime, WORD, 1200

As shown in the docs but I look at Setpoint and Runtime using MicroCode studio ICD I get 'FF' for Setpoint and 'FFFF' for RunTime. The 'default value is not created when I execute the above.

If I then do this:
@ EE_write_default _Setpoint
@ EE_write_default _RunTime

The values become 150 and 1200 but only after I perform EE_write_default

I must be doing something wrong. Note as I said before I have set the start address to 511 but I do see the new values 150 an 1200 stored in EEprom up above 511 so I think this is working properly

Darrel Taylor
- 2nd October 2008, 22:58
Hi Bob,

Is the program jumping over those statements?

Some people have a GOTO Start or something at the beginning, which doesn't allow the program to initialize the values.

Those lines (and the INCLUDE) must be allowed to execute on Power-up.
<br>

brittons
- 3rd October 2008, 16:53
Hi Darrel, this is what I have:

INCLUDE "Defines.bas"
INCLUDE "EE_Vars.PBP" 'Darrel Taylors EE_Vars program
INCLUDE "VarDefs.bas" ' These are my variable definitions
Goto start 'Jump over assembly routine
INCLUDE "AsmInt.bas" 'Assembly interrupt service routines
INCLUDE "200819_2.BAS" 'Model#, Serial# configuration
INCLUDE "LcdText.bas" 'Strings, lookup tables

SysDat VAR WORD[100] 'This is in the VarDefs.bas include file listed above

This is also in the VarDefs.bas INCLUDE FILE

msNLamps VAR SysDat[50]:@ EE_var _msNLamps, WORD, 2

SysDat is an Array the I created for looping through variables but this still seems to be ok. The 'start' label is after all of this. Shouldn't msNLamps be '2' when first programmed? I can set it to the default value if I do:

@ EE_write_default _msNlamps

after the start:

Is there a way to reset all vars to the default value as if this was the 'First Run' you talk about. As I understand it if I assign default values using the 'EE_var' command that the default value is written and the variable will always be powered up to that value unless you change it. I seem to be getting values of 'FFFF' for word on power up until I do a 'EE_write_default'

I know I've got something out of sorts but I'll keep trying. I also really like the EE_Vars program and thanks for sharing it. Starting to study macro's now too, but they don't really click yet.

Thanks, Bob

Shouldn't msNLamps be 2

brittons
- 3rd October 2008, 19:38
Oh and another thing, the statment 'Shouldn't msNLamps be 2' after:

Thanks, Bob

Shouldn't be there. I really nead to proof read my posts a little better. Hard to see in the little 'Reply to Thread' message window.

C'est La Vie

brittons
- 3rd October 2008, 19:40
and maybe 'nead' to spell check too.

brittons
- 3rd October 2008, 22:35
Well, I may have answered my own question. As I said I am using MicroCode Studio. There is a checkbox under View/Loader Options to enable Program Data. I had it unchecked and when I checked it I seem to be getting the correct results.

Darrel Taylor
- 3rd October 2008, 23:02
That's great Bob. I'm glad you found it.

I've been sitting here trying to figure out what was going on, but that thought never popped up.

When programmed, it resets the "Initialized flag" that tells it to write all the default values to EEPROM on the First Run. I guess it figured they had already been initialized, since that wasn't written during programming.

To answer your other question ... by writing a 0 to the EE_start address, ALL defaults will be restored on the next reset. Or you can cause a reset manually (on the 18F's).
WRITE EE_start, 0
@ RESET
But you probably don't need that anymore.
It would have helped figured out the problem though :o

Cheers,

brittons
- 6th October 2008, 20:50
Thanks, Darrel. I really like your program and am starting to experiment with it. The way I was working with EEProm Vars was quite the convoluted mess with the same problems you mentioned in your EE_Vars documentation. Hopefully this will make life easier.

So from what I understand if I just set the value in EE_start to zero everything gets reinitialized when I reset the pic.

So if I use EE_Vars to link numerous variables as follows:

msType VAR SysDat[51]:@ EE_var _msType, WORD, 0

Does the compiler insert the macro code for each variable? Is there a lable created by the macro to find the default values for each variable? I'm just trying to understand how this works a little better.

I have a case where I may want to loop through a group if variables and save them to EEProm, is there a way to do this using EE_Vars.

Can you recomend any reading to better familiarize myself with macros?

Thanks again for your help and for posting the EE_Vars program.

Darrel Taylor
- 7th October 2008, 07:07
Thanks, Darrel. I really like your program and am starting to experiment with it. The way I was working with EEProm Vars was quite the convoluted mess with the same problems you mentioned in your EE_Vars documentation. Hopefully this will make life easier.
You are very welcome, and I hope it helps you too.

> So from what I understand if I just set the value in EE_start to zero everything gets reinitialized when I reset the pic.

Correct!

> Does the compiler insert the macro code for each variable? Is there a lable created by the macro to find the default values for each variable? I'm just trying to understand how this works a little better.

Yes it does, and this will probably add more confusion instead of answering the question, but since you want to learn, here goes.<hr>

When you create an EE_var, several of it's properties are stored as Constants in the assembler.
For this variable ...

MyVar VAR WORD : @ EE_var _MyVar, WORD, 1000

Between the EE_var and EE_assign macros, it will create the following constants.



EE_Var1_Default = 1000 ; the Default value
EE_Var1_PTR = 1 ; the address of the data in EEPROM
EE_Var1_Size = 2 ; size of the variable
EE_Var1_HasVariable = 1 ; 1 if Linked to a PBP variable
EE_Var1_Variable = 60 ; Address to the PBP variable that's linked
EE_VarLink60 = 1 ; and a way to find the "link" from the variable


If you create a second EE_var ...

SecondVar VAR BYTE : @ EE_var _SecondVar, BYTE, 75

it would create these constants ...

EE_Var2_Default = 75 ; the Default value
EE_Var2_PTR = 3 ; the address of the data in EEPROM
EE_Var2_Size = 1 ; size of the variable
EE_Var2_HasVariable = 1 ; 1 if Linked to a PBP variable
EE_Var2_Variable = 62 ; Address to the PBP variable that's linked
EE_VarLink62 = 2 ; and a way to find the "link" from the variable

At this point, they're all just a bunch of constants. They don't do anything, and they haven't used any code space. But you can see them in the "Symbol Table" at the bottom of the .lst file.

And in an odd sort of way, it becomes a "database" of information that you can query for the desired results.

For instance, if I know the variable name (SecondVar), and I want to know which EEPROM variable has been "linked" to it?
Using the same Text Substitution that the macro's use ....

TheEEvar = EE_VarLink#v(_SecondVar)

The #v(_SecondVar) part is the "Text Substitution". It will be replaced with the value inside the brackets. In this case it's the address of the variable which was 62.

So it turns into ...

TheEEvar = EE_VarLink62

Which returns 2. The second EE_var that was linked to a PBP variable.

Now that you know which EE_var was linked to it, you can use that value to query the other parameters.

<pre>EE_Default = EE_Var#v(TheEEvar)_Default<br>EE_Loc = EE_Var#v(TheEEvar)_PTR<br>EE_Size = EE_var#v(TheEEvar)_Size</pre>This pulls up all the pertinent data about that EE_var. Which is what the GetEEinfo macro does.

If you want to use those constants in PBP, all you need to do is declare a CON EXT for each one.


EE_Default CON EXT
EE_Loc CON EXT
EE_Size CON EXT
And walla, a variable database, with zero code space. :)<hr>
If none of this makes any sense, don't worry. I write this stuff for everyone. Someday, someone will slap themself on the forehead and go. "That's It!". And if not now, six months from now might result in the same slap. Which of course, makes me "Slap Happy".


> I have a case where I may want to loop through a group if variables and save them to EEProm, is there a way to do this using EE_Vars.

Well, EE_vars wasn't set up for persistent Arrays. It's not that it can't be done. I just didn't do it. :o

> Can you recommend any reading to better familiarize myself with macros?

I'll say the same thing I always say ...
If you want to learn Macro's, you already have the best "Interactive" tutorial there is ... PBP.

For all the things you can do with PBP, you can create a 1-line program. More when you get better at it. That answers the specific question you may have. Like, "how do I set a port to Output?

Just create a small program that has 1 line ...

OUTPUT PORTB.0

After you compile it, you'll find a .ASM .MAC and .LST file in the folder that the original program was in.
Start with the .ASM

Those files will give you more insight into the workings of macro's, than ANY book I've ever seen.

Really, no I'm serious. Try it!
You can ask it any question (that PBP can do), and you'll get an answer that relates to your question, instead of an example to some project that the book was based on.

SteveB
- 7th October 2008, 16:11
I'll say the same thing I always say ...
If you want to learn Macro's, you already have the best "Interactive" tutorial there is ... PBP.
...
Those files will give you more insight into the workings of macro's, than ANY book I've ever seen.

Really, no I'm serious. Try it!
You can ask it any question (that PBP can do), and you'll get an answer that relates to your question, instead of an example to some project that the book was based on.
I whole heartedly aggree with Darrel on this, but with one correction: With PBP and Darrel's include files, you have got the best tutorial possible.

Also, for details, the help file for MPASM assembler has info about syntax and stuff that can be helpful as well.

Steve

brittons
- 7th October 2008, 16:45
Thanks SO MUCH! This stuff just fascinates me. I have to buckle down and start working with macros. Thanks for the insight into learning by doing. It's pretty much the way I've learned what I already know but I just wanted to see if anyone else had the light bulb turned on by something they stumbled across.

Darrel, when you stated that I could use the folowing constants in PBP do you mean I can examine the values after running EE_var or EE_assign and I would see the values of these three vars change in PBP according to the var assigned? Should I still use CON or should I use VAR? If I know the starting location of an EEProm var and the first element of my Array of vars starts at EE_Loc couldn't I loop through the elements and save them at the correct location? Of course my EE_Var assigns have to be assigned consecutively.

EE_Default CON EXT
EE_Loc CON EXT
EE_Size CON EXT

I did save a piece you wrote on EXT, I probably should go back and examine that.

Thanks, Bob

MitchStipp2
- 21st January 2009, 22:10
Hi Darrel,
I am working on a piece of code that uses the Timer 1 to create a timed interupt for turning on and off LEDs. The PIC is a 16F887. I wish use the EEPROM for saving information. All of the code seems to work well until I include and try to use the EEPROM Variables (EE_Vars.pbp). The EE_Vars seem to operate as expected - however my Timer 1 interupt runs erratically and sometimes halts. The time base is rather brief (1 mS) and I am using an external resonator as clock source (20MHz). I am using your "DT_INTS-14.bas" and "ReEnterPBP.bas" to support the Timer 1 interupt.
I am curious as to what I am doing wrong. The best diagnostic indication I have was sending the OSCCON variable to the port D. The values indicated that the PIC was going to internal LF oscillator when it should have been using the external resonator. Can you give me some wise counsel???

Thanks in advance, Mitch

Darrel Taylor
- 21st January 2009, 23:46
It's difficult to say with "large chunk of code left out .." in the routine that's having a problem.

I don't see any usage of the EE_Var routines, other than the declarations.
Are you trying to use them inside the interrupt handler? In the missing code?
<br>

Darrel Taylor
- 22nd January 2009, 00:49
After a closer inspection, it looks like you are probably overflowing the Stack.

When the Timer triggers an interrupt, that uses 1 level.
When it gets to the handler, it GOSUB's to TimerIO. That's level 2.
An Array operation uses 3 levels internally for a total of 5 levels.

Then in the Main loop, you also GOSUB MonitorIO, so you are already 4 levels deep when it gets interrupted.

16F's only have 8 stack levels.

MitchStipp2
- 22nd January 2009, 13:10
I can provide the chunk of code if you would like to review it, however your point about the stack is well taken and "me thinks" you are on target. I will see if I can simplify. Thanks

Byte_Butcher
- 22nd January 2009, 21:05
I'm sure everyone on the planet (except me) already knows about this, but since I just blew a couple hours trying to figure this out I figured I'd post it here incase it trips up someone else...

I've been playing with Darrel's EE_Vars.pbp, trying to make it work. (I'm using PBP/MCS)

The sample file "EE_1_Example.bas" worked PERFECT, after I changed the LCD formatting for my hardware.

But then I tried it with one of my existing programs, and it wouldn't compile... MCS kept whining about "Symbol not previously defined (Byte)"

At one point I ended up with 2 apparently identical lines of code, and 1 worked and the other didn't. :( ???

As it turns out, it was because of incorrect case in my variable definition. But what threw me was that part of the declaration wants UPPER case and part wants LOWER case.


This works fine:


wastedtime var byte : @ EE_var _wastedtime, BYTE, 139

This does not work:


wastedtime var byte : @ EE_var _wastedtime, byte, 139

This does not work:


wastedtime var BYTE : @ EE_var _wastedtime, BYTE, 139

This does not work:


wastedtime var BYTE : @ EE_var _wastedtime, byte, 139

Of course it would have been much easier to figure out if the "Uppercase All" option for the reserved word formatting hadn't been on. But of course since it makes all the reserved words BOLD uppercase it all looked the same. I couldn't figure out why with 2 apparently identical lines, one would work and the other not. Once I turned off the Uppercase All option, then it became clear that BYTE was not in the same case...

So... why does it demand lowercase on one side of the definition and uppercase on the other?


Steve

Darrel Taylor
- 22nd January 2009, 22:49
So... why does it demand lowercase on one side of the definition and uppercase on the other?

It doesn't.

The only one that has to be in upper case is the one in the EE_var declaration. (right side)
There is a "case sensitive" note in post#4, EE_var section.

Case doesn't matter on the VAR statement.

I've double checked it here to be sure.

Byte_Butcher
- 5th February 2009, 19:22
It doesn't.

The only one that has to be in upper case is the one in the EE_var declaration. (right side)
There is a "case sensitive" note in post#4, EE_var section.

Case doesn't matter on the VAR statement.

I've double checked it here to be sure.


Well Darrel, you're absolutely right of course ...

I tried it about 100 times and couldn't get it to work. Then other real life problems cropped up and I had to set it aside for a couple weeks .

Now that I've got time to work with it again, it works *perfectly*, just as advertised.

There was obviously a problem with that little lump of gray matter between my ears, but it seems to be better now... :o

Sorry to bother you. Thanks for your help.

Steve

brittons
- 17th March 2009, 21:35
Hi, I have incorporated EE_Vars into my project. I have replied to to this thread previously and mentioned two things in particular. I have changed 'EE_start' to 511 (I am using an 18F2525) because I am using the bottom half of the EEProm for some other functions. I only mention it as it a modification to the original program and may give an insight to my problem. The other thing is I discovered that while using MicroCode Studio I must have Loader Options set to program Data of the EEProm and Variables do not get intitialized.

My problem is that sometimes the EEProm and Variables get reinitialized after the initial programming is done. I do not have anything in my program that sets EE_Start to zero or resets it. This happens when I first power up, doesn't happen all the time. Sometimes I notice it when I pull a chip out of board after turning off power and put it in another board then power up. It seems kind of random.

The start of my progam looks like this:

INCLUDE "Defines.bas"
INCLUDE "EE_Vars.PBP" 'Darrel Taylors EE_Vars program
INCLUDE "VarDefs.bas" 'Define vars and use EE_Vars routines
Goto start ;Jump over assembly routine
INCLUDE "AsmInt.bas" ;Assembly interrupt service routines
INCLUDE "LcdText.bas" ;Strings, lookup tables
'------------GetAddress Macro - Location insensitive --------------------
ASM
GetAddress macro Label, Wout ; Returns the Address of a Label as a Word
CHK?RP Wout
movlw low Label
movwf Wout
movlw High Label
movwf Wout + 1
endm
ENDASM
start:
INCLUDE "Init.bas" ;Initialize I/O
INCLUDE "InitVars.bas" ;Initialize Variables
INCLUDE "ModSerVer.bas" ;to configure my model, serial, version

Having a hard time figuring this one out. Any help would be appreciated.

Thanks, Bob

Darrel Taylor
- 17th March 2009, 23:11
I have changed 'EE_start' to 511 (I am using an 18F2525) because I am using the bottom half of the EEProm for some other functions.
How much of the "bottom half" are you using?

Technically, 511 is in the "bottom half".
<br>

brittons
- 17th March 2009, 23:36
Well I'm not using all of it. I picked 511 as I thought it was midway. I used to use chips that only had 255 bytes of EEProm before I started using EE_Vars. So I just picked 511 randomly and started moving Vars to it. Some of them can't be used this way so I left them at the beginning. Do you think it has an effect on the operation?

Thanks, Bob

Darrel Taylor
- 18th March 2009, 00:11
Do you think it has an effect on the operation?
Without knowing how you are using the lower half, there's no way to answer that.

If you are using a variable to access lower EEPROM locations, you could be accidentally overwriting other locations if you're not careful.

If location 511 gets overwritten at any point along the way, it will automatically restore the default values on the next Reset. So it doesn't surprise me that it only happens when you unplug the chip or turn off power.

If you are unsure of whether or not it gets overwritten, you can use the EEIF interrupt which triggers after every WRITE completion. Then in the handler ... Read back 511 and see if it's changed. If it has changed, an address in the routine that changed it will be sitting on the stack (TOS).
<br>

brittons
- 18th March 2009, 15:11
Ok, I see what your saying. As I said it seems random. I don't believe I am accessing any EEPROM addresses up at 511 but I have some checking to do. Is it true that the reset will occur only if '511' or EE_start is set to Zero? If it's not zero then a reset will not occur correct? I suppose if it is set to some other number it would only load the EE_vars up to the number it is set to.

I do have a timed interrupt routine that writes into one of the first 62 bytes of EEProm once a minute. When you said 'if your not careful' did you mean something could be happening that I may not be aware of or that there would be something I can spot in my program that would be causing the overwrite?

Thanks, Bob

brittons
- 18th March 2009, 16:34
Hi, another thing I was wondering about. I am curious about the EE_start variable size. I've been looking at the EEPROM after I download and run my program. EE_start (511) contains 17h (the number of EE_vars?). My first EE_var is byte size with a default value of 255. It is located at EE_start + 1. I was wondering about the fact the EE_start is only 1 byte size. Will it be set to word size if the number of EE_vars exceeded 255? The first EE_var I am storing (located at EE_start + 1) is a my variable called EEStat. I default it to 255 then after my Model Number, Serial Number and Version are configured by the user I write a 0 to bit 6 of EEStat. On next power up it's supposed to see the 0 at bit six and skip by the cofiguration code. When I complete the configuration the first time I write EEStat to the LCD in binary as follows.

EECfgInit = EEInitTrue
@ EE_write_var _EEStat
LCDOUT "-->CONFIG OK"
LCDOUT ScrL2,HEX EEStat,"-",BIN8 EEStat

I see that the bit has been written to zero.

I just did this again and cycled the power and the bit had been set back to one so the unit went into configuration mode. I pulled the chip out and uploaded it using my picstart plus so I could examine the EEProm and EEStart was '17h' and EEStart + 1 was 255. Still trying to figure it out. Hope what I've written here makes sense.

Thanks, Bob

brittons
- 18th March 2009, 16:59
at the end of my configuration I do a string of EE_write_var statments in a row. Do you thing I need a pause between these to allow the write to finish or does EE_write_var take care of it?

msvSave:
@ EE_write_var _msNLamps
@ EE_write_var _msType
@ EE_write_var _msLLen
@ EE_write_var _msWatts
@ EE_write_var _msLType
@ EE_write_var _msPipeS
@ EE_write_var _msPortS
@ EE_write_var _msPortT
@ EE_write_var _msSeq
@ EE_write_var _msVolts
@ EE_write_var _msJobYear
@ EE_write_var _msJobNum
@ EE_write_var _msJobItem
'ENABLE DEBUG
EECfgInit = EEInitTrue
@ EE_write_var _EEStat
LCDOUT "-->CONFIG OK"
LCDOUT ScrL2,HEX EEStat,"-",BIN8 EEStat

Thanks, Bob

brittons
- 18th March 2009, 20:13
I've been experimenting with EEVars. I downloaded the program using Microcode Studio with the ICD. I enabled debug and let the program step into EE_Vars.Pbp. I watched the EEProm values get set with 511 as the EE_start. All my EE variables were set to default values and everything was fine. After everything was complete and my last variable was done EE_start has the value '17h' in it. So I stopped the program. Unplugged my power to my processor. Plugged it back in and restarted the ICD without downloading the program again. I paused at the first line:

goto OverEEsubs ; Skip over subroutines

I then changed the value of my first EE_var from 'FFh' to 'A4h' and started single stepping again. I am expecting that the 'First Run' had set all values to default and now the values would be read into my variables but no longer set to defaults on power up.

Instead the EE_start value is set to zero, followed by my first EE_var at location EE_start + 1 is reset to 'FFh' and the whole process starts over again. Am I misunderstanding something about how EEVars works? Here is an example of how I define my first variable. All others are the same.

EEStat VAR BYTE:@ EE_var _EEStat, BYTE, 255

How does EEVars know not to set default values on subsequent power ups? Maybe this would give me some insight. I assumed it looks at EE_start to see if it is not equal to 255 or 0.

Thanks, Bob

Darrel Taylor
- 19th March 2009, 03:32
Sheesh, don't hesitate to ask questions if you have any ... :)

OK, let's start with the last one ...
How does EEVars know not to set default values on subsequent power ups? Maybe this would give me some insight. I assumed it looks at EE_start to see if it is not equal to 255 or 0.

Nope, when the chip is initially programed, the EEPROM EE_Start, [0] statement causes the programmer to load the 0 value into the EE_Start location of EEPROM (511 in your case). This only happens during programming. It can't zero it out at run-time.

Then every time the chip resets, it runs through the list of EE_vars counting them as it goes. If the EEPROM value at 511 is less than the variable count, then it knows it hasn't initialized that EE_var yet and will write the default value, and increment the value at EE_Start.

This way, if power is lost in the middle of the first initialization, it can tell that the init was not completed, and continue from where it left off.

All writes are self-timed. So no, you don't need pauses between successive writes.
All writes are verified after writing. If the value in EEPROM is not the value it tried to write ... it will retry up to 10 times to get it to write correctly, and on the last attempt will disable Global interrupts before trying. Then if after 10 tries it still doesn't verify ... the EE_Failed bit will be set. This would be a good bit to watch in the ICD. If it gets set, the configs probably have _WRTD_ON_6H, or in your case the bootloader.
<hr>

Plugged it back in and restarted the ICD without downloading the program again. I paused at the first line:

goto OverEEsubs ; Skip over subroutines

I then changed the value of my first EE_var from 'FFh' to 'A4h' and started single stepping again. I am expecting that the 'First Run' had set all values to default and now the values would be read into my variables but no longer set to defaults on power up.

When it gets to that point, absolutely nothing has been done yet.
The real work isn't done until the program encounters the variable declarations with the matching EE_var macros. Those macro's are what initialize the variables, so you would need to stop somewhere after the variables to see how it powered up, before changing any values with the ICD.

And again, if your program jumps over those variable declarations, nothing gets initialized.

brittons
- 19th March 2009, 15:38
Hi Darrel, really sorry about the barrage of questions. I have a problem I'm having a hard time solving. I love the EE_Vars program and it is making things easier but I have this reset problem and since I must be missing something I don't know who else to ask. I'm sure it's something on my end. I have been setting breakpoints, single stepping and trying to track it down but so far it's still there.

I'm not sure what you meant by:

'the configs probably have _WRTD_ON_6H, or in your case the bootloader'

From what I can see in Microcode studio all the vars are properly written to EEProm and to the associated variables.

I'll keep at it, thanks for all or your help.

brittons
- 20th March 2009, 20:46
Well, I have another question. I have been examining the .asm and .lst files to try to understand how macros create code and better grasp the EE_vars program. I found a variable called EE_VarCount that is EXT (external?) which I believe means it is not available in the actual downloaded code.

Can help me better understand what happens when the EE_Vars program is run the 2nd time after initialization is complete? I understand that:

EEPROM EE_Start, [0]

Sets EE_Start to zero on 'first run' only. At the end of initialization EE_Start contains the number of EE_Vars assigned. After that I assume that EE_Start is never written to correct? Can you give me some insight into what the program does on 2nd and consecutive runs. What is it examining to know that it is finished with initialization? Is there a variable I can look at to know to see what happens?

Thanks again, Bob

Darrel Taylor
- 20th March 2009, 23:47
I found a variable called EE_VarCount that is EXT (external?) which I believe means it is not available in the actual downloaded code.If you do a FIND (ctrl-F) and type in EE_VarCount, you'll see that variable used many times in the program. So yes, it IS in the actual downloaded code.


Can help me better understand what happens when the EE_Vars program is run the 2nd time after initialization is complete? ...
I already went through that in post#38.

I understand that:
EEPROM EE_Start, [0]
Sets EE_Start to zero on 'first run' only. At the end of initialization EE_Start contains the number of EE_Vars assigned. After that I assume that EE_Start is never written to correct?
Correct.

What is it examining to know that it is finished with initialization? Is there a variable I can look at to know to see what happens?
Again, it's looking at the EEPROM location designated by the EE_Start constant. (post#38)

Look, we can go round and round trying to blame the Tried and Tested code (EE_vars), or we can try to find the problem in your program, which you seem to have stopped looking at.

You get to see all my code.
I need to see yours.
The whole thing, not just 10 lines somewhere that might apply.
<br>

Darrel Taylor
- 6th May 2009, 06:18
Hi again Bob,

After another similar question (http://www.picbasic.co.uk/forum/showthread.php?p=73803#post73803) from a different user, I've found a possible reason for your problems.
Of course, there's no way to verify it because I still haven't seen your code, but ...

Something I didn't realize before is that the DATA and EEPROM statements use the same internal "counter" to keep track of the next available EEPROM location.

So if the EE_start location is changed to a higher value, and DATA statements come AFTER the EE_vars include file, then the DATA statements will place the data in the same locations that EE_vars uses, instead of 0 like expected.

In other words, to do what you were trying to do, the DATA statements would have to be placed PRIOR to including the EE_vars module.

hth,

LinkMTech
- 30th July 2009, 23:17
Hi Darrel,
I'm just beginning to use the EEPROM of the PIC12F683 on the LAB-X4 platform with PB Pro 2.47 and using the MPASM compiler.
I downloaded the EE_Vars.PBP.txt file and copied it to my PBP folder where I resaved it as EE_Vars.PBP, I think I did right.
The good stuff:
I also download your EE_example_1 file to experiment with. After configuring the LCD setup, it works as advertised!


'************************************************* ***************
'* Name : EE_1_Example.bas *
'* Author : Darrel Taylor *
'* Date : 8/27/2005 *
'* Version : 1.0 *
'* Notes : This is an Example program for the EE_Vars.PBP *
'* : Include file. *
'************************************************* ***************
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
OSCCON = %01110001 ' Osc 8Mhz
ANSEL = %00111000 ' Fosc/64 and ANS3 set to analog
ADCON0 = %10001100 ' Right justified and AN3 selected
CMCON0 = 7 ' Analog comparators off
GPIO = %00111101 ' Set all ports to inputs except port 1
TRISIO = %00111101 ' Port 1 to output, rest inputs

;-- Define LCD connections -- (change these to match your hardware) ------------
Include "modedefs.bas" ' Mode definitions for Serout
INCLUDE "EE_Vars.PBP" ; Include the EE_var routines

define OSC 8 ' Declare for PAUSE and PAUSEUS statements
pause 1000
'================================================= ========================
' Variable pin names
'================================================= ========================
' Var GPIO.0 ' Pin 7
LCD Var GPIO.1 ' Pin 6
' Var GPIO.2 ' Pin 5
' Var GPIO.3 ' Pin 4
' Var GPIO.4 ' Pin 3
' var GPIO.5 ' Pin 2



Days VAR WORD : @ EE_var _Days, WORD, 365
Cats VAR WORD : @ EE_var _Cats, WORD, 1024
Mice VAR WORD : @ EE_var _Mice, WORD, 10000
PowerOn VAR BYTE : @ EE_var _PowerOn, BYTE, 0

PowerOn = PowerOn + 1 ; Increment number of Power-On cycles
@ EE_write_var _PowerOn ; save the new number to EEPROM

Serout LCD, T2400, [$fe, 1] ' Clear screen
pause 1000
Serout LCD, T2400, ["Days= ",#Days," Cats= ",#Cats]
pause 100
Serout LCD, T2400, [$fe, $c0,"Mice= ",#Mice," PowOn= ",#PowerOn]
pause 100

RANDOM Mice ; get a new value for Mice
@ EE_write_var _Mice ; save it to EEPROM

stop



The funny stuff:
If I first select and copy any one of the EE variables such as:


PowerOn VAR BYTE : @ EE_var _PowerOn, BYTE, 0

and change the Byte to a Word in both cases here, it gets mad when I compile it and reports these errors:


Error[113] c:\program~on and on~ee_1_e~.asm 163: Symbol not previously defined (Byte)
Error[113] c:\program~on and on~ee_1_e~.asm 172: Symbol not previously defined (Byte)
Error[113] c:\program~on and on~ee_1_e~.asm 173: Symbol not previously defined (Byte)


So now if I change it back to BYTE in both cases, it still gets mad after compiling.

Here's the stranger part: I now select the troubled line of code and paste the original line of code prior to all this and the compiler is happy once more!?

I only tried this because when I wrote my own and got these messages, they stopped when I commented out my EE declaration lines and "pasted" your lines instead.

Are you using subliminal texts for this routine? Or did I not copy the Include file properly into my program?

Darrel Taylor
- 30th July 2009, 23:22
Watch the CASE of the parameters.
Use WORD or BYTE instead of Word or Byte.

You can tell from the error message ... Symbol not previously defined (Byte).
<br>

LinkMTech
- 30th July 2009, 23:38
Thanks again for your efforts Darrel!
That was it exactly. It turns out that I took the editor's "Auto cap" feature for granted when I typed the parameters. It's turned me into "Auto lazy".

That feature is no more.

Thanks again...

El_AMPo
- 4th September 2010, 15:45
Thanks Darrel,

As usual your INCLUDES are awesome.


P.D.: I would buy you a beer but then is the problem of distance

Any local brewery that takes online orders? :)

RossWaddell
- 7th May 2012, 02:44
Hi Darrel,

Just found your EE_Vars.PBP include file and have been playing around with it - thanks for making the documentation so thorough; it made getting started very easy. Is it possible to use a variable/constant/symbol in the default value portion of EE_var? Something like this:


NacelleSpeed VAR WORD : @ EE_var _NacelleSpeed, WORD, initNacelleSpeed

MPASM throws this error no matter how I set up initNacelleSpeed (variable/constant/symbol):


Error[113] c:\pbp~1\pbp2.60c\ee_2~1.asm 122 : Symbol not previously defined (initNacelleSpeed)

Thanks,
Ross

Darrel Taylor
- 7th May 2012, 17:18
With the thread as messed up as it got after HTML was turned off, I'm surprised you were still able to read it.

Constants that are declared in PBP will have an underscore before them in ASM.



initNacelleSpeed CON 300

NacelleSpeed VAR WORD : @ EE_var _NacelleSpeed, WORD, _initNacelleSpeed

The value must be known at compile time, so variables will not work. The default values must be constants.

RossWaddell
- 7th May 2012, 17:29
Thanks Darrel! I should have guess that based on the underscore for the variable. The reason I wanted to use a constant is that I was having trouble with EE_write_default; it didn't seem to save the original value defined in EE_var to EEPROM when I turned off the circuit and restarted it, but now it seems to work (although the first time I powered up the chip after programming and when to show the value on an LCD screen using your example it had something like '366565' rather than '1000').

BTW, I spent about an hour removing all the HTML tags to make it readable. I've saved a copy in Word as I anticipate going back to it over and over.

Last question (unrelated to your include): does reprogramming a chip clear it's EEPROM memory?

Darrel Taylor
- 7th May 2012, 23:02
does reprogramming a chip clear it's EEPROM memory?
That depends on the programmer and options.

A bulk erase will erase everything.
But if you are using options for low voltage erase, or not programming config words, it's possible that EEPROM will not get erased.

With melabs programmer software, go to Options > More Options > Set Options to Defaults to be sure that "Bulk Erase" is being used.

RossWaddell
- 7th May 2012, 23:28
Thanks Darrel!

RossWaddell
- 20th October 2012, 22:21
I'm seeing some strange behaviour with my EEPROM variable - the first time the chip is powered up it seems like the linked variable isn't being set to the default as in this code:



MotorRPM VAR BYTE : @ EE_var _MotorRPM, BYTE, 150


I know this because this loop is meant to spin up two motors connected to CCP1 & CCP2 on a PIC16F1825; rather than increase the duty to the mid-range RPM as in the default (150), it spins up to the max (255):

[CODE
IF MotorRPM > 66 THEN
FOR I = 65 to MotorRPM
pause 30
HPWM 1, I, 20000 ' Stbd engine (CCP1)
HPWM 2, I, 20000 ' Port engine (CCP2)
NEXT I
EndIf
[/CODE]

This only happens the first time the chip is powered up after re-programming. If I unplug the breadboard power and turn it back on again, the motors spin up to the expected default.

Full code attached. Any ideas? Should I put an EE_READ in even though it shouldn't be needed?

6707

RossWaddell
- 21st October 2012, 16:38
Looking over my post #49, this recent problem appears to be similar to what I was seeing there (but went away). I don't have enough available pins on my 16F1825 to display the start up value of _MotorRPM but I suspect the same thing is happening - after first programming the chip, the initial value is way over 150 (and why the PWM command to the motor ends up spinning it to its max value [255]).

I've switched to PBP3 and MicroCode Studio Plus (v5.0.0.3) and PBP compiler vPBPX 3.0.5.4. I tried what you posted in #50 but no lucy. Could this be a case of bulk erase not working? Why would that happen with one project but not another similar one (as I posted in this (http://www.picbasic.co.uk/forum/showthread.php?t=17270) thread)

RossWaddell
- 22nd October 2012, 01:06
If I add this:



MotorRPM = 150


before the the PWM command, all works well (completely negating the use of EEPROM of course) so this does indicate to me that somehow the initial value of _MotorRPM is getting messed up after first programming the chip (if I use my mechanical rotary encoder to reduce the RPM, this does get saved properly and the motor starts up with this saved value next time power is turned on).

Darrel?

Darrel Taylor
- 22nd October 2012, 23:08
Ross,

Try putting a pause 100 or so at the very beginning of your program.

The programmer goes through several cycles of power-on and resets to program each section of memory.
And the EEPROM write is one of the first things that happens in the program.

The EEPROM write takes ~5ms, so it's probably getting powered down in the middle of the write cycle.

With a pause at the beginning, it will insure that the programming cycles are completed before it starts running the rest of the program.

I've single stepped through the program several times in the simulator, and everything works fine.
I'm not in the office today, so I can't try it with a real programmer.

RossWaddell
- 23rd October 2012, 00:12
Thanks Darrel! I'll try that tonight when I get home.

BTW, I've been using MCLR_OFF in my config but w/o a pull up resistor connected between the MCLR pin and +5v - should I have that resistor?

Darrel Taylor
- 23rd October 2012, 00:19
With MCLR disabled, you don't need a pull-up, unless your input requires one for a switch or something.
And on the 16F1 (Enhanced Core) devices, you don't even need a pull-up when enabled. They have an internal pull-up on MCLR.

RossWaddell
- 23rd October 2012, 00:30
Thanks again, Darrel! I remember now reading about the internal pull-up in the data sheet. This is what happens when you start a project and come back to it 6 months later :)

RossWaddell
- 23rd October 2012, 02:56
Hmm. That seemed to work on a simpler project but when I add it to the one I attached above (and which I'm attaching here for you to see) it doesn't help the _MotorRPM problem (motors still spin up to their maximum speed, i.e. MotorRPM >= 255) but what is weird is that it now takes almost 6 seconds for them to start spinning!?!??! I only added a pause of 100.

6710

Darrel Taylor
- 23rd October 2012, 03:49
The internal oscillator runs at 500 Khz on power-up, which is 1/64th the 32 Mhz PBP is expecting.
So if you put it before the OSCCON statement, it will be equivelent to PAUSE 6400 or 6.4 seconds.

I'll try it on some real hardware tomorrow.

RossWaddell
- 23rd October 2012, 03:59
That solved the 6 sec delay (by moving the 'pause 100' to after the OSCON statement) but it still spins up to max RPM ...

6711

Darrel Taylor
- 23rd October 2012, 22:13
Ross,

I've run your program here on real hardware and real programmers.
I still cannot duplicate your reported problems.

The EEPROM is initialized correctly on the first run after programming.
The PWM ramps up to 150 dutycycle every time, and never goes to 255.
I'm measuring the dutycycle with an oscilloscope. I do not have motors hooked up.

I've used an melabs U2 programmer.
I've also used a PICkit3 programmer, and single stepped through it.
It always works exactly like it should.

What are your software versions (PBP3 and meProg)?
How are you driving the motors?
Do you have a scope?

RossWaddell
- 24th October 2012, 01:26
Here's what I've observed:


Just adding the 'pause 100' doesn't seem to change anything
Adding 'MotorRPM = 127' just before the spin up does work (although negating the use of EEPROM)
I know the motors are spinning up to their max cycle becuase I have a mechanical rotary encoder which allows me to adjust the RPM; when I turn the knob CW the speed does **not** increase, while turning it CCW does reduce the speed. Also, this rotary encoder has a push button which I've set up to return the motor speed to default - this also works
If I alter the speed (either by adjust the RPM up or down, or pressing the 'reset' button), the chip remembers this value the next time it's powered up
If I grab a brand new chip, never previously programmed, it works straight away



I don't have a scope, Darrel - I wish I did :) Hopefully the above is helpful. Here are my version details:


OS: Windows 7 (running on a VM on my MacBook Pro)
MicroCode Studio Plus: 5.0.0.3
PicBasic Pro compiler: PBPX 3.0.6.4
meLabs Programmer: v4.50 (with the U2 programmer)



Here are the two .pbp files (the only difference being the addition of the 'MotorRPM = 127'):

67126713

I've shared my .hex & .asm files here (https://www.dropbox.com/sh/5v599r2ylsf83zm/iqXmPGF4EX).

Here's my schematic. I'm using a SN754110 to drive the motors:

6714

RossWaddell
- 24th October 2012, 01:48
And here's a screenshot of my meLabs programmer settings:

6716

Demon
- 24th October 2012, 03:26
Ross,

I've run your program here on real hardware and real programmers.
I still cannot duplicate your reported problems.

The EEPROM is initialized correctly on the first run after programming.
The PWM ramps up to 150 dutycycle every time, and never goes to 255.
I'm measuring the dutycycle with an oscilloscope. I do not have motors hooked up.

I've used an melabs U2 programmer.
I've also used a PICkit3 programmer, and single stepped through it.
It always works exactly like it should.

What are your software versions (PBP3 and meProg)?
How are you driving the motors?
Do you have a scope?

Ross, after reading that, I would put my money on a hardware problem; mis-wired PIC, inadequate power, possibilities are countless.

You'd be surprised how often I put a resistor backwards. :D

Robert

RossWaddell
- 24th October 2012, 05:02
But if I use the same chip and re-program it with the first code, it works; if I then pre-program it with the second code, it doesn't. And I can keep going backwards and forwards like that ...

RossWaddell
- 24th October 2012, 05:14
Also: after I re-program the new chip from my inventory a second time, the problem re-appears.

Darrel Taylor
- 24th October 2012, 05:29
•Adding 'MotorRPM = 127' just before the spin up does work
The default value was 150, so it seems logical that setting it to 127 would make it run slower.

And I assume this is just a schematic error ?? Might cause a few problems. Sure confused me for awhile. :)

http://support.melabs.com/DT/BadEncoderInputs.png

Try the attached program.

RossWaddell
- 24th October 2012, 13:51
I just changed it to 127 so it would be even slower to make it obvious. If I use 150 it has the exact same effect.

Thanks for spotting the schematic error! The board itself is fine, though.

RossWaddell
- 24th October 2012, 15:24
BTW, this problem applies to both EE_vars (MotorRPM & PortEngDir) - unless I specifically set them in code they do not get initialized with the default values (150/127 & 0). I know this for the 2nd EE_var because in a later iteration of the same code I do a check on PortEngDir: if it's 0 make the motor spin CCW; else make the motor spin CW. Without the line 'PortEngDir = 0' the motor **always** spins CW after the chip has been programmed more than once.

Darrel - I missed seeing that you had provided a code file too. I'll try that out tonight after work (and thanks).

RossWaddell
- 25th October 2012, 00:12
Darrel - your file works (all except the interrupt handler to reset the motor speed via the rotary encoder's button)! Does that tell you anything more about what's going on?

Darrel Taylor
- 25th October 2012, 05:21
Oops,

Add this line after the WRITE command in the RotEncBtnPress: handler.

MotorRPM = MotorRPM_Default

RossWaddell
- 25th October 2012, 14:52
It works! Thanks again Darrel.

Does this mean there's a problem with EE_var? I've used that include in a bunch of projects and love it. For this project, I still have more work to do (possibly with more EEPROM variables) and would ideally continue to use your EE_var if possible. Could this be a problem with my local version of DT_INTS-14.bas (which I had to modify for the PIC16F1825)?

6723

Darrel Taylor
- 25th October 2012, 20:58
First off, you should not be modifying DT_INTS-14.
It even says so in the code that you modified.
The changes that you made were incorrect (see the comments in DT_INTS-14), but I don't think they would have affected EE_Vars.

Since I cannot duplicate your problems with the same hardware and software, I can't agree that there is a problem with EE_Vars.
It all works perfectly here.

You don't have any way to debug your program/hardware, no LCD, the USART pins are used for other purposes.
So you are left to make guesses on what is happening, and I can't ask you to check register values.
Naturally, those guesses point blame at everything you didn't do. It's human nature.

I would recommend building in some form of debugging capabillity in your next project.
A serial LCD that only uses one pin can be extremely usefull.

With that said, there have been many changes to PBP since I wrote EE_Vars, and much of it's functionality is now included in the compiler.
So there's not much reason to use EE_Vars anymore. :(

RossWaddell
- 25th October 2012, 21:25
I wasn't trying to blame you or the excellent EE_var include, Darrel. Honestly. It's worked so well for me in the past that I would prefer to continue using it if at all possible although I guess I should dig into your changed code and see if the code you used is easier than EE_var. The only reason I think there's something odd with the use of EE_var in this particular project is that the difference between working code and not-working code is the addition of the 'MotorRPM = 127 (or 150)' line into the working code, and that from then on it seems to remember the saved value.

I don't have a serial LCD, only one that needs 6 pins to work. It's been spotty at best and I did spend the better part of an evening removing code and trying to hook it up to see what the value was, but no luck. I will look into getting a serial LCD if I can find a suitable one.

As for your other include, DT_INTS-14.bas, I thought the instructions on your website or forum posting said to update if it you encounter compiler issues, which is what happens to me with this chip and a few others. Perhaps I misread the instructions, but how else do I resolve the compile errors?

Once again, thanks Darrel - seriously not trying to be a pain here, I just need to finish this project which I've been working on for almost 6 months now ...

Darrel Taylor
- 25th October 2012, 21:51
The only reason I think there's something odd with the use of EE_var in this particular project is that the difference between working code and not-working code is the addition of the 'MotorRPM = 127 (or 150)' line into the working code
That's pretty much my point.
You assume something is "odd" with EE_Vars, because you added a line that made it work without knowing why it worked.
Without any way to debug, you can't know why it worked. So the assumption is that is was EE_Vars fault.
It could very easily be something else.
And again, on the same chip for me, it works perfectly.


Perhaps I misread the instructions, but how else do I resolve the compile errors?
Here is the section of DT_INTS-14 that you modified. Although this is the unmodified version.
The comments say it all.

;-- Place a copy of these variables in your Main program -------------------
;-- The compiler will tell you which lines to un-comment --
;-- Do Not un-comment these lines --
;---------------------------------------------------------------------------
;wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
;wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
;wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
;wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

RossWaddell
- 25th October 2012, 22:00
I'm assuming you mean the 2nd 'wave' line that I modified in my earlier post, right? Then I guess I've seriously misunderstood how to implement this include for various PICs. Do I (temporarily) copy the two 'wave' lines to my code and on compile it will tell me which of the wave1, wave2, wave3 lines farther down to uncomment? And then remove the 'wave' lines?

Sorry to be so thick. Looks like I picked a bad week to reduce my caffeine intake ...

Darrel Taylor
- 25th October 2012, 23:25
I don't have a serial LCD, only one that needs 6 pins to work.
You can make your own serial interface to a parallel LCD using just about any PIC and this sample code ...
But it's easiest with a 16F676.
http://melabs.com/samples/LABX4-12F675/BPX4.htm


Do I (temporarily) copy the two 'wave' lines to my code and on compile it will tell me which of the wave1, wave2, wave3 lines farther down to uncomment? And then remove the 'wave' lines?
No, copy the entire block to your main program (permanently). Do not uncomment the lines in the include file.
Compile your code, and uncomment the lines the compiler tells you to.

However, with the 16F1825 ... You don't need any wsave vars, because those chips have automatic context saving and the compiler would not tell you to uncomment anything, So you don't need them in your code, and you never needed to modify the include to begin with.

RossWaddell
- 26th October 2012, 00:50
Wow. Totally missed that. Since I didn't see that section in the samples I looked at, I completely misinterpreted the instructions. Sure enough, restoring the original DT_INTS-14.bas and re-compiling with the 16F1825 was successful. Tried the same thing with other code on a 12F683 and it told me what to uncomment.

And guess what - reverting to the original DT_INTS-14.bas resolves the problem. No more runaway motor, no matter how many times I reprogram the chip. Sigh. The architect of my doom ... is me.

SteveB
- 26th October 2012, 01:06
The architect of my doom ... is me.
We've all been there, done than. Experience is a great instructor, but the lessons are often more painful than we'd like ;)