MOSFET Shield Frequency Errors with Multiple Signal Frequencies

Hi,

I'm using this 12 channel MOSFET shield on my Mega to drive 8 of these electromagnets.

I'm switching them on and off at varying duty cycles so that the magnet oscillates and turns the magnetic field on and off at specific frequencies. Each frequency per channel stays the same, i.e., there's no ramp up or down to the desired duty cycle, but each channel uses a different duty cycle. When I turn on a channel individually, it works exactly as intended. When I turn on more than one channel so that each channel has its own duty cycle, it affects the duty cycle of each individual channel.

I put a scope on my board to look at the signal's duty cycle, and the duty cycle is solid, even with all eight channels on the wave looks exactly as it should, so I suspect that it's the hardware. Unfortunately, the unit is on-site at the moment. Otherwise, I'd put the scope on the MOSFET end of things to confirm my suspicion that the MOSFETS interfere with each other when they are driven at the same time.

Does this sound like a familiar issue to anyone?

No, absolutely not but the reason is probably common.

If You want any serious help, provide technical information, links to components, code, wiring diagram.

Links to the parts are listed above, but here they are for clarity:

12 channel MOSFET shield
8 of these electromagnets

I didn't post the code because it is very long, and I've ruled out a code issue. The duty cycle for the signal going to the MOSFETs is showing up on the oscilloscope exactly as expected, regardless of how many pins are activated. It's the output from the FETs that are giving me a problem.

// ---------------------------- WINE_GLASS_RINGER -------------------------
#include <TimerOne.h>
//#define MENU_ON             For debug. Uncomment if you wan the menu to be displayed
//#define DEBUG_REPORT_STATUS
#define DEBUG_REPORT_SERIAL_PARAMS

// ------------------ PIN DEFINITIONS MASKS AND CONSTANTS -----------------

int delayVal = 0;
int randDelay = 100;

long CHANNEL_0_ON_COUNT =  26;
long CHANNEL_1_ON_COUNT =  10;
long CHANNEL_2_ON_COUNT =  35;
long CHANNEL_3_ON_COUNT =  45;    //30
long CHANNEL_4_ON_COUNT =  47;
long CHANNEL_5_ON_COUNT =  23;
long CHANNEL_6_ON_COUNT =  51;    //47  //50
long CHANNEL_7_ON_COUNT =  37;
long CHANNEL_8_ON_COUNT =  55;
long CHANNEL_9_ON_COUNT =  10;
long CHANNEL_10_ON_COUNT =  10;
long CHANNEL_11_ON_COUNT =  10;

long CHANNEL_0_OFF_COUNT =  17;
long CHANNEL_1_OFF_COUNT =  10;
long CHANNEL_2_OFF_COUNT =  16;
long CHANNEL_3_OFF_COUNT =  15;   //31
long CHANNEL_4_OFF_COUNT =  17;
long CHANNEL_5_OFF_COUNT =  25;
long CHANNEL_6_OFF_COUNT =  18;   //18  //19
long CHANNEL_7_OFF_COUNT =  29;
long CHANNEL_8_OFF_COUNT =  25;
long CHANNEL_9_OFF_COUNT =  10;
long CHANNEL_10_OFF_COUNT =  10;
long CHANNEL_11_OFF_COUNT =  10;

const int CHANNEL_0_PIN = 8;
const int CHANNEL_1_PIN = 9;  //problem with mosfet
const int CHANNEL_2_PIN = 10;
const int CHANNEL_3_PIN = 11;
const int CHANNEL_4_PIN = 12;
const int CHANNEL_5_PIN = 13;
const int CHANNEL_6_PIN = 22;
const int CHANNEL_7_PIN = 25;
const int CHANNEL_8_PIN = 26;
const int CHANNEL_9_PIN = 23;
const int CHANNEL_10_PIN = 27;  //problem with mosfet
const int CHANNEL_11_PIN = 24; //problem with mosfet

//CHANNEL ARRAY - USED FOR DEMO
int timer = 100;
int CHANNEL_PIN[] = {
  CHANNEL_0_PIN, CHANNEL_2_PIN, CHANNEL_3_PIN,
  CHANNEL_4_PIN, CHANNEL_5_PIN,  CHANNEL_6_PIN,
  CHANNEL_7_PIN, CHANNEL_8_PIN
};
int pinCount = 8;

int CHANNEL_0_CYCLE_COUNT = 0;
int CHANNEL_2_CYCLE_COUNT = 0;
int CHANNEL_3_CYCLE_COUNT = 0;
int CHANNEL_4_CYCLE_COUNT = 0;
int CHANNEL_5_CYCLE_COUNT = 0;
int CHANNEL_6_CYCLE_COUNT = 0;
int CHANNEL_7_CYCLE_COUNT = 0;
int CHANNEL_8_CYCLE_COUNT = 0;

boolean CHANNEL_0_FLICKED = false;
boolean CHANNEL_2_FLICKED = false;
boolean CHANNEL_3_FLICKED = false;
boolean CHANNEL_4_FLICKED = false;
boolean CHANNEL_5_FLICKED = false;
boolean CHANNEL_6_FLICKED = false;
boolean CHANNEL_7_FLICKED = false;
boolean CHANNEL_8_FLICKED = false;

long CHANNEL_0_FLICK_TIME = 200;
long CHANNEL_2_FLICK_TIME = 200;
long CHANNEL_3_FLICK_TIME = 200;
long CHANNEL_4_FLICK_TIME = 200;
long CHANNEL_5_FLICK_TIME = 200;
long CHANNEL_6_FLICK_TIME = 200;
long CHANNEL_7_FLICK_TIME = 200;
long CHANNEL_8_FLICK_TIME = 200;

boolean CHANNEL_0_FLICK_FLAG = false;
boolean CHANNEL_2_FLICK_FLAG = false;
boolean CHANNEL_3_FLICK_FLAG = false;
boolean CHANNEL_4_FLICK_FLAG = false;
boolean CHANNEL_5_FLICK_FLAG = false;
boolean CHANNEL_6_FLICK_FLAG = false;
boolean CHANNEL_7_FLICK_FLAG = false;
boolean CHANNEL_8_FLICK_FLAG = false;



const int TIMING_TEST_PIN = 50;

boolean CHANNEL_0_PIN_STATE = false;
boolean CHANNEL_1_PIN_STATE = false;
boolean CHANNEL_2_PIN_STATE = false;
boolean CHANNEL_3_PIN_STATE = false;
boolean CHANNEL_4_PIN_STATE = false;
boolean CHANNEL_5_PIN_STATE = false;
boolean CHANNEL_6_PIN_STATE = false;
boolean CHANNEL_7_PIN_STATE = false;
boolean CHANNEL_8_PIN_STATE = false;
boolean CHANNEL_9_PIN_STATE = false;
boolean CHANNEL_10_PIN_STATE = false;
boolean CHANNEL_11_PIN_STATE = false;

boolean TIMING_TEST_PIN_STATE = false;



String CHANNEL_PORT[12];
byte PORTA_STATE;
byte PORTH_STATE;
byte PORTE_STATE;
byte PORTG_STATE;



// ------------------------ COMMUNICATION VARIABLES --------------------------
String inputString = "";                          // a string to hold incoming data
boolean stringComplete = false;                   // whether the string is complete
char COMMAND = ' ';                               // Command from serial input
unsigned int  COMMAND_PARAMETER = 0;                      // Command Parameter from serial input

const char SET_ON_TIME_COMMAND = 'O';                         // O for (O)n
const char SET_OFF_TIME_COMMAND = 'F';                        // F of(F) time
const char SET_ON_TIME_COMMAND_ALL_CHANNELS = 'X';            // X for ??????
const char SET_OFF_TIME_COMMAND_ALL_CHANNELS = 'Z';           // Z for ?????
const char RUN_CHANNEL_COMMAND = 'R';                         // R (R)un one channel
const char STOP_CHANNEL_COMMAND = 'S';                        // S (S)top one channel
const char RUN_ALL_CHANNELS_COMMAND = 'C';                    // C Run all (C)hannels
const char STOP_ALL_CHANNELS_COMMAND = 'T';                   // T s(T)op all channels
const char QUERY_STATUS_OF_ALL_CHANNELS_COMMAND = 'Q';        // Q for (Q)uery. Returns status of all channels seperated by commas
const char PRINT_MENU = 'M';                                  // M Send a list of these commands to the serial port
/*
  QUERY_STATUS_OF_ALL_CHANNELS_COMMAND returns the following
  Channel #,On time,Off time,Running\n
  example
  Channel 1 on time = 4000 usec.  Off time - 40000 usec.   Is running
  01,4000,40000,O\n

  Channel 1 on time = 4000 usec.  Off time - 40000 usec.   Is not unning
  01,4000,40000,F\n
*/

int COMMAND_STRING_COUNT = 0;
int CHANNEL_STRING_COUNT = 0;

char COMMAND_STRING_CHAR = ' ';
String PARAMETER_STRING = "";
String CMD_STRING = "";
unsigned int CHANNEL = 0;
boolean COMMAND_STRING_IS_VALID = false;

/*
  STRINGS FORM THE SERIAL PORT TAKE THE FOLLOWING FORM

  First character = a command

    SET_ON_TIME_COMMAND = 'O';                         // O for (O)n
    SET_OFF_TIME_COMMAND = 'F';                        // F of(F) time
    SET_ON_TIME_COMMAND_ALL_CHANNELS = 'X';            // X for ??????
    SET_OFF_TIME_COMMAND_ALL_CHANNELS = 'Z';           // Z for ?????
    RUN_CHANNEL_COMMAND = 'R';                         // R (R)un one channel
    STOP_CHANNEL_COMMAND = 'S';                        // S (S)top one channel
    RUN_ALL_CHANNELS_COMMAND = 'C';                    // C Run all (C)hannels
    STOP_ALL_CHANNELS_COMMAND = 'T';                   // T s(T)op all channels
    QUERY_STATUS_OF_ALL_CHANNELS_COMMAND = 'Q';        // Q for (Q)uery. Returns status of all channel

  Second and third characters = hannel number 00 to 11

    Must be two characters i.e. Channel 2 = 02
    NOTE: Not all commands take the channel parameter see note below.

  Third to nth character

    Time Parameter

    On Time in msec.
    Off Time in msec.
    NOTE: Not all commands take the time parameter see note below.

    NOTES:
    The (R)un channel command,  S (S)top one channel, take the channel parameter but no time parameter.

    The C Run all (C)hannels, T s(T)op all channels, and Q for (Q)uery take neither channel nor time parameters.

    Command script strings must be followed by ‘\n’

  Examples:

    Set Channel 9 Off time to 3000 usec (3 msec).
    F093000\n

    Set Channel 10 On time to 1000000 usec. (1 sec).
    O101000000\n

    Run channel 7
    R07\n

    Run all channels
    C\n

    Stop all channels

    T\n

    NOTE: If you did not set the timing, the channel runs with the default parameters. Currently
    ON_TIME[CH] = 1000;                                   // On time = 1000 usec.
    OFF_TIME[CH] = 1000;                                  // Off time = 1000 usec.

    Query status of all channels

    Q\n

    QUERY_STATUS_OF_ALL_CHANNELS_COMMAND returns the following
    Channel #,On time,Off time,Running\n
    example
    Send Q\n
    00,4
    Channel 1 on time = 4000 usec.  Off time - 40000 usec.   Is running
    01,4000,40000,O\n

    Channel 1 on time = 4000 usec.  Off time - 40000 usec.   Is not running
    01,4000,40000,F\n
*/


// ---------------------- TIMER VARIABLES AND CONSTANTS -------------------------------

// ********* NOTE:  ALL TIMES EVERYWHERE IN THIS PROGRAM ARE IN MILLUSECONDS *********

// ---------------- FET DRIVE TIMING VARIABLES AND CONSTANTS ---------------------------

long CHANNEL_0_ON_COUNTER = 0;
long CHANNEL_1_ON_COUNTER = 0;
long CHANNEL_2_ON_COUNTER = 0;
long CHANNEL_3_ON_COUNTER = 0;
long CHANNEL_4_ON_COUNTER = 0;
long CHANNEL_5_ON_COUNTER = 0;
long CHANNEL_6_ON_COUNTER = 0;
long CHANNEL_7_ON_COUNTER = 0;
long CHANNEL_8_ON_COUNTER = 0;
long CHANNEL_9_ON_COUNTER = 0;
long CHANNEL_10_ON_COUNTER = 0;
long CHANNEL_11_ON_COUNTER = 0;

long CHANNEL_0_OFF_COUNTER = 0;
long CHANNEL_1_OFF_COUNTER = 0;
long CHANNEL_2_OFF_COUNTER = 0;
long CHANNEL_3_OFF_COUNTER = 0;
long CHANNEL_4_OFF_COUNTER = 0;
long CHANNEL_5_OFF_COUNTER = 0;
long CHANNEL_6_OFF_COUNTER = 0;
long CHANNEL_7_OFF_COUNTER = 0;
long CHANNEL_8_OFF_COUNTER = 0;
long CHANNEL_9_OFF_COUNTER = 0;
long CHANNEL_10_OFF_COUNTER = 0;
long CHANNEL_11_OFF_COUNTER = 0;

const byte  CHANNEL_MASK_0 =  B00100000;     //PE5 BIT MASK   B00100000
const byte  CHANNEL_MASK_1 =  B00100000;     //PG5 BIT MASK   B00100000
const byte  CHANNEL_MASK_2 =  B00001000;     //PE3 BIT MASK   B00001000
const byte  CHANNEL_MASK_3 =  B00001000;     //PH3 BIT MASK   B00001000
const byte  CHANNEL_MASK_4 =  B00010000;     //PH4 BIT MASK   B00010000
const byte  CHANNEL_MASK_5 =  B00100000;     //PH5 BIT MASK   B00100000
const byte  CHANNEL_MASK_6 =  B00000001;     //PA0 BIT MASK   B00000001
const byte  CHANNEL_MASK_7 =  B00000010;     //PA1 BIT MASK   B00000010
const byte  CHANNEL_MASK_8 =  B00000100;     //PA2 BIT MASK   B00000100
const byte  CHANNEL_MASK_9 =  B00001000;     //PA3 BIT MASK   B00001000
const byte  CHANNEL_MASK_10 = B00010000;     //PA4 BIT MASK   B00100000
const byte  CHANNEL_MASK_11 = B00100000;     //PA5 BIT MASK   B01000000

boolean CHANNEL_0_ON_FLAG  = false;
boolean CHANNEL_1_ON_FLAG  = false;
boolean CHANNEL_2_ON_FLAG  = false;
boolean CHANNEL_3_ON_FLAG  = false;
boolean CHANNEL_4_ON_FLAG  = false;
boolean CHANNEL_5_ON_FLAG  = false;
boolean CHANNEL_6_ON_FLAG  = false;
boolean CHANNEL_7_ON_FLAG  = false;
boolean CHANNEL_8_ON_FLAG  = false;
boolean CHANNEL_9_ON_FLAG  = false;
boolean CHANNEL_10_ON_FLAG  = false;
boolean CHANNEL_11_ON_FLAG  = false;

boolean CHANNEL_0_HIGH_FLAG  = false;
boolean CHANNEL_1_HIGH_FLAG  = false;
boolean CHANNEL_2_HIGH_FLAG  = false;
boolean CHANNEL_3_HIGH_FLAG  = false;
boolean CHANNEL_4_HIGH_FLAG  = false;
boolean CHANNEL_5_HIGH_FLAG  = false;
boolean CHANNEL_6_HIGH_FLAG  = false;
boolean CHANNEL_7_HIGH_FLAG  = false;
boolean CHANNEL_8_HIGH_FLAG  = false;
boolean CHANNEL_9_HIGH_FLAG  = false;
boolean CHANNEL_10_HIGH_FLAG  = false;
boolean CHANNEL_11_HIGH_FLAG  = false;

boolean CHANNEL_0_GO_HIGH_FLAG  = false;
boolean CHANNEL_1_GO_HIGH_FLAG  = false;
boolean CHANNEL_2_GO_HIGH_FLAG  = false;
boolean CHANNEL_3_GO_HIGH_FLAG  = false;
boolean CHANNEL_4_GO_HIGH_FLAG  = false;
boolean CHANNEL_5_GO_HIGH_FLAG  = false;
boolean CHANNEL_6_GO_HIGH_FLAG  = false;
boolean CHANNEL_7_GO_HIGH_FLAG  = false;
boolean CHANNEL_8_GO_HIGH_FLAG  = false;
boolean CHANNEL_9_GO_HIGH_FLAG  = false;
boolean CHANNEL_10_GO_HIGH_FLAG  = false;
boolean CHANNEL_11_GO_HIGH_FLAG  = false;

boolean CHANNEL_0_GO_LOW_FLAG  = false;
boolean CHANNEL_1_GO_LOW_FLAG  = false;
boolean CHANNEL_2_GO_LOW_FLAG  = false;
boolean CHANNEL_3_GO_LOW_FLAG  = false;
boolean CHANNEL_4_GO_LOW_FLAG  = false;
boolean CHANNEL_5_GO_LOW_FLAG  = false;
boolean CHANNEL_6_GO_LOW_FLAG  = false;
boolean CHANNEL_7_GO_LOW_FLAG  = false;
boolean CHANNEL_8_GO_LOW_FLAG  = false;
boolean CHANNEL_9_GO_LOW_FLAG  = false;
boolean CHANNEL_10_GO_LOW_FLAG  = false;
boolean CHANNEL_11_GO_LOW_FLAG  = false;

boolean demo = false;
boolean demoB = true;

String CHANNEL_STRING = "";
boolean PARSE_COMMAND (String COMMAND_STRING)
{
  /*
    Get the command, channel, and time parameter form the serial input string.
    Channel number 00 to 11     Must be two characters i.e. Channel 2 = 02
    NOTE: Not all commands take the channel parameter see note below.
    NOTE: Not all commands take the time parameter see note below.
    The (R)un channel command, S (S)top one channel, take only the channel parameter but no time parameter.
    The C Run all (C)hannels, T s(T)op all channels, and the Q for (Q)uery commands take neither channel
    nor time parameters.
  */

  COMMAND = COMMAND_STRING[0];                // First character is always COMMAND

  if (COMMAND == 'D') {
    Serial.println("EXECUTED DEMO KNIGHT_RIDER");
    demo = !demo;
  }
  if (COMMAND == 'B') {
    Serial.println("EXECUTED DEMO B");
    demoB = !demoB;



    if (demoB == false) {
      CHANNEL_0_ON_FLAG  = false;
      CHANNEL_1_ON_FLAG  = false;
      CHANNEL_2_ON_FLAG  = false;
      CHANNEL_3_ON_FLAG  = false;
      CHANNEL_4_ON_FLAG  = false;
      CHANNEL_5_ON_FLAG  = false;
      CHANNEL_6_ON_FLAG  = false;
      CHANNEL_7_ON_FLAG  = false;
      CHANNEL_8_ON_FLAG  = false;
      CHANNEL_9_ON_FLAG  = false;
      CHANNEL_10_ON_FLAG  = false;
      CHANNEL_11_ON_FLAG  = false;
      for (int thisPin = 0; thisPin < pinCount; thisPin++) {
        digitalWrite(CHANNEL_PIN[thisPin], LOW);
      }
    }
  }




  // Serial.println(COMMAND);
  //  -----------------------  Check for valid commands -------------------------------
  //
  //   if ((COMMAND != 'O') && (COMMAND != 'F') && (COMMAND != 'X') && (COMMAND != 'Z') && (COMMAND != 'R')
  //        && (COMMAND != 'S') && (COMMAND != 'C') && (COMMAND != 'T') && (COMMAND != 'Q')&& (COMMAND != 'M'))
  //    {
  //      Serial.print(F("Invalid Command     "));
  //      Serial.print(F("Command recieved was: "));
  //      Serial.println(COMMAND);
  //      Serial.println(F("Valid commands are: O, F, X, Z, R, S, C, T, Q and M"));
  //      Serial.println(F("********* ALL COMMANDS MUST BE IN CAPS ************"));
  //      COMMAND_STRING_IS_VALID = false;
  //      return (false);
  //    }// end if(!((COMMAND != 'O') || (COMMAND != 'F') || (COMMAND !='X') || (COMMAND !='Z') || (COMMAND !='R')
  //|| (COMMAND != 'S') || (COMMAND != 'C') || (COMMAND !='T') || (COMMAND !='Q')))

  //  //  --------  Check for proper length of commands which take parameters. ---------------
  //  //  This means COMMAND + CHANNEL + at least on COMMAND_PARAMETER digit (zero based)
  //  if ((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND == 'X') || (COMMAND == 'Z'))
  //  {
  //    Serial.println(COMMAND_STRING);
  //    int sl = COMMAND_STRING.length();
  //    Serial.println(sl);
  //    if (!(COMMAND_STRING.length() >= 5))  // (zero based)
  //    {
  //      Serial.println(F("Serial input string is to short.  Must be at least 4 characters"));
  //      Serial.println(F("for commands O, F, X, and Z"));
  //      return (false);
  //    }
  //  }


  //  if ((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND == 'R') || (COMMAND == 'S'))
  //  // These commands take a channel parameter
  //  {
  ////  CHANNEL_STRING = "";
  //    CHANNEL = 0;
  //    int CS_COUNT = 0;
  //    for (int STRING_COUNT = 1; STRING_COUNT < 3; STRING_COUNT++)
  //    {
  //      CHANNEL_STRING[CS_COUNT] =  COMMAND_STRING[STRING_COUNT];
  //      Serial.println(COMMAND_STRING[STRING_COUNT]);
  //      Serial.println(CHANNEL_STRING[CS_COUNT]);
  //      CS_COUNT++;
  //    }
  //  }// end  if((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND =='R') || (COMMAND == 'S'))
  ////
  //  CHANNEL_STRING += '\n';
  //  Serial.print(F("CHANNEL_STRING: "));
  //  Serial.println(CHANNEL_STRING);
  //delay(1000);
  //  CHANNEL = atoi(CHANNEL_STRING);
  //  Serial.print(F(" Channel "));
  //  Serial.println(CHANNEL);

  // if ((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND == 'R') || (COMMAND == 'S'))
  //  // These commands take a channel parameter
  //  {
  CHANNEL = 0;
  CHANNEL_STRING = "";
  COMMAND_STRING_COUNT = 1;
  while (COMMAND_STRING[COMMAND_STRING_COUNT] != '\n')
  {
    if (COMMAND_STRING_COUNT < 3)
    {
      CHANNEL_STRING += COMMAND_STRING[COMMAND_STRING_COUNT];
    }
    COMMAND_STRING_COUNT++;
  }
  //
  //  }// end  if((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND =='R') || (COMMAND == 'S'))
  //
  //  CHANNEL_STRING += '\n';
  //  Serial.print(F("CHANNEL_STRING: "));
  //  Serial.println(CHANNEL_STRING);
  CHANNEL = CHANNEL_STRING.toInt();
  //  Serial.print(F(" Channel "));
  //  Serial.println(CHANNEL);




  //-----------------  Check for channel in range ---------------------
  //  if (!((CHANNEL >= 0) && (CHANNEL <= 11)))
  //  {
  //    Serial.println(F(" Channel is not valid"));
  //    Serial.println(F(" Must be in range 0 - 11"));
  //    COMMAND_STRING_IS_VALID = false;
  //    return (false);
  //  }
  PARAMETER_STRING = "";
  // if ((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND == 'X') || (COMMAND == 'Z'))  // These are the commands that take a time parameter
  // {
  COMMAND_STRING_COUNT = 3;
  while (COMMAND_STRING[COMMAND_STRING_COUNT] != '\n')
  {
    PARAMETER_STRING += COMMAND_STRING[COMMAND_STRING_COUNT];
    ////      if (! (isDigit(COMMAND_STRING[COMMAND_STRING_COUNT])))
    ////      {
    ////        Serial.println(F("Time parameter is not a number"));
    ////        COMMAND_STRING_IS_VALID = false;
    ////        return (false);
    ////      }
    COMMAND_STRING_COUNT ++;
  }// end while(COMMAND_STRING[COMMAND_STRING_COUNT] != '\n')
  //  }// end if((COMMAND = 'O') || (COMMAND != 'F') || (COMMAND !='X') || (COMMAND !='Z'))
  COMMAND_PARAMETER = PARAMETER_STRING.toInt();
  //  Serial.println(COMMAND_PARAMETER);



  if ( (COMMAND == 'X') || (COMMAND == 'Z') ) {
    PARAMETER_STRING = "";
    // if ((COMMAND == 'O') || (COMMAND == 'F') || (COMMAND == 'X') || (COMMAND == 'Z'))  // These are the commands that take a time parameter
    // {
    COMMAND_STRING_COUNT = 1;
    while (COMMAND_STRING[COMMAND_STRING_COUNT] != '\n')
    {
      PARAMETER_STRING += COMMAND_STRING[COMMAND_STRING_COUNT];
      ////      if (! (isDigit(COMMAND_STRING[COMMAND_STRING_COUNT])))
      ////      {
      ////        Serial.println(F("Time parameter is not a number"));
      ////        COMMAND_STRING_IS_VALID = false;
      ////        return (false);
      ////      }
      COMMAND_STRING_COUNT ++;
    }// end while(COMMAND_STRING[COMMAND_STRING_COUNT] != '\n')
    //  }// end if((COMMAND = 'O') || (COMMAND != 'F') || (COMMAND !='X') || (COMMAND !='Z'))
    COMMAND_PARAMETER = PARAMETER_STRING.toInt();
    //      Serial.println(COMMAND_PARAMETER);
  }


  return (true);
}//end void PARSE_COMMAND (String COMMAND_STRING)

void ON_TIME_ISR(void)
// Interrupt service routine.  Fires every 1 msec.
// On time and off time counters are incremented here.
// They are updated whether a channel is running or not.
{
  TIMING_TEST_PIN_STATE = !TIMING_TEST_PIN_STATE;
  digitalWrite(TIMING_TEST_PIN, TIMING_TEST_PIN_STATE);
  if (CHANNEL_0_PIN_STATE)
  {
    CHANNEL_0_ON_COUNTER++;
  }
  else
  {
    CHANNEL_0_OFF_COUNTER++;
  }

  if (CHANNEL_1_PIN_STATE)
  {
    CHANNEL_1_ON_COUNTER++;
  }
  else
  {
    CHANNEL_1_OFF_COUNTER++;
  }

  if (CHANNEL_2_PIN_STATE)
  {
    CHANNEL_2_ON_COUNTER++;
  }
  else
  {
    CHANNEL_2_OFF_COUNTER++;
  }

  if (CHANNEL_3_PIN_STATE)
  {
    CHANNEL_3_ON_COUNTER++;
  }
  else
  {
    CHANNEL_3_OFF_COUNTER++;
  }

  if (CHANNEL_4_PIN_STATE)
  {
    CHANNEL_4_ON_COUNTER++;
  }
  else
  {
    CHANNEL_4_OFF_COUNTER++;
  }

  if (CHANNEL_5_PIN_STATE)
  {
    CHANNEL_5_ON_COUNTER++;
  }
  else
  {
    CHANNEL_5_OFF_COUNTER++;
  }

  if (CHANNEL_6_PIN_STATE)
  {
    CHANNEL_6_ON_COUNTER++;
  }
  else
  {
    CHANNEL_6_OFF_COUNTER++;
  }

  if (CHANNEL_7_PIN_STATE)
  {
    CHANNEL_7_ON_COUNTER++;
  }
  else
  {
    CHANNEL_7_OFF_COUNTER++;
  }

  if (CHANNEL_8_PIN_STATE)
  {
    CHANNEL_8_ON_COUNTER++;
  }
  else
  {
    CHANNEL_8_OFF_COUNTER++;
  }

  if (CHANNEL_9_PIN_STATE)
  {
    CHANNEL_9_ON_COUNTER++;
  }
  else
  {
    CHANNEL_9_OFF_COUNTER++;
  }

  if (CHANNEL_10_PIN_STATE)
  {
    CHANNEL_10_ON_COUNTER++;
  }
  else
  {
    CHANNEL_10_OFF_COUNTER++;
  }

  if (CHANNEL_11_PIN_STATE)
  {
    CHANNEL_11_ON_COUNTER++;
  }
  else
  {
    CHANNEL_11_OFF_COUNTER++;
  }

  TIMING_TEST_PIN_STATE = !TIMING_TEST_PIN_STATE;
  digitalWrite(TIMING_TEST_PIN, TIMING_TEST_PIN_STATE);
}// end void ON_TIME_ISR(void)


//------------------------------ Setup ------------------------------------
void setup()
{

  inputString.reserve(50);
  PARAMETER_STRING.reserve(50);

  // The Baked MOSFET Shield V is a shield for the Arduino Mega and Duo layout. It has 2 MOSFETs
  // on pins 8-3 (pwm) and 22-27(digital). This board also breaks out pins 2-7, 6-2, 28-33, and A0-A5
  // to a screw down terminal along the outside of the board. Pins 28-33 have space for optional Pull-up
  // or Pull-down resistors. The N-channel MOSFETs installed on this board allow for the users to be able
  // to switch on and off DC motors, LEDs or other devices that operate at a voltages different then the
  // arduous 5VDC or at an amperage greater than what the Arduino can handle on its own.

  PORTA_STATE = 0x00;
  PORTH_STATE = 0x00;
  PORTE_STATE = 0x00;
  PORTG_STATE = 0x00;
  //  DDRA = 0xFF;
  //  DDRH = 0xFF;
  //  DDRE = 0xFF;
  //  DDRG = 0xFF;
  //  PORTA = PORTA_STATE;
  //  PORTH = PORTH_STATE;
  //  PORTE = PORTE_STATE;
  //  PORTG = PORTG_STATE;


  pinMode(CHANNEL_0_PIN, OUTPUT);
  pinMode(CHANNEL_2_PIN, OUTPUT);
  pinMode(CHANNEL_3_PIN, OUTPUT);
  pinMode(CHANNEL_4_PIN, OUTPUT);
  pinMode(CHANNEL_5_PIN, OUTPUT);
  pinMode(CHANNEL_6_PIN, OUTPUT);
  pinMode(CHANNEL_7_PIN, OUTPUT);
  pinMode(CHANNEL_8_PIN, OUTPUT);
  pinMode(CHANNEL_9_PIN, OUTPUT);
  pinMode(CHANNEL_10_PIN, OUTPUT);
  pinMode(CHANNEL_11_PIN, OUTPUT);

  pinMode(TIMING_TEST_PIN, OUTPUT);

  digitalWrite(CHANNEL_0_PIN, CHANNEL_0_PIN_STATE);
  digitalWrite(CHANNEL_1_PIN, CHANNEL_1_PIN_STATE);
  digitalWrite(CHANNEL_2_PIN, CHANNEL_2_PIN_STATE);
  digitalWrite(CHANNEL_3_PIN, CHANNEL_3_PIN_STATE);
  digitalWrite(CHANNEL_4_PIN, CHANNEL_4_PIN_STATE);
  digitalWrite(CHANNEL_5_PIN, CHANNEL_5_PIN_STATE);
  digitalWrite(CHANNEL_6_PIN, CHANNEL_6_PIN_STATE);
  digitalWrite(CHANNEL_7_PIN, CHANNEL_7_PIN_STATE);
  digitalWrite(CHANNEL_8_PIN, CHANNEL_8_PIN_STATE);
  digitalWrite(CHANNEL_9_PIN, CHANNEL_9_PIN_STATE);
  digitalWrite(CHANNEL_10_PIN, CHANNEL_10_PIN_STATE);
  digitalWrite(CHANNEL_11_PIN, CHANNEL_11_PIN_STATE);

  Timer1.initialize(1000);       // 1 msec
  Timer1.attachInterrupt(ON_TIME_ISR);
  // initialize serial:
  Serial.begin(9600);
  delay(500);

  randomSeed(analogRead(A3));

  Serial.println(F("SETUP"));
  Serial.println(F("SET_ON_TIME_COMMAND = 'O'"));                       // O for O(N)
  Serial.println(F("SET_OFF_TIME_COMMAND = 'F'"));                      // F of(F) time
  Serial.println(F("SET_ON_TIME_COMMAND_ALL_CHANNELS = 'X'"));          //  X for ???
  Serial.println(F("SET_OFF_TIME_COMMAND_ALL_CHANNELS = 'Z'"));          // Z for ???
  Serial.println(F("RUN_CHANNEL_COMMAND = 'R'"));                        // R (R)un one channel
  Serial.println(F("STOP_CHANNEL_COMMAND = 'S'"));                       // S (S)top one channel
  Serial.println(F("RUN_ALL_CHANNELS_COMMAND = 'C'"));                   // C Run all (C)hannels
  Serial.println(F("STOP_ALL_CHANNELS_COMMAND = 'T'"));                  // T S(T)op all channels
  Serial.println(F("QUERY_STATUS_OF_ALL_CHANNELS_COMMAND = 'Q'"));       // Q Query. Returns status of all channels sepe
  Serial.println(F("TURN ON/OFF DEMO MODE = 'D'"));       // Q Query. Returns status of all channels sepe
  Serial.println(F("DISPLAY THIS MENU 'M'"));
  //COMMAND = 'S';
  //CHANNEL = 0;
  //COMMAND_PARAMETER = 100;

  //  shuffle();
  //  shuffle();
  //  shuffle();
  //  delay(88888888888888888888888888888888888);
}// end setup

int i = 0;
int y = 0;

long prevShuffleTime = 0;

String outputString;
// ---------------------------------- Main Loop --------------------------------
void loop()
{

  //  if (millis() > 2000 && i == 0) {
  //    i = 1;
  //    inputString = "D\n";
  //    stringComplete = true;
  //    Serial.print(inputString);
  //  }

  //  while (millis() < 10000000000000000000000000000) {
  //    shuffle();
  //  }



  // ------------------------------ Serial Loop --------------------------------
  // serialEvent() builds a null terminated string (inputString) as a global variable and asserts
  // stringComplete = true when a '\n' is read.  stringComplete allows entrance to the serial loop
  // where the string is parsed and cammands are reacted to.

  if (stringComplete)
  {
    //    REPORT_STATUS();

    if (PARSE_COMMAND(inputString))
    {

      //    Serial.print(F("inputString: "));
      //    Serial.print(inputString);
      //    Serial.print(F("COMMAND: "));
      //    Serial.println(COMMAND);
      //    Serial.print(F("CHANNEL: "));
      //    Serial.println(CHANNEL);
      //    Serial.print(F("COMMAND_PARAMETER: "));
      //    Serial.println(COMMAND_PARAMETER);

      switch (COMMAND)
      {
        case SET_ON_TIME_COMMAND:
          {
            Serial.print(F("EXECUTED SET_ON_TIME_COMMAND "));
            Serial.print(F("FOR CHANNEL "));
            Serial.println(CHANNEL);
            switch (CHANNEL)
            {
              case 0:
                CHANNEL_0_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 1:
                CHANNEL_1_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 2:
                CHANNEL_2_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 3:
                CHANNEL_3_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 4:
                CHANNEL_4_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 5:
                CHANNEL_5_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 6:
                CHANNEL_6_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 7:
                CHANNEL_7_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 8:
                CHANNEL_8_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 9:
                CHANNEL_9_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 10:
                CHANNEL_10_ON_COUNT = COMMAND_PARAMETER;
                break;
              case 11:
                CHANNEL_11_ON_COUNT = COMMAND_PARAMETER;
                break;
            }// end switch (CHANNEL)
          }// end case SET_ON_TIME_COMMAND:
          break;

        case SET_OFF_TIME_COMMAND:
          {
            Serial.print(F("EXECUTED SET_OFF_TIME_COMMAND "));
            Serial.print(F("FOR CHANNEL "));
            Serial.println(CHANNEL);
            switch (CHANNEL)
            {
              case 0:
                CHANNEL_0_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 1:
                CHANNEL_1_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 2:
                CHANNEL_2_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 3:
                CHANNEL_3_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 4:
                CHANNEL_4_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 5:
                CHANNEL_5_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 6:
                CHANNEL_6_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 7:
                CHANNEL_7_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 8:
                CHANNEL_8_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 9:
                CHANNEL_9_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 10:
                CHANNEL_10_OFF_COUNT = COMMAND_PARAMETER;
                break;
              case 11:
                CHANNEL_11_OFF_COUNT = COMMAND_PARAMETER;
                break;
            }// end switch (CHANNEL)
          }// end case SET_OFF_TIME_COMMAND:
          break;

        case SET_ON_TIME_COMMAND_ALL_CHANNELS:
          {
            Serial.println(F("EXECUTED SET_ON_TIME_COMMAND_ALL_CHANNELS "));
            CHANNEL_0_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_1_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_2_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_3_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_4_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_5_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_6_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_7_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_8_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_9_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_10_ON_COUNT = COMMAND_PARAMETER;
            CHANNEL_11_ON_COUNT = COMMAND_PARAMETER;
          }
          break;

        case SET_OFF_TIME_COMMAND_ALL_CHANNELS:
          {
            Serial.println(F("EXECUTED SET_OFF_TIME_COMMAND_ALL_CHANNELS "));
            CHANNEL_0_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_1_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_2_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_3_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_4_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_5_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_6_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_7_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_8_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_9_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_10_OFF_COUNT = COMMAND_PARAMETER;
            CHANNEL_11_OFF_COUNT = COMMAND_PARAMETER;
          }
          break;

        case RUN_CHANNEL_COMMAND:
          {
            Serial.print(F("EXECUTED RUN_CHANNEL_COMMAND "));
            Serial.print(F("CHANNEL "));
            Serial.println(CHANNEL);

            if (CHANNEL == 0)
            {
              CHANNEL_0_ON_FLAG  = true;
              //              CHANNEL_0_ON_COUNTER = 0;
              //              CHANNEL_0_OFF_COUNTER = 0;
              CHANNEL_0_FLICK_FLAG = true;
              CHANNEL_0_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 1)
            {
              CHANNEL_1_ON_FLAG  = true;
              //              CHANNEL_1_ON_COUNTER = 0;
              //              CHANNEL_1_OFF_COUNTER = 0;
              //              CHANNEL_1_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 2)
            {
              CHANNEL_2_ON_FLAG  = true;
              //              CHANNEL_2_ON_COUNTER = 0;
              //              CHANNEL_2_OFF_COUNTER = 0;
              //              CHANNEL_1_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 3)
            {
              CHANNEL_3_ON_FLAG  = true;
              //              CHANNEL_3_ON_COUNTER = 0;
              //              CHANNEL_3_OFF_COUNTER = 0;
              CHANNEL_3_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 4)
            {
              CHANNEL_4_ON_FLAG  = true;
              //              CHANNEL_4_ON_COUNTER = 0;
              //              CHANNEL_4_OFF_COUNTER = 0;
              CHANNEL_4_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 5)
            {
              CHANNEL_5_ON_FLAG  = true;
              //              CHANNEL_5_ON_COUNTER = 0;
              //              CHANNEL_5_OFF_COUNTER = 0;
              CHANNEL_5_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 6)
            {
              CHANNEL_6_ON_FLAG  = true;
              //              CHANNEL_6_ON_COUNTER = 0;
              //              CHANNEL_6_OFF_COUNTER = 0;
              CHANNEL_6_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 7)
            {
              CHANNEL_7_ON_FLAG  = true;
              //              CHANNEL_7_ON_COUNTER = 0;
              //              CHANNEL_7_OFF_COUNTER = 0;
              CHANNEL_7_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 8)
            {
              CHANNEL_8_ON_FLAG  = true;
              //              CHANNEL_8_ON_COUNTER = 0;
              //              CHANNEL_8_OFF_COUNTER = 0;
              CHANNEL_8_CYCLE_COUNT = 0;
            }
            else if (CHANNEL == 9)
            {
              CHANNEL_9_ON_FLAG  = true;
              //              CHANNEL_9_ON_COUNTER = 0;
              //              CHANNEL_9_OFF_COUNTER = 0;
            }
            else if (CHANNEL == 10)
            {
              CHANNEL_10_ON_FLAG  = true;
              //              CHANNEL_10_ON_COUNTER = 0;
              //              CHANNEL_10_OFF_COUNTER = 0;
            }
            else if (CHANNEL == 11)
            {
              CHANNEL_11_ON_FLAG  = true;
              //              CHANNEL_11_ON_COUNTER = 0;
              //              CHANNEL_11_OFF_COUNTER = 0;
            }


          }// end case RUN_CHANNEL_COMMAND:
          break;

        case STOP_CHANNEL_COMMAND:
          {
            Serial.print(F("EXECUTED STOP_CHANNEL_COMMAND "));
            Serial.print(F("FOR CHANNEL "));
            Serial.println(CHANNEL);
            if (CHANNEL == 0)
            {
              CHANNEL_0_ON_FLAG  = false;
              digitalWrite(CHANNEL_0_PIN, LOW);
            }
            else if (CHANNEL == 1)
            {
              CHANNEL_1_ON_FLAG  = false;
              digitalWrite(CHANNEL_1_PIN, LOW);
            }
            else if (CHANNEL == 2)
            {
              CHANNEL_2_ON_FLAG  = false;
              digitalWrite(CHANNEL_2_PIN, LOW);
            }
            else if (CHANNEL == 3)
            {
              CHANNEL_3_ON_FLAG  = false;
              digitalWrite(CHANNEL_3_PIN, LOW);
            }
            else if (CHANNEL == 4)
            {
              CHANNEL_4_ON_FLAG  = false;
              digitalWrite(CHANNEL_4_PIN, LOW);
            }
            else if (CHANNEL == 5)
            {
              CHANNEL_5_ON_FLAG  = false;
              digitalWrite(CHANNEL_5_PIN, LOW);
            }
            else if (CHANNEL == 6)
            {
              CHANNEL_6_ON_FLAG  = false;
              digitalWrite(CHANNEL_6_PIN, LOW);
            }
            else if (CHANNEL == 7)
            {
              CHANNEL_7_ON_FLAG  = false;
              digitalWrite(CHANNEL_7_PIN, LOW);
            }
            else if (CHANNEL == 8)
            {
              CHANNEL_8_ON_FLAG  = false;
              digitalWrite(CHANNEL_8_PIN, LOW);
            }
            else if (CHANNEL == 9)
            {
              CHANNEL_9_ON_FLAG  = false;
              digitalWrite(CHANNEL_9_PIN, LOW);
            }
            else if (CHANNEL == 10)
            {
              CHANNEL_10_ON_FLAG  = false;
              digitalWrite(CHANNEL_10_PIN, LOW);
            }
            else if (CHANNEL == 11)
            {
              CHANNEL_11_ON_FLAG  = false;
              digitalWrite(CHANNEL_11_PIN, LOW);
            }

          }//end case STOP_CHANNEL_COMMAND:
          break;

        case RUN_ALL_CHANNELS_COMMAND:
          {
            Serial.println(F("EXECUTED RUN_ALL_CHANNELS_COMMAND "));


            CHANNEL_0_ON_COUNTER = 0;
            CHANNEL_1_ON_COUNTER = 0;
            CHANNEL_2_ON_COUNTER = 0;
            CHANNEL_3_ON_COUNTER = 0;
            CHANNEL_4_ON_COUNTER = 0;
            CHANNEL_5_ON_COUNTER = 0;
            CHANNEL_6_ON_COUNTER = 0;
            CHANNEL_7_ON_COUNTER = 0;
            CHANNEL_8_ON_COUNTER = 0;
            CHANNEL_9_ON_COUNTER = 0;
            CHANNEL_10_ON_COUNTER = 0;
            CHANNEL_11_ON_COUNTER = 0;

            CHANNEL_0_OFF_COUNTER = 0;
            CHANNEL_1_OFF_COUNTER = 0;
            CHANNEL_2_OFF_COUNTER = 0;
            CHANNEL_3_OFF_COUNTER = 0;
            CHANNEL_4_OFF_COUNTER = 0;
            CHANNEL_5_OFF_COUNTER = 0;
            CHANNEL_6_OFF_COUNTER = 0;
            CHANNEL_7_OFF_COUNTER = 0;
            CHANNEL_8_OFF_COUNTER = 0;
            CHANNEL_9_OFF_COUNTER = 0;
            CHANNEL_10_OFF_COUNTER = 0;
            CHANNEL_11_OFF_COUNTER = 0;

            CHANNEL_0_ON_FLAG  = true;
            CHANNEL_1_ON_FLAG  = true;
            CHANNEL_2_ON_FLAG  = true;
            CHANNEL_3_ON_FLAG  = true;
            CHANNEL_4_ON_FLAG  = true;
            CHANNEL_5_ON_FLAG  = true;
            CHANNEL_6_ON_FLAG  = true;
            CHANNEL_7_ON_FLAG  = true;
            CHANNEL_8_ON_FLAG  = true;
            CHANNEL_9_ON_FLAG  = true;
            CHANNEL_10_ON_FLAG  = true;
            CHANNEL_11_ON_FLAG  = true;


            CHANNEL_0_HIGH_FLAG  = true;
            CHANNEL_1_HIGH_FLAG  = true;
            CHANNEL_2_HIGH_FLAG  = true;
            CHANNEL_3_HIGH_FLAG  = true;
            CHANNEL_4_HIGH_FLAG  = true;
            CHANNEL_5_HIGH_FLAG  = true;
            CHANNEL_6_HIGH_FLAG  = true;
            CHANNEL_7_HIGH_FLAG  = true;
            CHANNEL_8_HIGH_FLAG  = true;
            CHANNEL_9_HIGH_FLAG  = true;
            CHANNEL_10_HIGH_FLAG  = true;
            CHANNEL_11_HIGH_FLAG  = true;
          }
          break;

        case STOP_ALL_CHANNELS_COMMAND:
          {
            Serial.println(F("EXECUTED STOP_ALL_CHANNELS_COMMAND "));
            CHANNEL_0_ON_FLAG  = false;
            CHANNEL_1_ON_FLAG  = false;
            CHANNEL_2_ON_FLAG  = false;
            CHANNEL_3_ON_FLAG  = false;
            CHANNEL_4_ON_FLAG  = false;
            CHANNEL_5_ON_FLAG  = false;
            CHANNEL_6_ON_FLAG  = false;
            CHANNEL_7_ON_FLAG  = false;
            CHANNEL_8_ON_FLAG  = false;
            CHANNEL_9_ON_FLAG  = false;
            CHANNEL_10_ON_FLAG  = false;
            CHANNEL_11_ON_FLAG  = false;
            digitalWrite(CHANNEL_0_PIN, LOW);
            digitalWrite(CHANNEL_1_PIN, LOW);
            digitalWrite(CHANNEL_2_PIN, LOW);
            digitalWrite(CHANNEL_3_PIN, LOW);
            digitalWrite(CHANNEL_4_PIN, LOW);
            digitalWrite(CHANNEL_5_PIN, LOW);
            digitalWrite(CHANNEL_6_PIN, LOW);
            digitalWrite(CHANNEL_7_PIN, LOW);
            digitalWrite(CHANNEL_8_PIN, LOW);
            digitalWrite(CHANNEL_9_PIN, LOW);
            digitalWrite(CHANNEL_10_PIN, LOW);
            digitalWrite(CHANNEL_11_PIN, LOW);
          }
          break;

        case QUERY_STATUS_OF_ALL_CHANNELS_COMMAND:
          {
            Serial.println(F("EXECUTED QUERY_STATUS_OF_ALL_CHANNELS_COMMAND "));
            REPORT_STATUS_OF_ALL_CHANNELS();
          }
          break;

        case PRINT_MENU:
          {
            Serial.println(F("PRINT_MENU: "));
            Serial.println(F("COMMANDS "));
            Serial.println(F("SET_ON_TIME_COMMAND = 'O'"));                       // O for O(N)
            Serial.println(F("SET_OFF_TIME_COMMAND = 'F'"));                      // F of(F) time
            Serial.println(F("SET_ON_TIME_COMMAND_ALL_CHANNELS = 'X'"));          //  X for ???
            Serial.println(F("SET_OFF_TIME_COMMAND_ALL_CHANNELS = 'Z'"));          // Z for ???
            Serial.println(F("RUN_CHANNEL_COMMAND = 'R'"));                        // R (R)un one channel
            Serial.println(F("STOP_CHANNEL_COMMAND = 'S'"));                       // S (S)top one channel
            Serial.println(F("RUN_ALL_CHANNELS_COMMAND = 'C'"));                   // C Run all (C)hannels
            Serial.println(F("STOP_ALL_CHANNELS_COMMAND = 'T'"));                  // T S(T)op all channels
            Serial.println(F("QUERY_STATUS_OF_ALL_CHANNELS_COMMAND = 'Q'"));       // Q Query. Returns status of all channels seperated by commas
            Serial.println(F("TURN ON/OFF DEMO MODE = 'D'"));       // Q Query. Returns status of all channels sepe
            Serial.println(F("DISPLAY THIS MENU 'M'"));
          }
          break;
        default:
          {
            //            Serial.println(F("end switch (COMMAND)"));
          }
          break;
      }//end switch (COMMAND)

    }//if(PARSE_COMMAND(inputString))
    inputString = "";
    stringComplete = false;
    COMMAND = ' ';
    COMMAND_PARAMETER = 0;
  }//end if (stringComplete)
  // --------------------------- End Serial Loop -------------------------------
  // ----------------------------- Timer Loop ----------------------------------
  // ***************** CHANNEL 0 *******************
  if (CHANNEL_0_ON_COUNTER >= CHANNEL_0_ON_COUNT)
  {
    CHANNEL_0_ON_COUNTER = 0;
    CHANNEL_0_PIN_STATE = false;
    CHANNEL_0_CYCLE_COUNT = CHANNEL_0_CYCLE_COUNT + 1;
  }

  if (CHANNEL_0_OFF_COUNTER >= CHANNEL_0_OFF_COUNT)
  {
    CHANNEL_0_OFF_COUNTER = 0;
    CHANNEL_0_PIN_STATE = true;
  }
  //***************** CHANNEL 1 *******************
  if (CHANNEL_1_ON_COUNTER >= CHANNEL_1_ON_COUNT)
  {
    CHANNEL_1_ON_COUNTER = 0;
    CHANNEL_1_PIN_STATE = false;
  }

  if (CHANNEL_1_OFF_COUNTER >= CHANNEL_1_OFF_COUNT)
  {
    CHANNEL_1_OFF_COUNTER = 0;
    CHANNEL_1_PIN_STATE = true;
  }
  //***************** CHANNEL 2 *******************
  if (CHANNEL_2_ON_COUNTER >= CHANNEL_2_ON_COUNT)
  {
    CHANNEL_2_ON_COUNTER = 0;
    CHANNEL_2_PIN_STATE = false;
    CHANNEL_2_CYCLE_COUNT = CHANNEL_2_CYCLE_COUNT + 1;
  }

  if (CHANNEL_2_OFF_COUNTER >= CHANNEL_2_OFF_COUNT)
  {
    CHANNEL_2_OFF_COUNTER = 0;
    CHANNEL_2_PIN_STATE = true;
  }
  //***************** CHANNEL 3 *******************
  if (CHANNEL_3_ON_COUNTER >= CHANNEL_3_ON_COUNT)
  {
    CHANNEL_3_ON_COUNTER = 0;
    CHANNEL_3_PIN_STATE = false;
    CHANNEL_3_CYCLE_COUNT = CHANNEL_3_CYCLE_COUNT + 1;
  }

  if (CHANNEL_3_OFF_COUNTER >= CHANNEL_3_OFF_COUNT)
  {
    CHANNEL_3_OFF_COUNTER = 0;
    CHANNEL_3_PIN_STATE = true;
  }
  //***************** CHANNEL 4 *******************
  if (CHANNEL_4_ON_COUNTER >= CHANNEL_4_ON_COUNT)
  {
    CHANNEL_4_ON_COUNTER = 0;
    CHANNEL_4_PIN_STATE = false;
    CHANNEL_4_CYCLE_COUNT = CHANNEL_4_CYCLE_COUNT + 1;
  }

  if (CHANNEL_4_OFF_COUNTER >= CHANNEL_4_OFF_COUNT)
  {
    CHANNEL_4_OFF_COUNTER = 0;
    CHANNEL_4_PIN_STATE = true;
  }
  //***************** CHANNEL 5 *******************
  if (CHANNEL_5_ON_COUNTER >= CHANNEL_5_ON_COUNT)
  {
    CHANNEL_5_ON_COUNTER = 0;
    CHANNEL_5_PIN_STATE = false;
    CHANNEL_5_CYCLE_COUNT = CHANNEL_5_CYCLE_COUNT + 1;
  }

  if (CHANNEL_5_OFF_COUNTER >= CHANNEL_5_OFF_COUNT)
  {
    CHANNEL_5_OFF_COUNTER = 0;
    CHANNEL_5_PIN_STATE = true;
  }
  //***************** CHANNEL 6 *******************
  if (CHANNEL_6_ON_COUNTER >= CHANNEL_6_ON_COUNT)
  {
    CHANNEL_6_ON_COUNTER = 0;
    CHANNEL_6_PIN_STATE = false;
    CHANNEL_6_CYCLE_COUNT = CHANNEL_6_CYCLE_COUNT + 1;
  }

  if (CHANNEL_6_OFF_COUNTER >= CHANNEL_6_OFF_COUNT)
  {
    CHANNEL_6_OFF_COUNTER = 0;
    CHANNEL_6_PIN_STATE = true;
  }
  //***************** CHANNEL 7 *******************
  if (CHANNEL_7_ON_COUNTER >= CHANNEL_7_ON_COUNT)
  {
    CHANNEL_7_ON_COUNTER = 0;
    CHANNEL_7_PIN_STATE = false;
    CHANNEL_7_CYCLE_COUNT = CHANNEL_7_CYCLE_COUNT + 1;
  }

  if (CHANNEL_7_OFF_COUNTER >= CHANNEL_7_OFF_COUNT)
  {
    CHANNEL_7_OFF_COUNTER = 0;
    CHANNEL_7_PIN_STATE = true;
  }
  //***************** CHANNEL 8 *******************
  if (CHANNEL_8_ON_COUNTER >= CHANNEL_8_ON_COUNT)
  {
    CHANNEL_8_ON_COUNTER = 0;
    CHANNEL_8_PIN_STATE = false;
    CHANNEL_8_CYCLE_COUNT = CHANNEL_8_CYCLE_COUNT + 1;
  }

  if (CHANNEL_8_OFF_COUNTER >= CHANNEL_8_OFF_COUNT)
  {
    CHANNEL_8_OFF_COUNTER = 0;
    CHANNEL_8_PIN_STATE = true;
  }
  //***************** CHANNEL 9 *******************
  if (CHANNEL_9_ON_COUNTER >= CHANNEL_9_ON_COUNT)
  {
    CHANNEL_9_ON_COUNTER = 0;
    CHANNEL_9_PIN_STATE = false;
  }

  if (CHANNEL_9_OFF_COUNTER >= CHANNEL_9_OFF_COUNT)
  {
    CHANNEL_9_OFF_COUNTER = 0;
    CHANNEL_9_PIN_STATE = true;
  }
  //***************** CHANNEL 10 *******************
  if (CHANNEL_10_ON_COUNTER >= CHANNEL_10_ON_COUNT)
  {
    CHANNEL_10_ON_COUNTER = 0;
    CHANNEL_10_PIN_STATE = false;
  }

  if (CHANNEL_10_OFF_COUNTER >= CHANNEL_10_OFF_COUNT)
  {
    CHANNEL_10_OFF_COUNTER = 0;
    CHANNEL_10_PIN_STATE = true;
  }
  //***************** CHANNEL 11 *******************
  if (CHANNEL_11_ON_COUNTER >= CHANNEL_11_ON_COUNT)
  {
    CHANNEL_11_ON_COUNTER = 0;
    CHANNEL_11_PIN_STATE = false;
  }

  if (CHANNEL_11_OFF_COUNTER >= CHANNEL_11_OFF_COUNT)
  {
    CHANNEL_11_OFF_COUNTER = 0;
    CHANNEL_11_PIN_STATE = true;
  }

  // ------ Write all the pins with their states --------
  if (CHANNEL_0_ON_FLAG)
    digitalWrite(CHANNEL_0_PIN, CHANNEL_0_PIN_STATE);
  if (CHANNEL_1_ON_FLAG)
    digitalWrite(CHANNEL_1_PIN, CHANNEL_1_PIN_STATE);
  if (CHANNEL_2_ON_FLAG)
    digitalWrite(CHANNEL_2_PIN, CHANNEL_2_PIN_STATE);
  if (CHANNEL_3_ON_FLAG)
    digitalWrite(CHANNEL_3_PIN, CHANNEL_3_PIN_STATE);
  if (CHANNEL_4_ON_FLAG)
    digitalWrite(CHANNEL_4_PIN, CHANNEL_4_PIN_STATE);
  if (CHANNEL_5_ON_FLAG)
    digitalWrite(CHANNEL_5_PIN, CHANNEL_5_PIN_STATE);
  if (CHANNEL_6_ON_FLAG)
    digitalWrite(CHANNEL_6_PIN, CHANNEL_6_PIN_STATE);
  if (CHANNEL_7_ON_FLAG)
    digitalWrite(CHANNEL_7_PIN, CHANNEL_7_PIN_STATE);
  if (CHANNEL_8_ON_FLAG)
    digitalWrite(CHANNEL_8_PIN, CHANNEL_8_PIN_STATE);
  if (CHANNEL_9_ON_FLAG)
    digitalWrite(CHANNEL_9_PIN, CHANNEL_9_PIN_STATE);
  if (CHANNEL_10_ON_FLAG)
    digitalWrite(CHANNEL_10_PIN, CHANNEL_10_PIN_STATE);
  if (CHANNEL_11_ON_FLAG)
    digitalWrite(CHANNEL_11_PIN, CHANNEL_11_PIN_STATE);

  if (demo == true) {
    //    KNIGHT_RIDER();
  }
  if (demoB == true) {
    //    demoOutput1();
    shuffle();
  }



}// end loop

void REPORT_STATUS_OF_ALL_CHANNELS(void)
{
  Serial.print("CHANNEL 0: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_0_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_0_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_0_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 1: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_1_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_1_OFF_COUNT);
  Serial.print(" msec. ");

  if (CHANNEL_1_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 2: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_2_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_2_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_2_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 3: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_3_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_3_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_3_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 4: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_4_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_4_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_4_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 5: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_5_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_5_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_5_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 6: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_6_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_6_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_6_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 7: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_7_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_7_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_7_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 8: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_8_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_8_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_8_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 9: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_9_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_9_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_9_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 10: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_10_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_10_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_10_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }

  Serial.print("CHANNEL 11: ");
  Serial.print("ON_TIME: ");
  Serial.print(CHANNEL_11_ON_COUNT);
  Serial.print(" msec. ");
  Serial.print("OFF_TIME: ");
  Serial.print(CHANNEL_11_OFF_COUNT);
  Serial.print(" msec. ");
  if (CHANNEL_11_ON_FLAG)
  {
    Serial.println(" ON ");
  }
  else
  {
    Serial.println(" OFF ");
  }
}// end void REPORT_STATUS_OF_ALL_CHANNELS(void)
// ------------------------------ End Main Loop --------------------------------

// --------------------------- Serial Event Handler ----------------------------
/*
  SerialEvent occurs whenever a new data comes in the
  hardware serial RX.  This routine is run between each
  time loop() runs, so using delay inside loop can delay
  response.  Multiple bytes of data may be available.
*/



void serialEvent()
{
  while (Serial.available())
  {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n')
    {
      stringComplete = true;
    }
  }
}

// ------------------------- End Serial Event Handler -------------------------

// -------------------------------- Demo Mode ------------------------------

void KNIGHT_RIDER() {
  for (int thisPin = 0; thisPin < pinCount; thisPin++) {
    // turn the pin on:
    digitalWrite(CHANNEL_PIN[thisPin], HIGH);
    delay(timer);
    // turn the pin off:
    digitalWrite(CHANNEL_PIN[thisPin], LOW);
  }

  //  delay(1000);

  // loop from the highest pin to the lowest:
  for (int thisPin = pinCount - 1; thisPin >= 0; thisPin--) {
    // turn the pin on:
    digitalWrite(CHANNEL_PIN[thisPin], HIGH);
    delay(timer);
    // turn the pin off:
    digitalWrite(CHANNEL_PIN[thisPin], LOW);
  }

  delay(1000);
}

// --------------------------- End Demo Function ------------------------------

// --------------------------- Begin Test Output ------------------------------



long CHANNEL_0_START_TIME = 0;
long CHANNEL_2_START_TIME = 0;
long CHANNEL_3_START_TIME = 0;
long CHANNEL_4_START_TIME = 0;
long CHANNEL_5_START_TIME = 0;
long CHANNEL_6_START_TIME = 0;
long CHANNEL_7_START_TIME = 0;
long CHANNEL_8_START_TIME = 0;

long CHANNEL_0_START_TIME1 = 0;
long CHANNEL_2_START_TIME1 = 0;
long CHANNEL_3_START_TIME1 = 0;
long CHANNEL_4_START_TIME1 = 0;
long CHANNEL_5_START_TIME1 = 0;
long CHANNEL_6_START_TIME1 = 0;
long CHANNEL_7_START_TIME1 = 0;
long CHANNEL_8_START_TIME1 = 0;

long CHANNEL_0_ON_TIME = 0;
long CHANNEL_2_ON_TIME = 0;
long CHANNEL_3_ON_TIME = 0;
long CHANNEL_4_ON_TIME = 0;
long CHANNEL_5_ON_TIME = 0;
long CHANNEL_6_ON_TIME = 0;
long CHANNEL_7_ON_TIME = 0;
long CHANNEL_8_ON_TIME = 0;

long prevOnTime = 0;
long randomPauseTime = 1000;



void demoOutput() {

  //choose 1 bell to play and for how long
  //"flick" the hammer to start it
  //lower to desired frequency
  //wait for some time to pass (10 ms to 8 sec)




  const int randomLow = 500;
  const int randomHigh = 1500;


  //  Serial.print(CHANNEL_0_ON_FLAG);
  //  Serial.print(CHANNEL_2_ON_FLAG);
  //  Serial.println(CHANNEL_3_ON_FLAG);

  if (millis() - prevOnTime > randomPauseTime) {

    prevOnTime = millis();
    randomPauseTime = random(100, 6000);       //how long to wait before activating a
    randomPauseTime = 5000;
    switch (random(0, 0)) {
      case 0:
        if (CHANNEL_0_ON_FLAG == false) {
          CHANNEL_0_START_TIME = millis();
          CHANNEL_0_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_0_ON_TIME = 100;
          //          CHANNEL_0_ON_COUNT = 55;
          CHANNEL_0_FLICK_FLAG = false;
          Serial.print("CHANNEL_0 ON FOR ");
          Serial.print(CHANNEL_0_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_0_ON_FLAG = true;
        break;
      case 1:
        if (CHANNEL_2_ON_FLAG == false) {
          CHANNEL_2_START_TIME = millis();
          CHANNEL_2_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_2_FLICK_FLAG = true;
          Serial.print("CHANNEL_2 ON FOR ");
          Serial.print(CHANNEL_2_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_2_ON_FLAG = true;
        break;
      case 2:
        if (CHANNEL_3_ON_FLAG == false) {
          CHANNEL_3_START_TIME = millis();
          CHANNEL_3_ON_TIME = random(randomLow + 1000, randomHigh + 1000);
          CHANNEL_3_FLICK_FLAG = true;
          Serial.print("CHANNEL_3 ON FOR ");
          Serial.print(CHANNEL_3_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_3_ON_FLAG = true;
        break;
      case 3:
        if (CHANNEL_4_ON_FLAG == false) {
          CHANNEL_4_START_TIME = millis();
          CHANNEL_4_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_4_FLICK_FLAG = true;
          Serial.print("CHANNEL_4 ON FOR ");
          Serial.print(CHANNEL_4_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_4_ON_FLAG = true;
        break;
      case 4:
        if (CHANNEL_5_ON_FLAG == false) {
          CHANNEL_5_START_TIME = millis();
          CHANNEL_5_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_5_FLICK_FLAG = true;
          Serial.print("CHANNEL_5 ON FOR ");
          Serial.print(CHANNEL_5_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_5_ON_FLAG = true;
        break;
      case 5:
        if (CHANNEL_6_ON_FLAG == false) {
          CHANNEL_6_START_TIME = millis();
          CHANNEL_6_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_6_FLICK_FLAG = true;
          Serial.print("CHANNEL_6 ON FOR ");
          Serial.print(CHANNEL_6_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_6_ON_FLAG = true;
        break;
      case 6:
        if (CHANNEL_6_ON_FLAG == false) {
          CHANNEL_7_START_TIME = millis();
          CHANNEL_7_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_7_FLICK_FLAG = true;
          Serial.print("CHANNEL_7 ON FOR ");
          Serial.print(CHANNEL_7_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_7_ON_FLAG = true;
        break;
      case 7:
        if (CHANNEL_8_ON_FLAG == false) {
          CHANNEL_8_START_TIME = millis();
          CHANNEL_8_ON_TIME = random(randomLow, randomHigh);
          CHANNEL_8_FLICK_FLAG = true;
          Serial.print("CHANNEL_8 ON FOR ");
          Serial.print(CHANNEL_8_ON_TIME);
          Serial.print(" MS");
        }
        CHANNEL_8_ON_FLAG = true;
        break;
    }
    Serial.print(" ");
    Serial.print(randomPauseTime);
    Serial.println(" MS until next ping ");
  }


  CHANNEL_0_FLICK_TIME = 300;
  CHANNEL_2_FLICK_TIME = 300;
  CHANNEL_3_FLICK_TIME = 500;
  CHANNEL_4_FLICK_TIME = 300;
  CHANNEL_5_FLICK_TIME = 300;
  CHANNEL_6_FLICK_TIME = 300;
  CHANNEL_7_FLICK_TIME = 300;
  CHANNEL_8_FLICK_TIME = 300;

  int FLICK_COUNT_OFFSET_0 = 20;
  int FLICK_COUNT_OFFSET_2 = 20;
  int FLICK_COUNT_OFFSET_3 = 0;
  int FLICK_COUNT_OFFSET_4 = 20;
  int FLICK_COUNT_OFFSET_5 = 20;
  int FLICK_COUNT_OFFSET_6 = 20;
  int FLICK_COUNT_OFFSET_7 = 0;
  int FLICK_COUNT_OFFSET_8 = 20;


  //flick the hammer
  if (millis() - CHANNEL_0_START_TIME < CHANNEL_0_FLICK_TIME && CHANNEL_0_FLICK_FLAG == true) {
    CHANNEL_0_ON_COUNT += FLICK_COUNT_OFFSET_8;
    CHANNEL_0_FLICKED = true;
    CHANNEL_0_FLICK_FLAG = false;
    Serial.print("CHAN 0 FLICKED: ");
    Serial.println(CHANNEL_0_ON_COUNT);
  }
  if (millis() - CHANNEL_0_START_TIME > CHANNEL_0_FLICK_TIME && CHANNEL_0_FLICKED == true) {
    CHANNEL_0_ON_COUNT -= FLICK_COUNT_OFFSET_8;
    CHANNEL_0_FLICKED = false;
    Serial.print("CHAN 0 FLICKED: ");
    Serial.println(CHANNEL_0_ON_COUNT);
  }

  if (millis() - CHANNEL_2_START_TIME < CHANNEL_2_FLICK_TIME && CHANNEL_2_FLICK_FLAG == true) {
    CHANNEL_2_ON_COUNT += FLICK_COUNT_OFFSET_2;
    CHANNEL_2_FLICKED = true;
    CHANNEL_2_FLICK_FLAG = false;
    Serial.print("CHAN 2 FLICKED: ");
    Serial.println(CHANNEL_2_ON_COUNT);
  }
  if (millis() - CHANNEL_2_START_TIME > CHANNEL_2_FLICK_TIME && CHANNEL_2_FLICKED == true) {
    CHANNEL_2_ON_COUNT -= FLICK_COUNT_OFFSET_2;
    CHANNEL_2_FLICKED = false;
    Serial.print("CHAN 2 FLICKED: ");
    Serial.println(CHANNEL_2_ON_COUNT);
  }

  if (millis() - CHANNEL_3_START_TIME < CHANNEL_3_FLICK_TIME && CHANNEL_3_FLICK_FLAG == true) {
    CHANNEL_3_ON_COUNT += FLICK_COUNT_OFFSET_3;
    CHANNEL_3_FLICKED = true;
    CHANNEL_3_FLICK_FLAG = false;
    Serial.print("CHAN 3 FLICKED: ");
    Serial.println(CHANNEL_3_ON_COUNT);
  }
  if (millis() - CHANNEL_3_START_TIME > CHANNEL_3_FLICK_TIME && CHANNEL_3_FLICKED == true) {
    CHANNEL_3_ON_COUNT -= FLICK_COUNT_OFFSET_3;
    CHANNEL_3_FLICKED = false;
    Serial.print("CHAN 3 FLICKED: ");
    Serial.println(CHANNEL_3_ON_COUNT);
  }

  if (millis() - CHANNEL_4_START_TIME < CHANNEL_4_FLICK_TIME && CHANNEL_4_FLICK_FLAG == true) {
    CHANNEL_4_ON_COUNT += FLICK_COUNT_OFFSET_4;
    CHANNEL_4_FLICKED = true;
    CHANNEL_4_FLICK_FLAG = false;
    Serial.print("CHAN 4 FLICKED: ");
    Serial.println(CHANNEL_4_ON_COUNT);
  }
  if (millis() - CHANNEL_4_START_TIME > CHANNEL_4_FLICK_TIME && CHANNEL_4_FLICKED == true) {
    CHANNEL_4_ON_COUNT -= FLICK_COUNT_OFFSET_4;
    CHANNEL_4_FLICKED = false;
    Serial.print("CHAN 4 FLICKED: ");
    Serial.println(CHANNEL_4_ON_COUNT);
  }

  if (millis() - CHANNEL_5_START_TIME < CHANNEL_5_FLICK_TIME && CHANNEL_5_FLICK_FLAG == true) {
    CHANNEL_5_ON_COUNT += FLICK_COUNT_OFFSET_5;
    CHANNEL_5_FLICKED = true;
    CHANNEL_5_FLICK_FLAG = false;
    Serial.print("CHAN 5 FLICKED: ");
    Serial.println(CHANNEL_5_ON_COUNT);
  }
  if (millis() - CHANNEL_5_START_TIME > CHANNEL_5_FLICK_TIME && CHANNEL_5_FLICKED == true) {
    CHANNEL_5_ON_COUNT -= FLICK_COUNT_OFFSET_5;
    CHANNEL_5_FLICKED = false;
    Serial.print("CHAN 5 FLICKED: ");
    Serial.println(CHANNEL_5_ON_COUNT);
  }

  if (millis() - CHANNEL_6_START_TIME < CHANNEL_6_FLICK_TIME && CHANNEL_6_FLICK_FLAG == true) {
    CHANNEL_6_ON_COUNT += FLICK_COUNT_OFFSET_6;
    CHANNEL_6_FLICKED = true;
    CHANNEL_6_FLICK_FLAG = false;
    Serial.print("CHAN 6 FLICKED: ");
    Serial.println(CHANNEL_6_ON_COUNT);
  }
  if (millis() - CHANNEL_6_START_TIME > CHANNEL_6_FLICK_TIME && CHANNEL_6_FLICKED == true) {
    CHANNEL_6_ON_COUNT -= FLICK_COUNT_OFFSET_6;
    CHANNEL_6_FLICKED = false;
    Serial.print("CHAN 6 FLICKED: ");
    Serial.println(CHANNEL_6_ON_COUNT);
  }

  if (millis() - CHANNEL_7_START_TIME < CHANNEL_7_FLICK_TIME && CHANNEL_7_FLICK_FLAG == true) {
    CHANNEL_7_ON_COUNT += FLICK_COUNT_OFFSET_7;
    CHANNEL_7_FLICKED = true;
    CHANNEL_7_FLICK_FLAG = false;
    Serial.print("CHAN 7 FLICKED: ");
    Serial.println(CHANNEL_7_ON_COUNT);
  }
  if (millis() - CHANNEL_7_START_TIME > CHANNEL_7_FLICK_TIME && CHANNEL_7_FLICKED == true) {
    CHANNEL_7_ON_COUNT -= FLICK_COUNT_OFFSET_7;
    CHANNEL_7_FLICKED = false;
    Serial.print("CHAN 7 FLICKED: ");
    Serial.println(CHANNEL_7_ON_COUNT);
  }

  if (millis() - CHANNEL_8_START_TIME < CHANNEL_8_FLICK_TIME && CHANNEL_8_FLICK_FLAG == true) {
    CHANNEL_8_ON_COUNT += FLICK_COUNT_OFFSET_8;
    CHANNEL_8_FLICKED = true;
    CHANNEL_8_FLICK_FLAG = false;
    Serial.print("CHAN 8 FLICKED: ");
    Serial.println(CHANNEL_8_ON_COUNT);
  }
  if (millis() - CHANNEL_8_START_TIME > CHANNEL_8_FLICK_TIME && CHANNEL_8_FLICKED == true) {
    CHANNEL_8_ON_COUNT -= FLICK_COUNT_OFFSET_8;
    CHANNEL_8_FLICKED = false;
    Serial.print("CHAN 8 FLICKED: ");
    Serial.println(CHANNEL_8_ON_COUNT);
  }

  //turn off the channel
  if (millis() - CHANNEL_0_START_TIME > CHANNEL_0_ON_TIME && CHANNEL_0_ON_FLAG == true) {
    CHANNEL_0_ON_FLAG = false;
    digitalWrite(CHANNEL_0_PIN, LOW);
  }
  if (millis() - CHANNEL_2_START_TIME > CHANNEL_2_ON_TIME && CHANNEL_2_ON_FLAG == true) {
    CHANNEL_2_ON_FLAG = false;
    digitalWrite(CHANNEL_2_PIN, LOW);
  }
  if (millis() - CHANNEL_3_START_TIME > CHANNEL_3_ON_TIME && CHANNEL_3_ON_FLAG == true) {
    CHANNEL_3_ON_FLAG = false;
    digitalWrite(CHANNEL_3_PIN, LOW);
  }
  if (millis() - CHANNEL_4_START_TIME > CHANNEL_4_ON_TIME && CHANNEL_4_ON_FLAG == true) {
    CHANNEL_4_ON_FLAG = false;
    digitalWrite(CHANNEL_4_PIN, LOW);
  }
  if (millis() - CHANNEL_5_START_TIME > CHANNEL_5_ON_TIME && CHANNEL_5_ON_FLAG == true) {
    CHANNEL_5_ON_FLAG = false;
    digitalWrite(CHANNEL_5_PIN, LOW);
  }
  if (millis() - CHANNEL_6_START_TIME > CHANNEL_6_ON_TIME && CHANNEL_6_ON_FLAG == true) {
    CHANNEL_6_ON_FLAG = false;
    digitalWrite(CHANNEL_6_PIN, LOW);
  }
  if (millis() - CHANNEL_7_START_TIME > CHANNEL_7_ON_TIME && CHANNEL_7_ON_FLAG == true) {
    CHANNEL_7_ON_FLAG = false;
    digitalWrite(CHANNEL_7_PIN, LOW);
  }
  if (millis() - CHANNEL_8_START_TIME > CHANNEL_8_ON_TIME && CHANNEL_8_ON_FLAG == true) {
    CHANNEL_8_ON_FLAG = false;
    digitalWrite(CHANNEL_8_PIN, LOW);
  }

}

void demoOutput1() {
  //  CHANNEL_0_CYCLE_COUNT

  //  if (CHANNEL_0_CYCLE_COUNT == true)

  //  if (CHANNEL_0_CYCLE_COUNT <= 4 && CHANNEL_0_ON_FLAG == true) {
  //    CHANNEL_0_ON_FLAG = true;
  //  }
  //  else {
  //    CHANNEL_0_CYCLE_COUNT = 0;
  //    CHANNEL_0_ON_FLAG = false;
  //    digitalWrite(CHANNEL_0_PIN, LOW);
  //  }

  if (CHANNEL_0_ON_FLAG == true && CHANNEL_0_CYCLE_COUNT > 3) {
    CHANNEL_0_CYCLE_COUNT = 0;
    CHANNEL_0_ON_FLAG = false;
    digitalWrite(CHANNEL_0_PIN, LOW);
  }
  if (CHANNEL_2_ON_FLAG == true && CHANNEL_2_CYCLE_COUNT > 3) {
    CHANNEL_2_CYCLE_COUNT = 0;
    CHANNEL_2_ON_FLAG = false;
    digitalWrite(CHANNEL_2_PIN, LOW);
  }

  if (CHANNEL_3_ON_FLAG == true && CHANNEL_3_CYCLE_COUNT > 3) {
    CHANNEL_3_CYCLE_COUNT = 0;
    CHANNEL_3_ON_FLAG = false;
    digitalWrite(CHANNEL_3_PIN, LOW);
  }

  if (CHANNEL_4_ON_FLAG == true && CHANNEL_4_CYCLE_COUNT > 3) {
    CHANNEL_4_CYCLE_COUNT = 0;
    CHANNEL_4_ON_FLAG = false;
    digitalWrite(CHANNEL_4_PIN, LOW);
  }

  if (CHANNEL_5_ON_FLAG == true && CHANNEL_5_CYCLE_COUNT > 3) {
    CHANNEL_5_CYCLE_COUNT = 0;
    CHANNEL_5_ON_FLAG = false;
    digitalWrite(CHANNEL_5_PIN, LOW);
  }

  if (CHANNEL_6_ON_FLAG == true && CHANNEL_6_CYCLE_COUNT > 40) {
    CHANNEL_6_CYCLE_COUNT = 0;
    CHANNEL_6_ON_FLAG = false;
    digitalWrite(CHANNEL_6_PIN, LOW);
  }

  if (CHANNEL_7_ON_FLAG == true && CHANNEL_7_CYCLE_COUNT > 3) {
    CHANNEL_7_CYCLE_COUNT = 0;
    CHANNEL_7_ON_FLAG = false;
    digitalWrite(CHANNEL_7_PIN, LOW);
  }

  if (CHANNEL_8_ON_FLAG == true && CHANNEL_8_CYCLE_COUNT > 3) {
    CHANNEL_8_CYCLE_COUNT = 0;
    CHANNEL_8_ON_FLAG = false;
    digitalWrite(CHANNEL_8_PIN, LOW);
  }
}



int f;
int ii;
int n;
int p;
int x;

int RANDOM_CHANNEL[] = {0, 1, 2, 3, 4, 5, 6, 7, 0};

long prevPlayTime = 0;
long previousArrayTime = 0;

boolean playChannel = true;
boolean shuffleArray = true;

boolean PLAY_0_FLAG = false;
boolean PLAY_2_FLAG = false;
boolean PLAY_3_FLAG = false;
boolean PLAY_4_FLAG = false;
boolean PLAY_5_FLAG = false;
boolean PLAY_6_FLAG = false;
boolean PLAY_7_FLAG = false;
boolean PLAY_8_FLAG = false;

int CURRENT_CHANNEL = 0;

int RAND_COUNT_0 = 40;
int RAND_COUNT_2 = 40;
int RAND_COUNT_3 = 40;
int RAND_COUNT_4 = 40;
int RAND_COUNT_5 = 40;
int RAND_COUNT_6 = 40;
int RAND_COUNT_7 = 40;
int RAND_COUNT_8 = 40;


void shuffle() {

  //        randomSeed(analogRead(A2));


  if (millis() - prevPlayTime > delayVal) {
    delayVal = random(3000, 9000);
    delayVal = 15000;
    prevPlayTime = millis();
    playChannel = true;
    shuffleArray = true;
    //    randomSeed(analogRead(A1));
  }

  if (shuffleArray == true && playChannel == true) {

    shuffleArray = false;

    int numPins = 8;
    int CHANNEL_PIN[numPins + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 0};

    //    for (f = 0; f < numPins; f++) // here we print the "new" array to pick from
    //    {
    //      Serial.print(CHANNEL_PIN[f]);
    //      Serial.print(" ");
    //    }
    //    Serial.println();

    for (n = numPins; n > 0; n--) // here we pick random elements in the array until we got 'em all
    {
      x = random(n);
      p = CHANNEL_PIN[x];
      //      Serial.println(x);

      //      Serial.print("picked the ");
      //      Serial.print(x + 1);
      //      Serial.print("th element out of the array above. So no more |");
      //      Serial.print(p);
      //      Serial.println("| in the array!  New array =");


      RANDOM_CHANNEL[n] = p;

      ///////////

      for (ii = x; x < n; x++) // here we shift all elements (who come AFTER the chosen one) in the array one place to the left
      {
        CHANNEL_PIN[x] = CHANNEL_PIN[x + 1];
      }

      //      for (f = 0; f < numPins; f++) // here we print the "new" array to pick from
      //      {
      //        Serial.print(CHANNEL_PIN[f]);
      //        Serial.print(" ");
      //        delay(10);
      //      }
      //      Serial.println();

    }

    playChannel = true;
    shuffleArray = false;

    for (int i = 0; i < numPins; i ++) {
      Serial.print(RANDOM_CHANNEL[i]);
      Serial.print(" ");
    }
    Serial.println("- ARRAY");
    Serial.println();
  }

  if (millis() - previousArrayTime > randDelay && playChannel == true) {
    previousArrayTime = millis();

    Serial.print(CURRENT_CHANNEL);
    Serial.print(" OUT: ");
    Serial.print(RANDOM_CHANNEL[CURRENT_CHANNEL]);
    Serial.print(" ");
    Serial.println(randDelay);
    randDelay = random(30, 2000);
    //    randDelay = 100;

    switch (RANDOM_CHANNEL[CURRENT_CHANNEL - 1]) {
      //    switch (CURRENT_CHANNEL - 1) {
      case 0:
        CHANNEL_0_CYCLE_COUNT = 0;
        PLAY_0_FLAG = true;
        CHANNEL_0_ON_FLAG = true;
        break;
      case 1:
        CHANNEL_2_CYCLE_COUNT = 0;
        PLAY_2_FLAG = true;
        CHANNEL_2_ON_FLAG = true;
        break;
      case 2:
        CHANNEL_3_CYCLE_COUNT = 0;
        PLAY_3_FLAG = true;
        CHANNEL_3_ON_FLAG = true;
        break;
      case 3:
        CHANNEL_4_CYCLE_COUNT = 0;
        PLAY_4_FLAG = true;
        CHANNEL_4_ON_FLAG = true;
        break;
      case 4:
        CHANNEL_5_CYCLE_COUNT = 0;
        PLAY_5_FLAG = true;
        CHANNEL_5_ON_FLAG = true;
        break;
      case 5:
        CHANNEL_6_CYCLE_COUNT = 0;
        PLAY_6_FLAG = true;
        CHANNEL_6_ON_FLAG = true;
        break;
      case 6:
        CHANNEL_7_CYCLE_COUNT = 0;
        PLAY_7_FLAG = true;
        CHANNEL_7_ON_FLAG = true;
        break;
      case 7:
        CHANNEL_8_CYCLE_COUNT = 0;
        PLAY_8_FLAG = true;
        CHANNEL_8_ON_FLAG = true;
        break;
    }

    CURRENT_CHANNEL = CURRENT_CHANNEL + 1;

  }

  if (CURRENT_CHANNEL > pinCount) {
    Serial.println();
    CURRENT_CHANNEL = 1;
    playChannel = false;
  }


  if (CHANNEL_0_ON_FLAG == true && CHANNEL_0_CYCLE_COUNT > RAND_COUNT_0) {

    CHANNEL_0_CYCLE_COUNT = 0;
    CHANNEL_0_ON_FLAG = false;
    PLAY_0_FLAG = false;
    digitalWrite(CHANNEL_0_PIN, LOW);
    RAND_COUNT_0 = random(20, 40);
    Serial.print("COUNT 0: ");
    Serial.print(RAND_COUNT_0);
    Serial.println(" ");
  }
  if (CHANNEL_2_ON_FLAG == true && CHANNEL_2_CYCLE_COUNT > RAND_COUNT_2) {
    CHANNEL_2_CYCLE_COUNT = 0;
    CHANNEL_2_ON_FLAG = false;
    PLAY_2_FLAG = false;
    digitalWrite(CHANNEL_2_PIN, LOW);
    RAND_COUNT_2 = random(40, 60);
    Serial.print("COUNT 2: ");
    Serial.print(RAND_COUNT_0);
    Serial.println(" ");
  }

  if (CHANNEL_3_ON_FLAG == true && CHANNEL_3_CYCLE_COUNT > RAND_COUNT_3) {
    CHANNEL_3_CYCLE_COUNT = 0;
    CHANNEL_3_ON_FLAG = false;
    PLAY_3_FLAG = false;
    digitalWrite(CHANNEL_3_PIN, LOW);
    RAND_COUNT_3 = random(55, 75);
    Serial.print("COUNT 3: ");
    Serial.print(RAND_COUNT_3);
    Serial.println(" ");
  }

  if (CHANNEL_4_ON_FLAG == true && CHANNEL_4_CYCLE_COUNT > RAND_COUNT_4) {
    CHANNEL_4_CYCLE_COUNT = 0;
    CHANNEL_4_ON_FLAG = false;
    PLAY_4_FLAG = false;
    digitalWrite(CHANNEL_4_PIN, LOW);
    RAND_COUNT_4 = random(40, 60);
    Serial.print("COUNT 4: ");
    Serial.print(RAND_COUNT_4);
    Serial.println(" ");
  }

  if (CHANNEL_5_ON_FLAG == true && CHANNEL_5_CYCLE_COUNT > RAND_COUNT_5) {
    CHANNEL_5_CYCLE_COUNT = 0;
    CHANNEL_5_ON_FLAG = false;
    PLAY_5_FLAG = false;
    digitalWrite(CHANNEL_5_PIN, LOW);
    RAND_COUNT_5 = random(40, 60);
    Serial.print("COUNT 5: ");
    Serial.print(RAND_COUNT_5);
    Serial.println(" ");
  }

  if (CHANNEL_6_ON_FLAG == true && CHANNEL_6_CYCLE_COUNT > RAND_COUNT_6) {
    CHANNEL_6_CYCLE_COUNT = 0;
    CHANNEL_6_ON_FLAG = false;
    PLAY_6_FLAG = false;
    digitalWrite(CHANNEL_6_PIN, LOW);
    RAND_COUNT_6 = random(40, 60);
    Serial.print("COUNT 6: ");
    Serial.print(RAND_COUNT_6);
    Serial.println(" ");
  }

  if (CHANNEL_7_ON_FLAG == true && CHANNEL_7_CYCLE_COUNT > RAND_COUNT_7) {
    CHANNEL_7_CYCLE_COUNT = 0;
    CHANNEL_7_ON_FLAG = false;
    PLAY_7_FLAG = false;
    digitalWrite(CHANNEL_7_PIN, LOW);
    RAND_COUNT_7 = random(40, 60);
    Serial.print("COUNT 7: ");
    Serial.print(RAND_COUNT_7);
    Serial.println(" ");
  }

  if (CHANNEL_8_ON_FLAG == true && CHANNEL_8_CYCLE_COUNT > RAND_COUNT_8) {
    CHANNEL_8_CYCLE_COUNT = 0;
    CHANNEL_8_ON_FLAG = false;
    PLAY_8_FLAG = false;
    digitalWrite(CHANNEL_8_PIN, LOW);
    RAND_COUNT_8 = random(60, 80);
    Serial.print("COUNT 8: ");
    Serial.print(RAND_COUNT_8);
    Serial.println(" ");
  }

}

// --------------------------- End Test Function ------------------------------
// ----------------------------- End Functions --------------------------------
// -------------------------- END WINE_GLASS_RINGER ---------------------------

I think I'm close to the problem. There are no resistors on the shield. Could it be that I just need to add proper resistors? These are the FETs that are on the shield: PSMN3R4-30PL

When the signal is pulled LOW, there's a floating voltage:

When I set it to a 50% duty cycle, I believe that the floating voltage is added into the duty cycle:

Hi,

I'm using this 12 channel MOSFET shield and running into some issues related to duty cycle when I turn multiple FETs on at the same time. I think I've narrowed the problem down to the shield not using any resistors with the FETs.

When I digitalWrite(FET, LOW) to one of my FETs, it doesn't fully turn off my drain. See pic below. That ripple is when I pull the pin to LOW. Is this normal, or am I able to fully turn off the FETs? These are the MOSFETS installed on the shield: PSMN3R4-30PL

Thanks :slight_smile:

You have not shown your wiring diagram. It seems to me that you have not connected an input signal to your oscilloscope.

Topics merged. @xxmamakinxx please only create one forum topic for each distinct subject matter. Creating multiple topics on the same subject matter results in parallel discussions that can waste the time of the people attempting to provide assistance.

Thanks in advance for your cooperation.

The probe isn’t connected in the photo. I froze the screen and removed it to take a better picture.

I’ll post a wiring diagram shortly, but it’s a shield, so there isn’t much wiring. The electromagnets get attached to the terminal block pins that are touching the FETs drains, then there’s a 5v supply for the Arduino 5v pin and a +12v that’s connected to one side of each magnet, and negative shared between the power supplies, Arduino gnd, and the source for each MOSFET. Gnd and source connections are taken care by the shield.

Apologies, I assumed this wiring was simple enough as to not require a schematic, but I’ll put together a hand drawn circuit shortly.

**edit - this was not measured with the load (electromagnet) on it, however, the FET frequency does still fluctuate when I set the duty cycle of any other FETs on the shield. The duty cycle coming out of the Arduino however, stays the same.

Circuit diagram below. Hope it makes sense🤞

Is the Arduino pin set to OUTPUT?
The 60 Hz signal is probably mains hum.

Hi,
@xxmamakinxx shield.


Solenoids

Solenoid Spec.

  • Input Voltage: 12V DC ;Peak Force :250N Holding Force : 185N Duty-cycle (ED%) : 50%; Electric time:Less than 7 minutes ; Thread size : M5*8;Material: Pure Iron
  • Overall Size : 40 x 20 mm /1.6 x 0.8 inch(Dia. *T) ; Lead Length : 24cm/9. 5 inch
  • Use QA-1/155 Varnished Wire, withstand high temperature up to 155C, better than the QA-1/130 in the market
  • Use UL1332 lead wire, non-deformation withstand high temperature up to 155C
  • Use PA66GF30 nylon plastic for framework; high temperature resistance

You do have ALL the gnds connected together?
That is the, what model Arduino?, gnd and the shield gnd and the 12V power supply gnd ALL together.

Tom.... :grinning: :+1: :coffee: :australia:

And you do have kickback diodes across the loads ?

Hi,
You may need to add the two resistors


A back EMF diode on the solenoid will help too.

Can you post a picture of your project so we can see your component layout?

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

I can't understand, is the load connected or not?
If you have not connected a load, then your oscilloscope probe will simply be in the air after closing the MOSFET and will pick up interference, not a signal.
Connect at least resistors instead of solenoids.

Examine your shield carefully. The photo does not show where the source pins of the MOSFETs are connected. Are they connected to the GND?

If not the MOSFETs are likely all burned up.... They are only rated 30V and those
electromagnets look beefy enough to fry practically any semiconductor device
if not given free-wheel diodes across them.

Thanks all for the comments, much appreciated!!!!

In order of appearance:

  • @Smajdalf Arduino pins are set to output
  • @TomGeorge All the gnds are together. I tested that multiple times hoping for an easy fix. And it’s an Arduino Mega.
  • @LarryD There aren’t kickback diodes, I thought that was only needed for motors. Oops.
  • @TomGeorge Thanks a bunch for putting the schematic together. I’ll add the resistors and see if that helps. I’d hoped that using a shield would’ve taken care of the necessary components 🤦. I’m heading back on site this afternoon if not tomorrow morning and will post a photo of my components.
  • @Boffin Re: load not connected. I put the EMs on barrel jack connectors, unplugged one and connected my probe to the open end without the EM. I’m new to using a scope and didn’t realize that I still needed the load on there.
  • The source pins are connected to gnd. I checked, and they do work to switch the EMs on/off. My issue is when sending a duty cycle signal to more than one, neither FET produces the correct frequency, and it gets worse when I pulse additional FETS.
  • @MarkT Lucky for me the MOSFETs haven’t burnt up. The EMs are 12v.

Thanks again for all you help and input. I’ll incorporate the suggestions and report back ASAP!

Build the scheme suggested to you in post #13. Connect a solenoid with diode or equivalent resistor. Connect an oscilloscope between the source and drain of the transistor. Measure.

That's what you think, in practice they may be degraded in performance, high voltage transients can cause pin-holes in the gate oxide that only show up as excess gate leakage currents - although high voltages can also melt the whole chip, so you should be circumspect about the FETs being unscathed.

Your electromagnet is likely to be more inductive than many motors, as there will be many
more turns of wire in an electromagnet than a typical DC motor armature.

Project update:

I went ahead and added all of the recommended suggestions, and it helped a bit. Then after working ok for a while my EMs stopped pulling as strong as they should've been. Very frustrated and confused, I finally found the problem. These are 12v EMs and I'm using a 5v power supply (I have lots of 5v LEDs to power) a step-up converter to supply the voltage to the EMs:

  • Conventional Constant Voltage Output BOOST Fully Integrated Solutions, Integrated MOSFET, Fewer External Components, Smaller Cos System
  • XL6019 5A Current DC to DC Adjustable Boost Power Supply Board Module
  • Adjust the blue knob of the potentiometer (counterclockwise general impulse, buck clockwise rotation) and with a multimeter to monitor the output voltage reaches the required voltage
  • Built-in over temperature protection, full set overcurrent protection circuit reliability, high reliability

Yeah, that step-up converter stopped operating properly. It definitely overheated. I had the converter set to 12v out, but it wasn't supplying the full voltage. further, if I activated more EMs, it was distributing the available power across the devices, producing the problem originally described of each EM affecting the next if they were on. I tested the circuit with a separate power supply and everything worked as intended :slight_smile:

I'll have to put a meter on the magnets to see how much current they're actually drawing, but the question now is did the boost circuit fail because it was drawing too much current or because there weren't diodes across the electromagnets and it sent voltage back into the circuit?

Too much current.
Voltage spikes from inductive load are problem for the switching transistors, not the power supply.