Pages: 1 2 [3]   Go Down
Author Topic: Mini Stage Show x 20  (Read 3342 times)
0 Members and 1 Guest are viewing this topic.
Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Dubuque, Iowa, USA
Offline Offline
Edison Member
*
Karma: 30
Posts: 2246
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Grand Rapids, MI, USA
Offline Offline
Sr. Member
****
Karma: 6
Posts: 256
Yes, I remember
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Jroorda for making a very sensible suggestion. I checked out the specs on the USBtinyISP AVR Programmer kit at adafruit:
https://www.adafruit.com/products/46
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.
Logged

Grand Rapids, MI, USA
Offline Offline
Sr. Member
****
Karma: 6
Posts: 256
Yes, I remember
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

https://www.sparkfun.com/products/9046
Logged

Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?



Logged

Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
Code:
#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;
  }
}
Logged

Sydney Australia
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Pages: 1 2 [3]   Go Up
Jump to: