Welcome to Synthiam!

Program robots using technologies created from industry experts. ARC is our free-to-use robot programming software that makes features like vision recognition, navigation and artificial intelligence easy.

Get Started
Asked — Edited

Dc Motor Control Question

Hello,

We are a team of engineering students working on a robotics project about to participate in a robotics competition. We have only a few days to finish up and we are currently having a problem with
the DC motors for our second robot. We are trying to drive two DC motors to move the robot using PWM signals sent from an arduino card. Using an H bridge we are able
to deliver PWM signals with a controllable duty cycle from the arduino card, which are -24V/+24V. Thus in theory at 50% the motors are at 0V, and close to +24V or -24V
at 100% or 0% respectively by average voltage.
When the cables we use to connect to the motors are checked with an oscilloscope, the signals are fine and as expected.

When we connect our motors to them, the signals are significantly degraded (can tell its supposed to be a PWM cycle but it's not as clean as before) and the over all
average voltage is lower then what we had before. In this situation, with the robot lifted off the ground and the wheels not touching anything, the motors seem to turn
fine, at a decent speed etc. However the torque seems quite low, not as much as we should be getting from our motors.

The real issue is as soon as we place the robot on the ground, the wheels can not move. In this situation the expected rough 21.5V average voltage we measured previously
drops to around 3 to 3.2V. If observed at this point the PWM cycles are totally degraged, can barely make out a square signal, and the average voltage is around
3V.

We can not figure out what is causing this problem. When we connect our generator directly to the motors without going through our electronic card, as soon as we go above 5V
on a motor the wheel is able to move the robot easily, and at a decent speed above 7 or 8V. What adds to our confusion is another team last year used these motors
and drove them with a -24/+24 V PWM signal in the same way as far as we know.

We are totally stuck, and are available to answer any questions or provide any data that could help debug our issue.

Thanks for any help!

We are using the 2322G/GP022C motors from this datasheet, the last one (24V/1621) : http://store.mdpmotor.fr/media/documents/pdf/2322g_gp022c.pdf

AI Support Bot
Related Content
Synthiam
Based on your post activity, we found some content that may be interesting to you. Explore these other tutorials and community conversations.
PRO
Canada
#7  
Ok thanks, two items that generate questions for me:

How many peak amps can this generator deliver? Most bench top power supplies can deliver up to 10A continuous but have a hard time with the in-rush current spikes that DC motors can draw. Testing with LiPo batteries directly is likely a better scenario. Just use a high current in-line fuse (like a 20A automotive fuse) just in case anything happens.

What does your L298 based H-Bridge look like, do you have flyback diodes installed and do you have a good sized heatsink on the L298?

Are you using PWM signals on the input lines or the enable lines?
South Africa
#8  
To upload a picture you need a link so post the picture in a nother website and enter the websites URL so you can upload the picture on this website
#9  
For the generator, we easily moved the robot when connecting it directly to one of the motors and turned it up to just 6-7V, do you really think the batteries would fix this issue? We need to take apart a lot of stuff to switch battery power and were hoping to do it only when all our debugging was done and it worked ok ^^

We do have flyback diodes and a decent sized heatsink that doesn't seem to get to hot (easily touchable).

We use only the PWM signals on the input lines.

I'm gonna upload our oscilloscope pictures and our schematics somewhere and post the links here.
#10  
We got this response on another forum :

"major issue - the 22R current sesnsing resistors - thet bridge will never ever let you pass enough current with such a current sesing resistors. considering your motors (rated at 0.5 Amps @ 24V) you would loss 11 volds on those 22R sensisng resistors.
change those for something more suitable. according to the datasheet you should use 0.5 Ohm for 2Amps limit."

This seems like this might be the issue, we are going to try and test this now but are open to all opinions on this verdict / other ideas!
PRO
Canada
#11  
Yep I would have to agree with that other forum, using 22ohm current sensing resistors is quite high. I usually use 0.1ohm myself.

Actually it's funny that @DJ (the founder of EZ-Robot) found you don't even need current sensing resistors when doing current sensing, just attach an analog input to the ground of the H-Bridge and you will get readings (albeit small) when the motors are under stress.
#12  
If you still have issues, I'd suggest looking at the motor impedance. When the robot is lifted off the ground, the mechanical load on the motor is low and so the total impedance of the electromechanical system is also low. When you put the robot on the ground the mechanical load increases the impedance of the electromechanical system. It's possible that under mechanical load, the voltage you are supplying is not sufficient to get the amount of current you need to get the motor moving. On the other side of the coin, you may not be able to supply sufficient current to get the motor moving due to a limit on the H-bridge. Either way, it's possible you are running into a physical limit due to the capability of the H-bridge and the change in impedance of the electromechanical system.
PRO
Synthiam
#13  
This can be a real easy fix.

Post your Arduino code please. Either ZIP it and use the Attach File option to the right of the edit box when replying to the post - or paste it in using the [ code ] and [/ code ] tags. Look to at the UBB Code commands to the right of the edit box when replying to the thread.

You are PWM the IN of the L298? I would not recommend that. I would recommend modulating the EN instead. This is for many reasons... One of the reasons is pulsing the IN requires both INA and INB of the first channel receive their HIGH and LOW pulses at the exact same time. That will never happen and that tiny little bit of overlap causes the L298 to do what it's asked at the time - meaning an overlap the current to the motor is reversed for a very small amount of time until the expected pulses are both HIGH or LOW as desired. And the PWM frequency is also going to increase the chance of the PWM never being on at the same time.

I don't know if I explained myself properly without drawings. In short, do not PWM the IN lines.

Use the IN lines as they are meant to be used. Use the EN as they were meant to be used.

Lastly, assuming your custom L298 motor driver circuit is designed correctly - then following my instructions to modulate the EN instead of INx will work:)
#14  
We will test this tommorow and get back to you with feedback regardless of how it turns out, but I'm fairly sure we don't have any resistors below 12 or 10 ohm....
#15  
Hmm very interesting comment DJ Sures.
I think the way we designed our electronic cards it is to late to be able to apply the PWMs to the enable and put whatever is required on the IN ports. In theory the 2 PWM signals on inA and inB should be perfectly sync, since I'm generating 2 opposed phase PWM signals from the same timer for one pair, and another pair with another timer on the other. They are seperate from timer0 as well so there should be no interference causing any issues with these signals

This was a choice that was made early on and not by me since I wasn't really involved in the card design.

Part of the project was designing and making our own electronic cards so they are hooked up in such a way that now we can't switch to this other solution.


This is the code I used to generate the PWM signals, I took it from the rest because there is a lot of unrelated stuff, but I can post it if you want.

We used this system and slightly different code for a slower moving smaller first robot that has functioned without any issues

Note : this is for an Arduino Mega 2560

Code:


// Motor 1 on the card (functioning at 31khz)
void PWM_Left_Motor(int direct){
// direct : value between 0 and 255
// sends the value of direct to pin 9 and its opposed phase equivalent to pin 10
//COM2 A1 and A0 at 1 for inverse PWM mode, just B1 at 1 for normal PWM
// |= to not modify existing bit conditions on other registers
TCCR2A |= _BV(COM2A1) | _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20); // 8 bit phase correct PWM mode
TCCR2B |= _BV(CS20);// prescale = 1 CS2:0
TCCR2B = TCCR2B & 0b11111001;
OCR2A=direct;
OCR2B=direct;
}

// Motor 2 on the card (functioning at 31khz)
void PWM_Right_Motor(int direct){
// direct : value between 0 and 255
// sends the value of direct to pin 12 and its opposed phase equivalent to pin 11
//COM2 A1 and A0 at 1 for inverse PWM mode, just B1 at 1 for normal PWM
TCCR1A |= _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(WGM20); // 8 bit phase correct PWM mode
TCCR2B |= _BV(CS20);// prescale = 1 CS2:0
TCCR1B = TCCR1B & 0b11111001;
OCR1A=direct;
OCR1B=direct;
}




Here is an archive with some extra things that might help you get a better sense of our issue :
<a href="http://speedy.sh/bMtUE/photos-robot.rar">Download at SpeedyShare</a>

Included are the 2 schematics of our 2 cards (one with 2 Arduino mega) and one which serves to distribute power throughout the robot.

Also I've added 3 oscilloscope pictures, in descending quality :
-img3 : signals that arrive to the motors with them disconnected (after passing from the Arduino, through the optocoupler and leaving the H-bridge)
- img1 : signals with the motors attached but the robot raised from the ground (wheels turning with low torque)
- img2 : signals with the robot placed on the ground and wheels unable to turn


All things considered, our sensor resistors being at 22 seems like a likely issue, since it would lead directly to limiting current autoput and dropping voltage on the motor when we ask for to much current. Also, the datasheet does say no more then 0.5 ideally and we have 22.
PRO
Synthiam
#16  
1) Have you connected a two channel oscilloscope to the INA and INB of the first motor to verify the modulation peaks are correctly aligned?

2) Connect the oscilloscope to the output of the L298 to the motor and see if the PWM is correct and that there are no reverse polarity. If test #1 was success then there should be no reverse polarity anomalies

Do you have a circuit diagram for the motor controller?
#17  
1) Yes for this robot and the first smaller one, the picture of the signals on inA and inB for our left motor is img3 in the archive I attached to the previous post. It seems to be working fine.

2) Not sure what you want me to check exactly, but it's past midnight in France we've called it a night and gone home so all further testing will be done tommorow.

What do you mean by the motor controller? The only two circuits we have are the two pdfs I included in the archive.
If you mean the automatic control system for generating motor command, we coded and simulated it in Matlab and have now coded it into C on the arduino. We're using odometry and correcting motor speed command by both position and velocity. Currently we have not hooked it up to our actual motors to try it yet, we wanted to make sure we could actually get the robot to move forward first.

Calling it a night for now, class in around 6 hours;)

I will be sure to get back to you all tommorow with updates and any more info you might need in case the resistor issue isn't the cause of our troubles.

Thanks to everyone for all the help!
#18  
I'm pretty sure when DJ said "Motor Controller" he meant your H-Bridge.
#19  
Definitely interested to know how you solved this one! Let us know, and good luck ultrablaze!
#20  
Well we switched out the 22 ohm resistor for a 0.22 ohm resistor and that fixed the problem!
The robot now moves forward easily. Clearly during the electronic card design R22 was misread as 22R

We have however encountered a new issue we are once again puzzled by...
If we have the robot drive extremely slowly, the encoders are extremely accurate for our odometry when the robot drives slowly.
However, as soon as we try to go at even a medium speed they are very far off from what we expect and so our robot ends up overshooting the target
distance by a considerable amount (thinking it has covered 30cm from the odometry when it has actually gone 35cm).

We are thinking this is from some kind of interference from the motors functioning at a higher speed and messing up the encoders ability to pick up values...?

It is odd though, these encoders + these motors were used last year and seemed to have no issue remaining accurate when moving at high speeds.

Hard to describe everything in detail that could be contributing to this issue...
We are trying to test many things and see what could be causing the problem. Any ideas are welcome.

Possible ideas we are pursuing to try and debug this problem :
-We think this might also be due to an issue with interruption handling through our arduino (4 interrupts from the 2 encoders + flexi_Timer_2 using one interrupt for the
control function calculation
-Interference between the two

Just now we had the robot raised, wheels turning full power, and if we turned the encoder exactly 1 full circle we got nearly exactly the right value, every time.
Depending on the sampling speed we use (as in how many times per second the interrupt control function is called), it seems to directly impact the accuracy of our
encoder wheels...

We have no idea what is wrong once again.
#21  
Here is one version of our code we are trying to use to function with the encoders to control our motors, not sure how clear it will be to someone trying to understand it. In this version we reduced the amount of calculations in the isrt by going with just tick values and sticking to ints as much as possible.

Ignore all the parts with EasyTransfer and data structures, that it just for sending values to our screen for debugging purposes.
You need FlexiTimer2 library in order for this to function.Easy_Slave_V5.zip
PRO
Canada
#22  
Sorry I haven't had a chance to look at the code but I was going to ask if you had noise decoupling capacitors on your motors, like a 0.1uF from each motor lead to the motor chassis and one across the motor leads as well? These help to cut down motor noise, but you do have high quality motors so I'm not all that certain that it would make too much of a difference.

Are you doing any kind of averaging of the encoding values that are coming in? Taking several samples and then averaging the result out usually helps diminish spurious values.
#23  
I will ask the guys in charge of the electronic cards about the capacitors and let you know.

The main issue here seems to be our rotary encoders that arbitrarily are extremely accurate or are way off. They were used effectively by robotics teams the last couple years with a nearly identical setup so we are very confused as to what it causing us problems. I can't find the datasheet for them currently but I will try to locate it.

We think it might be a problem with interrupts being used for the encoders as well as at set intervals to calculate the new motor command value using our PID setup based on the position error we have from our odometry.

We spent hours testing and it makes no sense. We lift the robot off the ground, and we decreased the time between each interrupt routine call that calculates new motor command, and when we turned the encoders a full turn they were extremely accurate.

We then added lots of extra heavy calculations to this interrupt routine / increased the frequency with which the routine was called, and in both cases this lead to our encoders needing more then a full circle to get to the expected value. This seems like behaviour that would be coherent with some interrupts from the encoders being dropped / missed.

We originally had a heavy calculation function based on our matlab simulation of the automatic control, which had a lot of floats and whatnot. We had the idea that maybe this was to demanding of a function in an interrupt routine, so as a test in the interrupt routine we called these calculations 3, 6, etc times and each time the amount of distance required by the encoders to reach the value of a full circle increased.
When we called the interrupt routine with no code in it, they seemed perfectly accurate again.

So we thought great, this is the issue. We then recoded in a much lighter way, with mostly ints and fewer calculations. Tested the encoders with the robot raised, seemed extremely precise, great!

Put the robot on the ground and let it drive : exactly the same, it overshoots the 30cm or whatever command we give it by a fair amount because the encoders seem to be dropping ticks....

So we're pretty stuck...
And this thing is supposed to be done and finished in about 32 hours max >.<

edit : here are the encoders we are using : http://docs-europe.electrocomponents.com/webdocs/0173/0900766b801738c2.pdf
PRO
Canada
#24  
One thing that may help and something I've ran into in my previous experience with Arduinos is that you can't call delay functions such as millis() and micros() when using interrupts as the timing will be off every time an interrupt occurs, see here for more info, looks like you can use delayMicroseconds() instead as it doesn't rely on interrupts.
#25  
Is milliis() really an issue? We use it once or twice, but I thought only delay() really messed with timing, we will try without it later and see.
However I doubt that is the problem, when we move the robot forward without powering the motors the encoder results are extremely accurate despite using a Millis wait cycle to transmit data to our screen.

These same encoders have been used several times before with an arduino mega with no problems as far as we know.
When we roll our robot forward by hand the precision is perfect, over a 30 or 60 cm distance it's off by a couple mm. The arduino has no problem picking up the interruptions accurately
So really there seems to be some issue with the way we are calling interrupts when we are trying to drive the motors, or some kind of interference from powering the motors