Using global array in function

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?

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

Why don't you post your code?

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

Why didn’t I think of that AWOL :-[ ;D here is the code:

#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:

#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.

Both those compile - what's the problem?

if (offdelay[n] > millis()) { digitalWrite(lamppin[n], LOW); } //set output high if time is less then offdelay

I think your comments need some editing.

#define channels 1

Could this be part of the problem?

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

  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.)

cheer westfw