Shop OBEX P1 Docs P2 Docs Learn Events
out of variable space — Parallax Forums

out of variable space

dwbowendwbowen Posts: 30
edited 2008-02-29 15:48 in BASIC Stamp
Hello All,

Is it possible to define a variable as a size between byte and word. Byte 0 to 255 is too small to give my array of 7 photo-resistors enough range to read the fluctuating range of the photos. If I define them as word variables I run out of variable space. The program I am working on takes an initial light reading from the space. From that it subtracts all of the numbers from a base number and uses the difference to start all of the new readings at the same point. Here is an example of a debugging version....

' {$STAMP BS2}
' {$PBASIC 2.5}

photo0 VAR WORD
photo1 VAR WORD
photo2 VAR WORD
photo3 VAR WORD
photo4 VAR WORD
photo5 VAR WORD
photo6 VAR WORD

dif0 VAR WORD
dif1 VAR WORD
dif2 VAR WORD
dif3 VAR WORD
dif4 VAR WORD
dif5 VAR WORD
dif6 VAR WORD

base CON 100

start:

HIGH 0
HIGH 1
HIGH 2
HIGH 3
HIGH 4
HIGH 5
HIGH 6
PAUSE 3
RCTIME 0,1,photo0
RCTIME 1,1,photo1
RCTIME 2,1,photo2
RCTIME 3,1,photo3
RCTIME 4,1,photo4
RCTIME 5,1,photo5
RCTIME 6,1,photo6

dif0 = ABS (photo0 - base)
dif1 = ABS (photo1 - base)
dif2 = ABS (photo2 - base)
dif3 = ABS (photo3 - base)
dif4 = ABS (photo4 - base)
dif5 = ABS (photo5 - base)
dif6 = ABS (photo6 - base)

main:

HIGH 0
HIGH 1
HIGH 2
HIGH 3
HIGH 4
HIGH 5
HIGH 6
PAUSE 3
RCTIME 0,1,photo0
RCTIME 1,1,photo1
RCTIME 2,1,photo2
RCTIME 3,1,photo3
RCTIME 4,1,photo4
RCTIME 5,1,photo5
RCTIME 6,1,photo6

DEBUG HOME, DEC5 ? ABS (photo0-dif0)
DEBUG DEC5 ? ABS (photo1-dif1)
DEBUG DEC5 ? ABS (photo2-dif2)
DEBUG DEC5 ? ABS (photo3-dif3)
DEBUG DEC5 ? ABS (photo4-dif4)
DEBUG DEC5 ? ABS (photo5-dif5)
DEBUG DEC5 ? ABS (photo6-dif6)

GOTO main

I will use the (photo#-dif#) readings to articulate a series of servo motors. I realize that photo-resistors are not the most accurate way to gather light information for this piece accuracy is not important. I embrace the fact that they fluctuate.... I just need the readings to start off all at the same place... if that makes any since. Is there way to divide a word variable in half? 0 to 32767 would give me more than enough range to do what I want. Any assistance would be great.

Check out my latest piece currently on exhibit in brainwave at exit art http://www.dwbowen.com/swarm.html

cheers!

david bowen

Comments

  • PatMPatM Posts: 72
    edited 2008-02-27 01:16
    Do you need to have all the readings at the same time? Could you get a reading, do whatever needs to be done, then go back and get the next reading and deal with that, etc?

    Something like

    photo var word
    diff var word
    channel var nibble
    base con 100

    main:
    for channel = 0 to 6
    high channel
    pause 3
    RCTIME 0,1,photo
    diff = abs(photo-base)
    debug home,dec5 ? ABS(photo - diff)

    next

    goto main

    I guess it depends on how you plan to manipulate the servos and how time critical it is. If the servos can be commanded at different times then just calculate the value you need in each loop and send that to the relevent servo. If all servos need their commands as close together as possible then you might be able to use a single variable to contain a cumulative value in.

    Say you had those sensors arranged in a circle and you wanted to head to the brightest point. You would just store the brightness value in one variable and then a direction value for that sensor in another. Each loop you check the new brightness against the stored value and it the new one is brighter you store the new brightness and the new direction and keep cycling until all sensors had been checked. When the loop finishes you can command the servos to do what you want based on the stored direction value.

    Of course, thats just one example off the top of my head. If we knew more about what you wanted to do it'd be easier to make suggestions.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-27 01:22
    You can't declare a variable as being between a byte and a word in size, but you can do the packing and unpacking yourself. For example, you could use 1.5 bytes to store a 12 bit number, but you have to fetch or store first 8 bits as a byte, then 4 bits as a nibble. For example:
    a   var  byte  ' least significant 8 bits of 1st value
    b   var  byte  ' least significant 8 bits of 2nd value
    ax var  nibble ' most significant 4 bits of 1st value
    bx var  nibble ' most significant 4 bits of 2nd value
    temp var  word  ' temporary 16 bit value
    
    temp = ax shl 4 + a  ' assemble the 12 bit value
    bx = temp.nib2  ' store the most significant nibble
    b = temp.byte0  ' store the least significant byte
    
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2008-02-27 16:52
    I·agree·with PatM…Unless you have a need to keep each original reading, plus all the difference readings you could just deal with each one, one at a time as you’re displaying them. At minimum, even if you save all the end results, the original values could be gotten one at a time saving several variables and using just one work variable in its place.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • dwbowendwbowen Posts: 30
    edited 2008-02-28 21:07
    Thanks for the replies guys,

    PatM and Chris,

    The readings will be compiled and sent to a servo driver ideally causing the servos to respond in real time simultaneously to whatever the readings are. I do not think that storing the values would work as the device will be continuously updating its position based on the light readings it gathers. When the piece is turned on I would like the servos to gather a light reading when centered from the space and then continually change the composition based on the fluctuation of the light through out the day. The only way I can see to do this in realtime is to store all of the variables so the controller can access them and adapt to the changing readings... if this makes any sense at all???



    Mike,

    I think I understand what you mean by storing partial variables by splitting them and adding them back together... but I am a little shaky on how I would adapt it to my program.

    photos var word
    photo1 var photos.lowbyte
    photo2 var photos.hightbyte

    main:

    high 0
    pause 1
    rctime 0,1, (photo1+photo2)

    debug home, dec4 ? (photo1+photo2)

    goto main

    Of course this doesn't work or even solve my problem with memory as I am still using a word variable to define one photo.... but am I at least on the right track?

    cheeri0!
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2008-02-28 23:18
    I’m not sure where the direction went to go to an array or single byte variables. You can have two word variables. One stores the raw RCTIME reading, and the other stores the calculated reading. You then display this and get the reading for the next sensor in the same variables. Basically re-using the variables. This is what was suggested. 4 bytes would be used in this scheme.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • dwbowendwbowen Posts: 30
    edited 2008-02-29 01:18
    Hi Everyone,

    Here is the program I would like to run.

    ' {$STAMP BS2}
    ' {$PBASIC 2.5}

    photo0 VAR WORD
    photo1 VAR WORD
    photo2 VAR WORD
    photo3 VAR WORD
    photo4 VAR WORD
    photo5 VAR WORD
    photo6 VAR WORD

    dif0 VAR WORD
    dif1 VAR WORD
    dif2 VAR WORD
    dif3 VAR WORD
    dif4 VAR WORD
    dif5 VAR WORD
    dif6 VAR WORD 'out o variable space

    pw_x VAR WORD
    pw_y VAR WORD
    baud_driver CON 396
    z CON 1

    base CON 20

    start:

    HIGH 13 'start water pump

    HIGH 0 'collect an initial light reading from the space
    HIGH 1
    HIGH 2
    HIGH 3
    HIGH 4
    HIGH 5
    HIGH 6
    PAUSE 3
    RCTIME 0,1,photo0
    RCTIME 1,1,photo1
    RCTIME 2,1,photo2
    RCTIME 3,1,photo3
    RCTIME 4,1,photo4
    RCTIME 5,1,photo5
    RCTIME 6,1,photo6

    pw_x = 750 'center all x servos
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 0, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 2, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 4, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 6, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 8, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 10, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 12, 15, pw_x.LOWbyte, pw_x.highbyte, CR]

    pw_y = 750 'center all y servos
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 1, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 3, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 5, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 7, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 9, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 11, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 13, 15, pw_y.LOWbyte, pw_y.highbyte, CR]

    dif0 = ABS (photo0 - base) 'determine difference between initial light reading AND base # in order to unify the readings
    dif1 = ABS (photo1 - base)
    dif2 = ABS (photo2 - base)
    dif3 = ABS (photo3 - base)
    dif4 = ABS (photo4 - base)
    dif5 = ABS (photo5 - base)
    dif6 = ABS (photo6 - base)

    IF IN14 = 0 THEN main 'check water level

    GOTO start

    main:

    LOW 13 'stop pump

    HIGH 0 'collect new light reading form space updated every time the program loops
    HIGH 1
    HIGH 2
    HIGH 3
    HIGH 4
    HIGH 5
    HIGH 6
    PAUSE 3
    RCTIME 0,1,photo0
    RCTIME 1,1,photo1
    RCTIME 2,1,photo2
    RCTIME 3,1,photo3
    RCTIME 4,1,photo4
    RCTIME 5,1,photo5
    RCTIME 6,1,photo6

    pw_x = ABS (((((((photo1-dif1)+(photo6-dif6))/2)+(photo0-dif0))/2)/z)+750-((((photo3-dif3)+(photo4-dif4))/2)/z)) 'use updated (realtime) readings-unified readings (initial-base) to articulate x servos
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 0, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 2, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 4, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 6, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 8, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 10, 15, pw_x.LOWbyte, pw_x.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 12, 15, pw_x.LOWbyte, pw_x.highbyte, CR]

    pw_y = ABS ((((photo6-dif6)+(photo5-dif5))/5)/z)+750-((((photo1-dif1)+(photo2-dif2))/5)/z) 'use updated (realtime) readings-unified readings (initial-base) to articulate x servos
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 1, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 3, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 5, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 7, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 9, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 11, 15, pw_y.LOWbyte, pw_y.highbyte, CR]
    SEROUT 15, baud_driver+$8000,[noparse][[/noparse]"!sc", 13, 15, pw_y.LOWbyte, pw_y.highbyte, CR]

    goto main


    I have seven devices arranged in a circle. Each has an x servo and a y servo connected to a vertical piece with a photoresistor on the end. As you can see the servos are controlled by a servo driver. Ideally I would like the collective of seven to move toward the light in a particular space in realtime. The movement of the devices will fluctuate when people walk around the piece casting shadows on particular photoresistos. They will be repelled by shadows and attracted to light. I have the system working by defining the dif# variables as byte, but the photoresistors can fluctuate from 50 to 500. From my perspective the dif# readings need to be saved throughout the program but the byte variables cannot handle this range so the system doesn't always work. I like the fact that photoresistors fluctuate so drastically. I would like to find a way for the basic stamp to handle it. One option I am considering is wiring two stamps together and splitting the photos between them. Any ideas on solving this through the programing.

    cheers!

    david bowen
  • PatMPatM Posts: 72
    edited 2008-02-29 01:44
    Well, the simplest solution would be to divide the photoresistor values by 2 so you can use bytes. Do you actually need 495 steps to determine movement?
  • allanlane5allanlane5 Posts: 3,815
    edited 2008-02-29 15:48
    Yeah, any time there's THAT much parallelism in your code, it's just crying out for subroutines. That, or FOR loops.

    The BS2 IS quite limited in variable space. So you need to define some "Tempxxx" variables, use them in subroutines, and only 'save' the data you really need.

    You DO have 13 'Word' variables, which gives you 7 to 'store' with, leaving 6 to process with. But then you need to be very careful about those 6.
Sign In or Register to comment.