Go Down

Topic: Using global array in function (Read 1 time) previous topic - next topic

smartroad

Hi all,

I have delcared an array in the main program which I am trying to use in a function. I am getting a host of issues from it when I call more then one of the functions in the main loop. Can I assume you can't call on variables from outside the function?

AWOL

No, you can't assume that (if it's what I think you're saying)

Why don't you post your code?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

retrolefty

#2
Mar 14, 2010, 05:30 pm Last Edit: Mar 14, 2010, 05:30 pm by retrolefty Reason: 1
If you define the array variable(s) before the setup(), loop(), and any other functions you define, it should then be globle for any function.

Lefty

smartroad

#3
Mar 14, 2010, 06:20 pm Last Edit: Mar 14, 2010, 06:22 pm by smartroad Reason: 1
Why didn't I think of that AWOL  :-[ ;D here is the code:
Code: [Select]
#define channels 1 //number of channels: 0=1 channel, 1=2 channels etc.

byte lamppin[] = {11, 12, 13}; //output pins for each channel

byte flashes[channels];
unsigned long ondelay[channels];
unsigned long offdelay[channels];
boolean run[channels];

void setup()
{
 Serial.begin(9600);
 for (int c=0; c<=channels; c++)
 {
   Serial.print(c, DEC);
   pinMode(lamppin[c], OUTPUT); //set output
   randomSeed(analogRead(0)); //set random seed from open analog input
   flashes[c] = random(3,11); //number of flashes for lamp
   run[c] = LOW;
 }
}

void loop()
{
 fluor(0);
 fluor(1);
 fluor(2);
}

void fluor(int n)
{
 if (run[n] == LOW) //run if flash cycle complete
 {
   ondelay[n]=random(1,8) * 50; //number of mS delay for on flash
   offdelay[n]=(random(1,8) * 50) + ondelay[n]; //number of mS delay for off flash adding on delay
 
   ondelay[n] = ondelay[n] + millis(); //add on delay to current runtime mS
   offdelay[n] = offdelay[n] + millis(); //add off delay to current runtime mS
 
   run[n] = HIGH; //reset status1 to not run on next program loop
 }
 
 if (flashes[n] > 0) //run if there are still flashes to go
 {
   if (ondelay[n] > millis() && offdelay[n] > millis()) { digitalWrite(lamppin[n], HIGH); } //set output high if time is still less then ondelay and offdelay
   else if (offdelay[n] > millis()) { digitalWrite(lamppin[n], LOW); } //set output high if time is less then offdelay
   else
   {
     flashes[n]--; //otherwise reduce flash cycle by 1
     run[n] = LOW; //set status to refresh on/off delay times
     digitalWrite(lamppin[n], HIGH); //set output high for
   }
 }
}


I have taken the procedure out of a working program that I wrote, the only difference is that to get more then one pin to flash the whole block was copied and then re-pasted with updated variable names (flashes1, flashes2 etc).

I was hoping to have it in a function so that I can clean the code up and only have one instance of the block rather then loads of copies of the same thing.

Code that the above was stripped from:

Code: [Select]
#define lamp1 11
byte flashes1;
unsigned long ondelay1;
unsigned long offdelay1;
boolean status1 = LOW;

#define lamp2 12
byte flashes2;
unsigned long ondelay2;
unsigned long offdelay2;
boolean status2 = LOW;

void setup()
{
 pinMode(lamp1, OUTPUT); //set output for first lamp
 randomSeed(analogRead(0)); //set random seed from open analog input
 flashes1 = random(3,11); //number of flashes for lamp1

 pinMode(lamp2, OUTPUT); //set output for second lamp
 randomSeed(analogRead(0)); //set random seed from open analog input
 flashes2 = random(3,11); //number of flashes for lamp2
}


void loop()
{
 // channel 1 - copy this block for more channels changing relivant variables

 if (status1 == LOW) //run if flash cycle complete
 {
   ondelay1=random(1,8) * 50; //number of mS delay for on flash
   offdelay1=(random(1,8) * 50) + ondelay1; //number of mS delay for off flash adding on delay
 
   ondelay1 = ondelay1 + millis(); //add on delay to current runtime mS
   offdelay1 = offdelay1 + millis(); //add off delay to current runtime mS
 
   status1 = HIGH; //reset status1 to not run on next program loop
 }
 
 if (flashes1 > 0) //run if there are still flashes to go
 {
   if (ondelay1 > millis() && offdelay1 > millis()) { digitalWrite(lamp1, HIGH); } //set output high if time is still less then ondelay and offdelay
   else if (offdelay1 > millis()) { digitalWrite(lamp1, LOW); } //set output high if time is less then offdelay
   else
   {
     flashes1--; //otherwise reduce flash cycle by 1
     status1 = LOW; //set status to refresh on/off delay times
     digitalWrite(lamp1, HIGH); //set output high for
   }
 }

 //end channel 1

 if (status2 == LOW)
 {
   ondelay2=random(1,8) * 50;
   offdelay2=(random(1,8) * 50) + ondelay2;
 
   ondelay2 = ondelay2 + millis();
   offdelay2 = offdelay2 + millis();
 
   status2 = HIGH;
 }
 
 if (flashes2 > 0)
 {
   if (ondelay2 > millis() && offdelay2 > millis()) { digitalWrite(lamp2, HIGH); }
   else if (offdelay2 > millis()) { digitalWrite(lamp2, LOW); }
   else
   {
     flashes2--;
     status2 = LOW;
     digitalWrite(lamp2, HIGH);
   }
 }

}


-edit-
Forgot to say what it is meant to do. I wanted to simulate the start up flashing of a fluoresecnt tube. The second code here works fine and flashes the LEDs on pins 11 and 12. The first code is meant to flash pins 11, 12 and 13. All it seems to do is flash pin 12 without stopping.

AWOL

#4
Mar 14, 2010, 09:19 pm Last Edit: Mar 14, 2010, 09:22 pm by AWOL Reason: 1
Both those compile - what's the problem?

Code: [Select]
if (offdelay[n] > millis()) { digitalWrite(lamppin[n], LOW); } //set output high if time is less then offdelay
I think your comments need some editing.

Code: [Select]
#define channels 1
Could this be part of the problem?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

smartroad

#5
Mar 14, 2010, 09:53 pm Last Edit: Mar 14, 2010, 09:56 pm by smartroad Reason: 1
OK I didn't read my own comments in program  :-[ didn't add enough channels in my #define. Changed it to 3 and works fine. Sorry to bother you guys!

If anyone is interested I have made a video of what the code actually does here: http://www.youtube.com/watch?v=RmNCNlDrK5Q

westfw

Code: [Select]
 for (int c=0; c<=channels; c++)
For an array of size [channels], you had better change that "<=" to a "<", or you'll end up referencing one beyond the end of the arrays (and possibly modifying random bits of memory.)


Go Up