Motor file driving a dual PWM Magnevation Board

16 Mar 2011

Hi everyone, I'm trying to run two motors up to full speed in one direction then reverse them using an old Magnevation board I have. The problem I have is at full speed in one direction the output for speed direction changes hence not a nice result! The pwm voltage output ramps up nicely from 0v to +3.2v then ramps down again to 0v. Where am I going wrong in the code please??

// Sweep the motor speed from full-speed reverse (-1.0) to full speed forwards (1.0)
// Thank you for the code :-)

#include "mbed.h"
#include "Motor.h"


// For the Magnevation dual PWM module:-
// Channel 1: p5 remains low on pin40(Magnevation) which is the brake pin to allow the motor to run.
// When p6 is toggled between high/low motor direction is reversed.
// Channel 2: p7 remains low on pin38(Magnevation) which is the brake pin to allow the motor to run.
// When p8 is toggled between high/low motor direction is reversed.
// p5 and p7 outputs are not connected - pin40 and pin38 tied to Gnd (Magnevation)
Motor RightWheel(p23, p6, p5); // pwm, fwd/rev, brake
Motor LeftWheel(p25, p8, p7);  // pwm, fwd/rev, brake

DigitalOut DirectionR=p6;
DigitalOut DirectionL=p8;

void DriveForward() {
    for (float s= -1.0; s < 1.0 ; s += 0.01) {
        DirectionR=1;//Set the direction Right motor
        DirectionL=1;//Set the direction Left motor
        RightWheel.speed(s);
        LeftWheel.speed(s);
        wait(0.2);
    }
}

void DriveReverse() {
    for (float s= -1.0; s < 1.0 ; s += 0.01) {
        DirectionR=0;//Set the direction Right motor
        DirectionL=0;//Set the direction Left motor
        RightWheel.speed(s);
        LeftWheel.speed(s);
        wait(0.2);
    }
}

void ZeroSpeedForward() {
           for (float s = 1.0; s = 0.0; s -= 0.01) {
            DirectionR=1;//Set the direction Right motor
            DirectionL=1;//Set the direction Left motor
            RightWheel.speed(s);
            LeftWheel.speed(s);
            wait(0.2);
        }
   }
   
void ZeroSpeedReverse() {   
          for (float s = -1.0; s = 0.0; s += 0.01) {
            DirectionR=0;//Set the direction Right motor
            DirectionL=0;//Set the direction Left motor
            RightWheel.speed(s);
            LeftWheel.speed(s);
            wait(0.2);
        }
}

int main() {
    while (1) {
        DriveForward();
        wait(5);
        ZeroSpeedForward();//Before changing direction best to zero the speed on the motors!
        wait(5);
        DriveReverse();
        wait(5);
        ZeroSpeedReverse();
    }
}
16 Mar 2011

I don't know why I do this but for some reason I read backwards. The first thing I noticed is no wait(5) between the ZeroSpeedReverse() at the end of the loop and the DriveForward(); at the start of the loop. Is that an issue?

16 Mar 2011

LOL, thanks Andy I will code it now and try it..............

16 Mar 2011

Derek,

in the FOR statements for both ZeroSpeedForward() and ZeroSpeedReverse(), the comparison operation is using an assignment (= instead of ==). Another problem is you are trying to compare equality with a floating point value which should never be done. Floating point values are approximations of the value you request, not exact, always use an inequality such as <=, >= or just <, or >.

Don

16 Mar 2011

Well whats happening now is the motors are still jumping off the table because they reverse direction at max speed then ramp down. At their zero speed they reverse direction perfectly???

16 Mar 2011

Made the changes Don kindly suggested - Result.....When motors reach zero speed and pause for 5 secs they start at full speed? When they reach full speed same result as before, instant change at full speed to full speed in other direction??

16 Mar 2011

Ok, read a bit more, I'm confused about your setting for the PWM. The comment indicates the range is -1.0 to 1.0 for full reverse to full forward, however there is also a direction pin, so my question is: should range be 0.0 to 1.0 and a specified direction? Or am I missing something else?

Also noticed DriveReverse() is a copy of DriveForward() with the direction bits changed. The starting value of s and the direction should probably be different.

16 Mar 2011

Time for bed I'm afraid, thanks Don I think this thread is almost there I've changed the range to 0.0 - 1.0 and -1.0 0.0 and its almost there. They only jump off the table when they change speed from zero speed in one direction only if that makes sense?

More tomorrow....

16 Mar 2011

Glad to be of some help. Hopefully it will all be clear after some rest.

17 Mar 2011

After a sleep (and hard day at work) here we go again. So far tonight the forward speed is working perfectly ramping up to full speed and then ramping back down to zero. The output voltage from pins 23 and 25 on the mbed is +0 to +3.2v

The problem is still occurring however that for the reverse functions the output voltage from pins 23 and 25 on the mbed starts for some reason at +3.2 then ramps to +0?? So in reverse mode I still have the motors jumping off the table!

I'm pretty sure thanks to Dans comments and advice the code is correct.

Any more advice is very welcome, here is the new code I'm using.

// Sweep the motor speed from full-speed reverse (-1.0) to full speed forwards (1.0)
// Thank you for the code :-)

#include "mbed.h"
#include "Motor.h"


// For the Magnevation dual PWM module:-
// Channel 1: p5 remains high on pin40 which is the brake pin to allow the motor to run.
// When p6 is toggled between high/low motor direction is reversed.
// Channel 2: p7 remains high on pin38 which is the brake pin to allow the motor to run.
// When p8 is toggled between high/low motor direction is reversed.

Motor RightWheel(p23, p6, p5); // pwm, fwd/rev, brake
Motor LeftWheel(p25, p8, p7);  // pwm, fwd/rev, brake

DigitalOut DirectionR=p6;
DigitalOut DirectionL=p8;

void DriveForward() {
    for (float s= 0.0; s < 1.0 ; s += 0.01) {
        DirectionR=1;//Set the direction Right motor
        DirectionL=1;//Set the direction Left motor
        RightWheel.speed(s);
        LeftWheel.speed(s);
        wait(0.2);
    }
}

void DriveReverse() {
    for (float s= 0.0; s < -1.0 ; s -= 0.01) {
        DirectionR=0;//Set the direction Right motor
        DirectionL=0;//Set the direction Left motor
        RightWheel.speed(s);
        LeftWheel.speed(s);
        wait(0.2);
    }
}

void ZeroSpeedForward() {
           for (float s = 1.0; s > 0.0; s -= 0.01) {
            DirectionR=1;//Set the direction Right motor
            DirectionL=1;//Set the direction Left motor
            RightWheel.speed(s);
            LeftWheel.speed(s);
            wait(0.2);
        }
   }
   
void ZeroSpeedReverse() {   
          for (float s = -1.0; s < 0.0; s += 0.01) {
            DirectionR=0;//Set the direction Right motor
            DirectionL=0;//Set the direction Left motor
            RightWheel.speed(s);
            LeftWheel.speed(s);
            wait(0.2);
        }
}



int main() {
    while (1) {
      DriveForward();
      wait(5);
      ZeroSpeedForward();//Before changing direction best to zero the speed on the motors!
      wait(5);
      
     //   DriveReverse();
     //   wait(5);
     //   ZeroSpeedReverse();
     //   wait(5);
    }
}
17 Mar 2011

Apologies first to Don for spelling his name wrong. This link is the type of motor driver board I am using.

http://www.magnevation.com/oopic/pwmx2/index.htm

17 Mar 2011

Hi Derek,

No worries about the name, I get called Dan all the time since my o's tend to look like a's to most people.

I took another look at Motor.cpp and noticed a few things:

You are realy only using the pwm out of the object and trying to override the direction bits, which get set back when you set speed.

Motor expects to set a forward or a reverse bit for direction, both on for break, of both off for coast. The controls for your driver are realy direction and break.

The pwm output gets set to the absolute value of the value passed, so always 0.0 to 1.0, and the sign is used to set the forward and reverse bits.

I suggest you use simple PwmOut()'s for the speeds and the direction bits you already have defined. Change the range for speed to 0.0 to 1.0 for both directions.

If that works, you might want to restructure the code a bit to have a single RampUp and RampDown function since the forward and reverse routines will be almost identical. Set the direction bits, call ramp up, wait, call ramp down, change direction and repeat.

Cheers,

Don

17 Mar 2011

Thanks very much Don, I'll digest this and have a go at your suggestions, got my old books out today to read up on class and member functions so I can understand motor.cpp Is a simple PwmOut()'s a function that just ramps up and down one of the mbed pwm pins?

17 Mar 2011

Thanks Don.............It's working perfectly now. Next I'll try to improve the software and try and write a class for a Magnevation board. Next 3 items are a 4x20 lcd, a temp sensor and a compass module!

#include "mbed.h"

// For the Magnevation dual PWM module:-
// Channel 1: p5 remains high on pin40 which is the brake pin to allow the motor to run.
// When p6 is toggled between high/low motor direction is reversed.
// Channel 2: p7 remains high on pin38 which is the brake pin to allow the motor to run.
// When p8 is toggled between high/low motor direction is reversed.

PwmOut MotorRightWheel(p23); // pwm
PwmOut MotorLeftWheel(p25);  // pwm

DigitalOut DirectionR=p6;
DigitalOut DirectionL=p8;

void DriveForward() {
    for (float s= 0.0; s < 1.0 ; s += 0.01) {
        DirectionR=1;//Set the direction Right motor
        DirectionL=1;//Set the direction Left motor
        MotorRightWheel=s;
        MotorLeftWheel=s;
        wait(0.2);
    }
}

void DriveReverse() {
    for (float s= 0.0; s < 1.0 ; s += 0.01) {
        DirectionR=0;//Set the direction Right motor
        DirectionL=0;//Set the direction Left motor
        MotorRightWheel=s;
        MotorLeftWheel=s;
        wait(0.2);
    }
}

void ZeroSpeedForward() {
    for (float s = 1.0; s > 0.0; s -= 0.01) {
        DirectionR=1;//Set the direction Right motor
        DirectionL=1;//Set the direction Left motor
        MotorRightWheel=s;
        MotorLeftWheel=s;
        wait(0.2);
    }
}

void ZeroSpeedReverse() {
    for (float s = 1.0; s > 0.0; s -= 0.01) {
        DirectionR=0;//Set the direction Right motor
        DirectionL=0;//Set the direction Left motor
        MotorRightWheel=s;
        MotorLeftWheel=s;
        wait(0.2);
    }
}



int main() {
    while (1) {
        DriveForward();
        wait(5);
        ZeroSpeedForward();//Before changing direction best to zero the speed on the motors!
        wait(5);
        DriveReverse();
        wait(5);
        ZeroSpeedReverse();
        wait(5);
    }
}

17 Mar 2011

The PwmOut is just what you said, it controls one of the mbed's pwm output pins. Just change

Motor RightWheel(p23, p6, p5); // pwm, fwd/rev, brake
Motor LeftWheel(p25, p8, p7);  // pwm, fwd/rev, brake

to

PwmOut RightWheel(p23);
PwmOut LeftWheel(p25);

then use either RightWheel.write( s ); or just RightWheel = s; Where s is a float representing duty cycle between 0.0 and 1.0

Take a look at http://mbed.org/handbook/PwmOut for more information on PwmOut(), a couple of things to note, default period is 20mS, default duty cycle is 0.0

So a sample of what you are doing could look something like this:

#include "mbed.h"

PwmOut RightWheel( p23 );
DigitalOut DirectionR=p6;

void RampUp( void )
{
    while( RightWheel < 1.0 )
    {
        RightWheel = LeftWheel = RightWheel + 0.01;
        wait( 0.2 );
    }
    RightWheel = LeftWheel = 1.0
}

void RampDown( void )
{
    while( RightWheel > 0.0 )
    {
        RightWheel = LeftWheel = RightWheel - 0.01;
        wait( 0.2 );
    }
    RightWheel = LeftWheel = 0.0
}

int main()
{
    while (1) 
    {
        DirectionR = DirectionL = 1;
        RampUp();
        wait(5);
        RampDown();
        wait(5);
        DirectionR = DirectionL = 0;
        RampUp();
        wait(5);
        RampDown();
        wait(5);
    }
}


While I was typing this in I just got your response, glad to hear this part is working.

Don

17 Mar 2011

Thanks again Don, I can see your example code is much more efficient. Piece by piece I'll build my roving bot up.

17 Mar 2011

That sounds good, don't forget about the "My Notebook" feature, you can log and post pictures of the progress so we can all see how it's going.