Motor connected to PWM pins move during Programming and Reset

Hi guys,

I'm using Arduino Due's PWM to control dc motors with absolute encoder as my feedback. I'm experiencing a problem where the motors move during programming, reset, and start-up of the code. The motor driver PWM input is connected at pins 7-13 of the Arduino Due. Btw, I'm using a Pololu MD31B as my motor drivers. (See attached schematic picture below for better visualization)

From what I've read, the arduino during these states default the pin to an input pin, and suggest to put a pull-down resistor for these pins. Is this correct? Any help and suggestions for the circuit will be greatly appreciated. Thank you.

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.

Do you have the gnd of the DUE connected to the gnd of the motor controllers?

You schematic does not show how you have power supplies connected to the DUE or the motor drivers.

Tom.... :slight_smile:

Hi,

I'm truly sorry for not following the guidelines. I will do my best from now on.

I'm powering up the arduino due using the USB port right now. Therefore, I think that the gnd of the input side of the motor driver is connected to the gnd of the arduino due. For the output side of the motor driver, we are using an external power supply, and the grounds of the input side and output side of the motor driver are not connected.

huskylcl:
I'm powering up the arduino due using the USB port right now. Therefore, I think that the gnd of the input side of the motor driver is connected to the gnd of the arduino due. For the output side of the motor driver, we are using an external power supply, and the grounds of the input side and output side of the motor driver are not connected.

That is not what you show on your schematic, where are the gnd connections between the DUE and the gnd terminals shown on the motor controller.
This is essential as the motor controller input needs the DUE gnd as reference for the input signal.
Use a DMM to check if need be.
The gnds of the input of the motor controller and the motor power supply terminals will be connected internally on the motor controller PCB.
Thanks.. Tom... :slight_smile:

Hi,
You also show three connections to the Bourns Absolute Encoders, where are the supply and gnd connections?
Tip; Your circuit is a screen grab, your CAD should be able to Export a jpg or png image file that will be clearer.(Not a pdf)

Tom... :slight_smile:

TomGeorge:
Hi,
You also show three connections to the Bourns Absolute Encoders, where are the supply and gnd connections?
Tip; Your circuit is a screen grab, your CAD should be able to Export a jpg or png image file that will be clearer.(Not a pdf)

Tom... :slight_smile:

Sorry for the confusing schematic since it is still ongoing. I'm powering up the arduino using the usb port connected to the computer, and the encoders power and gnd pins are connected to the 5V pin and GND pin of the arduino due respectively.

TomGeorge:
That is not what you show on your schematic, where are the gnd connections between the DUE and the gnd terminals shown on the motor controller.
This is essential as the motor controller input needs the DUE gnd as reference for the input signal.
Use a DMM to check if need be.

Yes, the gnd of the motor controller is connected to the gnd of the arduino due. And, an external power supply is used as supply for the Vin for more current draw.

Hi,
Okay, can you now post your code?
When you were writing your code did you do it in stages?
If so at what stage did this problem occur?

Tom... :slight_smile:

huskylcl:
and the encoders power and gnd pins are connected to the 5V pin and GND pin of the arduino due respectively.

The Due is 3.3volt logic...

TomGeorge:
Hi,
Okay, can you now post your code?
When you were writing your code did you do it in stages?
If so at what stage did this problem occur?

Tom... :slight_smile:

#include <DueTimer.h>
#include <PID_v1.h>
#include "EncoderReader.h"

//  encoder 
#define clkPin 52
#define csPin 53

// link 1
#define link1FeedbackPin 50
#define link1PWMPin 13
#define link1DirPin 15

// link 2
#define link2FeedbackPin 49
#define link2PWMPin 12
#define link2DirPin 16

// jaw 1
#define jaw1FeedbackPin 47
#define jaw1PWMPin 11
#define jaw1DirPin 17

// jaw 2
#define jaw2FeedbackPin 46
#define jaw2PWMPin 10
#define jaw2DirPin 18

// wrist
#define wrist1FeedbackPin 45
#define wrist1PWMPin 9
#define wrist1DirPin 19

// roll
#define rollFeedbackPin 44
#define rollPWMPin 8
#define rollDirPin 20

// prism
#define prismFeedbackPin 42
#define prismPWMPin 7
#define prismDirPin 21

double kp = 1 , ki = 0 , kd = 0;             // modify for optimal performance

double link1Input = 0, link1Output = 0, link1Setpoint = 0;
double link2Input = 0, link2Output = 0, link2Setpoint = 0;
double jaw1Input = 0, jaw1Output = 0, jaw1Setpoint = 0;
double jaw2Input = 0, jaw2Output = 0, jaw2Setpoint = 0;
double wristInput = 0, wristOutput = 0, wristSetpoint = 0;
double rollInput = 0, rollOutput = 0, rollSetpoint = 0;
double prismInput = 0, prismOutput = 0, prismSetpoint = 0;

PID link1PID(&link1Input, &link1Output, &link1Setpoint, kp, ki, kd, DIRECT); 
PID link2PID(&link2Input, &link2Output, &link2Setpoint, kp, ki, kd, DIRECT); 
PID jaw1PID(&jaw1Input, &jaw1Output, &jaw1Setpoint, kp, ki, kd, DIRECT); 
PID jaw2PID(&jaw2Input, &jaw2Output, &jaw2Setpoint, kp, ki, kd, DIRECT); 
PID wristPID(&wristInput, &wristOutput, &wristSetpoint, kp, ki, kd, DIRECT); 
PID rollPID(&rollInput, &rollOutput, &rollSetpoint, kp, ki, kd, DIRECT); 
PID prismPID(&prismInput, &prismOutput, &prismSetpoint, kp, ki, kd, DIRECT); 

EncoderReader link1;
EncoderReader link2;
EncoderReader jaw1;
EncoderReader jaw2;
EncoderReader wrist;
EncoderReader roll;
EncoderReader prism;

int ledPin = 13;
// int clkPin = 52;
// int csPin = 53;
// int rollPin = 44;
// int jaw1Pin = 47;
// int jaw2Pin = 46;
// int wristPin = 45;

// int PWMPin_jaw1 = 11;
// int PWMPin_jaw2 = 10;
// int PWMPin_wrist = 9;
// int dirPin_jaw1 = 17;
// int dirPin_jaw2 = 18;
// int dirPin_wrist = 19;

boolean ledState = false;

void ledStatus (){
  digitalWrite(ledPin, ledState = !ledState);
}

void encoderRead(){
  link1.reading = link1.ReadAbsoluteAngle();
  link2.reading = link2.ReadAbsoluteAngle();
  jaw1.reading = jaw1.ReadAbsoluteAngle();
  jaw2.reading = jaw2.ReadAbsoluteAngle();
  wrist.reading = wrist.ReadAbsoluteAngle();
  roll.reading = roll.ReadAbsoluteAngle();
  prism.reading = prism.ReadAbsoluteAngle();
}

void setup() {
  
  Serial.begin(115200);

  link1.Setup(clkPin, csPin, link1FeedbackPin);
  link2.Setup(clkPin, csPin, link2FeedbackPin);
  jaw1.Setup(clkPin, csPin, jaw1FeedbackPin);
  jaw2.Setup(clkPin, csPin, jaw2FeedbackPin);
  wrist.Setup(clkPin, csPin, wrist1FeedbackPin);
  roll.Setup(clkPin, csPin, rollFeedbackPin);
  prism.Setup(clkPin, csPin, prismFeedbackPin);

  link1PID.SetMode(AUTOMATIC);
  link1PID.SetSampleTime(1);
  link1PID.SetOutputLimits(-255, 255);

  link2PID.SetMode(AUTOMATIC);
  link2PID.SetSampleTime(1);
  link2PID.SetOutputLimits(-255, 255);

  jaw1PID.SetMode(AUTOMATIC);
  jaw1PID.SetSampleTime(1);
  jaw1PID.SetOutputLimits(-255, 255);

  jaw2PID.SetMode(AUTOMATIC);
  jaw2PID.SetSampleTime(1);
  jaw2PID.SetOutputLimits(-255, 255);

  wristPID.SetMode(AUTOMATIC);
  wristPID.SetSampleTime(1);
  wristPID.SetOutputLimits(-255, 255);

  rollPID.SetMode(AUTOMATIC);
  rollPID.SetSampleTime(1);
  rollPID.SetOutputLimits(-255, 255);

  prismPID.SetMode(AUTOMATIC);
  prismPID.SetSampleTime(1);
  prismPID.SetOutputLimits(-255, 255);

  // pinMode(ledPin, OUTPUT);

  pinMode(link1PWMPin, OUTPUT);
  pinMode(link1DirPin, OUTPUT);
  digitalWrite(link1DirPin, HIGH);

  pinMode(link2PWMPin, OUTPUT);
  pinMode(link2DirPin, OUTPUT);
  digitalWrite(link2DirPin, HIGH);

  pinMode(jaw1PWMPin, OUTPUT);
  pinMode(jaw1DirPin, OUTPUT);
  digitalWrite(jaw1DirPin, HIGH);
  
  pinMode(jaw2PWMPin, OUTPUT);
  pinMode(jaw2DirPin, OUTPUT);
  digitalWrite(jaw2DirPin, HIGH);
  
  pinMode(wrist1PWMPin, OUTPUT);
  pinMode(wrist1DirPin, OUTPUT);
  digitalWrite(wrist1DirPin, HIGH);
  
  pinMode(rollPWMPin, OUTPUT);
  pinMode(rollDirPin, OUTPUT);
  digitalWrite(rollDirPin, HIGH);
  
  pinMode(prismPWMPin, OUTPUT);
  pinMode(prismDirPin, OUTPUT);
  digitalWrite(prismDirPin, HIGH);

  Timer1.attachInterrupt(encoderRead).setFrequency(340).start();
  // Timer2.attachInterrupt(ledStatus).setFrequency(2).start();
}

void turnClockWise(int dirPin) {
  digitalWrite(dirPin, HIGH);
}

void turnCounterClockWise(int dirPin) {
  digitalWrite(dirPin, LOW);
}

void pwmOut(int pidOutput, int dirPin, int PWMPin){
  if (pidOutput > 0)
  {
    turnClockWise(dirPin);
    analogWrite(PWMPin, pidOutput);
    // digitalWrite(ledPin, HIGH);
    } else
  {
    turnCounterClockWise(dirPin);
    analogWrite(PWMPin, abs(pidOutput));
    // digitalWrite(ledPin, LOW);

  }
}

void loop(){

  if (Serial.available() > 0) {
    int i = Serial.parseInt();
    link1Setpoint = i;
  }

  link1Input = link1.reading / 21;
  
  wristPID.Compute();
  jaw1PID.Compute();
  
  pwmOut(wristOutput, wrist1DirPin, wrist1PWMPin);

  Serial.print("link1: ");
  Serial.print(link1.reading);
  Serial.print(" link2: ");
  Serial.print(link2.reading);
  Serial.print(" jaw1: ");
  Serial.print(jaw1.reading/21);
  Serial.print(" jaw2: ");
  Serial.print(jaw2.reading/21);
  Serial.print(" wrist: ");
  Serial.print(wrist.reading/21);
  Serial.print(" roll: ");
  Serial.println(roll.reading/21);
}

What stages? Currently, we are able to position the motors at the desired angle using PID controllers. The problem we have right now is that the motors spin during sketch upload or if the reset button of the arduino due is held (it stops when the reset button is released).

Wawa:
The Due is 3.3volt logic...

Yes. But the arduino due has an on-board regulator that provides a 5V output. We only use this to power up the encoders. We are primarily powering up the arduino using the USB port.

Hi,

What stages?

Didn't you write your code a section at a time, for example

  • Get an encoder working.
  • Just get all the encoders working.
  • Just get a motor driver working and running.
  • Just get all the motor drivers working.
  • Implement PID ONLY on one motor and get it running.
  • Implement PID on all motors and get it running.
  • Combine encoder and PID/motor combination.

If so, at what stage did the motor startup problem occur?
You do realize that you can use the ENA pins on the motor driver to disable the motor driver until you need it?

Tom..... :slight_smile:

Hi,


The SLP pin puts the driver to sleep.

Tom... :slight_smile:

TomGeorge:
Hi,
Didn't you write your code a section at a time, for example

  • Get an encoder working.
  • Just get all the encoders working.
  • Just get a motor driver working and running.
  • Just get all the motor drivers working.
  • Implement PID ONLY on one motor and get it running.
  • Implement PID on all motors and get it running.
  • Combine encoder and PID/motor combination.

If so, at what stage did the motor startup problem occur?
You do realize that you can use the ENA pins on the motor driver to disable the motor driver until you need it?

Tom..... :slight_smile:

Ohhhh. Yes we did all of the stages you've mentioned except for implementing it in all motors. The problem occurred in all stages. We decided to resolve this problem first before doing that.

TomGeorge:
Hi,


The SLP pin puts the driver to sleep.

Tom... :slight_smile:

Thank you for pointing this out. I didn't saw this. I'll try this one out.

Hi,
I'm not too familiar with the DUE, only used it a couple of times for contactless encoder (high speed) application.
As the specs state, the driver is 1V8, 3V3, and 5V compatible.

When the DUE boots, ALL outputs will be inputs and floating, knowing that the driver can read 1V8 as HIGH I wonder if the floating connection is causing the problem.
Try on one driver, connecting a 10K resistor from each of the signal wires to gnd, so the output during bootup is held at gnd potential.

Just a wild thought.

Tom... :slight_smile: