Programming problems..

I am an Ma student in Spatial Design that have run into some problems with the programming for this Arduino based project. The piece relays on a set of 20 electromagnets to switch on and off the one after the other with a short overlapping time so that they can hand over magnetic material from one to another.

I am using an Arduino 2560 Mega - 20 electromagnets connected to the 0-19 outputs.

I do not have a great deal of experience with programming so have been given some help. The problem I am having is that the magnet number does not increase - if I do list 0 as the first magnet only this magnet will go on and off - being off during the overlap time. If I don't list 0 as a magnet the magnet connected to output 0 will stay on indefinitely and the magnet connected to output 1 will switch on and off - being off during the overlap time. The rest of the magnets never switch on... I can only assume that the code that is setting 'the next magnet' is wrong. The idea is that the magnet number should increase up till 20 and then reset.

I'll paste the code here, hopefully someone can give me a helping hand..

//////////////////////////////
// initialise all variables.//
//////////////////////////////
int magnets[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; //sets up an array for 20 magnets/pin numbers - for more just ad them to the end.
int currentMagnet = 0; //this is the array number, though the pins start at 1 arrays start at zero... Confusing!!!
int nextMagnet = currentMagnet+1; //sets the next magnet number

// create variabe to track time - must be declared as an unsigned long variable type
unsigned long onDuration = 1000; // this is the duration magnet
unsigned long timeOff; // this is the time at which the magnet should be switched off
unsigned long timeOverlap = 250; // this is the overlap time, when both magnets are on.

///////////////////////////////////////////
//initialise pins and enable first magnet//
///////////////////////////////////////////

void setup () {
//the 'for' section cycles through all the pins and sets them to output and initially turns them all off.
int i;
for (i = 0; i < 19; i = i + 1) { //arrays start on 0 so the < value should be one less than the number of magnets.
// set the pins declared above to output
pinMode(magnets*, OUTPUT);*
//sets each pin to low (off) state
digitalWrite(magnets*, LOW);*
}
// Set the times for the first magnet - starts the process going
digitalWrite(magnets[currentMagnet], HIGH); // turns on the magnet on pin 1 (in this case)
timeOff = millis()+onDuration; // sets the time to turn off the current Magnet
}
/////////////////////////////////////////////////
//start the loop - should continue indefinately//
/////////////////////////////////////////////////
void loop () {
//tests when to switch on the next magnet
if(millis()>=(timeOff-timeOverlap)) { //test the current time to see if it is equal or greater than the current magnet off-time - the overlap.
digitalWrite(magnets[nextMagnet], HIGH); //turns on the next magnet
}
//detects if the current magnet should be switched off
if(millis()>=timeOff) {
digitalWrite(magnets[currentMagnet], LOW); //turns off the current magnet
currentMagnet = nextMagnet; // makes the current magnet now the next magnet
timeOff = millis()+onDuration;
// set the number for the next magnet
nextMagnet = currentMagnet+1;
//to ensure that the magnest cycle, if the nextMagnet value exceeds the number of magnets in the array we need to reset it.
if(nextMagnet=20) {
nextMagnet = 0;
}
}
}
Very much hope that someone can help - I am lost...
/Daniel

Does this work on arrays?
You may need to write this as little for:next loop as you did earlier.

// set the pins declared above to output
pinMode(magnets, OUTPUT);
//sets each pin to low (off) state
digitalWrite(magnets, LOW);

this may stop 1 sooner than you intended.
for (i = 0; i < 19; i = i + 1)

In your following if statement you are using an array name when the pinMode and digitalWrite functions requires a interger pin number variable, not an array name.

So Instead of this:

int i;
for (i = 0; i < 19; i = i + 1) { //arrays start on 0 so the < value should be one less than the number of magnets.
// set the pins declared above to output
pinMode(magnets, OUTPUT);
//sets each pin to low (off) state
digitalWrite(magnets, LOW);
}

Try this:

int i;
for (i = 0; i < 19; i = i + 1) { //arrays start on 0 so the < value should be one less than the number of magnets.
// set the pins declared above to output
pinMode(i, OUTPUT);
//sets each pin to low (off) state
digitalWrite(i, LOW);
}

If the array has the pin number as the value per location, wouldn't this work as well?
for (i = 0; i < 20; i = i + 1) { // locations used are 0-19, yes?
pinMode (magnets*, output);*
digitalWrite(magnets*, LOW);*
}
I would think setting 0, 1 as outputs would cause difficulty trying to download sketches later on.

I would think setting 0, 1 as outputs would cause difficulty trying to download sketches later on.

Most likely, but only because unless he mounts all the magnet driver circuitry on a shield that could be removed prior to uploading a new sketch, I'm sure the FTDI or 8u2 output to the 328p rec pin would have trouble driving the signal due to the 1k isolation resistor between the USB chip and the 328p chip. Once the chip is reset those mode assignments as output pins are no longer applicable, as all pins default back to being input pins and the bootloader code sets pins 0 and 1 as required for serial communications.

Lefty

First of all I want to say thank you for helping out as I'm completely stuck!

First I want to check with you what you think about this change:

In the void loop:

// set the number for the next magnet
nextMagnet = currentMagnet+1;
//to ensure that the magnest cycle, if the nextMagnet value exceeds the number of magnets in the array we need to reset it.
if(nextMagnet==5) {
nextMagnet = 0;

I changed

if(nextMagnet=5) {
nextMagnet = 0;

to

if(nextMagnet==5) {
nextMagnet = 0;

as apparently = is an assignment operator while == is a comparison operator?

Making this change made the magnets connected to pin 0, 1 & 2 work but no more... It doesn't matter how many magnets I set up in the array... If I do set up a greater number of magnets.. the first 3 switches on and off with overlaps as they should... then they do nothing for a while (I assume this is the time during which magnets 3-19, lets say, should switch on) before starting over again.

Should I not use pin output 0 and use 1-20 rather than 0-19 as I set 'int currentMagnet = 0;' ?

Changing 'pinMode(magnets, OUTPUT);' to 'pinMode(i, OUTPUT);' gave no apparent result but the 3 first magnets still worked as before.

Any ideas why only the first 3 work?

What's wrong with
pinMode(magnets[i], OUTPUT);' ?

Can you post your code as it is now, please?

Use the # icon on the editor's toolbar, and paste your code between the tags.

//////////////////////////////
// initialise all variables.//
//////////////////////////////
int magnets[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; //sets up an array for 20 magnets/pin numbers - for more just ad them to the end.
int currentMagnet = 0; //this is the array number, though the pins start at 1 arrays start at zero... Confusing!!!
int nextMagnet = currentMagnet+1; //sets the next magnet number

// create variabe to track time - must be declared as an unsigned long variable type
unsigned long onDuration = 1000; // this is the duration magnet
unsigned long timeOff; // this is the time at which the magnet should be switched off
unsigned long timeOverlap = 250; // this is the overlap time, when both magnets are on.

///////////////////////////////////////////
//initialise pins and enable first magnet//
///////////////////////////////////////////

void setup () {
  //the 'for' section cycles through all the pins and sets them to output and initially turns them all off.
  int i;
  for (i = 0; i < 19; i = i + 1) { //arrays start on 0 so the < value should be one less than the number of magnets.
    // set the pins declared above to output
    pinMode(i, OUTPUT);
    //sets each pin to low (off) state
    digitalWrite(i, LOW);  
  }
  
  // Set the times for the first magnet - starts the process going
  digitalWrite(magnets[currentMagnet], HIGH); // turns on the magnet on pin 1 (in this case)
  timeOff = millis()+onDuration; // sets the time to turn off the current Magnet
}

/////////////////////////////////////////////////
//start the loop - should continue indefinately//
/////////////////////////////////////////////////

void loop () {
  
  //tests when to switch on the next magnet
  if(millis()>=(timeOff-timeOverlap)) { //test the current time to see if it is equal or greater than the current magnet off-time - the overlap. 
     digitalWrite(magnets[nextMagnet], HIGH); //turns on the next magnet
  }
  
  //detects if the current magnet should be switched off
  if(millis()>=timeOff) {
    digitalWrite(magnets[currentMagnet], LOW); //turns off the current magnet
    currentMagnet = nextMagnet; // makes the current magnet now the next magnet
    timeOff = millis()+onDuration;
    
    // set the number for the next magnet
    nextMagnet = currentMagnet+1;
    //to ensure that the magnest cycle, if the nextMagnet value exceeds the number of magnets in the array we need to reset it. 
    if(nextMagnet==20) {
      nextMagnet = 0;
    }
  }    
}

Better would be:

void setup () 
{
  for (int i = 0; i < 20; ++i) {
    pinMode(magnets[i], OUTPUT);
    digitalWrite(magnets[i], LOW);  
  }
digitalWrite(magnets[currentMagnet], HIGH); // turns on the magnet on pin 1 (in this case)

Which is meant to be the case - the code or the comment?

How are you powering all this?

the comment within brackets about this case is just a comment on the code - that in this case (my project) this would happen.

Have got an Arduino 2560 Mega which through 3 transistor arrays connect to 20 relays (5V 2A DPDT) (one for each electromagnet). The Arduino is powered with its 9V Wall Power Adapter. The electromagnets are powered by a separate 80W Power Supply which connects through the relays..

the comment within brackets about this case is just a comment on the code - that in this case (my
project) this would happen.

But "currentMagnet" is initialised to zero, and "magnets [ 0 ]" is pin zero.

Oh sorry!

I see what you mean. That was what I was asking about here earlier.

-Should I not use pin 0 if "CurrentMagnet" is initialised to zero?

I tend to avoid using pins that the serial interface uses, because it limits debug options, but if you must, you must!