PDA

View Full Version : variable space



Jsav
04-16-2007, 10:11 PM
I'm running out of variable space really quickly, the program may not look like much, and I know there is stuff that needs to be worked out still, so here is just a sample, though things will change, my question now is since these inputs are from four different things, without using a multiplexer is there any way to reduce the amount of variables i need to use?

however...since i'm going to be working with decimal numbers, i would need to multiply everything up to the 65k size, even furthur reducing the variable space i have. any suggestions? ( i know two sections at the end are currently dependent on decimals )

' {$STAMP BS2p}
' {$PBASIC 2.5}
' VARIABLES TO BE USED

'Variables for Input 1

adcbits VAR Byte
v VAR Byte
r VAR Byte
v2 VAR Byte
v3 VAR Byte

cs PIN 0
clk PIN 1
dataoutput PIN 2

'Variables for Input 2

adcbitstwo VAR Byte
vtwo VAR Byte
rtwo VAR Byte
v2two VAR Byte
v3two VAR Byte

cs2 PIN 3
clk2 PIN 4
dataoutput2 PIN 5

'Variables for Input 3

adcbitsthree VAR Byte
vthree VAR Byte
rthree VAR Byte
v2three VAR Byte
v3three VAR Byte

cs3 PIN 6
clk3 PIN 7
dataoutput3 PIN 8

'Variables for Input 4

adcbitsfour VAR Byte
vfour VAR Byte
rfour VAR Byte
v2four VAR Byte
v3four VAR Byte

cs4 PIN 9
clk4 PIN 10
dataoutput4 PIN 11

'Variables for conversion to pounds

actvoltone VAR Byte
actvolttwo VAR Byte
actvoltthree VAR Byte
actvoltfour VAR Byte

pound1 VAR Byte
pound2 VAR Byte
pound3 VAR Byte
pound4 VAR Byte

'Variables for calculation of total weight and center of gravity

x VAR Byte
y VAR Byte
load VAR Byte


'THIS PORTION OF THE CODE IS FOR THE ACCUMULATING OF THE READINGS

'Input from strain gage 1

DEBUG CLS
main:
DO
· GOSUB adc_data
· GOSUB calc_volts
· GOSUB display
· GOSUB adc_data_two
· GOSUB calc_volts_two
· GOSUB display_two
· GOSUB adc_data_three
· GOSUB calc_volts_three
· GOSUB display_three
· GOSUB adc_data_four
· GOSUB calc_volts_four
· GOSUB display_four
· GOSUB actual_volts
· GOSUB conversion
· GOSUB calculation
LOOP

'Input from strain gage 1

adc_data:
· HIGH cs
· LOW cs
· LOW clk
· PULSOUT clk, 210
· SHIFTIN dataoutput,clk,MSBPOST, [adcbits\8]
RETURN

calc_volts:
· v = 5 * adcbits / 255
· r = 5 * adcbits // 255
· v2 = 100 * r / 255
· v3 = 100 * r // 255
· v3 = 10 * v3 / 255
· IF (v3 >=5) THEN v2 = v2 + 1
· IF (v2 >=100) THEN
··· v = v +1
··· v2 = 0
· ENDIF
RETURN

display:
· DEBUG HOME
· DEBUG "8-bit binary value:· ", BIN8 adcbits
· DEBUG CR, CR, "Decimal value:· ", DEC3 adcbits
· DEBUG CR, CR, "Strain Gage reading: "
· DEBUG DEC1 v, ".", DEC2 v2, "Volts"
RETURN

'Input from strain gage 2

adc_data_two:
· HIGH cs2
· LOW cs2
· LOW clk2
· PULSOUT clk2, 210
· SHIFTIN dataoutput2,clk2,MSBPOST, [adcbitstwo\8]
RETURN

calc_volts_two:
· vtwo = 5 * adcbitstwo / 255
· rtwo = 5 * adcbitstwo // 255
· v2two = 100 * rtwo / 255
· v3two = 100 * rtwo // 255
· v3two = 10 * v3two / 255
· IF (v3two >=5) THEN v2two = v2two + 1
· IF (v2two >=100) THEN
··· vtwo = vtwo +1
··· v2two = 0
· ENDIF
RETURN

display_two:
· DEBUG HOME
· DEBUG "8-bit binary value:· ", BIN8 adcbitstwo
· DEBUG CR, CR, "Decimal value:· ", DEC3 adcbitstwo
· DEBUG CR, CR, "Strain Gage reading: "
· DEBUG DEC1 vtwo, ".", DEC2 v2two, "Volts"
RETURN

'Input from strain gage 3

adc_data_three:
· HIGH cs3
· LOW cs3
· LOW clk3
· PULSOUT clk3, 210
· SHIFTIN dataoutput3,clk3,MSBPOST, [adcbitsthree\8]
RETURN

calc_volts_three:
· vthree = 5 * adcbitsthree / 255
· rthree = 5 * adcbitsthree // 255
· v2three = 100 * rthree / 255
· v3three = 100 * rthree // 255
· v3three = 10 * v3three / 255
· IF (v3three >=5) THEN v2three = v2three + 1
· IF (v2three >=100) THEN
··· vthree = vthree +1
··· v2three = 0
· ENDIF
RETURN

display_three:
· DEBUG HOME
· DEBUG "8-bit binary value:· ", BIN8 adcbitsthree
· DEBUG CR, CR, "Decimal value:· ", DEC3 adcbitsthree
· DEBUG CR, CR, "Strain Gage reading: "
· DEBUG DEC1 vthree, ".", DEC2 v2three, "Volts"
RETURN

'Input from strain gage 4

adc_data_four:
· HIGH cs4
· LOW cs4
· LOW clk4
· PULSOUT clk4, 210
· SHIFTIN dataoutput4,clk4,MSBPOST, [adcbitsfour\8]
RETURN

calc_volts_four:
· vfour = 5 * adcbitsfour / 255
· rfour = 5 * adcbitsfour // 255
· v2four = 100 * rfour / 255
· v3four = 100 * rfour // 255
· v3four = 10 * v3four / 255
· IF (v3four >=5) THEN v2four = v2four + 1
· IF (v2four >=100) THEN
··· vfour = vfour +1
··· v2four = 0
· ENDIF
RETURN

display_four:
· DEBUG HOME
· DEBUG "8-bit binary value:· ", BIN8 adcbitsfour
· DEBUG CR, CR, "Decimal value:· ", DEC3 adcbitsfour
· DEBUG CR, CR, "Strain Gage reading: "
· DEBUG DEC1 vfour, ".", DEC2 v2four, "Volts"
RETURN

'CREATING ACTUAL VOLTAGE OF THE FOUR READINGS

actual_volts:
· actvoltone = DEC1 v + (DEC2 v2 / 100)
· actvolttwo = DEC1 vtwo + (DEC2 v2two / 100)
· actvoltthree = DEC1 vthree + (DEC2 v2three / 100)
· actvoltfour = DEC1 vfour + (DEC2 v2four / 100)
RETURN

'CONVERTING THE INPUT VOLTAGE TO POUNDS

conversion:
· pound1 = actvoltone * 1000 / 0.0667 * 0.002204
· pound2 = actvolttwo * 1000 / 0.0667 * 0.002204
· pound3 = actvoltthree * 1000 / 0.0667 * 0.002204
· pound4 = actvoltfour * 1000 / 0.0667 * 0.002204
RETURN

'CALCULATION OF TOTAL WEIGHT AND CENTER OF GRAVITY
calculation:
· load = pound1 + pound2 + pound3 + pound 4
· x = ( pound2 + pound3 ) * 73.25 / load
· y = ( pound2 + pound1 ) * 171.9 / load
RETURN

Jsav
04-16-2007, 10:11 PM
also, what about float type? does BS2P only work with fixed point integer math?

Mike Green
04-16-2007, 10:20 PM
All of the Basic Stamps only work with 16-bit integer arithmetic. Tracy Allan's website www.emesystems.com (http://www.emesystems.com) has some excellent tutorials on doing fixed point and multiple precision arithmetic on the Stamps. As you've noticed, there exist only 26 bytes (13 words) of variables. There is a small (64-128 byte) separate RAM area (the scratchpad RAM) accessible with the GET/PUT statements that can be used for storing additional information (a little awkwardly, but it works).

Loopy Byteloose
04-16-2007, 10:39 PM
Physically, the SXes limited variable space.
So, if you can let go of some of it and reuse such for other portions of the program; you won't have to resort to GET/PUT statements as much.

Even if you have to use GET/PUT, sharing the registers is still about the only way to manage the limitations.

In other words, can you use a few generically named variables for obvious interim work instead of designating a specific identity to each and every variable?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"If you want more fiber, eat the package.· Not enough?· Eat the manual."········


···················· Tropical regards,····· G. Herzog [·黃鶴 ]·in Taiwan

Jsav
04-16-2007, 11:44 PM
what about storing decimals? if you do a calculation by whole integer math, knowing that the result is a decimal, but that value is stored in a variable still, and then used in a new calculation. will the BS2p keep the places after the decimal point and use them in the new calculation if this value was never touched until it was used again? or does it drop the decimal as soon as the calculation is performed?

Jsav
04-16-2007, 11:47 PM
for instance, using the code above to get a decimal value from the a/d converter, can i use the following to convert to a decimal value to be used in a calculation?

actual_volts:
actvoltone = v + (v2 / 100)
actvolttwo = vtwo + (v2two / 100)
actvoltthree = vthree + (v2three / 100)
actvoltfour = vfour + (v2four / 100)
RETURN


will this section of code give me an actual voltage like 3.25 to be used in the calculations to following using the actvoltone variable etc.?

Mike Green
04-17-2007, 12:04 AM
The Stamp knows nothing about decimal places and won't automatically do anything about them. The idea is that you are changing the units of your program from whole numbers to tenths or hundreths or whatever.

Instead of having a voltage of 3.25V, you carry numbers like 325 hundreths of a volt or 3250 millivolts, then you do all your calculations that way.

Jsav
04-17-2007, 02:32 AM
i'm having trouble with this situation though,

using the constants 33.0434, 73.25 and 171.9, the following code would effectively get rid of the decimal requirements

conversion:
· pound1 = (actvoltone*33) + (actvoltone*4/100) + (actvoltone*3/1000) + (actvoltone*4/10000)
· pound2 = (actvolttwo*33) + (actvolttwo*4/100) + (actvolttwo*3/1000) + (actvolttwo*4/10000)
· pound3 = (actvoltthree*33) + (actvoltthree*4/100) + (actvoltthree*3/1000) + (actvoltthree*4/10000)
· pound4 = (actvoltfour*33) + (actvoltfour*4/100) + (actvoltfour*3/1000) + (actvoltfour*4/10000)
RETURN

calculation:
· load = pound1 + pound2 + pound3 + pound4
· x = ((pound2 + pound3) * 73) + ((pound2 + pound3)*(1/4)) / load
· y = ((pound2 + pound1)*171) + ((pound2 + pound1)*(1/(1+(1/9)))) / load
RETURN


however, the top value of pound1 will only be displayed as 00033 in DEC5 format through the BS2p, if i try to multiply these values by 1000 to get the answer to be 33043 (assuming that my input for actvoltone was 1v ) i do not get 33043. i noticed that multiplying this by 256 gives me 0 and 255 gives me 254, is this my limit? i thought i was safe within the 65k region, and how can i then use these equations to get an answer in the ten thousands range?

Mike Green
04-17-2007, 02:46 AM
You're really going to have to work out all the details yourself since there's a lot of detail. I suggest you start with some actual input values and carry the calculations through by hand understanding that all results including intermediate values are computed as 16-bit integers. If their values are more than 65535, the result is truncated at 16-bits. If that won't work for you, you'll need to do double precision arithmetic and, again, I refer you to Tracy Allen's website.

Do keep in mind that these calculations have to be fixed point, so you can add two values together if they have the same number of decimal places, but, if you multiply them, you have to divide by the appropriate power of 10. If you divide two numbers with the same number of decimal places, you will get an integer quotient. You may need multiple precision multiplication and division routines to maintain adequate precision.

Tom Walker
04-17-2007, 02:55 AM
Jsav,
As Mike has been trying to inform you, the Stamp has no concept of anything beyond the decimal point. That doesn't mean that those digits are somehow "hidden" and can be revealed by multiplying by 1000...they are simply not there....so multiplying 33 * 1000 will not give you 33043.
Assuming actvoltone1 =1 (the only way I can see your first equation evaluating to your predicted value of 33043), then your first equation will evaluate thusly:
pound1 = (1*33) + (1*4/100) + (1*3/1000) + (1*4/10000)
pound1 = (33) + (4/100) + (3/1000) + (4/10000) * the Stamp evaluates from let to right, ignoring precedence, inside parentheses *
pound1 = (33) + (0) + (0) + (0) * this is integer arithmetic...everything past the decimal point is lost.

Is this clearer?

You could multiply both sides of your equation by 10000 and arrive at a figure of 33043, which you could then use as you see fit.

Decimals are part of another dimension and do not exist on the Stamp. Scale everything up, or as Mike has so patiently suggested and re-suggested, check out the emesys site...

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Truly Understand the Fundamentals and the Path will be so much easier...

Jsav
04-19-2007, 02:03 AM
hey mike, if i may call you so Mr. Green

you've been an excellent help to me first of all, so thank you

secondly, as far as using the scratch-pad RAM goes, i notice you still have to define the variable at the top of the program even if you are going to store a value there and later call it to use it. The program says "out of variable space" now without attempting to store things in scratchpad ram, is using this extra 128 bytes (for the BS2P) going to actually allow me to define more variables in my program since i need to use many?

allanlane5
04-19-2007, 02:21 AM
It also looks like you're doing basically the same thing with adc_data 1, 2, 3, and 4, but you declare new variables each time. You only need one set of 'temp' variables for each of these, and one (or two) result variables.

I can't figure out what you're doing in your 'voltage' calcs, but you use a LOT of temp variables there which you can reuse, also.

Jsav
04-19-2007, 02:33 AM
can i reuse each variable for the new section of code then? same variables for acd_data 1, 2, 3, and 4?

will the fact that these input readings will be acquired constantly, and that the calculations will be updated as quickly as the MC can process them change the fact that i reuse the variables? I mentioned that we are NOT using a multiplexer, so i'm saying that each of the four inputs will be comming into the MC at the same time, which i think means that i need different variables each section.

the path of the program does suggest that though four input are running to the MC at the same time, only 1 of them is being addressed by the program at a time. This WOULD suggest that I will be able to use the same defined variables for the four sections of input, am I correct in agreeing with you and assuming this? If that is the case, then I will be able to use 3 PIN definitions, 1 WORD definition and 4 BYTE definitions four times over, one for each of the inputs.

the code has been changed from what's posted above to compensatate for the decimal values in the program, and each of the sections of code have been testing and give desired results, individually. I am running out of space when I try to run them all together.

Aside from the fact that I will save this space from your suggestion, it won't be enough as I still have 12 WORD definitions that I am out of space for, so scratchpad seems like the only option, if it does indeed work.

I understand the GET/PUT statements, but as I said in the last post, it seems like I still need to define the variable to be used before its value is stored in SPRAM, so would I run out of room still?

allanlane5
04-19-2007, 02:58 AM
The BS2 is a single-threaded processor, so yes, it only does one thing at one time, so you are safe to reuse those variables.

Now, the 'PIN' definitions usually specify a 'hard-wired' connection to the BS2, so unless you have a multi-plexer out there switching your A-to-D converters to a single pin, you probably can't 're-use' pin assignments. But VAR assignments you can definitely re-use.

Now, what you use SPRAM for is storage of 'intermediate' results. In your case, you have 4 A-to-D input values. So you read one, store that result in SPRAM, read the second (reusing all the variables), store that one, etc.

Then, when ready to 'report out', you pull the stored values out of SPRAM into variables and send your report -- maybe one variable at a time, worst case.

allanlane5
04-19-2007, 03:01 AM
Note also in Digital electronics, there's no such thing as "constantly". Everything has a clock. Everything is 'sampled' at some rate. Even a multi-tasking system APPEARS to be multi-tasking, the system is really switching one tasks code in and out of the processor.

You may still run out of room, if you MUST have 14 Words of variables at the same time. But from looking at your code so far, that's not the case.

Jsav
04-19-2007, 03:02 AM
so you're still saying that there's no way to define more variables? i'll supply my newest code, though it's STILL a work in progress :) and aside from reusing the variables for the input sections, is there anything I can do about the calculation sections or finding more space to DEFINE variables.


I actually lost a lot of space since i had to define more things as words since they are all decimal values, i had to make them bigger to get the values to carry, any suggestions?








' {$STAMP BS2p}
' {$PBASIC 2.5}

' VARIABLES TO BE USED


'Variables for Input 1
adcbits VAR Byte
v VAR Word
r VAR Byte
v2 VAR Byte
v3 VAR Byte

cs PIN 0
clk PIN 1
dataoutput PIN 2

'Variables for Input 2
adcbitstwo VAR Byte
vtwo VAR Word
rtwo VAR Byte
v2two VAR Byte
v3two VAR Byte

cs2 PIN 3
clk2 PIN 4
dataoutput2 PIN 5

'Variables for Input 3
adcbitsthree VAR Byte
vthree VAR Word
rthree VAR Byte
v2three VAR Byte
v3three VAR Byte

cs3 PIN 6
clk3 PIN 7
dataoutput3 PIN 8

'Variables for Input 4
adcbitsfour VAR Byte
vfour VAR Word
rfour VAR Byte
v2four VAR Byte
v3four VAR Byte

cs4 PIN 9
clk4 PIN 10
dataoutput4 PIN 11

'Variables for conversion to pounds
actvoltone VAR Word
actvolttwo VAR Word
actvoltthree VAR Word
actvoltfour VAR Word

pound1 VAR Word
pound2 VAR Word
pound3 VAR Word
pound4 VAR Word

'Variables for calculation of total weight and center of gravity
x VAR Word
y VAR Word
load VAR Word




'THIS PORTION OF THE CODE IS FOR THE ACCUMULATING OF THE READINGS

'Input from strain gage 1

DEBUG CLS

main:
DO
GOSUB adc_data
GOSUB calc_volts
GOSUB display
GOSUB adc_data_two
GOSUB calc_volts_two
GOSUB display_two
GOSUB adc_data_three
GOSUB calc_volts_three
GOSUB display_three
GOSUB adc_data_four
GOSUB calc_volts_four
GOSUB display_four
GOSUB actual_volts
GOSUB conversion
GOSUB calculation
LOOP


'Input from strain gage 1

adc_data:
HIGH cs
LOW cs
LOW clk
PULSOUT clk, 210
SHIFTIN dataoutput,clk,MSBPOST, [adcbits\8]
RETURN

calc_volts:
v = 5 * adcbits / 255
r = 5 * adcbits // 255
v2 = 100 * r / 255
v3 = 100 * r // 255
v3 = 10 * v3 / 255
IF (v3 >=5) THEN v2 = v2 + 1
IF (v2 >=100) THEN
v = v +1
v2 = 0
ENDIF
RETURN

display:
DEBUG HOME
DEBUG "8-bit binary value: ", BIN8 adcbits
DEBUG CR, CR, "Decimal value: ", DEC3 adcbits
DEBUG CR, CR, "Strain Gage reading: "
DEBUG DEC1 v, ".", DEC2 v2, "Volts"
RETURN


'Input from strain gage 2

adc_data_two:
HIGH cs2
LOW cs2
LOW clk2
PULSOUT clk2, 210
SHIFTIN dataoutput2,clk2,MSBPOST, [adcbitstwo\8]
RETURN

calc_volts_two:
vtwo = 5 * adcbitstwo / 255
rtwo = 5 * adcbitstwo // 255
v2two = 100 * rtwo / 255
v3two = 100 * rtwo // 255
v3two = 10 * v3two / 255
IF (v3two >=5) THEN v2two = v2two + 1
IF (v2two >=100) THEN
vtwo = vtwo +1
v2two = 0
ENDIF
RETURN

display_two:
DEBUG HOME
DEBUG "8-bit binary value: ", BIN8 adcbitstwo
DEBUG CR, CR, "Decimal value: ", DEC3 adcbitstwo
DEBUG CR, CR, "Strain Gage reading: "
DEBUG DEC1 vtwo, ".", DEC2 v2two, "Volts"
RETURN


'Input from strain gage 3

adc_data_three:
HIGH cs3
LOW cs3
LOW clk3
PULSOUT clk3, 210
SHIFTIN dataoutput3,clk3,MSBPOST, [adcbitsthree\8]
RETURN

calc_volts_three:
vthree = 5 * adcbitsthree / 255
rthree = 5 * adcbitsthree // 255
v2three = 100 * rthree / 255
v3three = 100 * rthree // 255
v3three = 10 * v3three / 255
IF (v3three >=5) THEN v2three = v2three + 1
IF (v2three >=100) THEN
vthree = vthree +1
v2three = 0
ENDIF
RETURN

display_three:
DEBUG HOME
DEBUG "8-bit binary value: ", BIN8 adcbitsthree
DEBUG CR, CR, "Decimal value: ", DEC3 adcbitsthree
DEBUG CR, CR, "Strain Gage reading: "
DEBUG DEC1 vthree, ".", DEC2 v2three, "Volts"
RETURN


'Input from strain gage 4

adc_data_four:
HIGH cs4
LOW cs4
LOW clk4
PULSOUT clk4, 210
SHIFTIN dataoutput4,clk4,MSBPOST, [adcbitsfour\8]
RETURN

calc_volts_four:
vfour = 5 * adcbitsfour / 255
rfour = 5 * adcbitsfour // 255
v2four = 100 * rfour / 255
v3four = 100 * rfour // 255
v3four = 10 * v3four / 255
IF (v3four >=5) THEN v2four = v2four + 1
IF (v2four >=100) THEN
vfour = vfour +1
v2four = 0
ENDIF
RETURN

display_four:
DEBUG HOME
DEBUG "8-bit binary value: ", BIN8 adcbitsfour
DEBUG CR, CR, "Decimal value: ", DEC3 adcbitsfour
DEBUG CR, CR, "Strain Gage reading: "
DEBUG DEC1 vfour, ".", DEC2 v2four, "Volts"
RETURN


'CREATING ACTUAL VOLTAGE OF THE FOUR READINGS

actual_volts:
actvoltone = (100*v) + v2
actvolttwo = (100*vtwo) + v2two
actvoltthree = (100*vthree) + v2three
actvoltfour = (100*vfour) + v2four
RETURN


'CONVERTING THE INPUT VOLTAGE TO POUNDS

conversion:
pound1 = (actvoltone*33) + (actvoltone*4/100) + (actvoltone*3/1000) + (actvoltone*4/10000)
pound2 = (actvolttwo*33) + (actvolttwo*4/100) + (actvolttwo*3/1000) + (actvolttwo*4/10000)
pound3 = (actvoltthree*33) + (actvoltthree*4/100) + (actvoltthree*3/1000) + (actvoltthree*4/10000)
pound4 = (actvoltfour*33) + (actvoltfour*4/100) + (actvoltfour*3/1000) + (actvoltfour*4/10000)
RETURN


'CALCULATION OF TOTAL WEIGHT AND CENTER OF GRAVITY

calculation:
load = (pound1/100) + (pound2/100) + (pound3/100) + (pound4/100)
x = (((pound2/100) + (pound3/100)) * 73) + (((pound2/100) + (pound3/100))*(1/4)) / load
y = (((pound2/100) + (pound1/100))*171) + (((pound2/100) + (pound1/100))*(1/(1+(1/9)))) / load
RETURN

allanlane5
04-19-2007, 03:41 AM
Ok, here's what I got so far. I'm still not content that your calculations are correct yet, though.

Note:· PIN and CON parameters take up no variable space.· Only 'VAR' statements take up variable space.· "Comments" also take up no space on the BS2p.

Post Edited (allanlane5) : 4/18/2007 8:45:59 PM GMT

Jsav
04-19-2007, 05:07 AM
allan you were an amazing help thanks!, i didn't know the CON statement could be used without ram space taken up, with that in mind, i can reduce the variable size to under what i needed. i just have two add 2 conditional IF statements to the end of this for the rest of my code, but it looks great now.

the calculations that are used in my program are used in a way that i won't need to use decimals, i know they look odd, and there is probably a better way to do them, but (1/(1+(1/9))) = 0.9, and soforth in order to replace decimal values. likewise, my constant conversion from volts to pounds was 1v = 33.0434, which is how i got the pound1 and soforth equations.

thanks again for the help, and i'll be back if i get stuck again! :)