PDA

View Full Version : Help with calling a function and returning a variable



turbosupra
10-20-2011, 04:40 PM
With this generic code, I'm passing rxInput to PUB serialCom and the data is not passing properly. I've tried both the reference to rxInput and the variable itself, but I believe it has to be referenced because of the fact that it is a string being passed. With the reference, I get the first character of the string.

According to the prop manual all method parameters are longs, how do I pass strAddr properly into my method, and not just the first byte of strAddr?






CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
byteLimit = 100

VAR
byte rxInput[byteLimit]
long returnTemp[byteLimit]

PUB Main

returnTemp := serialCom(@rxInput)


PUB serialCom(strAddr) : returnValue

{stuff done here}

returnValue := {something}

Mike Green
10-20-2011, 04:50 PM
In what you've posted, you're passing the address of the first byte of rxInput to serialCom. That's the way you pass a reference to an array. Within serialCom, you have to refer to the bytes of the array using the address like:

byte[strAddr][index]

This will refer to the index'th byte of the passed array.

MagIO2
10-20-2011, 06:34 PM
You have to keep in mind what the variables contain. So, it's a good practice to give it a good name like

p_rxInput in the function definition of serialCom. p_ for pointer ... or maybe you prefere a_ for address ...

This way you can see from the name of the variable how it should be used in the code. And you can also see from the first glance what the function expects as parameter - either a value or a pointer.

As your function is named serialCom I'd expect that your function will somehow use other functions of a serial interface object. Some of those work with strings. A string is simply a pointer to some memory which contains characters and a 0 (zero-byte) at the end. So, if you want to use those with the p_rxInput, you have to remember that p_rxInput already contains exactly that pointer. The call would then look like.
serial.str( p_rxInput )
NO @!

If you want to fill this buffer in your function then you don't want to change p_rxInput itself and you have to use the way proposed by Mike:
byte[ p_rxInput ][ idx++ ] := serial.rx

turbosupra
10-20-2011, 07:22 PM
Hi Mike,

Do you mean it would look like this (I'm guessing that I'm misunderstanding, as this did not work either)

returnTemp := serialCom(byte[@rxInput][byteLimit])


In what you've posted, you're passing the address of the first byte of rxInput to serialCom. That's the way you pass a reference to an array. Within serialCom, you have to refer to the bytes of the array using the address like:

byte[strAddr][index]

This will refer to the index'th byte of the passed array.

turbosupra
10-20-2011, 07:24 PM
Hi,

You are right, I am going to have to start doing that (another wise German has also advised this habit :) ) and probably something similar to differentiate between longs, bytes, constants, etc. What do you use for those? l_ , b_, and c_ ?


You have to keep in mind what the variables contain. So, it's a good practice to give it a good name like

p_rxInput in the function definition of serialCom. p_ for pointer ... or maybe you prefere a_ for address ...

This way you can see from the name of the variable how it should be used in the code. And you can also see from the first glance what the function expects as parameter - either a value or a pointer.

As your function is named serialCom I'd expect that your function will somehow use other functions of a serial interface object. Some of those work with strings. A string is simply a pointer to some memory which contains characters and a 0 (zero-byte) at the end. So, if you want to use those with the p_rxInput, you have to remember that p_rxInput already contains exactly that pointer. The call would then look like.
serial.str( p_rxInput )
NO @!

If you want to fill this buffer in your function then you don't want to change p_rxInput itself and you have to use the way proposed by Mike:
byte[ p_rxInput ][ idx++ ] := serial.rx

MagIO2
10-20-2011, 07:31 PM
No, what Mike says is:

if you pass the address of the array to the function and you want to access a single byte of that array inside of the function, you have to use the mentioned notation.

For example:


PUB Main

returnTemp := serialCom(@rxInput)


PUB serialCom(strAddr) : returnValue

byte[ strAddr ][ 0 ] := "X" ' this would set the first byte in the array rxInput

returnValue := {something}


As your array contains 100 bytes you can use
byte[ strAddr ][ 0 ] up to byte[ strAddr ][ 99 ]

MagIO2
10-20-2011, 07:54 PM
Ehmmm ... what do I use ... well, you should simply follow the advice and not ask.... LOL

Ok, to be honest, I'm not strictly following this advice as such because I am the wise guy and know all of my variables. ;o)

For constants I use uppercase names.
For variables I try to use the abbreviation of longer names which describe what these are good for. For example tim_tab for timing table or smpl_tab for sample table or key_buf for key buffer or buf_adr for buffer address ...
Somehow I like the idea of names speaking for themselves but I don't like typing ;o)
For counters -for example in a loop- I'm simply old school, using i,j,k ...

But I think unless you're a wise guy as well, it's good to be aware of these differences and might help to find bugs.
For example

serial.str( l_maxspeed )

would hopefully make you think: "Hmm, why do I call a function expecting a string with a long value instead?"

turbosupra
10-20-2011, 08:03 PM
Thanks for the reply, it is working now!

I will start to implement your and Stefans recommendations on naming conventions tonight!