PDA

View Full Version : Reading Array values into variables



Tom Gonser
- 27th February 2005, 20:01
This is probably easy, but I can't seem to figure it out.

I have an array of 34 bytes collected via Serin2. I can see each of these. What I need to do tho is read several of them and convert them from the hex values they represent now to decimal.

So imagine:

SSMAX(23) contains 83
SSMAX(34) contains 03

These make up a temperature measurement.

I need to reverse these so I get 03 83, then convert these to DECIMAL

03 83 to Decimal should give me 899. There is an implied decimal between the 9's so I'd divide by 10. the result would be 89.9

BUT.. I can't find a way to get the data out of the array to deal with it.

Does anyone have any ideas about this?

I was planning to read each character 0 - 3 - 8 - 3 in sequence via a loop and multiply the 0*4096+3*256+8*16+3*1... But I can't seem to get data ouf of the array..

I can't seem to get the array values into variables to work on them either.

Thanks - this is new stuff for me.

Tom

Demon
- 27th February 2005, 20:27
Did you know the array starts at element 0?

(suggestion from a newb)

Robert
:)

Demon
- 27th February 2005, 20:32
Are you sure you are processing your array in the proper order?

I am also converting, DATAIN VAR BYTE[5] to one byte.

RESULT=DATAIN[0]+(DATAIN[1]*10)+(DATAIN[2]*100)+(DATAIN[3]*1000)+(DATAIN[4]*10000)

I was just about to search for a post. Someone had told me lately how to do the conversion and I was going to doublecheck my formula.

Robert
:)

mister_e
- 27th February 2005, 22:55
SSMAX(23) contains 83
SSMAX(34) contains 03



what about the following


DEFINE BOOTLOADER_USED 1
DEFINE OSC 20

' Lcd defines
' ===========
'
define LCD_DREG PORTB ' Set data pin of LCD to
define LCD_DBIT 0 ' PORTB.0-PORTB.3

define LCD_RSREG PORTB ' Set RS bit of LCD to
define LCD_RSBIT 4 ' PORTB.4

define LCD_EREG PORTB ' Set E bit of LCD to
define LCD_EBIT 5 ' PORTB.5

DEFINE LCD_LINES 4 ' 4 Lines LCD
define LCD_COMMANDUS 2000 ' Command delay time in uSec
DEFINE LCD_DATAUS 100 ' Data delay time in uSec

WholeDecimalNumber var word
SSD4 var byte
SSD3 var byte
SSD2 var byte
SSD1 var byte
SSMAX var byte [80]
MSB var byte
LSB var byte


ssmax[34]=$03
SSmax[23]=$83
SSD4= (ssmax[34]>>4)
SSD3= (ssmax[34] & $f)
SSD2= (ssmax[23]>>4)
SSD1= (ssmax[23] & $f)

WholeDecimalNumber=(ssd4*4096)+(ssd3*256)+(ssd2*16 )+ssd1

lcdout $fe,1,"myval=",#wholedecimalnumber dig 3,_
#wholedecimalnumber dig 2,#wholedecimalnumber dig 1,_
".",dec1 wholedecimalnumber

here: goto here

Tom Gonser
- 28th February 2005, 00:20
The 4th post includes this:

SSD4= (ssmax[34]>>4)
SSD3= (ssmax[34] & $f)
SSD2= (ssmax[23]>>4)
SSD1= (ssmax[23] & $f)

It appears that somehow this is reading the digits out of the bytes, but I have never seen the notation before.

>>

& $f

Do these somehow mean first digit and second digit?

TG

mister_e
- 28th February 2005, 03:36
>>4 => shift byte 4 position to the right. so you keep only the 4 high bits
& $F => Bitwise and with hex F. so you keep only the 4 low bits

everything is in the PBP manual section 4.17

Bruce
- 28th February 2005, 04:14
It's no more difficult than copying data from a single variable to another.

X VAR BYTE
Y VAR BYTE

X = 3
Y = X

You can state X = SSMAX(23), Y = SSMAX(34), etc,,.

Since the resulting value will be a word, then use something like this;

SSMAX(23) contains 83h
SSMAX(34) contains 03h

Result VAR WORD

Result.LowByte = SSMAX(23) ' Place 83h into lowbyte
Result.HighByte = SSMAX(34) ' Place 03h into highbyte
HSEROUT [DEC Result] ' Print decimal value of 0383h = 899

Tom Gonser
- 17th March 2005, 02:31
Seems like I should be able to figure this out, but I can't ...

I have an array that contains 24 bits which equate to an altitude in tenths of meters.

alt[1]
alt[2]
alt[3]


I need to 1) display this, and 2) convert from meters to feet, so I need to stuff all these into a single variable which represents actual meters as opposed to tenths of meters, then convert to feet....

Any ideas out there? They way I am doing it now is not working. I am just reading these into alt1, alt2, alt2, and showing them as #alt1, #alt2, #alt3... I get 13130 which may be 131.30 meters,(which would be about right) but I am not sure. I am also not sure how to make this a single variable ..

Thanks !

Tom

Demon
- 17th March 2005, 02:50
I have no answer, but I do see an immediate problem.

A byte contains 8 bits, a word contains 2 bytes; that's a total of 16 bits.

There is a way to do 32 bit math, I saw a section in the manual. You work with 2 separate words or something, I didn't pay much attention.

Robert
:)

Demon
- 17th March 2005, 02:51
Page 33, 4.17.1 - Multiplication.

Using * and **, / and //.

Good luck!

Robert
:)

Tom Gonser
- 17th March 2005, 04:40
Exactly the problem.. I have 3 bytes that need to be put into one variable.. this is a 24 bit container that relates a number - the altitude in tenths of meters..

How to get this into ONE variable I can work with is the first issue..

Tom

Acetronics2
- 17th March 2005, 07:33
Hi, Tom

Let's have another view of the problem ...

You get an altitude measurement, ...but what is your sensor ??? and mostly what is its precision ???

I do not know lots of altitude sensors seriously able to give 1 cm on a hundred meters ... 1/10 000 precision, you sure ??? ... !!!

May be a little look here could reduce your number sizes ...and simplify you work.

24 and 32 bits arithmetics can be downloded from Melabs site ... if you really want to keep "ghost" centimeters !!!

Alain

Ingvar
- 17th March 2005, 12:52
Hi Tom,

What ranges are we talking about? Are you interested in altitudes higher than 21501 feet? If not, you can treat your input as a word(skip top 8 bits) and do your calculations on that. If you need to go higher, things will get more complicated but still possible. Higher than 65535 feet will get nasty ....

Do you really need 0.1m(0.3feet) resolution? Will 1m(3feet) enough?

Another thing .... you need to know how your inputdata(24bits) is formatted. My guess(based on your information) is that you are located at about 1096 feet. I'm assuming that "alt[3]" contains the most significant byte, 0,13,13 would be 000D0D in hex which is 3341 in decimal. 3341 tenths of a metre is 334.1m which is 334.1*3.28084=1096 feet.

/Ingvar

Tom Gonser
- 17th March 2005, 13:42
Thanks for the responses..

The precision is only tenths of meters. I don't know *why* the data is stored in 24 bits, it just is - not under my control, I am only trying to read it.

Regardless - the fundamental problem is that I have a 24 bit value stored in 3 bytes that I need to make into a variable I can do something with..... like read it digit by digit, and put a "." in the tenth's spot, and then multiply it by a factor to convert to feet..

TG

Acetronics2
- 17th March 2005, 14:38
Have a look to that thread :
http://www.picbasic.co.uk/forum/showthread.php?t=1217

here you have the solution to put your 24 bits into something usable ... just divide them as soon to reduce it to less than 16 bits ...

and that's all !!!

Alain

Ingvar
- 17th March 2005, 16:06
And the answers to my questions are ...... ? Can't help if i don't know.

/Ingvar

Tom Gonser
- 18th March 2005, 03:14
Oh- yes, sorry.

We are at about 300ft. Should be reading about 100meters or so. The GPS alt data 'wanders' so tenths of meters is a little silly, yes, but that is what is output.

The full range would want to support over 100,000ft in altitude.

TOm

Ingvar
- 18th March 2005, 10:21
Ok, you're building a spaceship, 100000 ft is high. I'd love to see this baby fly :)

First i think you need to look over your inputdata, methinks it's not properly extracted. I can't see any correlation between your data and 100(ish) metres, unless ofcourse it's already in tenths of ft(000D0Dhex=3341dec 3341*0,3048=1018.34 which would be close to your 100m).

Are you getting the data from a NMEA sentence($GPGGA) or is it a binary protocol? If it's NMEA you need to know that the data is separated by "," characters, they're not at a fixed position in the string. Atleast not towards the end of the string. This makes it difficult to extract and convert the data.

When you have your data properly extracted, the conversion would look something like this(pseudocode) ....



R0.HIGHBYTE = 0 'Prepare system variables for DIV32
R0.LOWBYTE = alt[2]
R2.HIGHBYTE = alt[1]
R2.LOWBYTE = alt[0]
AltMetres = DIV32 10
Alt10Ft = AltMetres ** 21501 '21501/65536=0.32808
SEROUT blah..,blah..,["Altitude :",dec Alt10Ft, "0 ft",13,10]


..... you could increase the resolution when "alt[2]" = 0 ......



AltMetres.HIGHBYTE = alt[1]
AltMetres.LOWBYTE = alt[0]
AltFt = AltMetres ** 21501 '21501/65536=0.32808
SEROUT blah..,blah..,["Altitude :",dec AltFt, " ft",13,10]


.... you could ofcourse combine them .....



IF alt[2] = 0 THEN
AltMetres.HIGHBYTE = alt[1]
AltMetres.LOWBYTE = alt[0]
AltFt = AltMetres ** 21501 '21501/65536=0.32808
SEROUT blah..,blah..,["Altitude :",dec AltFt, " ft",13,10]
ELSE
R0.HIGHBYTE = 0 'Prepare system variables for DIV32
R0.LOWBYTE = alt[2]
R2.HIGHBYTE = alt[1]
R2.LOWBYTE = alt[0]
AltMetres = DIV32 10
Alt10Ft = AltMetres ** 21501 '21501/65536=0.32808
SEROUT blah..,blah..,["Altitude :",dec Alt10Ft, "0 ft",13,10]
ENDIF


/Ingvar

Tom Gonser
- 18th March 2005, 21:45
Thanks much!!

Apparently it is important for the system to report over 100k...

The data is binary, not NMEA. The 3 bytes are the altitude, and it is in tenths of a meter. (binary value in tenths of meters)

My challenge is that I have THREE bytes.. each with values that together equal the value I need.

Value is sent in these 3 bytes as LSB first, then NMSB, then MSB.

Does that help?

TG

Ingvar
- 21st March 2005, 10:30
The code i posted handles your THREE bytes, alt[0] to alt[2], when needed. Alt[0] = LSB, alt[2] = MSB. At high resolution(1ft) it will go to 21500ft, low res(10ft) will go to 215000ft.