Macros & Local variables

For Flowcode users to discuss projects, flowcharts, and any other issues related to Flowcode 2 and 3.

Moderators: Benj, Mods

Post Reply
Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Macros & Local variables

Post by Ron »

Hi,

I have written several macros that use local variables. When my macro completes and exits does the information in the local variables get dumped or is it retained?

Help file did not say.......

Thanks

Ron

Ron
Posts: 225
Joined: Wed Apr 11, 2007 6:15 pm
Has thanked: 2 times
Contact:

Re: Macros & Local variables

Post by Ron »

Hi,

Sorry, already asked this....

Been a long week..... I have worked 2, 30 hour shifts this week, plus organic chemistry.

Sean
Valued Contributor
Valued Contributor
Posts: 548
Joined: Tue Jun 26, 2007 11:23 am
Has thanked: 6 times
Been thanked: 44 times
Contact:

Re: Macros & Local variables

Post by Sean »

Hello Ron.

The Flowcode local variables declared in a macro do not exist when the macro is not being run.

There is a way to keep the contents of local variables between successive runs of a macro - by declaring the variable as 'static'. This should only be used when necessary as the variable will be permanently resident in memory (like a global variable), but will only be accessible from the the macro that defined it.

The static variable declaration must be done in a C Code block. C Code blocks must also be used to transfer values between the local Flowcode variables and the static variables.


Example:

A C Code block with the following contents, at the top of a macro, will declare a static local integer variable called statvar.

static int statvar = 0;

The initialisation (statvar = 0) is optional and will only occur the first time the macro is run after power-up or reset. All subsequent runs will retain the value left by the previous run.


If a local Flowcode variable called data1 is declared in the macro details editor, it will have the C name FCL_DATA1 (FCL_ is the C prefix for Flowcode local variables and FCV_ for global. Both are always in upper-case). A C Code block containing the following code would copy the dynamic Flowcode local variable data1 to the static C variable statvar:

statvar = FCL_DATA1;

The following C code would return the static C variable to the local flowcode variable:

FCL_DATA1 = statvar;

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Macros & Local variables

Post by Ondra »

Good day all I am trying to use static variables using the examples given. I have macro with four decision blocks each with 1 C block in a if else type setup.

The macro which is called from main, runs one C code instruction each time it's called.
If I only run the first two static declarations It compiles OK. In the first two incidence I want to capture the values from the flowcode variables. In the next two instances I want to write the c variables captured earlier back

to the Flowcode variables.

Macro do something
If whichcmd =1
static char *ISP_2_PhoneNo = FCV_ISP2;
else If whichcmd =2
static char *ISP_2_usname = FCV_USR_NM2;
else If whichcmd =3
FCV_ISP2 = ISP_2_PhoneNo;
else If whichcmd =4
FCV_USR_NM2 = ISP_2_usname;
end If

These are the errors I get. What am I missing?

LCD_Mar_15_09.c(6277:13): error: unknown identifier 'ISP_2_PhoneNo'
LCD_Mar_15_09.c(6277:13): error: invalid operand 'ISP_2_PhoneNo'
LCD_Mar_15_09.c(6277:11): error: failed to generate expression
LCD_Mar_15_09.c(6319:16): error: unknown identifier 'ISP_2_usname'
LCD_Mar_15_09.c(6319:16): error: invalid operand 'ISP_2_usname'
LCD_Mar_15_09.c(6319:14): error: failed to generate expression

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Macros & Local variables

Post by Benj »

Hello Ondra

In the following lines

static char *ISP_2_PhoneNo = FCV_ISP2;
static char *ISP_2_usname = FCV_USR_NM2;

Try removing the aterisks " * ", these are making the C code think they are address pointers rather then data values.

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Macros & Local variables

Post by Ondra »

Thanks Benj. I removed the asterisks " * " and compiled. I got the following error.

LCD_Mar_15_09.c(6245:30): error: can't convert 'unsigned char[]' to 'unsigned char'
LCD_Mar_15_09.c(6245:28): error: failed to initialize variable 'ISP_2_PhoneNo'
LCD_Mar_15_09.c(6256:29): error: can't convert 'unsigned char[]' to 'unsigned char'
LCD_Mar_15_09.c(6256:27): error: failed to initialize variable 'ISP_2_usname'
LCD_Mar_15_09.c(6277:13): error: unknown identifier 'ISP_2_PhoneNo'
LCD_Mar_15_09.c(6277:13): error: invalid operand 'ISP_2_PhoneNo'
LCD_Mar_15_09.c(6277:11): error: failed to generate expression
LCD_Mar_15_09.c(6319:16): error: unknown identifier 'ISP_2_usname'
LCD_Mar_15_09.c(6319:16): error: invalid operand 'ISP_2_usname'
LCD_Mar_15_09.c(6319:14): error: failed to generate expression

User avatar
Steve
Matrix Staff
Posts: 3422
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: Macros & Local variables

Post by Steve »

Code: Select all

1.    If whichcmd =1
2.      static char *ISP_2_PhoneNo = FCV_ISP2; 
3.    else If whichcmd =2
4.      static char *ISP_2_usname = FCV_USR_NM2; 
5.    else If whichcmd =3
6.      FCV_ISP2 = ISP_2_PhoneNo;
7.    else If whichcmd =4
8.      FCV_USR_NM2 = ISP_2_usname;
9.    end If
I think that the problem is because the variables are defined in lines 2 and 4, but they immediately go "out of scope" at the "else" statements and so lines 6 and 8 cannot "see" these definitions.

The way around it is to add the definitions to the beginning of your code:

Code: Select all

static char *ISP_2_PhoneNo; 
static char *ISP_2_usname; 
And then refer to them as follows:

Code: Select all

If whichcmd == 1
  *ISP_2_PhoneNo = FCV_ISP2; 
else If whichcmd == 2
  *ISP_2_usname = FCV_USR_NM2; 
else If whichcmd == 3
  FCV_ISP2 = ISP_2_PhoneNo;
else If whichcmd == 4
  FCV_USR_NM2 = ISP_2_usname;
end If

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Macros & Local variables

Post by Ondra »

Thanks Steve. I tried your suggestion, I got the following errors.

LCD_Mar_15_09.c(6283:11): error: left operand must be l-value
LCD_Mar_15_09.c(6283:11): error: failed to generate expression
LCD_Mar_15_09.c(6326:14): error: left operand must be l-value
LCD_Mar_15_09.c(6326:14): error: failed to generate expression

I created a file with only the C code. Here is what I discovered If I leave off the last 2 "else if" statements the program will compile. With that being the case I think the problem is with the below statements. Any Idea what I am missing?

else If whichcmd == 3
FCV_ISP2 = ISP_2_PhoneNo;
else If whichcmd == 4
FCV_USR_NM2 = ISP_2_usname;
end If

Ondra

User avatar
Steve
Matrix Staff
Posts: 3422
Joined: Tue Jan 03, 2006 3:59 pm
Has thanked: 114 times
Been thanked: 422 times
Contact:

Re: Macros & Local variables

Post by Steve »

Try removing the '*' symbols from the static variables:

Code: Select all

static char ISP_2_PhoneNo; 
static char ISP_2_usname; 
and

Code: Select all

if whichcmd == 1
  ISP_2_PhoneNo = FCV_ISP2; 
else if whichcmd == 2
  ISP_2_usname = FCV_USR_NM2; 
else if whichcmd == 3
  FCV_ISP2 = ISP_2_PhoneNo;
else if whichcmd == 4
  FCV_USR_NM2 = ISP_2_usname;
endif

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Macros & Local variables

Post by Benj »

Hello Ondra

I believe the code should look like this to work correctly.

Code: Select all

static char ISP_2_PhoneNo;
static char ISP_2_usname; 

if (whichcmd == 1)
{
  ISP_2_PhoneNo = FCV_ISP2;
}
else if (whichcmd == 2)
{
  ISP_2_usname = FCV_USR_NM2;
}
else if (whichcmd == 3)
{
  FCV_ISP2 = ISP_2_PhoneNo;
}
else if (whichcmd == 4)
{
  FCV_USR_NM2 = ISP_2_usname;
}

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Macros & Local variables

Post by Ondra »

I'm still getting error and the code won't compile. Maybe I'm not understanding. Here is a copy of the macro.
Attachments
test ISP_2_Conn.fcm
(3.31 KiB) Downloaded 269 times

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Macros & Local variables

Post by Benj »

Hello

Ok I see the problem. The variable "FCV_ISP2" is defined in Flowcode as a string variable. Should this be a byte instead?

Same problem with the Username variable.

If you need to copy the whole string then why not use the Flowcode built-in String manipulation icons. This may also get rid of the need for static variables. Any variable defined in the main Flowcode variable window is essentially a global or static value.

Ondra
Posts: 325
Joined: Wed Aug 29, 2007 7:33 pm
Been thanked: 2 times
Contact:

Re: Macros & Local variables

Post by Ondra »

Thanks Benj
I have device that connects to the internet. I what to change the dialup number and user name values when the device connects. If the unit is powered down and then restarted, I want the new values that are captured over the dialup connection to remain when the unit is powered back on. This is the reason for using static variables. Are you saying that this can be done using flowcode variable?
At the moment I am capturing a phone number and user name as a string variable over the modem. Could you give me an example of how I might accomplish what I'm trying to do if I make the the current FCV_ISP2 a byte variable. can I create a byte array? If so I haven't done this before how would I define it. could you give me an example?

Thanks in advance.

Ondra

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Macros & Local variables

Post by Benj »

Hello Ondra

Static variable will not retain their value while the device is powered down. You will have to write the string information into the EEPROM a byte at a time whenever the variables get updated and then retreive at the start of your program to make sure you have the correct values.

Creating a byte array is quite easy. Simply enterthe byte variable name in the variable manager and add [8] after the variable name. Change 8 for the number of bytes you require in your array. Single bytes can then be referenced as such varname[0] <---> varname[7]

Hope this helps.

Post Reply