Storing a servo position in an 08m NV memory

elanman99

Senior Member
I am controlling one axis of a camera pan/tilt by using two momentary buttons for clockwise and anticlockwise movement (movement stops when button released). I have written and tested the programme but now want to add a 'calibration' feature to limit the ends of travel.

I am using the servo and servopos command and basically now want to store high and low pulse width values (using another two switches) that will then become the max and min pulse values so preventing the camera 'seeing' more than I want it to.

I have tried using the read and write commands but I am fairly new to programming and the command reference PDF does not give enough examples of usage IMHO.
 

Attachments

elanman99

Senior Member
Apologies, I hit the 'post' button to soon.

I wanted to show my programme rather than attach it, and also explain that since making a few changes to the write instruction the programme has gone awry!

Ian

'For Picaxe 08M

'All LCD code removed now as Stamp is used as pulse width monitor

'Controls single servo but has ends of travel calibration feature, possibly setting
'mid point automatically (half way between numeric values?)

'Servo on output 0 (IC pin 7)
'Increment sw on Input 1 (IC pin 6)
'Decrement sw on input 2 (IC pin 5)
'End of CW travel calibration switch on input 3 (IC pin 4)
'End of CW travel calibration switch on input 4 (IC pin 3)


Symbol CW = B4 'Variable to decrement output pulse width
Symbol ACW = B5 'Variable to increment output pulse width
Symbol POSN = B6 'VAR Word, current servo position
Symbol CWEOT = B0 'Clockwise end of (useful) travel, to be saved/stored
Symbol ACWEOT = B1 'Anticlockwise end of (useful) travel, to be saved/stored
Input 1 'Makes i/o 1 into an input
Input 2 'Makes i/o 2 into an input

Servo 0,125 'Only issued once, 2nd number appears irrelevant

CWEOT = 200 'Initial starting value
ACWEOT = 50 'Initial starting value

POSN = 125 'Start with servo in mid position

'Write B0,POSN

'Start of program


'Read B0,CWEOT

'CWEOT = B0


Main:

Read B0,CWEOT
CWEOT = B0

If Pin3 = 0 Then SETCWEOT 'SETCWEOT will be a routine to store the current POSN as new max value
If Pin4 = 0 Then SETACWEOT 'SETACWEOT will be a routine to store the current POSN as new max value

'Pause 200 'Artificially slows travel speed


Button 1, 1, 1, 1, CW, 0, NOTPRESSED1
POSN=POSN +1 Max CWEOT
NOTPRESSED1:

Button 2, 1, 1, 1, ACW, 0, NOTPRESSED2
POSN=POSN -1 Min ACWEOT
NOTPRESSED2:

Pause 2

Servopos 0,POSN 'Output the servo pulse on 0

Goto Main



SETCWEOT:
Write B0, POSN 'Puts current servo position into non volatile memory
Goto Main

SETACWEOT:
Write B1, POSN 'Puts current servo position into non volatile memory
Goto Main
 

Chavaquiah

Senior Member
I only took a very cursory look at your code, but seems you're not assigning values to b0 before using it in the read and write instructions (if you do, I apologize).

You should do READ ADDRESS, REGISTER and WRITE ADDRESS, VALUE.

Say you want to use locations 0 and 1 for Min and Max values:

SYMBOL MIN_ADDR = 0
SYMBOL MAX_ADDR = 1
...
WRITE MIN_ADDR, whatever
WRITE MAX_ADDR, b0 'Just an example
...
READ MIN_ADDR, b0
READ MAX_ADDR, b1


Something like this.

Also be aware that the 08M does not have a separate area for permanent storage. If you download a new (or, indeed, the same) program, I think previous values will be erased.
 

elanman99

Senior Member
I thought I had the used the symbol command but now I am not sure.

I do not fully understand the usage, in your example you assign to locations 0 and 1, but then refer to them as B0 and B1.

The values I want to save are CWEOT and ACWEOT and I put;

Symbol CWEOT = B0

Is that correct or should it just be a 0 ?

Ian
 

BCJKiwi

Senior Member
Have another read of Chev's response.

Write works one way, read another way.

You appear to be trying to use the same thing both ways.

The symbol statements are pointing to the NV storage addresses and are where to put the data using WRITE.

The b0, b1 variables are places to put what is stored in the NV into working variables using the READ for the program to work with.
 
Last edited:

Chavaquiah

Senior Member
I'm jumping between Portuguese, French and English at the moment. No wonder I'm not making myself clear.

For READ you say first where (what address) you start reading from and then the variable (or variables) where you want to place what has been read. Using SYMBOL really is not necessary. Perhaps that made things even more confusing.

Say you want to read the value stored at address 0. You use READ 0, bx. "bx" is any register that will receive the value. For instance READ 0, b0.

Same for WRITE.

And you can both write or read more than one value at a time, from contiguous addresses:

Code:
symbol FIRSTVAL = 10
symbol SECONDVAL = 20

b6 = FIRSTVAL
WRITE 0, b6, SECONDVAL

'Now location 0 has the value 10 and location 2 stores the value 20

READ 1, b9
READ 0, b10

'b9 has 20, b10 has 10
'COULD have done this with
   READ 0, b10, b9
'In the previous line, valur stored at 0 is read into b10 and the value at
'the next location (1) goes to b9
 

elanman99

Senior Member
Have another read of Chev's response.

Write works one way, read another way.

You appear to be trying to use the same thing both ways.

The symbol statements are pointing to the NV storage addresses and are where to put the data using WRITE.

The b0, b1 variables are places to put what is stored in the NV into working variables using the READ for the program to work with.
Thanks for your help, however I am still struggling and have a couple of questions which I would be gratefull if you could answer.

You say the symbol statement points to storage address, however Chav seems to use the symbol command to actually put a numeric value in the location. That seems to make the write command superfluous.

I understand b0, b1, etc are storage addresses but to me the read commands shown in Chav's example read from 0, 1, etc and then put the results in b9 b10. How do I read these addresses and use the result as a semi fixed variable in my programme?

Can you point me to any example code that shows the read and write commands in use?

Many thanks in advance.

Ian Phillips
 

BCJKiwi

Senior Member
The symbol command is simply a labelling system so the program is easier to understand for us humans.

So using the symbol command simply creates an alias for the number. It does not actually store any data. it is just used once at the beginning of the program before the main loop. Hence Chev's comment that showing symbol commands in his post may have confused things and might have better been left out.

Have you tried the actual sample program snippet provided (Chev's Post #9) in the simulator? This would give you a better understanding of how these commands actually behave.
 
Last edited:

elanman99

Senior Member
The symbol command is simply a labelling system so the program is easier to understand for us humans.

So using the symbol command simply creates an alias for the number. It does not actually store any data. it is just used once at the beginning of the program before the main loop. Hence Chev's comment that showing symbol commands in his post may have confused things and might have better been left out.

Have you tried the actual sample program snippet provided (Chev's Post #9) in the simulator? This would give you a better understanding of how these commands actually behave.
I have tried Chev's example and followed it in the simulator (which is great and I use a lot) but am still not clear on what happens. After running his programme 3 (not just two) of the 'b' addresses contain numeric values. and I am not sure how to read those numbers out and give them variable names I can use.

Ian
 

Chavaquiah

Senior Member
BCJKiwi's idea of trying this in the simulator seems very good.

I suggest you copy and paste the following code and then hit the Simulate button. The program will pause between instructions whenever that DO LOOP is found. To move on, press the button for pin1 (to simulate it high) and then again to simulate pin1 low.

After each instruction please look at the window that shows register values (b0, b1, b2, ...) and the memory window. You'll see "10" and "20" appearing there.

Again, as BCJKiwi's said, the SYMBOL statement doesn't do anything by itself. Doing SYMBOL XXX = 99 just means that later on, in the "real" code, you can write "XXX" instead of "99". This is useful, for instance, to document the connections you made. For instance, say you have one LED connected to pin1. If you write "SYMBOL LED = pin1", later in the program you can have something like "HIGH LED". Easier to know what it's supposed to do.

Besides, if later on you have to move the LED to another pin, you just have to change the SYMBOL statement, rather than chasing through the program for all references to pin1.

And now, the code:

Code:
symbol FIRSTVAL = 10
symbol SECONDVAL = 20

do loop until pin1 = 1
do loop until pin1 = 0

b6 = FIRSTVAL

do loop until pin1 = 1
do loop until pin1 = 0

WRITE 0, b6, SECONDVAL

'Now location 0 has the value 10 and location 2 stores the value 20

do loop until pin1 = 1
do loop until pin1 = 0


READ 1, b9

do loop until pin1 = 1
do loop until pin1 = 0


READ 0, b10

'b9 has 20, b10 has 10

do loop until pin1 = 1
do loop until pin1 = 0


'COULD have done this with

READ 0, b4, b7
'In the previous line, value stored at 0 is read into b4 and the value at
'the next location (1) goes to b7

do loop until pin1 = 1
do loop until pin1 = 0

end
 

elanman99

Senior Member
Chavaquiah

I have run the simulator and am starting to get a better idea of what is happening but still confused (old age!).

When the programme has run through I end up with values in 4 addresses, Why does it need 5 places (b4, 6, 7, 9, and 10) to store 2 numbers?

Thanks for helping me

Ian
 

Chavaquiah

Senior Member
It does not. I just kept using different registers to show where the values were going.

Of course, as examples go, this was a little bit silly.

Let me go back to your original code and try to explain what is happening:

Symbol POSN = B6 'VAR Word, current servo position

This tells the compiler "whenever you see "POSN", pretend I wrote "B6"

Symbol CWEOT = B0
Symbol ACWEOT = B1


Same thing. CWEOT becomes an alias for B0, ACWEOT for B1.

CWEOT = 200 'Initial starting value
This was the same as writing B0 = 200

ACWEOT = 50 'Initial starting value

Or B1 = 50.

POSN = 125 'Start with servo in mid position

B6 = 125

Write B0,POSN

(I removed the comment indicator)

B0 contains 200. B6 contains 125. This would write the value 125 (POSN = B6) to memory location 200.
 

elanman99

Senior Member
Chavaquiah

That's a really good explanation, especially so if English is not your native tongue. I understood what is happening now even if I dont know the reason for some of it.

What I mean is, for example,

This tells the compiler "whenever you see "POSN", pretend I wrote "B6"​

Why can't I just use 'POSN' and not bother with B6?

B0 contains 200. B6 contains 125. This would write the value 125 (POSN = B6) to memory location 200.​

Also, where is memory location 200?

I really appreciate your assistance, I'm learning a lot.


Ian Phillips
Cheshire UK
 

tjetson

Senior Member
Why can't I just use 'POSN' and not bother with B6?
Any number you want to use MUST be stored in a byte variable (b1, b2 etc). If you use the symbol command, you are telling the program "I don't want to use b6, I want to use POSN instead". So, when you write POSN, the program knows what you are talking about.
 

lbenson

Senior Member
>where is memory location 200?

On your 08M (and for the whole "M" series of picaxe), EEPROM memory locations as used with the "read" and "write" commands are shared with the 256-byte program memory, so you have to use care with "read" and "write" so that you don't overwrite program memory. With the "X" series chips you have separate EEPROM memory.
 

lbenson

Senior Member
The use of the SYMBOL command doesn't change the +location+ where values are stored, it just gives you an alternative (and, one hopes, more instructive) +name+ for that location (or static value).

For example

Code:
symbol temperature = b13  ' symbolic name for storage location
symbol ds18b20Pin = 1       ' symbolic name for static value
symbol highTemp = 30

readtemp ds18b20Pin, temperature ' reads the temperature from a ds18b20 on pin 1
if temperature > highTemp then
  gosub itsHot
endif
 

MPep

Senior Member
I'm jumping between Portuguese, French and English at the moment. No wonder I'm not making myself clear.
There are some people here that only know English, and still get explanations wrong!! :eek:
 
Last edited:
Top