NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » Pulse Width Modulation on the ATMega168
NerdKits » Forums » Microcontroller Programming » Pulse Width Modulation on the ATMega168 (11 posts)
|
|
May 04, 2010 by Malicious |
I am attempting to use PWM to change the speed of a brushless electric motor. The issue is, the motor does not run smoothly, it stutters. The code I am using for the PWM is
Obviously I am using Timer0, but what I do not understand is how to change the PWM. I 'stole' this code from the iPhone R/C project, and after spending hours on forums and pouring over the datasheet, I just cannot figure out how to modify the timing. I set the top or bottom, not sure which it is with
and mag can be anything from -255 to 255. The motor spins slowly correctly with a value of +/- 4,5,6, but any other value causes the motor to spin erratically. What exactly does the line below mean, and how can I modify it to create a smooth-running motor? Do I need to use a different timer?
Thank you in advance -Malicious |
---|---|
May 04, 2010 by mongo |
Most brushless motors can't be controlled this way. Inside, they are basically like a stepper motor with all the drivers built in. Variable speed brushless motors, from what I have seen to date, have extra leads for speed control where the internal clocking frequency is adjusted.PWM works well with normal motors. Some industrial speed controls work on a variant of the same concept, while the majority uses the phase angle / switching method where speed is controlled by just how much of a single phase is switched on. |
May 04, 2010 by Malicious |
Well then I mis-spoke, they are regular brushed motors. |
May 05, 2010 by hevans (NerdKits Staff) |
Hi Malicious, PWM can be a tricky concept to wrap your head around. I suggest setting your timer to fast PWM mode, it is a bit easier to think about than phase correct PWM mode. To do this you need to set the WGM01, and WGM00 bits of TCCR0A (from the table at the bottom of page 104 of the datasheet). That same table tells you that in this mode the counters TOP value is set at 0xFF, or 255 the largest number available with 8 bits. So the timer counter is going to count up every tick of the clock, and just roll over to 0 when it reaches the top. That handles the counter part, now lets set handle the PWM part. You have two compare units on each counter, so you can have two separate PWM outputs per timer. Lets just hanlde the output on OC0A. You want to to turn on COM0A1, because you want the pin OC0A to be set (high) at BOTTOM of the timer, and then cleared (low) when the compare match happens. This is coming from the table at the bottom of page 102 on the datasheet. The "compare match" is done against the the number in OCR0A, so by setting this to any number between 0 and 255 you can change the duty cycle! So your TCCR0A line should look something like this. TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00); Note you will have to make sure OC0A is set as an output, and you also need to set a few bits in TCCR0B to set the clock prescaler. If you wanted to also use the output on OCR0B, then you need to turn on the appropriate bit for that too, and the compare match for that would be done against the value in register OCR0B. That is the overview of PWM. We go over all this in the Servo Squirter tutorial if you have not gone through that. In this context a negative value for OCR0A really doesn't make sense, as you can't have a negative duty cycle. The compare match will just be confused. I suggest you simplify this away from your other project and make sure your PWM function is doing what you expect before trying to hook it up to your motors. Put together a quick project with the PWM output connected to an LED and control its brightness gently using PWM. This will help you understand the code so you can later apply it. Humberto |
May 05, 2010 by Malicious |
Humberto, Your a God-send. Yes, PWM has been a tricky concept to try and master, yet slowly but surly I'm coming around. I employed the settings you specified and it worked wonderfully. I had investigated the servo squirter tutorial, but I couldn't make complete sense of it for my purposes. I got the LED and my remote controlled engines running via the Fast PWM mode. While scanning through the datasheet myself I had no idea what all those modes meant and whether or not I should use one of them. So, the Fast PWM mode works for forward and reverse of the motors, 1-20 or 21 is reverse and everything else is forward, or so it seems after my first few test. Is their any method of determining how the transmitter of my device decides forward or reverse and the power of said direction? Some values still cause the rotors to erratically rotate while others result in smooth rotation. I would prefer to have constantly smooth rotation, just like the analog device that was controlling it. Just so you know where I am coming from, I would say that a duty cycle value of 22 would be the center position on the potentiometer joystick that used to control the motor, so 1-21 is varying speeds of reverse and 23-255, or whatever the manufacturer capped it at, is the joystick all the way forward or any step in between. Am I grasping the analog to digital conversion correctly? If so, then I would suppose that once I set the PWM to the correct cycle type (Fast, Phase Correct, What-have-you) then the rotors would spin correctly with any value? Am I on the correct track? Thank you very very much for you help Humberto. It is greatly appreciated. -Malicious |
May 05, 2010 by hevans (NerdKits Staff) |
Hi Malicious, Like Mike pointed out before in your other thread there is most likely some time dependent stuff that is happening in your circuit. The changing resistance of your pot via the control stick would change this timing in a way that would be interpreted by the electronics in your transmitter. By doing the PWM with the MOSFET you are changing the apparent resistance of the 100 ohm resistor you have put in, however it is not entirely clear that this PWM is going to be interpreted exactly the same as the smoothly changing resistance of the pot. All that you really know at this point is that with the PWM set up at around 22, your transmitter is interpreting that the same way as it was interpreting a center joystick position. Smaller duty cycles are being interpreted as forward joystick positions, and larger duty cycles are being interpreted as reverse joystick positions. Remember the manufacturer never meant this thing to be driven with a PWM signal, they meant it to be driven with a changing resistance from a potentiometer. This has nothing to do with choosing a "correct" PWM mode, you are trying to emulate something that was happening in a circuit so its just a game of tweaking until it works. If you feel really adventurous you can try changing the PWM mode to Fast PWM Mode with top at OCR0A, instead of 0xFF (by turning on WGM02 of TCCR0B) See bottom table on p104 of the datasheet. Then use OC0B as your PWM output. What this lets you do is also control the TOP value of the timer/counter. Now instead of that being stuck at 0xFF you can lower it to make your PWM frequency increase. You will then have to adjust OC0B to get the same duty cycle. The higher PWM frequency might help make things a little smoother, but it will also give you less resolution on the duty cycle, so I'm not really sure it will help but it is worth a shot. Humberto |
May 05, 2010 by Malicious |
Humberto, Ok, so i am grasping this correctly, phew. My next question would then be, should I ditch the PWM method of controlling the submarine, and attempt something incorporating the MCP4251 IC so that I can get the results I am looking for (without days or months of blind testing)? The overall goal I have is to control a submersible via a serial port on my laptop; I'm interfacing this with Adobe Director for controls. I just jumped on PWM because of the two tutorials on the site - specifically the iPhone R/C car one. If I remember correctly, Mike pointed out the IC I mentioned above on my other thread, but mentioned the voltage must be below 5v, which it is. So, my gut would tell me that I should use that, since it would perfectly mimic the analog device (actually two of them), and be a lot less headache. You think that is correct, or should I stay the course? Without too much experience with either I'm not sure at this point. Thank you again for your continued support. -Malicious |
May 06, 2010 by hevans (NerdKits Staff) |
Hi Malicious, I would say it never hurts to experiment. You will probably have better luck with the potentiometer, but it is really hard to tell without trying it. At worst if it doesn't work you have yourself a brand new digital potentiometer to play with =) Humberto |
May 13, 2010 by Malicious |
Wonderful, So I orders two of those Digital POT IC, just in case I accidentally destroy one, and they are arriving tomorrow. I was reading over the data sheet to try and figure out how I am going to program this and I have a few questions. Firstly, I saw that the chip has serial pins, one in and one out, so I was wondering if I am going to be writing separate code for this chip and the ATMega168? Or will the code compiled on the ATMega control the digital POT? Then I got to thinking about how I would actually code it. I learned from my PWM experience how to set the registers and so on, and I can see what they are called and what they do from the data sheet, but I honestly have no idea were to even begin. I there a book, or tutorial, or something that could help me through programming this IC. I could just fool around until I found something that worked, but I do not want to harm any components, and am running short on time for this project. I probably should start another thread about this since the topic has changed slightly. Anyway, thank you for your help. Malicious |
May 13, 2010 by hevans (NerdKits Staff) |
Hi Malicious, You will not be writing code to load onto your digital POT, but you will have to write code that goes on your MCU that is in charge of communicating with the electronics no board your digitla pot. Since you mention there are TX and RX pins im guessing your digital pot follows a serial protocol. The game here is going to be to send the right signals over the serial lines to it to tell it what to do. You will probably have two options: 1) use the onboard UART (another word for serial) module to send the data. 2) emulate the serial protocol in software and just send send the right signals at the right time. Both approaches have their pros and cons. If you post the datasheet, im sure there are folks on this forum that would be willing to help you. Humberto |
May 14, 2010 by Malicious |
Humberto, Thank you very much for your continued support.. For everyone, I have started a new thread here for the next phases of the process if your interested. Also I posted the Data Sheet for the IC there. Malicious |
Please log in to post a reply.
Did you know that NerdKits also has extra parts available for its customers? Learn more...
|