Controlling DC motors with Micro switch

I am trying to create a claw machine using an arduino. So far the biggest issue is getting the DC motor to move with a microswitch joystick. I am using is a MultiMoto to control the motors and claw. Whenever I use an IF statement with a SWITCH, only one of the motors will barley move with the joystick. I know the code is working, because I made it light an LED whenever a motor should move. I did try a plain IF/ELSE IF but nothing worked. Does anyone have any ideas that I could try?

Original:

/*
    Robot Power MultiMoto v1.0 demo
    This software is released into the Public Domain
    
    This demo shows the setup of the L9958 chips and runs the 4 motor outputs
    independently.  Also Timer0 and Timer1 are set to higher frequency than standard.
    This may affect the millisecond timer function.
    
    v1.0 - initial release

*/

// include the SPI library:
#include <SPI.h>

// L9958 slave select pins for SPI
#define SS_M4 14
#define SS_M3 13
#define SS_M2 12
#define SS_M1 11

// L9958 DIRection pins
#define DIR_M1 2
#define DIR_M2 3
#define DIR_M3 4
#define DIR_M4 7

// L9958 PWM pins
#define PWM_M1 9
#define PWM_M2 10    // Timer1
#define PWM_M3 5
#define PWM_M4 6     // Timer0

// L9958 Enable for all 4 motors
#define ENABLE_MOTORS 8

int pwm1, pwm2, pwm3, pwm4;
int dir1, dir2, dir3, dir4;


//Crane variables
    //Arduino used pins
    const int joyup = 15;
    const int joydown = 16;
    const int joyleft = 17;
    const int joyright = 18;
    const int joypress = 19;
    const int coin = 20;
    const int front = 21;
    const int left = 22;
    const int clawup = 23;
    const int clawdown = 24;
    const int ledPin =  13; 
    
    //Mics Variables
    int moveLeft = 0;
    int moveRight = 0;
    int moveBack = 0;
    int moveFront = 0;
    int pressButton = 0;
    int coinIn = 0;
    int limitFront = 0;
    int limitLeft = 0;
    int limitUp = 0;
    int limtiDown = 0;
    int opt = 0;

void setup() {
  unsigned int configWord;
  
    // put your setup code here, to run once:
  pinMode(SS_M4, OUTPUT); digitalWrite(SS_M4, HIGH);  // HIGH = not selected
  pinMode(SS_M3, OUTPUT); digitalWrite(SS_M3, HIGH);
  pinMode(SS_M2, OUTPUT); digitalWrite(SS_M2, HIGH);
  pinMode(SS_M1, OUTPUT); digitalWrite(SS_M1, HIGH);
  
  // L9958 DIRection pins
  pinMode(DIR_M1, OUTPUT);
  pinMode(DIR_M2, OUTPUT);
  pinMode(DIR_M3, OUTPUT);
  pinMode(DIR_M4, OUTPUT);
  
  // L9958 PWM pins
  pinMode(PWM_M1, OUTPUT);  digitalWrite(PWM_M1, LOW);
  pinMode(PWM_M2, OUTPUT);  digitalWrite(PWM_M2, LOW);    // Timer1
  pinMode(PWM_M3, OUTPUT);  digitalWrite(PWM_M3, LOW);
  pinMode(PWM_M4, OUTPUT);  digitalWrite(PWM_M4, LOW);    // Timer0
  
  // L9958 Enable for all 4 motors
  pinMode(ENABLE_MOTORS, OUTPUT);  digitalWrite(ENABLE_MOTORS, HIGH);   // HIGH = disabled
  
  /******* Set up L9958 chips *********
  ' L9958 Config Register
  ' Bit
  '0 - RES
  '1 - DR - reset
  '2 - CL_1 - curr limit
  '3 - CL_2 - curr_limit
  '4 - RES
  '5 - RES
  '6 - RES
  '7 - RES
  '8 - VSR - voltage slew rate
  '9 - ISR - current slew rate
  '10 - ISR_DIS - current slew disable
  '11 - OL_ON - open load enable
  '12 - RES
  '13 - RES
  '14 - 0 - always zero
  '15 - 0 - always zero
  */
  
  // set to max current limit and disable ISR slew limiting
  configWord = 0b0000010000001100;
  
  SPI.begin();
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(SPI_MODE1);  // clock pol = low, phase = high
  
  // Motor 1
  digitalWrite(SS_M1, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M1, HIGH); 
  // Motor 2
  digitalWrite(SS_M2, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M2, HIGH);
  // Motor 3
  digitalWrite(SS_M3, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M3, HIGH);
  // Motor 4
  digitalWrite(SS_M4, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M4, HIGH);
  
  // Reduce the PWM frequency to about 8kHz
  // Note, this will screw up the timer functions that use Timer0 such as millis()
  setPwmFrequency(PWM_M1, 8);
  setPwmFrequency(PWM_M3, 8);

    pinMode(joyup, INPUT);
    pinMode(joydown, INPUT);
    pinMode(joyleft, INPUT);
    pinMode(joyright, INPUT);
    pinMode(joypress, INPUT);
    pinMode(coin, INPUT);
    pinMode(front, INPUT);
    pinMode(left, INPUT);
    pinMode(clawup, INPUT);
    pinMode(clawdown, INPUT);
    pinMode(ledPin, OUTPUT);

}


// *******************************************
// ************** Main Loop ******************
// *******************************************
void loop() {
 
  moveLeft = digitalRead(joyleft);
  moveRight = digitalRead(joyright);
  moveBack = digitalRead(joyup);
  moveFront = digitalRead(joydown);
  pressButton = digitalRead(joypress);
  coinIn = digitalRead(coin);
  limitFront = digitalRead(front);
  limitLeft = digitalRead(left);
  limitUp = digitalRead(clawup);
  limtiDown = digitalRead(clawdown);

if (moveLeft == HIGH)
  {
    opt = 1;
  }

else if (moveRight == HIGH)
  {
    opt = 2;
  }
else if (moveBack == HIGH)
  {
    opt = 3;
  }

else if (moveFront == HIGH)
  {
    opt = 4;
  }
else
  {
    opt = 0;
  }
  
  switch (opt)
  {

    case 0:
      analogWrite(PWM_M1, 0);  digitalWrite(DIR_M1, 0);
      analogWrite(PWM_M2, 0);  digitalWrite(DIR_M2, 0);
      analogWrite(PWM_M3, 0);  digitalWrite(DIR_M3, 0);
      digitalWrite(ledPin, LOW);
      break;

    case 1:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
      break;

    case 2:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 1);
      break;

    case 3:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M3, 255);  digitalWrite(DIR_M3, 0);
      break;

    case 4:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M3, 255);  digitalWrite(DIR_M3, 1);
      break;
  }
  
  digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW      
}
// ***********************************************
// ************** End Main Loop ******************
// ***********************************************


/*
 * Divides a given PWM pin frequency by a divisor.
 * 
 * The resulting frequency is equal to the base frequency divided by
 * the given divisor:
 *   - Base frequencies:
 *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
 *      o The base frequency for pins 5 and 6 is 62500 Hz.
 *   - Divisors:
 *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
 *        256, and 1024.
 *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
 *        128, 256, and 1024.
 * 
 * PWM frequencies are tied together in pairs of pins. If one in a
 * pair is changed, the other is also changed to match:
 *   - Pins 5 and 6 are paired (Timer0)
 *   - Pins 9 and 10 are paired (Timer1)
 *   - Pins 3 and 11 are paired (Timer2)
 * 
 * Note that this function will have side effects on anything else
 * that uses timers:
 *   - Changes on pins 5, 6 may cause the delay() and
 *     millis() functions to stop working. Other timing-related
 *     functions may also be affected.
 *   - Changes on pins 9 or 10 will cause the Servo library to function
 *     incorrectly.
 * 
 * Thanks to macegr of the Arduino forums for his documentation of the
 * PWM frequency divisors. His post can be viewed at:
 *   http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/0#4
 */
 
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) { // Timer0 or Timer1
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) { 
      TCCR0B = TCCR0B & 0b11111000 | mode; // Timer0
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode; // Timer1
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode; // Timer2
  }
}

If i use this line in place of the IF statement the motors will work:

     analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
     analogWrite(PWM_M3, 255);  digitalWrite(DIR_M3, 0);
     digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW

Thanks,
Draco

Why not add some debug statements so you can see what the code is doing?

Are you trying to drive the motors using the current from the Arduino directly? Each Arduino pin can supply max 40 ma., and all of them together (if I remember right) about 200 ma. Maybe you need to supply the current from the Arduino to a transistor base, and drive the motors with transistors.

jrdoner:
Are you trying to drive the motors using the current from the Arduino directly? Each Arduino pin can supply max 40 ma., and all of them together (if I remember right) about 200 ma. Maybe you need to supply the current from the Arduino to a transistor base, and drive the motors with transistors.

A MultiMoto shield is a h-bridge shield.

Hi,

Can you please post a picture of your project?

What are the specs of the motor?
Can you post a link to the shield please?
How are you powering the motors?
An LED draws less current than a motor.

Tom... :slight_smile:

DuaneDegn:
Why not add some debug statements so you can see what the code is doing?

My coding knowledge is minimal. I'm learning as I'm going. I test the code by adding a line for a LED. So that it will light up when the motors should activate. So far the LED will turn on with the microswitch joystick movement, but the motors wont move.

TomGeorge:
Hi,

Can you please post a picture of your project?

What are the specs of the motor?
Can you post a link to the shield please?
How are you powering the motors?
An LED draws less current than a motor.

Tom... :slight_smile:

http://www.robotpower.com/products/MultiMoto_info.html

I'm not sure about anything on the DC Motors. They came with the crane machine (1980's). They are working with the MultiMotor shield. Also the motors will work with a code that just has them always on, or both of the Arduino sketches provided by the manufacture of the shield.

I am using a 24v power supply for the MultiMotor shield, and a light.

Here are some pictures.

Thanks,
Draco

Draco_Elessar:
Whenever I use an IF statement with a SWITCH, only one of the motors will barley move with the joystick.

I wonder if the way your code is written keeps the motor on for long enough to notice any movement.

If this was my problem I would strip down my code to the absolute minimum - just one switch and one motor.

...R

Robin2:
I wonder if the way your code is written keeps the motor on for long enough to notice any movement.

If this was my problem I would strip down my code to the absolute minimum - just one switch and one motor.

...R

I got a motor to move, but it doesn't respond to the joystick. Here is the new void loop:

void loop() {
 
  moveLeft = digitalRead(joyleft);
  moveRight = digitalRead(joyright);
  moveBack = digitalRead(joyup);
  moveFront = digitalRead(joydown);
  pressButton = digitalRead(joypress);
  coinIn = digitalRead(coin);
  limitFront = digitalRead(front);
  limitLeft = digitalRead(left);
  limitUp = digitalRead(clawup);
  limtiDown = digitalRead(clawdown);
 
  if (pressButton == HIGH)
  {
      analogWrite(PWM_M4, 255);  digitalWrite(DIR_M4, 0);
  }
  digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW  
}

if I add an else it does not work.

It should close the claw when the button is pressed. But it closes the claw as soon as it gets power. Then doesn't respond to the microswitch at all. Tried it with all of the motors and microswitches same result. When I added a delay(10000) to the original and above code and saw no change.

Draco_Elessar:
My coding knowledge is minimal. I'm learning as I'm going. I test the code by adding a line for a LED.

LEDs are useful for debugging but nothing beats adding a few serial statements to the program so you can find out exactly what's going on.

For example, if the value of "opt" being correctly set?

Here's how to add some debug statements.

Add the following line to your setup function.

  Serial.begin(9600);

"9600" is the baud. I generally use 115200 but just about all the example sketches use 9600. You need to make sure the serial terminal's baud setting matches the one you're using in the program.

The above "begin" call needs to occur prior to any debug statements.

Here's an example of a possible debug statement.

else
  {
    opt = 0;
  }
  Serial.print(F("Pausing program to report the value of opt. opt = "));
  Serial.println(opt);
  delay(1000); // For debugging only. Remove from working code.
  
  switch (opt)

I included some of the surrounding code so you can tell where in the program I added the statements.

The "F" in "Serial.print(F(" tells the compiler to place the unchanging text in program memory. If you use a lot of debug statements without adding the "F" option, your "dynamic memory" (I think the variable use dynamic memory) gets used up very quickly.

The line "Serial.println(opt);" sends the value of the variable "opt" to the terminal. The "ln" at the end of "println" adds a carriage return and a new line character to the end of the message (so the next debug statement will show up one line down).

I added a one second delay to make sure you can see the value of "opt" before anything else in the program occurs.

IMO, you'd be well served by adding these sorts of debug statements in various places in your code. You can use them to identify which branch of the program was executed. These sorts of debug statements make writing programs much much easier.

To view the debug statements, you select "Tools\Serial Monitor".

You will likely need to close the terminal window every so often if the IDE has trouble finding your Arduino. I usually have to do this if I've unplugged the Arduino from the USB.

This post combined with code was too long. I'll add the code in the next post.

Here's the code as posted in the top post with the above debug statements added.

/*
    Robot Power MultiMoto v1.0 demo
    This software is released into the Public Domain

    This demo shows the setup of the L9958 chips and runs the 4 motor outputs
    independently.  Also Timer0 and Timer1 are set to higher frequency than standard.
    This may affect the millisecond timer function.

    v1.0 - initial release

*/

// include the SPI library:
#include <SPI.h>

// L9958 slave select pins for SPI
#define SS_M4 14
#define SS_M3 13
#define SS_M2 12
#define SS_M1 11

// L9958 DIRection pins
#define DIR_M1 2
#define DIR_M2 3
#define DIR_M3 4
#define DIR_M4 7

// L9958 PWM pins
#define PWM_M1 9
#define PWM_M2 10    // Timer1
#define PWM_M3 5
#define PWM_M4 6     // Timer0

// L9958 Enable for all 4 motors
#define ENABLE_MOTORS 8

int pwm1, pwm2, pwm3, pwm4;
int dir1, dir2, dir3, dir4;


//Crane variables
//Arduino used pins
const int joyup = 15;
const int joydown = 16;
const int joyleft = 17;
const int joyright = 18;
const int joypress = 19;
const int coin = 20;
const int front = 21;
const int left = 22;
const int clawup = 23;
const int clawdown = 24;
const int ledPin =  13;

//Mics Variables
int moveLeft = 0;
int moveRight = 0;
int moveBack = 0;
int moveFront = 0;
int pressButton = 0;
int coinIn = 0;
int limitFront = 0;
int limitLeft = 0;
int limitUp = 0;
int limtiDown = 0;
int opt = 0;

void setup() 
{
  unsigned int configWord;
  Serial.begin(9600);
  // put your setup code here, to run once:
  pinMode(SS_M4, OUTPUT); digitalWrite(SS_M4, HIGH);  // HIGH = not selected
  pinMode(SS_M3, OUTPUT); digitalWrite(SS_M3, HIGH);
  pinMode(SS_M2, OUTPUT); digitalWrite(SS_M2, HIGH);
  pinMode(SS_M1, OUTPUT); digitalWrite(SS_M1, HIGH);

  // L9958 DIRection pins
  pinMode(DIR_M1, OUTPUT);
  pinMode(DIR_M2, OUTPUT);
  pinMode(DIR_M3, OUTPUT);
  pinMode(DIR_M4, OUTPUT);

  // L9958 PWM pins
  pinMode(PWM_M1, OUTPUT);  digitalWrite(PWM_M1, LOW);
  pinMode(PWM_M2, OUTPUT);  digitalWrite(PWM_M2, LOW);    // Timer1
  pinMode(PWM_M3, OUTPUT);  digitalWrite(PWM_M3, LOW);
  pinMode(PWM_M4, OUTPUT);  digitalWrite(PWM_M4, LOW);    // Timer0

  // L9958 Enable for all 4 motors
  pinMode(ENABLE_MOTORS, OUTPUT);  digitalWrite(ENABLE_MOTORS, HIGH);   // HIGH = disabled

  /******* Set up L9958 chips *********
  ' L9958 Config Register
  ' Bit
  '0 - RES
  '1 - DR - reset
  '2 - CL_1 - curr limit
  '3 - CL_2 - curr_limit
  '4 - RES
  '5 - RES
  '6 - RES
  '7 - RES
  '8 - VSR - voltage slew rate
  '9 - ISR - current slew rate
  '10 - ISR_DIS - current slew disable
  '11 - OL_ON - open load enable
  '12 - RES
  '13 - RES
  '14 - 0 - always zero
  '15 - 0 - always zero
  */

  // set to max current limit and disable ISR slew limiting
  configWord = 0b0000010000001100;

  SPI.begin();
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(SPI_MODE1);  // clock pol = low, phase = high

  // Motor 1
  digitalWrite(SS_M1, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M1, HIGH);
  // Motor 2
  digitalWrite(SS_M2, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M2, HIGH);
  // Motor 3
  digitalWrite(SS_M3, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M3, HIGH);
  // Motor 4
  digitalWrite(SS_M4, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M4, HIGH);

  // Reduce the PWM frequency to about 8kHz
  // Note, this will screw up the timer functions that use Timer0 such as millis()
  setPwmFrequency(PWM_M1, 8);
  setPwmFrequency(PWM_M3, 8);

  pinMode(joyup, INPUT);
  pinMode(joydown, INPUT);
  pinMode(joyleft, INPUT);
  pinMode(joyright, INPUT);
  pinMode(joypress, INPUT);
  pinMode(coin, INPUT);
  pinMode(front, INPUT);
  pinMode(left, INPUT);
  pinMode(clawup, INPUT);
  pinMode(clawdown, INPUT);
  pinMode(ledPin, OUTPUT);

}


// *******************************************
// ************** Main Loop ******************
// *******************************************
void loop() {

  moveLeft = digitalRead(joyleft);
  moveRight = digitalRead(joyright);
  moveBack = digitalRead(joyup);
  moveFront = digitalRead(joydown);
  pressButton = digitalRead(joypress);
  coinIn = digitalRead(coin);
  limitFront = digitalRead(front);
  limitLeft = digitalRead(left);
  limitUp = digitalRead(clawup);
  limtiDown = digitalRead(clawdown);

  if (moveLeft == HIGH)
  {
    opt = 1;
  }

  else if (moveRight == HIGH)
  {
    opt = 2;
  }
  else if (moveBack == HIGH)
  {
    opt = 3;
  }

  else if (moveFront == HIGH)
  {
    opt = 4;
  }
  else
  {
    opt = 0;
  }
  Serial.print(F("Pausing program to report the value of opt. opt = "));
  Serial.println(opt);
  delay(1000); // For debugging only. Remove from working code.
  
  switch (opt)
  {

    case 0:
      analogWrite(PWM_M1, 0);  digitalWrite(DIR_M1, 0);
      analogWrite(PWM_M2, 0);  digitalWrite(DIR_M2, 0);
      analogWrite(PWM_M3, 0);  digitalWrite(DIR_M3, 0);
      digitalWrite(ledPin, LOW);
      break;

    case 1:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
      break;

    case 2:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 1);
      break;

    case 3:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M3, 255);  digitalWrite(DIR_M3, 0);
      break;

    case 4:
      digitalWrite(ledPin, HIGH);
      analogWrite(PWM_M3, 255);  digitalWrite(DIR_M3, 1);
      break;
  }

  digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
}
// ***********************************************
// ************** End Main Loop ******************
// ***********************************************


/*
 * Divides a given PWM pin frequency by a divisor.
 *
 * The resulting frequency is equal to the base frequency divided by
 * the given divisor:
 *   - Base frequencies:
 *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
 *      o The base frequency for pins 5 and 6 is 62500 Hz.
 *   - Divisors:
 *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
 *        256, and 1024.
 *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
 *        128, 256, and 1024.
 *
 * PWM frequencies are tied together in pairs of pins. If one in a
 * pair is changed, the other is also changed to match:
 *   - Pins 5 and 6 are paired (Timer0)
 *   - Pins 9 and 10 are paired (Timer1)
 *   - Pins 3 and 11 are paired (Timer2)
 *
 * Note that this function will have side effects on anything else
 * that uses timers:
 *   - Changes on pins 5, 6 may cause the delay() and
 *     millis() functions to stop working. Other timing-related
 *     functions may also be affected.
 *   - Changes on pins 9 or 10 will cause the Servo library to function
 *     incorrectly.
 *
 * Thanks to macegr of the Arduino forums for his documentation of the
 * PWM frequency divisors. His post can be viewed at:
 *   http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/0#4
 */

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if (pin == 5 || pin == 6 || pin == 9 || pin == 10) { // Timer0 or Timer1
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if (pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode; // Timer0
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode; // Timer1
    }
  } else if (pin == 3 || pin == 11) {
    switch (divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode; // Timer2
  }
}

Draco_Elessar:
I got a motor to move, but it doesn't respond to the joystick. Here is the new void loop:

Why not take EVERYTHING out of that code except moveLeft = digitalRead(joyleft); and the parts directly related to that.

Then you will have a few lines of code that is much easier to debug. When it works, add a second move etc etc.

...R

  if (pressButton == HIGH)
  {
      analogWrite(PWM_M4, 255);  digitalWrite(DIR_M4, 0);
  }
  digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW

Shouldn't the digitalWrite statement be inside the "if"?
Like this:

  if (pressButton == HIGH)
  {
      analogWrite(PWM_M4, 255);  digitalWrite(DIR_M4, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW 
  }

Thank you everyone for the help!

DuaneDegn:
Here's the code as posted in the top post with the above debug statements added.

I'm getting something odd here is a bit of the output:

Pausing program to report the value of opt. opt = 0

Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 1
Pausing program to report the value of opt. opt = 1
Pausing program to report the value of opt. opt = 1
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 2
Pausing program to report the value of opt. opt = 2
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 3
Pausing program to report the value of opt. opt = 3
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 3
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 3
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 3
Pausing program to report the value of opt. opt = 0
Pausing program to report the value of opt. opt = 3
Pausing program to report the value of opt. opt = 0




If I have nothing attached to the arduino the value will be 0, sometimes 1 or 2. As soon as I only add wires I will get values. If I get near or touch the arduino, it will change the opt value. Everything installed but nothing press I will get an opt value. I have tried to add resistors (10k to ground and input side), but no luck. I'm not sure what this means. I have tried this on two different mega 2560, and the opt value will change on both without a button press. Both seams to like give the value 1 and 2 with everything installed but no button press. 



> Robin2:
> Why not take EVERYTHING out of that code except `moveLeft = digitalRead(joyleft);` and the parts directly related to that.
> 
> Then you will have a few lines of code that is much easier to debug. When it works, add a second move etc etc.
> 
> ...R



That's how I started. 





> Henry_Best:
> ```
>   if (pressButton == HIGH)

{
      analogWrite(PWM_M4, 255);  digitalWrite(DIR_M4, 0);
  }
  digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW




Shouldn't the digitalWrite statement be inside the "if"?
Like this:


if (pressButton == HIGH)
  {
      analogWrite(PWM_M4, 255);  digitalWrite(DIR_M4, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
  }

I noticed when I have the digitalWrite(ENABLE_MOTORS, LOW); // enable = LOW inside of multiple if statements nothing would work. It seams to have to only be in once but I'm not sure.

Is digitalReadd the only way to get an input value on an arduino?

Draco_Elessar:
That's how I started.

I did not realize that from your earlier posts.

Does that mean that you have a program that works properly with one input and movement in one direction?
If so, post that program.

...R

Robin2:
I did not realize that from your earlier posts.

Does that mean that you have a program that works properly with one input and movement in one direction?
If so, post that program.

...R

Here is what I used for void loop. Everything else was pretty much the same.

void loop() {
 
  if (digitalRead(joyleft) == HIGH)
  {
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
  }
}

As soon as I added a if else it would stop working. When I took the digitalWrite(ENABLE_MOTORS, LOW); // enable = LOW and put it at the end, I would sometimes get some type of movement or just a hum. I also got it to work with a while in place of the if. Again it only worked with one statement.

I think the issue I'm having is that it is reading digital inputs when there are none on two different Megas. Is there a way to make the Arduino less sensitive to the inputs? Or make it only accept a higher voltage? (Not sure if I am saying that right.) I have tried to add 10k resistors, but it will still read a digital input when nothing nothing is pressed.

Draco_Elessar:
Here is what I used for void loop. Everything else was pretty much the same.

"Pretty much the same" can include a whole host of errors. Post complete programs, not snippets.

Post the complete program that works and separately post the complete program with the changes that gave rise to the comment "As soon as I added a if else it would stop working"

That is the only way that I know to enable me to understand what you are actually doing.

Effective troubleshooting is a slow step-by-step business.

...R

It sounds as if your inputs are floating. Have you got pull-down resistors on them?

I decide to start from scratch. This is a basic code that works. When I move the joystick the motor moves.

/*
    Robot Power MultiMoto v1.0 demo
    This software is released into the Public Domain
    
    This demo shows the setup of the L9958 chips and runs the 4 motor outputs
    independently.  Also Timer0 and Timer1 are set to higher frequency than standard.
    This may affect the millisecond timer function.
    
    v1.0 - initial release

*/

// include the SPI library:
#include <SPI.h>

// L9958 slave select pins for SPI
#define SS_M4 14
#define SS_M3 13
#define SS_M2 12
#define SS_M1 11

// L9958 DIRection pins
#define DIR_M1 2
#define DIR_M2 3
#define DIR_M3 4
#define DIR_M4 7

// L9958 PWM pins
#define PWM_M1 9
#define PWM_M2 10    // Timer1
#define PWM_M3 5
#define PWM_M4 6     // Timer0

// L9958 Enable for all 4 motors
#define ENABLE_MOTORS 8

int pwm1, pwm2, pwm3, pwm4;
int dir1, dir2, dir3, dir4;

    const int joyup = 15;
    const int joydown = 19;
    const int joyleft = 24;
    const int joyright = 34;


void setup() {
  unsigned int configWord;
  
    // put your setup code here, to run once:
  pinMode(SS_M4, OUTPUT); digitalWrite(SS_M4, HIGH);  // HIGH = not selected
  pinMode(SS_M3, OUTPUT); digitalWrite(SS_M3, HIGH);
  pinMode(SS_M2, OUTPUT); digitalWrite(SS_M2, HIGH);
  pinMode(SS_M1, OUTPUT); digitalWrite(SS_M1, HIGH);
  
  // L9958 DIRection pins
  pinMode(DIR_M1, OUTPUT);
  pinMode(DIR_M2, OUTPUT);
  pinMode(DIR_M3, OUTPUT);
  pinMode(DIR_M4, OUTPUT);
  
  // L9958 PWM pins
  pinMode(PWM_M1, OUTPUT);  digitalWrite(PWM_M1, LOW);
  pinMode(PWM_M2, OUTPUT);  digitalWrite(PWM_M2, LOW);    // Timer1
  pinMode(PWM_M3, OUTPUT);  digitalWrite(PWM_M3, LOW);
  pinMode(PWM_M4, OUTPUT);  digitalWrite(PWM_M4, LOW);    // Timer0
  
  // L9958 Enable for all 4 motors
  pinMode(ENABLE_MOTORS, OUTPUT);  digitalWrite(ENABLE_MOTORS, HIGH);   // HIGH = disabled
  
  /******* Set up L9958 chips *********
  ' L9958 Config Register
  ' Bit
  '0 - RES
  '1 - DR - reset
  '2 - CL_1 - curr limit
  '3 - CL_2 - curr_limit
  '4 - RES
  '5 - RES
  '6 - RES
  '7 - RES
  '8 - VSR - voltage slew rate
  '9 - ISR - current slew rate
  '10 - ISR_DIS - current slew disable
  '11 - OL_ON - open load enable
  '12 - RES
  '13 - RES
  '14 - 0 - always zero
  '15 - 0 - always zero
  */
  
  // set to max current limit and disable ISR slew limiting
  configWord = 0b0000010000001100;
  
  SPI.begin();
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(SPI_MODE1);  // clock pol = low, phase = high
  
  // Motor 1
  digitalWrite(SS_M1, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M1, HIGH); 
  // Motor 2
  digitalWrite(SS_M2, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M2, HIGH);
  // Motor 3
  digitalWrite(SS_M3, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M3, HIGH);
  // Motor 4
  digitalWrite(SS_M4, LOW);
  SPI.transfer(lowByte(configWord));
  SPI.transfer(highByte(configWord));
  digitalWrite(SS_M4, HIGH);
  
  // Reduce the PWM frequency to about 8kHz
  // Note, this will screw up the timer functions that use Timer0 such as millis()
  setPwmFrequency(PWM_M1, 8);
  setPwmFrequency(PWM_M3, 8);


    pinMode(joyup, INPUT);
    pinMode(joydown, INPUT);
    pinMode(joyleft, INPUT);
    pinMode(joyright, INPUT);

}


// *******************************************
// ************** Main Loop ******************
// *******************************************
void loop() {
  // put your main code here, to run repeatedly:

  while (digitalRead(joyup) ==  HIGH)
    {
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  
  digitalWrite(ENABLE_MOTORS, HIGH);

 
  }
// ***********************************************
// ************** End Main Loop ******************
// ***********************************************


/*
 * Divides a given PWM pin frequency by a divisor.
 * 
 * The resulting frequency is equal to the base frequency divided by
 * the given divisor:
 *   - Base frequencies:
 *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
 *      o The base frequency for pins 5 and 6 is 62500 Hz.
 *   - Divisors:
 *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
 *        256, and 1024.
 *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
 *        128, 256, and 1024.
 * 
 * PWM frequencies are tied together in pairs of pins. If one in a
 * pair is changed, the other is also changed to match:
 *   - Pins 5 and 6 are paired (Timer0)
 *   - Pins 9 and 10 are paired (Timer1)
 *   - Pins 3 and 11 are paired (Timer2)
 * 
 * Note that this function will have side effects on anything else
 * that uses timers:
 *   - Changes on pins 5, 6 may cause the delay() and
 *     millis() functions to stop working. Other timing-related
 *     functions may also be affected.
 *   - Changes on pins 9 or 10 will cause the Servo library to function
 *     incorrectly.
 * 
 * Thanks to macegr of the Arduino forums for his documentation of the
 * PWM frequency divisors. His post can be viewed at:
 *   http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/0#4
 */
 
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) { // Timer0 or Timer1
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) { 
      TCCR0B = TCCR0B & 0b11111000 | mode; // Timer0
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode; // Timer1
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode; // Timer2
  }
}

NOTE: All of the code below uses the same as above with just the void loop being different.

When I add another while statement like below. The motor will go in different directions.

void loop() {
  // put your main code here, to run repeatedly:

  while (digitalRead(joyup) ==  HIGH)
    {
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  while (digitalRead(joydown) ==  HIGH)
    {
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 1);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  
  digitalWrite(ENABLE_MOTORS, HIGH);

 
  }

When I add code that uses the second motor (see below) is when things go a bit crazy. I believe it could be the inputs are floating, or something similar. When only one microswitch is pressed both motors will move. Its the same with all of them.

void loop() {
  // put your main code here, to run repeatedly:

  while (digitalRead(joyup) ==  HIGH)
    {
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  while (digitalRead(joydown) ==  HIGH)
    {
      analogWrite(PWM_M1, 255);  digitalWrite(DIR_M1, 1);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  while (digitalRead(joyright) ==  HIGH)
    {
      analogWrite(PWM_M2, 255);  digitalWrite(DIR_M2, 0);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  while (digitalRead(joyleft) ==  HIGH)
    {
      analogWrite(PWM_M2, 255);  digitalWrite(DIR_M2, 1);
      digitalWrite(ENABLE_MOTORS, LOW);  // enable = LOW
    }
  
  digitalWrite(ENABLE_MOTORS, HIGH);

 
  }

There is a 10K Resistor on the shared ground.

Here is a few things I have tried:
Putting another ground on the NC on the microswitch
Putting 5v on NC on the microswitch
Trying to change the pinMode(, INPUT); to pinMode(, INPUT_PULLUP);
Adding digitalWrite(****, HIGH) for each of the pinModes
moved the pins so they where not next to each other
All combination of above.

I'm wondering if it's the thin wire with pins I am using (it came with the Mega.)

Any ideas on how to get the Arduino to stop reading multiple inputs?

Draco_Elessar:
There is a 10K Resistor on the shared ground.

What does that mean?
Please provide a wiring diagram - preferably a photo of a pencil drawing.

I would expect INPUT_PULLUP to deal with any floating pin problem.

Is there an adequate power supply for the motors - I've forgotten if you mentioned it?

...R

Robin2:
What does that mean?
Please provide a wiring diagram - preferably a photo of a pencil drawing.

I would expect INPUT_PULLUP to deal with any floating pin problem.

Is there an adequate power supply for the motors - I've forgotten if you mentioned it?

...R

I combined all of the ground wires and then put a resistor before it goes into the arduino.

Hope this works. A hand drawing by me would not be legible. Not to sure on the correct symbols to use for the microswitches.

The power supply is a 24v, not sure of the wattage. Here are the specks and link.

-Input Voltage: 200V~240V/100V~120V ±20%
-Output Voltage: 24V DC
-Output Current: 0~15.0A
-Shell Material: Metal case / Aluminum base
-Protection: Shortage Protection, Overload Protection, Over Voltage Protection
-Widely used in Industrial automation, LED display, communications, etc.
-Safety Compliance: CCC/ FCC / CE
-Working Temperature: 0~40℃
-Storage Temperature: -20~60℃
-Ambient Humidity: 0~95% Non-Condensation

http://www.amazon.com/gp/product/B00ANFJ26U?psc=1&redirect=true&ref_=oh_aui_detailpage_o04_s01