Society of Robots - Robot Forum

Software => Software => Topic started by: Trumpkin on January 10, 2009, 03:05:51 PM

Title: motor control code
Post by: Trumpkin on January 10, 2009, 03:05:51 PM
I'm making a line following robot, and no matter what I do I can't seem to get the motors to turn. I am using the SN754410 H-Bridge. I'm newbish about this kind of stuff so go easy on me.  :D

Code: [Select]
#include <SoR_Utils.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int motor1_1 = 0;
int motor1_2 = 1;
int motor2_1 = 2;
int motor2_2 = 3;
int sensor_left = 5;
int sensor_right = 4;
int background_left = 0;
int background_right = 0;
int reading_left = 0;
int reading_right = 0;

/* Go Forward */
void go_forward()
{
PORT_ON(PORTD, motor1_1); //Port B pin 1 on
PORT_OFF(PORTD, motor1_2); //Port B pin 2 off
PORT_ON(PORTD, motor2_1); //Port B pin 3 on
PORT_OFF(PORTD, motor2_2); //Port B pin 4 off
}

/* Turn Right*/
void turn_right()
{

PORT_OFF(PORTD, motor1_1);
PORT_ON(PORTD, motor1_2);
PORT_ON(PORTD, motor2_1);
PORT_OFF(PORTD, motor2_2);
}

/* Auto Calibrate */
void calibrate()
{
  background_left = a2dConvert8bit(sensor_left); //read value of space left of the line
background_right = a2dConvert8bit(sensor_right); //read value of space right of the line
}

/* Turn Left */
void turn_left()
{
PORT_ON(PORTD, motor1_1);
PORT_OFF(PORTD, motor1_2);
PORT_OFF(PORTD, motor2_1);
PORT_ON(PORTD, motor2_2);
}

int main()
{
calibrate();
for (;;)
{
       
reading_left = a2dConvert8bit(sensor_left); //reading from left sensor
       
reading_right = a2dConvert8bit(sensor_right); //reading from right sensor
   
    if (reading_left < background_left)
    {
   
        while(reading_left < background_left)
    {
    turn_left();
                reading_left = a2dConvert8bit(sensor_left);
    }
}
else if (reading_right < background_right)
{
    while(reading_right < background_right)
{
    turn_right();
reading_right = a2dConvert8bit(sensor_right);
}
}
else if (reading_right >= background_right)
{
go_forward();
    }
    else if (reading_left >= background_left)
{
go_forward();
    }

  }
}
Title: Re: motor control code
Post by: Webbot on January 10, 2009, 07:34:52 PM
So the SN754410 is the chip at the heart of your H-Bridge - which is fine. So presumably you are using DC motors? Which H-bridge board are you using?

What I/O pins are you using on your mcu to talk to what connections on the H Bridge?
Title: Re: motor control code
Post by: Trumpkin on January 10, 2009, 08:11:28 PM
Here is the schematic i'm using http://letsmakerobots.com/node/2074 I know you are supposed to have seperate power supplies for the electronics and the motors, but I wanted to make it as simple as possible. On the atmega168 I am using PortD 0, PortD 1, PortD 2, and PortD 3. Hmm.. can you use RXD and TXD as regular ports? 
Title: Re: motor control code
Post by: Webbot on January 10, 2009, 08:36:31 PM
Your link shows an L293D circuit. You've replaced it with a pin compatible SN754410. This is fine. See http://www.societyofrobots.com/member_tutorials/node/164 (http://www.societyofrobots.com/member_tutorials/node/164) as they are plug-in compatible and much cheaper but still include the output stage didoes. All good so far.

I think that your main problem is that you should be using PWM to control the motor. Your code seems to be toggling individual pins rather than changing the PWM duty cycle. So the signal getting through to the motor is not what you want. Check out http://www.societyofrobots.com/member_tutorials/node/228 (http://www.societyofrobots.com/member_tutorials/node/228) and change your code to use PWM and change the duty cycle of the PWM wave form to change the speed between reverse-stop-forwards.

Title: Re: motor control code
Post by: Ro-Bot-X on January 10, 2009, 09:00:03 PM
Oh, are you sure this code is right?
Quote
PORT_ON(PORTD, motor1_1); //Port B pin 1 on
PORT_OFF(PORTD, motor1_2); //Port B pin 2 off

You need to have both pins set as Output, one set to HIGH and one set to LOW. Try to use direct code, not the functions.

Also try adding delays to let the motors react to sensor changes, code is running fast.
Title: Re: motor control code
Post by: Trumpkin on January 19, 2009, 09:43:43 AM
Here is my code, it still doesn't work. For each motor I have one pin of the H-Bridge connected to a PWM pin (PD5 and PD6) and the other connected to a regular digital output (PD3 and PD4). I'm using airman00's pwm.c code.

Code: [Select]
#include <util/delay.h>
#include <SoR_Utils.h>
int main()
{   
                PORT_OFF(PORTD, 3);
PORT_OFF(PORTD, 4);
pwmInit56();
pwmOn5();
pwmOn6();
pwmSet6(255);
pwmSet5(255);
_delay_ms(5000);
pwmOff56();
}
Doesn't PORT_OFF set the pin low?
Title: Re: motor control code
Post by: Admin on February 01, 2009, 09:12:28 AM
Quote
Doesn't PORT_OFF set the pin low?
yeap

So assuming that Webbot already verified the schematic, that means the code is either missing something or you made a wiring mistake.

To verify, get out a multimeter and verify that the pins are doing what you told them to do in software. This way you can narrow down the problem to specific locations in your code. For measuring PWM, set your multimeter to frequency mode, or use an oscilloscope.
Title: Re: motor control code
Post by: Webbot on February 02, 2009, 09:30:43 AM
The problem is that your main code doesn't have a loop - it just exits. It should probably look more like this:-

Code: [Select]
#include <util/delay.h>
#include <SoR_Utils.h>
int main()
{   
        PORT_OFF(PORTD, 3);
PORT_OFF(PORTD, 4);
pwmInit56();
pwmOn5();
pwmOn6();
pwmSet6(255);
pwmSet5(255);
        // Just keep looping with the PWM happening in the background
        while(true){
     _delay_ms(5000);
        }
pwmOff56();
}
Title: Re: motor control code
Post by: Trumpkin on February 05, 2009, 05:02:42 PM
Why would looping a delay do anything? The way I had it I thought it would turn on the motors, wait 5 seconds, and then turn off the motors.
Title: Re: motor control code
Post by: Webbot on February 05, 2009, 07:06:19 PM
It kinda depends on how the mcu reacts to a return from the main loop.I think (always a bad idea  :D) that it will cause the app to start running again. So OK the loop won;t add much but it just adds some clarity (ie we know that my main loop will keep circling) whereas your main loop may be called ad infinitum. So same result but one is more 'predictable' than the other.

So when you say 'it doesnt work' - what else do you observe?
Title: Re: motor control code
Post by: Trumpkin on February 05, 2009, 07:18:34 PM
Quote
So when you say 'it doesnt work' - what else do you observe?
Well, I turn it on and nothing happens.
Title: Re: motor control code
Post by: Trumpkin on February 09, 2009, 10:35:48 AM
So, does anyone have some simple code for driving a motor? Thanks for all your help.
Title: Re: motor control code
Post by: Webbot on February 09, 2009, 10:48:25 AM
Look at: http://www.societyofrobots.com/robotforum/index.php?topic=5590.0 (http://www.societyofrobots.com/robotforum/index.php?topic=5590.0)

Title: Re: motor control code
Post by: Trumpkin on February 12, 2009, 09:27:16 AM
Ok I was messing around with it last night and found out that if I connect pins 2 or 7 to ground, the motor connected to pins 3 and 8 will turn on. However If I connect pins 2 and 7 to the microcontroller and set them high or low nothing happens. So atleast now I know that I probably do not need to use PWM and that my motor driver is probably working correctly. Any help would be appreciated.  ;D
btw, heres my code:
Code: [Select]
int main()
{
while(1)
                {
PORT_ON(PORTD, 1);
PORT_OFF(PORTD, 2);
}
}
Title: Re: motor control code
Post by: Razor Concepts on February 12, 2009, 04:28:09 PM
If 2 and 7 are connected to the same thing (either both low or both high), motor should not turn. If they are connected to different things (one is low, one is high) the motor should spin.
Title: Re: motor control code
Post by: Trumpkin on February 12, 2009, 04:32:34 PM
Yeap one is low and one is high, as in my code.
Title: Re: motor control code
Post by: Webbot on February 12, 2009, 04:42:31 PM
Silly question: but I presume you have also connected Gnd from the microcontroller power supply to the Gnd supply of the motor driver?
Title: Re: motor control code
Post by: Trumpkin on February 12, 2009, 05:45:46 PM
Yes, I have.
Title: Re: motor control code
Post by: Razor Concepts on February 12, 2009, 05:47:29 PM
maybe only change the pins once and dont repeat over? No reason to put it in an infinite loop when it only needs to be done once
like
Code: [Select]
PORT_ON(PORTD, 1);
PORT_OFF(PORTD, 2);
while(1)
{
//donothing
}
Title: Re: motor control code
Post by: Webbot on February 12, 2009, 07:42:59 PM
Have you used a meter to check that your processor pins are the expected voltage - both at the output of the processor and at the input to the motor controller?
Title: Re: motor control code
Post by: Trumpkin on February 12, 2009, 07:44:51 PM
Quote
Have you used a meter to check that your processor pins are the expected voltage - both at the output of the processor and at the input to the motor controller?
yep

Quote
maybe only change the pins once and dont repeat over? No reason to put it in an infinite loop when it only needs to be done once
Nope, it still doesn't work.  :(
Title: Re: motor control code
Post by: cosminprund on February 13, 2009, 01:13:19 AM
Quote
Have you used a meter to check that your processor pins are the expected voltage - both at the output of the processor and at the input to the motor controller?
yep

So it's not a coding problem! If you checked with the multimeter and the pins are as expected (high and low) the motor should spin. In fact the circuit can be (temporarily) simplified, for testing purposes: Take out the MCU and just use pull up/down resistors on the two lines that previously went to the MCU. Does the motor start spinning? It should! If it doesn't it's clearly not a coding problem.
Title: Re: motor control code
Post by: Trumpkin on February 13, 2009, 09:27:38 AM
Low switches the pin to ground, correct? Does anyone know how I can test if I'm switching the pin low? I know that portd 1 is high because I can connect an LED to it and it will light (and I have checked with a meter).
Title: Re: motor control code
Post by: cosminprund on February 13, 2009, 09:42:53 AM
Yes, "low" means ground. You can also check that with a LED, connect an LED betwen the supposedly low pin and +5V.
When I'm testing for "low" with a multimeter I'm testing with the black pin on +5V and the red pin on the given pin. It should read -5V! That's because you get 0V when you measure betwen two things that are both at ground potential (ie: low) but you also get 0V if you measure between two things that are not connected. Measuring from +5V to the pin clears this up :)
Title: Re: motor control code
Post by: Trumpkin on February 13, 2009, 09:56:10 AM
PortD 2 is not low then for some stupid reason (checked with an LED). I know it's not a problem with my H-bridge, so it must be a problem with my Atmega168 (or my code).
Title: Re: motor control code
Post by: chelmi on February 13, 2009, 11:03:41 AM
PortD 2 is not low then for some stupid reason (checked with an LED). I know it's not a problem with my H-bridge, so it must be a problem with my Atmega168 (or my code).

My pedantic engineer advice, assume it's a problem with your code. It will save you time ;) Hardware rarely fails (unless you did something really bad with it).
Looking at your code, I don't see were you configure the pins an output pins. By default they are input pins, IIRC.
try to add
Code: [Select]
DDRD |= _BV(PD1) | _BV(PD2);

to set PD1 and PD2 to output

Chelmi
Title: Re: motor control code
Post by: Trumpkin on February 13, 2009, 11:37:35 AM
Well, they are set as outputs in SoR_Utils.h. But i'll try it with your code.
Title: Re: motor control code
Post by: Trumpkin on February 13, 2009, 11:56:11 AM
It sorta works now (thanks chelmi!). The motor is extremely jerky and very slow.
Title: Re: motor control code
Post by: chelmi on February 13, 2009, 12:23:06 PM
Well, they are set as outputs in SoR_Utils.h. But i'll try it with your code.

Are you calling configure_port() somewhere in your code ?
If not then the ports are not configured as outputs.
(I'm looking at the SoR_Utils.h file from the photovor v1 archive)

It sorta works now (thanks chelmi!). The motor is extremely jerky and very slow.

Good. So you can control the direction now, right ?
You're problem now sounds like a PWM issue. try to simply connect the enable pin of your H-bridge to Vcc, you're motor should spin full speed (check that the max voltage of your motor is compatible with what you are supplying)

Chelmi
Title: Re: motor control code
Post by: Trumpkin on February 13, 2009, 12:32:45 PM
I connected an LED to PD2. Without the H-bridge attached the LED is constant on (good) with the H-bridge plugged in the LED rapidly turns on and off (bad).
Quote
You're problem now sounds like a PWM issue. try to simply connect the enable pin of your H-bridge to Vcc, you're motor should spin full speed (check that the max voltage of your motor is compatible with what you are supplying)
That's the way I have it, with enable connected to VCC.
--edit--
I connected my H-bridge to unregulated 6v insted of 5v. Now everything seems to be working fine! Thanks everybody for your help!!