Loading...
Pages: [1] 2   Go Down
Author Topic: How do i change direction  (Read 339 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi.
I have a question - might be trivial. I am on my way to control a motor in both directions, using a MegaMoto shield. The thing is - changing direction is done by changing the PWM-outputpin, but when i do that, the old outputpin is still HIGH thereby making the motor act like a brake. So i need a way to flip between the pins and at the same time setting the last used as LOW. I have of cause tried adding a line of code at the end, changing both pins to low, but that seems like it is adding a lot of delay to the system and also making the motor change direction a few times before rotating in the desired direction. the same goes for adding a pull-down.

Thank you. 
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1000
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You have to switch the output between analogWrite() and pinMode() with digitalWrite().

I think it is like this (A=PWM-A, B=PWM-B):
Forward: B LOW, PWM to A
Backward: A LOW, PWM to B
Break: A LOW, B LOW

You don't need a pull-down resistor.
Logged

UK
Offline Offline
Tesla Member
***
Karma: 89
Posts: 6400
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have of cause tried adding a line of code at the end, changing both pins to low, but that seems like it is adding a lot of delay to the system and also making the motor change direction a few times before rotating in the desired direction.

You must be doing it wrong - what you're describing could be done in a fraction of a millisecond, far faster than the motor could react. I suggest you post your code, perhaps we can suggest how to improve it.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Post my code........ hmm.. okay, you asked for it.
I am very new to this (Arduino and code in general) so please leave me with some useful criticism that can help me get better.

What happens when loading this to the Arduino, is that the motor will spin in one direction (the initial one), but if i try to change direction the motor acts like a brake (the motor leads are shortened) and stay this way.


Here it is:
Code:

#include <PID_v1.h>

//Define Variables we'll be connecting to
double SetpointPin = A5; //Setpoint from transducer
double InputPin = 0; //Feedback signal
double OutputPinCCW = 3; // OutputCCW (PWM)
double OutputPinCW = 11;

double Setpoint = 0;
double Input = 0;
double Output = 0;

int ENA = 8;
int CW = 7;    //clockwise


//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

void setup()
{
  Serial.begin(9600);  //Opens serial at 9600 bps
 
    //initialize the variables we're linked to
 
  pinMode(InputPin, INPUT);                //are these necessary?
  pinMode(SetpointPin, INPUT);
  pinMode(OutputPinCCW, OUTPUT);
  pinMode(ENA, OUTPUT);
   
  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{
  digitalWrite(ENA, HIGH);              // Leave on HIGH 
  if (digitalRead(CW) == HIGH) {
   
 Input = analogRead(InputPin)*2;        //returns voltage*0.5 if full H-bridge config
 Input = map(Input,0, 611, 0, 1023);    //input ranging from 0-3V, converting to 0-1023
 Setpoint = analogRead(SetpointPin);
 
  myPID.Compute();
  analogWrite(11, Output);               
 
  }
 
  if (digitalRead(CW) == LOW){
   
    Input = analogRead(InputPin)*2;
    Input = map(Input,0, 611, 0, 1023);
 
    Setpoint = analogRead(SetpointPin);
    myPID.Compute();
    analogWrite(3, Output); //Output (PWM) on pin 11
   
  }

  Serial.write("OUTPUT:");
  Serial.println(Output);
  Serial.write("Setpointet er:");
  Serial.println(Setpoint);
  Serial.write("Inputtet er");
  Serial.println(Input);
  delay(2);
 
 
}


Thank you for your time, cant wait until i will be the one helping others out.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 316
Posts: 35566
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Input = analogRead(InputPin)*2;        //returns voltage*0.5 if full H-bridge config
 Input = map(Input,0, 611, 0, 1023);    //input ranging from 0-3V, converting to 0-1023
 Setpoint = analogRead(SetpointPin);
The analogRead and map functions deal with integers. Why are you using doubles?

Input and Setpoint are in the range 0 to 1023. Output will be in what range? I'd expect it to be in the same range, but you are using it as a PWM value, which needs to be in the range 0 to 255.

Where are you actually setting the direction pin?
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1000
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have some useful remarks: please delete the sketch.
I'm serious, you should make a fresh start.

You want to read input pins, use a motor shield, write a sketch, use a PID library (never easy).... all at once.
Not even a advanced programmer would try this.

Forget the PID for now.

Try to get the motor running. How is the shield connected ?
The motor should be connected to X1-1 and X1-2.
You need an enable but also two PWM outputs PWMA and PWMB.
Write a sketch that makes the motor run, nothing else.

To declare an output pin, use this: const int pinname = 10;
Not a 'double'.

Write to the serial monitor what you are doing, like this: Serial.println("Forward for 5 seconds");

Use delays between the actions, and let the motor run forward, backward, slow, fast.

After that, read the input pins.

After that, you could try the PID.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have some useful remarks: please delete the sketch. DONE
I'm serious, you should make a fresh start.

You want to read input pins, use a motor shield, write a sketch, use a PID library (never easy).... all at once.
Not even a advanced programmer would try this.

Forget the PID for now.

Try to get the motor running. How is the shield connected ? mounted on top of the Arduino (is that not the idea/function of a shield?)
The motor should be connected to X1-1 and X1-2. What is that?
You need an enable but also two PWM outputs PWMA and PWMB.
Write a sketch that makes the motor run, nothing else.

To declare an output pin, use this: const int pinname = 10;
Not a 'double'.

Write to the serial monitor what you are doing, like this: Serial.println("Forward for 5 seconds");

Use delays between the actions, and let the motor run forward, backward, slow, fast.

After that, read the input pins.

After that, you could try the PID.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@ PaulS
Yes i will be using PWM, but the pid basic example does that (converts from 0-1023 to 0-255) as i understand it.
Logged

Johannesburg UTC+2
Offline Offline
Edison Member
*
Karma: 34
Posts: 1705
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

But what's the PID for anyway?- are you actually reading a sensor to give you a setpoint that the PID homes to? (I haven't looked at that sketch closely, not even sure what that setpoint is... position? I see PID examples around which make a DC motor into a servo... is this one of them? Where did the code come from and what's it for?)

But I'm with Krodal on this, that there's too much to get going first time round the block, especially since you are new to both Arduino and coding....
Logged

IT Crowd:
Roy... "Have you tried turning it off and on again?"
Moss.. "Have you tried forcing an unexpected reboot?"

Offline Offline
Edison Member
*
Karma: 9
Posts: 1000
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The motor should be connected to X1-1 and X1-2. What is that?

I'm sorry, I was looking at the schematic, I should have been looking at the user manual.
Can you perhaps make a photo of the jumpers and attach it, so we can check the Arduino pins you use.
The normal way for a H-bridge mode seems this:
PWMA to D11
PWMB to D3
ENABLE to D8
SENSOR : jumper between A3 and A2 and A0, see figure 3 and 4 in user manual.

I would write the code like this:
Code:
const int pinPWMA 11;
const int pinPWMB 3;
const int pinENABLE 8;
const int pinSENSOR 0;        // analog input

Set the mode of the pins, set one pin high, the other low, and see the motor run.
Change the high and low for the pins, and the motor should run in the opposite direction.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The project i want to end up with is this:

I am trying to control the torque of a motor in both directions (CW & CCW) through MegaMoto Plus motor board:

http://www.robotpower.com/downloads/MegaMoto-user-manual.pdf

And the motor i want to control:

http://www.pml.com.cn/ver2en/motors/GPM16LR.html

The control signal (signal into the Arduino) is a +-5V where - = CW and + = CCW rotation. This signal is generated by a torque transducer. As an input signal is given to the Arduino, the motor must produce a torque and continue to do so, even after the motor has stopped because the load is greater than the torque produced from the motor.
You can think of it as a motor connected to a spring. When an input signal of eg. +2V the motor has to turn CCW with a torque 2/5 of maximum, hereby extending the spring  - at some point the force from the spring will be the same as the torque/force from the motor and then then the system has reached an equilibrium. if you apply a higher input the motor will start turning CCW again and if you lower the signal the motor will unroll the spring until a new equilibrium has been reached. If no signal is provided the motor must become "loose" and the spring will be the only force (neglecting friction) in the system.

Some will probably ask me why i dont just use a position servo so i will reveal right away that i need to control the torque, NOT the position.
 
My guess is that i can use a closed loop servo approach, but instead of the feedback signal being a encoder it will be a current measurement. I want to use the current sensors in the motor shield hereby generating an error signal for the feedback loop. The error signal will result in a change in the PWM cycle in order to reduce the error so the produced torque will actually reach the desired value. Is that right?

The system has to end up being a steer by wire system with haptic feedback. Because it will be a steering-mechanism it is important that there is no overshoot, thats why i think that the PID (or maybe PI only) is important to incorporate!
 
I am learning every day, so please bear with me.

Bjorn
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@ Krodal

I am using the pins just as in the manual, and as you are describing.

For now i have added a pot as the torque transducer (it easier to test with) and the motor connected is not the one i will be using (see previous post).
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1000
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for your explanation.

I suggest to continue with a very small sketch, just to make the motor run in both directions and with PWM.

A function that controls the motor would be needed. Perhaps with an integer parameter from -1000 to +1000. The sign is the direction and '0' would be a 'stop'.

But first you have to get to know the MegaMotor shield. Just try a few things.

I don't know about using the current feedback. A PID and a current feedback will create a torque. So far I understand it, but I don't know how it will be if you actually use it for real.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the reply.
Well, for PMDC motors the torque is proportional to current - the motor-shield i have, has an analog current sensor that provides a voltage to the Arduino.  You can monitor this with the Arduino to give torque feedback as torque is equal to T=Kt*I, where T is torque, Kt is the motor torque constant, and I is the current. I need a linearly increasing output torque with respect to my input (torque transducer).

Code:

const int pinPWMA = 11;
const int pinPWMB = 3;
const int pinENABLE = 8;
const int pinTRANSDUCER = 5;        // analog input (for now a POT)

int Setpoint = 5;

int CW = 7;


void setup()
{
  pinMode(pinPWMA, OUTPUT);
  pinMode(pinPWMB, OUTPUT);
  pinMode(pinENABLE, OUTPUT);
  pinMode(pinTRANSDUCER, INPUT);
  pinMode(Setpoint, INPUT);
  pinMode(CW, INPUT);
 
 
 
  Serial.begin(9600);

  digitalWrite(pinENABLE, HIGH);
  delay(500);
  digitalWrite(pinENABLE, LOW);// Reset overcurrent or overtemp fault.  May need to let the MegaMoto cool.
  delay(500);
  digitalWrite(pinENABLE, HIGH);
 
}

void loop()
{
  if (digitalRead(CW) == HIGH) {
    digitalWrite(pinPWMB, LOW);
    digitalWrite(pinPWMA, HIGH);
    /*Setpoint = analogRead(pinTRANSDUCER);
    analogWrite(pinPWMA, Setpoint / 4);
    */   
  }
 else {
   digitalWrite(pinPWMA, LOW);
   digitalWrite(pinPWMB, HIGH);
   /*Setpoint = analogRead(pinTRANSDUCER);
    analogWrite(pinPWMB, Setpoint / 4);
     */
 }
   
    Serial.write("Transducer input:");
    Serial.println(Setpoint);
    delay(10);
}


I am still having problems with the motor switching direction a few times when i connect CW to 3.3V (change direction) before "settling " in the correct direction. as you can see in the sketch i have tried with adjusting the speed and full speed.
 Also, when i get close to the pin with my finger, it does the same (switch direction) - do i need to add a pulldown or something to prevent that? 
 
Logged

Offline Offline
Edison Member
*
Karma: 9
Posts: 1000
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are doing fine.
But I would like to make smaller steps.
Don't use any input for now.

Can you try this:
Make the motor run; wait some time; run motor in other direction. You have that almost. Perhaps you can make a function for it.
Make a sketch to test the inputs and write strings to the serial monitor like this : Serial.println("Input is now high");
Only after that make a sketch that combines both.

I don't understand how you use the 3 inputs, but if an input is not connected, it can be anything and (barely) touching it has a big influence. The impedance of the inputs is very high.
Logged

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