Mini Stage Show x 20

OK sorry Marco. The code was a couple of posts back. I was not sure about re-posting stuff, but here it is:

/*
Fade up and down on multiple pins
Code written by Chagrin August 2012
*/
#define LED1 3 // assign the first LED to pin 3
#define LED2 5 // assign the second LED to pin 5, etc...
#define LED3 6

#define MAXPINNUMBER 6 // LED3 is the highest pin number -- number 6

#define MILLISPERDIMSTEP 10 // LED dimming is recalculated every X millis

// Group LED commands into a structure (struct)
struct command {
  byte pin;          // 0 to 255
  unsigned int time; // 0 to 65535
  byte brightness;   // 0 to 255
  char dimrate;      // -127 to 128
};

// The stored state of each LED; holds state of dimming.
struct state {
  unsigned int time;
  byte brightness;
  byte dimrate;
};

// Create the scene which is an array of "command" structs
struct command scene[] = {
  {LED1,0,255,0},
  {LED2,0,255,0},
  {LED3,0,255,0},
  {LED1,1000,0,0},
  {LED2,2000,0,0},
  {LED3,3000,0,10},
  {LED3,6000,255,-10},
  {LED3,9000,0,1},
  {LED3,12000,255,-1}
};

// Initialize the LED states to off. Note 0 to MAXPINNUMBER is (MAXPINNUMBER + 1) states.
struct state ledState[MAXPINNUMBER + 1] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

void setup(){
}

void loop(){
  static unsigned long kickoff = 0;
  static unsigned int sceneCtr = 0;
  byte ledCtr = 0;

  // wait for a button press here to kick off the scene if desired

  // Check the scene to see if we have a new command
  if (sceneCtr < sizeof(scene) / sizeof(command)) {
    if (scene[sceneCtr].time <= millis() - kickoff) {
      analogWrite(scene[sceneCtr].pin, scene[sceneCtr].brightness);
      if (scene[sceneCtr].dimrate != 0) {
        // It dims; we have to add this to our ledState array and keep track of it.
        ledState[scene[sceneCtr].pin].time = scene[sceneCtr].time + MILLISPERDIMSTEP;
        ledState[scene[sceneCtr].pin].brightness = scene[sceneCtr].brightness;
        ledState[scene[sceneCtr].pin].dimrate = scene[sceneCtr].dimrate;         
      }
      sceneCtr += 1;
    }
  }
  
  // Here we process through all the LEDs in a dimming state
  for (ledCtr = 0; ledCtr < MAXPINNUMBER + 1; ledCtr++) {
    if (ledState[ledCtr].dimrate != 0) { // only LEDs with a dimming are messed with.
      if (ledState[ledCtr].time <= millis() - kickoff) {
        if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate >= 0 &&
            ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate <= 255) {
          ledState[ledCtr].brightness += (char) ledState[ledCtr].dimrate;
          ledState[ledCtr].time += MILLISPERDIMSTEP; // mark the time of next LED adjustment
        } else if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate < 0) {
          // need to stop at zero and not a negative number.
          ledState[ledCtr].brightness = 0;
          ledState[ledCtr].dimrate = 0; // zero dimrate so we stop dimming it
        } else {
          // need to stop at 255.
          ledState[ledCtr].brightness = 255;
          ledState[ledCtr].dimrate = 0; // zero dimrate.
        }
        analogWrite(ledCtr, ledState[ledCtr].brightness);
      } 
    }
  }
  
  // Have 60 seconds elapsed? We need to restart if so.
  if (millis() - kickoff > 60000) {
    kickoff = millis();
    sceneCtr = 0;
  }
}

My mistake. I thought you had 'received' something else/more. Thanks for reposting.

If you needed a longer time period you'd need to change the "command" struct "time" data type to something larger. That of course eats up more memory.

You could also scale up the time to 10x the actual time, assuming you can settle for .01 millisecond accuracy of when you want to change LED activities. That would just require:

if (scene[sceneCtr].time * 10 <= millis() - kickoff) {

There are so many ways to approach a problem like this. I was just doing my best at aiming for a clear, straightforward solution.

With a little more testing under the belt I wonder if I have hit the ceiling with the Uno microprocessor. I wired up three more LEDs to my board to test multi fading on the 6 PWM pins, 3,5,6,9,10,11. It seems that I can have PWM action on 3,5,6 but not on 9,10,11. I can get switching on 9,10,11. Before I order up more processing power I thought I would check with people interested in this thread.

Here is the code I have been running. The code preserves the original settings posted by Chagrin except that I have increased MILLIDIMSTEP from 10 to 75 to produce longer fades. And of course I have declared the extra PWM pins along with a string of new commands.

/*
Fade up and down on multiple pins
Code written by Chagrin August 2012
*/

#define LED1 3 // assign the first LED to pin 3
#define LED2 5 // assign the second LED to pin 5, etc...
#define LED3 6
#define LED4 9 
#define LED5 10 
#define LED6 11
#define MAXPINNUMBER 6 // LED6 is the highest pin number -- number 6

#define MILLISPERDIMSTEP 75 // LED dimming is recalculated every X millis

// Group LED commands into a structure (struct)
struct command {
  byte pin;          // 0 to 255
  unsigned int time; // 0 to 65535
  byte brightness;   // 0 to 255
  char dimrate;      // -127 to 128
};

// The stored state of each LED; holds state of dimming.
struct state {
  unsigned int time;
  byte brightness;
  byte dimrate;
};

// Create the scene which is an array of "command" structs
struct command scene[] = {
  {LED1,0,255,0},
  {LED2,0,255,0},
  {LED3,0,255,0},
  {LED4,0,255,0},
  {LED5,0,255,0},
  {LED6,0,0,0},
  {LED1,900,255,-2},
  {LED6,1000,255,-2},
  {LED2,8000,255,-1},
  {LED1,15000,0,2},
  {LED3,27000,255,-5},
  {LED1,29000,255,-2},
   {LED1,40000,255,0}, 
  {LED1,40100,0,0},
   {LED1,41000,255,0},
  {LED1,41100,0,0},
   {LED1,42000,255,0},
  {LED1,42100,0,0},
   {LED1,43000,255,0},
  {LED1,43100,0,0},
   {LED1,44000,255,0},
  {LED1,44100,0,0},
   {LED1,45000,255,0},
  {LED1,45100,0,0},
   {LED1,46000,255,0},
  {LED1,46100,0,0},
   {LED1,47000,255,0},
  {LED1,47100,0,0},
  {LED4,48300,255,-5},
  {LED5,48400,255,-5},
  {LED6,48500,255,-5},
  {LED1,49000,0,1},
  {LED2,49100,0,2},
  {LED3,49200,0,3},
};

// Initialize the LED states to off. Note 0 to MAXPINNUMBER is (MAXPINNUMBER + 1) states.
struct state ledState[MAXPINNUMBER + 1] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

void setup(){
}

void loop(){
  static unsigned long kickoff = 0;
  static unsigned int sceneCtr = 0;
  byte ledCtr = 0;

  // wait for a button press here to kick off the scene if desired

  // Check the scene to see if we have a new command
  if (sceneCtr < sizeof(scene) / sizeof(command)) {
    if (scene[sceneCtr].time <= millis() - kickoff) {
      analogWrite(scene[sceneCtr].pin, scene[sceneCtr].brightness);
      if (scene[sceneCtr].dimrate != 0) {
        // It dims; we have to add this to our ledState array and keep track of it.
        ledState[scene[sceneCtr].pin].time = scene[sceneCtr].time + MILLISPERDIMSTEP;
        ledState[scene[sceneCtr].pin].brightness = scene[sceneCtr].brightness;
        ledState[scene[sceneCtr].pin].dimrate = scene[sceneCtr].dimrate;         
      }
      sceneCtr += 1;
    }
  }
  
  // Here we process through all the LEDs in a dimming state
  for (ledCtr = 0; ledCtr < MAXPINNUMBER + 1; ledCtr++) {
    if (ledState[ledCtr].dimrate != 0) { // only LEDs with a dimming are messed with.
      if (ledState[ledCtr].time <= millis() - kickoff) {
        if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate >= 0 &&
            ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate <= 255) {
          ledState[ledCtr].brightness += (char) ledState[ledCtr].dimrate;
          ledState[ledCtr].time += MILLISPERDIMSTEP; // mark the time of next LED adjustment
        } else if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate < 0) {
          // need to stop at zero and not a negative number.
          ledState[ledCtr].brightness = 0;
          ledState[ledCtr].dimrate = 0; // zero dimrate so we stop dimming it
        } else {
          // need to stop at 255.
          ledState[ledCtr].brightness = 255;
          ledState[ledCtr].dimrate = 0; // zero dimrate.
        }
        analogWrite(ledCtr, ledState[ledCtr].brightness);
      } 
    }
  }
  
  // Have 60 seconds elapsed? We need to restart if so.
  if (millis() - kickoff > 60000) {
    kickoff = millis();
    sceneCtr = 0;
  }
}

The code begins with all lights on except that there is a one second delay on LED6 (pin11) this is to help identify the begining of the scene when it loops. After 900 millis LED1 begins a slow fade, 100millis later LED6 is commanded to begin the same fade. LED1 fades nicely, but LED6 remains on full bright. Then follows a series of slow fades on LED1,2,3 which all execute nicely. At 40 seconds LED1 begins flashing leading to a set of commands to test LEDs 4,5,6. At this point, 48 seconds, the sketch reverts to kickoff rather than fading the last three LEDs. Interestingly, an additional three last commands to fade up LEDs 1,2,3 do not execute. The last 12 seconds of the sketch is lost. Who knows where the time goes?

#define MAXPINNUMBER 11 // LED11 is the highest pin number

so that the code knows to manage dimming for those higher pins and

// Initialize the LED states to off. Note 0 to MAXPINNUMBER is (MAXPINNUMBER + 1) states.
struct state ledState[MAXPINNUMBER + 1] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

you have to create a storage area to store the states of those pins.

Excellent! Works perfectly. I should have thought a little bit harder, I thought the six pins under management were the PMW pins only. I now see that the storage role of the struct state ledState[MAXPINNUMBER + 1] covers all pins, though not quite sure about the +1 -something to do with how the counter works I suppose. Anyway, I'm just the driver, not the mechanic.

Since there are actually 11 pins being managed the next step is to insert some commands for the non PMW pins and see how they perform with simple on/off tasks.

I have everything I asked for as far as this basic Uno board goes, but I do have 12 circuits to control and this board will only stretch to 6 fading channels. I have been looking into the add-on options for the Uno and there is a plug-in TLC5940 shield that will boost my PWM pins from 6 to 16. Or I could buy a bigger board, the Arduino Mega2560 has 14 PWM pins. The TLC chips deliver more power off the board, but from my reading this may not be good thing. I think it is safer to deliver power via transistors than rely on the proccessor to do the thinking and the heavy lifting. Since I want my installation to keep running for years I am trying to engineer things to keep cool.

So, is there any reason why this excellent code would not expand to meet the capabilities of the Arduino Mega? I think it will.

So. The code works with the digital pins as well as the analogue pins. Only one surprise, it seems the digital pins deliver more power to the LED. My digital LED is burning significantly brighter than the analogue pins at 255. This adds weight to my decision to use transistors to deliver power.

I have ordered an Arduino mega board to see if I can get more PWM action.

My Arduino megao board will arrive today - I got a card telling me its waiting at the post office. Jumping the gun here, but I'm pretty confident I will soon have my 12 channels of individually controlled lighting.

My little Uno board has been faithfully looping through my 60 second lightshow for 7 channels (6 PWM, 1 digital) ever since I installed the code some days ago. It looks beautiful. For anyone who missed the code earlier here it is. I have included commands for the scene I am running.

A simple code to allow individual fading of lights within a 60 second loop:

/*
Fade up and down on multiple pins
Code written by Chagrin August 2012
*/
#define LED1 3 // assign the first LED to pin 3
#define LED2 5 // assign the second LED to pin 5, etc...
#define LED3 6
#define LED4 9 
#define LED5 10 
#define LED6 11
#define LED7 1
#define MAXPINNUMBER 11 // LED11 is the highest pin number

#define MILLISPERDIMSTEP 75 // LED dimming is recalculated every X millis

// Group LED commands into a structure (struct)
struct command {
  byte pin;          // 0 to 255
  unsigned int time; // 0 to 65535
  byte brightness;   // 0 to 255
  char dimrate;      // -127 to 128
};

// The stored state of each LED; holds state of dimming.
struct state {
  unsigned int time;
  byte brightness;
  byte dimrate;
};

// Create the scene which is an array of "command" structs
struct command scene[] = {
  {LED1,0,255,0},
  {LED2,0,255,0},
  {LED3,0,255,0},
  {LED4,0,255,0},
  {LED5,0,255,0},
  {LED6,0,0,0},
  {LED7,0,255,0},
  {LED1,1000,255,-2},
  {LED6,1000,255,0},
  {LED5,0,0,0},
  {LED2,8000,255,-1},
  {LED1,15000,0,2},
  {LED3,27000,255,-5},
   {LED7,2700,0,0},
  {LED1,29000,255,-2},
   {LED1,40000,255,0}, 
  {LED1,40100,0,0},
   {LED1,41000,255,0},
  {LED1,41100,0,0},
   {LED1,42000,255,0},
  {LED1,42100,0,0},
   {LED1,43000,255,0},
  {LED1,43100,0,0},
   {LED1,44000,255,0},
  {LED1,44100,0,0},
   {LED1,45000,255,0},
  {LED1,45100,0,0},
   {LED1,46000,255,0},
  {LED1,46100,0,0},
   {LED1,47000,255,0},
  {LED1,47100,0,0},
  {LED4,48000,0,0},
  {LED5,48000,0,0},
  {LED6,48000,0,0},
  {LED4,48100,255,-4},
  {LED5,48100,255,-3},
  {LED6,48100,255,-2},
  {LED1,49000,0,2},
  {LED2,49100,0,4},
  {LED3,49200,0,3},
};

// Initialize the LED states to off. Note 0 to MAXPINNUMBER is (MAXPINNUMBER + 1) states.
struct state ledState[MAXPINNUMBER + 1] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

void setup(){
}

void loop(){
  static unsigned long kickoff = 0;
  static unsigned int sceneCtr = 0;
  byte ledCtr = 0;

  // wait for a button press here to kick off the scene if desired

  // Check the scene to see if we have a new command
  if (sceneCtr < sizeof(scene) / sizeof(command)) {
    if (scene[sceneCtr].time <= millis() - kickoff) {
      analogWrite(scene[sceneCtr].pin, scene[sceneCtr].brightness);
      if (scene[sceneCtr].dimrate != 0) {
        // It dims; we have to add this to our ledState array and keep track of it.
        ledState[scene[sceneCtr].pin].time = scene[sceneCtr].time + MILLISPERDIMSTEP;
        ledState[scene[sceneCtr].pin].brightness = scene[sceneCtr].brightness;
        ledState[scene[sceneCtr].pin].dimrate = scene[sceneCtr].dimrate;         
      }
      sceneCtr += 1;
    }
  }
  
  // Here we process through all the LEDs in a dimming state
  for (ledCtr = 0; ledCtr < MAXPINNUMBER + 1; ledCtr++) {
    if (ledState[ledCtr].dimrate != 0) { // only LEDs with a dimming are messed with.
      if (ledState[ledCtr].time <= millis() - kickoff) {
        if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate >= 0 &&
            ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate <= 255) {
          ledState[ledCtr].brightness += (char) ledState[ledCtr].dimrate;
          ledState[ledCtr].time += MILLISPERDIMSTEP; // mark the time of next LED adjustment
        } else if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate < 0) {
          // need to stop at zero and not a negative number.
          ledState[ledCtr].brightness = 0;
          ledState[ledCtr].dimrate = 0; // zero dimrate so we stop dimming it
        } else {
          // need to stop at 255.
          ledState[ledCtr].brightness = 255;
          ledState[ledCtr].dimrate = 0; // zero dimrate.
        }
        analogWrite(ledCtr, ledState[ledCtr].brightness);
      } 
    }
  }
  
  // Have 60 seconds elapsed? We need to restart if so.
  if (millis() - kickoff > 60000) {
    kickoff = millis();
    sceneCtr = 0;
  }
}

So my next challenge will be controlling my lights remotely. I need to start studying. I understand I will need to provide my mega board with an ethernet shield. From this point on I am clueless. Any tips on where I should go next would be greatly appreciated.

So, I'm still struggling with uploading the Chagrin code -as posted in the last post- onto my Mega 2560 board. I can upload the blink sketch and I have the little on-board LED happily blinking away. But when I try the longer code the upload fails to complete. LED 13 continues to blink and there are momentary occasional flashes from the TX and RX LEDs until some minutes pass and the upload attempt has failed. These are the messages I get from the Arduino IDE:

Binary sketch size: 2,510 bytes (of a 258,048 byte maximum)
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x10
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_command(): failed miserably to execute command 0x11
avrdude: stk500v2_disable(): failed to leave programming mode

I am running a 2007 macbook pro with OS 10.4.11. Admittedly it is getting long in the tooth, I use an external keyboard since the onboard one is faulty - so one of my USB ports is given over to the keys. RAM is also running short. But still I don't understand why I can upload this code onto my Uno board but not onto the Mega. And I can upload the blink example onto the Mega but not the longer code. To me this is mysterious.

My problems with the Arduino Mega board are not attracting any feedback from forum members, but for the sake of completion, or possibly to help other noobies, I will continue to update my progress. For me it is not a trivial topic that the Mega 2560 does not perform adequately. I was planning to use 20 of these little buggers.

It turns out I can upload my code to the board, but I get only one shot. I need to restart my computer to reload another program. Pressing the reset button on the board does not seem to work. I am assuming the problem is not with the code or my computer because I do not have an upload problem when using the Uno board. There is some difference between the boards.

So, at least I have a way to move forward - turn the computer off before trying to communicate with the board, but I would love to know what the problem is and try to fix it. Perhaps I should post in another forum section?

I would suggest posting in the Installation and Troubleshooting section.

You didn't mention if you have an official Arduino Mega, a clone mega, or you might even have a counterfeit Mega. If you bought from a disreputable seller the latter is quite possible.

Thanks for dropping in Chagrin. I'm pretty sure the Arduino boards are both genuine. The Uno and my Mega 2560 were both bought from Australian Robotics who clearly separate official Arduino product from "Arduino Compatible" on their website. I have sent off an email to Australian Robotics seeking advice, but so far no reply.

The fact that I have success with Uno board while the Mega board struggles leads me to think it is a bug in the software onboard the Mega. The computer, USB lead, Arduino IDE, code and test LED hardware are all one and the same.

One point of difference between the boards is that the LED marked L under pin 13 remains on with the Mega while the sketch is running, but it does not stay on while running on the Uno.

I have been reading my way through the trouble shooting section to make sure my issues have not been answered already. I've read about a lot of variations on upload problems with the Mega 2650, buy I am really no wiser. I think I might try a post to the Troubleshooters now.

Uploading issues are the worst, and I have never used the Mega, so I can't speak with much authority there, but you could try using an external programmer.

Arduinos are shipped with a bootloader that lets the board load new code when it is first started up. For more reasons than we would like, this approach doesn't always work out well and it sometimes leaves you with uploading issues. An in-system programmer (ISP) lets you upload the code at any time via the 6 pin connector that sits between the processor and the reset button on the Mega. This uploading method usually has a much better probability of going well.

As a side benefit you also get rid of the bootloader which gives you a little bit more space for your programs and it eliminates the delay from power on to program execution.

I got a USBtinyISP from www.adafruit.com after I could not upload to a Bluetooth Arduino and it has worked perfectly ever since. That particular ISP comes as a kit, so don't get it if you aren't comfortable with some thru-hole soldering. An ISP may seem like an unessesary tool when the bootloader should work, but trust me if you are going to be dealing with that many Megas it will be the best tool in your toolbox.

Thanks Jroorda for making a very sensible suggestion. I checked out the specs on the USBtinyISP AVR Programmer kit at adafruit:

Unfortunately it does not work with the large Atmega chips, so I'll score that as a near miss... but thanks again for the suggestion.

My guess is that I need to try uploading from another computer to see if I get the same results - to recap - a failure of the Mega 2560 to take on code without turning off the computer first. A problem that I don't have when using the Uno board.

Definitely try another computer, as there is a good chance that could solve your issues. It is too bad the USBtinyISP won't work with the Mega, but it is far from the only game in town.

Look through the list of programmers provided in the newest version of the Arduino IDE. The AVRISP MKII looks to work with the mega and I would bet some of the others will as well.

Many AVR programers have a 10 pin connector instead of the 6 pin one, but that is what this is for.

Thanks again jroorda, I will definitely consider an ISP kit if I don't get myself a new computer which is looking increasingly necessary. It seems the Mega 2650 is not happy to operate with my old version of OSX 10.4.11. I moved my code over to another mac running 10.6.8 and the results were perfect. The upload was almost instant. So, problem solved. Buy a new computer. Of course this is an outrageously expensive solution that I would not consider except that all sorts of other software has also outpaced my 5 year old mac. Plus the keyboard is broken and the battery is dead and the RAM is stuffed. So yeah, time to move on. But it was happy with the Uno.

Communication problems behind me I have carried on wiring up my LED channels to the arduino Mega 2650 via a bank of tranistors to switch the current load. The good news is that this all works perfectly. The LED lights are performing much better than when drawing power directly from the board, much brighter, perhaps 50% brighter. These are 10mm LEDs that draw between 20 and 40 mA.

The code works perfectly. But I am now wanting to have the light show divided into two modes; a resting phase and an active phase. The light box at rest would have a glow of UV light, perhaps fading up and down gently. When the viewer turns the timer the active light show overrides the resting phase. When the timer runs down the lightshow ends and the box reverts to the resting mode.

I can approach this several ways; I could use two arduino boards each with separate circuits with a relay switching power from the resting phase circuits to the active phase.

Another way is to rewrite the code so that one board can handle both phases with the timer used as an external input, switching the program from the resting commands to the active commands. In effect I would need the timer input to reset the counter as well as switching modes. The loop logic would recognize the timer input and run the active command sequence. When the timer ends the program reverts to the resting commands. If I stick with the code structure as written by Chagin I would also need to declare two sets of commands before the loop. My question is whether this is possible, to have two different sets of variables declared in the sketch set-up?

Having fun trying to create a two layered version of the Chagrin code. To recap; a set of "active mode" commands nested within the "resting mode". By activating a timer the LED show switches from resting to active. Each mode can run on the 65535 millisecond counter loop but perhaps two different timers are needed, (I have read that there is more than one timer onboard).

Anyway, here is my beginners attempt at restructuring the code while breaking a few rules. According to the compiler it seems I can define two LED states to the same output pin, but I run into trouble when I try two set up two alternative struct modes:

#define LED1 3 // assign the first LED to pin 3
#define LED1A 3 // assign the first LED active mode to pin 3
#define LED2 5 // assign the second LED to pin 5
#define LED2A 5 // assign the second LED to pin 5 in active mode, etc...
#define LED3 6

#define MAXPINNUMBER 6 // LED3 is the highest pin number -- number 6

#define MILLISPERDIMSTEP 75 // LED dimming is recalculated every X millis

// Group LED commands into a structure (struct)
struct command {
  byte pin;          // 0 to 255
  unsigned int time; // 0 to 65535
  byte brightness;   // 0 to 255
  char dimrate;      // -127 to 128
};

// The stored state of each LED; holds state of dimming.
struct state {
  unsigned int time;
  byte brightness;
  byte dimrate;
};

// Create the scene which is an array of "command" structs
struct command scene[] = {
  {LED1,0,255,0},
  {LED2,0,255,0},

};
// Create the active scene which is an array of "command" structs  
struct command scene[A] = {
  {LED1A,0,255,0},
  {LED2A,0,255,0},
  
};

// Initialize the LED states to off. Note 0 to MAXPINNUMBER is (MAXPINNUMBER + 1) states.
struct state ledState[MAXPINNUMBER + 1] = {{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};

void setup(){
}

void loop(){
  static unsigned long kickoff = 0;
  static unsigned int sceneCtr = 0;
  byte ledCtr = 0;

  // wait for timer here to kick off the active scene

  // Check the scene to see if we have a new command
  if (sceneCtr < sizeof(scene) / sizeof(command)) {
    if (scene[sceneCtr].time <= millis() - kickoff) {
      analogWrite(scene[sceneCtr].pin, scene[sceneCtr].brightness);
      if (scene[sceneCtr].dimrate != 0) {
        // It dims; we have to add this to our ledState array and keep track of it.
        ledState[scene[sceneCtr].pin].time = scene[sceneCtr].time + MILLISPERDIMSTEP;
        ledState[scene[sceneCtr].pin].brightness = scene[sceneCtr].brightness;
        ledState[scene[sceneCtr].pin].dimrate = scene[sceneCtr].dimrate;         
      }
      sceneCtr += 1;
    }
  }
  
  // Here we process through all the LEDs in a dimming state
  for (ledCtr = 0; ledCtr < MAXPINNUMBER + 1; ledCtr++) {
    if (ledState[ledCtr].dimrate != 0) { // only LEDs with a dimming are messed with.
      if (ledState[ledCtr].time <= millis() - kickoff) {
        if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate >= 0 &&
            ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate <= 255) {
          ledState[ledCtr].brightness += (char) ledState[ledCtr].dimrate;
          ledState[ledCtr].time += MILLISPERDIMSTEP; // mark the time of next LED adjustment
        } else if (ledState[ledCtr].brightness + (char) ledState[ledCtr].dimrate < 0) {
          // need to stop at zero and not a negative number.
          ledState[ledCtr].brightness = 0;
          ledState[ledCtr].dimrate = 0; // zero dimrate so we stop dimming it
        } else {
          // need to stop at 255.
          ledState[ledCtr].brightness = 255;
          ledState[ledCtr].dimrate = 0; // zero dimrate.
        }
        analogWrite(ledCtr, ledState[ledCtr].brightness);
      } 
    }
  }
  
  // Have 60 seconds elapsed? We need to restart if so.
  if (millis() - kickoff > 60000) {
    kickoff = millis();
    sceneCtr = 0;
  }
}

Coding is not my forte, so I have given up thinking about a single code that runs two light patterns. Instead I will be using two arduino boards to control each of my 20 light boxes. One board will run a resting light show that loops continuously while the box is unattended. When a viewer chooses to activate the manual timer the second board will over-ride the first board and display the active light show. Two modes, two boards.

The extra board will bring an added feature that I don't think I could have achieved using a single board. With 20 boxes hanging in a row and all sharing a common 240 volt power feed they will all power up simultaneously. The resting mode can be programmed to produce a light show that is coordinated between the 20 boxes. For instance, if they all carry the same program then they will all carry out the same changes at the same time, but if this code has a delay from box to box then there will be a wave of changes through the series of boxes.

I am making one assumption here, that the timer clock on each arduino board will perform similarly from board to board. Obviously, if one clock runs faster this will compound over time and that board will fall out of step. I am not sure if this will be a problem over short time periods, and in any case the lighting pattern would be able to be reset by simply turning the supply power off and on again. I wonder if I should look into upgrading the timer chip?