[ 3 / biz / cgl / ck / diy / fa / ic / jp / lit / sci / vr / vt ] [ index / top / reports ] [ become a patron ] [ status ]
2023-11: Warosu is now out of extended maintenance.

/diy/ - Do It Yourself


View post   

File: 227 KB, 1280x1024, Photo-0016.jpg [View same] [iqdb] [saucenao] [google]
70215 No.70215 [Reply] [Original]

Greetings fellow /diy/namites. In order to create something I wanted to make a servo turn to the left and then to the right. Anyway, I found out that AVR-Servo communication was a pretty hot topic around, so I present to you my simple servo-turning program for AVR studio. I used a Tower Hobbies TS-53 servo and an ATMEGA32 micro.

//servo.c
#define F_CPU 1000000UL /* 1 MHz CPU clock */
#include <avr/io.h>
#include <util/delay.h>


int main (void)
{
//PortD output
DDRD = 0xFF;

while(1) {
_delay_ms(1200);
for(int i = 1; i<4000; i = i+100)
{
PORTD = 0xFF;
_delay_ms(1);
PORTD = 0x00;
_delay_ms(19);
}

_delay_ms(1200);
for(int i = 4000; i> 1; i = i-100)

{

PORTD = 0xFF;
_delay_ms(2);
PORTD = 0x00;
_delay_ms(18);
}
}

return (1);
}

Now, this program is actually a dumb approach to PWM adn servo control, but he, if it works it's fine with me. I noted that the servo acted funny (joggedm failed to move etc) until I added an 100microfarad cap to it's power supply. It seems that it would drain the power from the system. Adding a diode to the signal line only made things better.

Pic related. It's the darn thing.

>> No.70218

now parametrize the main so you can add control to your device

I like programming .-.

>> No.70226

>>70215
Yeah when the motor starts it draws more current than the AVR can handle and wont do anything.

>> No.70257

https://spn.sr/juj?/AVR.pdf

>> No.70266

>>70257
Moneyclyck scammer

>> No.71162

That was informative, thanks!

>> No.71415

>>70215
>this program is actually a dumb approach to PWM adn servo control
Agreed. My chief concern is your use of _delay_ms, which is a blocking call. Using timers is a better approach if you are doing more than controlling a single motor. Most of the time you will be, because at some point you are going to want to check for input and control the motor speed/direction based on that input.
>Adding a diode to the signal line only made things better.
When working with motor circuits, a protection diode is always a good idea.

>> No.71423

> Using timers is a better approach if you are doing more than controlling a single motor

Mega32 has actual PWM hardware too. It's easy to use.

>> No.71527
File: 267 KB, 1024x768, 1249300958033.jpg [View same] [iqdb] [saucenao] [google]
71527

I tried to use timers, but to no avail, I failed miserably. Instead of a sweeping motion the servo only jogged a little to the left, then again, then again, etc. However, I haven't tried again since I added the cap.Note that I did get some strange behavior before adding the cap even with this simple program. I will take another shot with the timers and post results and program when I do.

>> No.72222

Ok, here is the updated program, with PWM.

//-------------------------

#define F_CPU 1000000UL /* 1 MHz CPU clock */
#include <avr/io.h>

int main(void) {

//TOP=ICR1;

//Output compare OC1A 8 bit non inverted PWM

//Clear OC1A on Compare Match, set OC1A at TOP

//Fast PWM

//ICR1=20000 defines 50Hz PWM

TCCR1A = 0;
// disable all PWM on Timer1 whilst we set it up

ICR1 = 19999;
// frequency is every 20ms

TCCR1A = (1<<WGM11);
TCCR1B = (1 << WGM13) | (1<<WGM12) | (1 << CS10);
// Configure timer 1 for Fast PWM mode using ICR1, with no prescaling

DDRD=0xFF;

//Set PORTD as output

TCCR1A |= 2 << 6;
// enable PWM on port B1 to use non-inverting mode - mode2

OCR1A = 1500;

while (1) {

while (OCR1A < 2000)

{

//increase duty cycle

OCR1A=OCR1A+1;

}

while (OCR1A > 10)
{

//decease duty cycle

OCR1A=OCR1A-1;

}

}

}

//----------------------------------


It SHOULD work, the way I see it, but the servo is erratic! It kinda shivers, as if it doesn't know where to turn. goes a tad bit to the left then to the right, etc. An interesting outcome, but not quite the sweeping motion I expected. Any suggestions?

>> No.72645

>>72222
What is the amp draw on the servo? I don't think you should be running it directly off of the controller pins (unless you know for a fact that the draw is less than 20mA).

>> No.72773

Get a power MOSFET and a pullup to drive it. Those servos draw depending on load, and I do not know what it is unloaded, but it's up too 100mA on a FUTABA servo that I used.

>> No.73329

Like others said, don't underestimate the power draw of servos. Over 2A peaks on a digital futabe are not uncommon, even without a load. For debug purposes you could wire a LED to the control line to make the PWM duty cycle visible. I'm not good with AVRs (yet) but how often are you updating the PWM? Once every few clock cycles or once every PWM cycle?

>> No.74237

What baffles me the most is why the servo works just fine with the _delay_ms routine and not with the timer one. If it was a power supply issue, it would fail in both occasions.

>> No.74465

All right! Gentlemen, we have an improvement. Here is the updated code, utilising pwm.

//-------------------------

#define F_CPU 1000000UL /* 1 MHz CPU clock */
#include <avr/io.h>
#include <util/delay.h>

int main() {
TCCR1A = 0x00;
TCCR1B = 0x00;
DDRD|=(1<<PORTD5);
TCCR1A |= (1<<COM1A1)|(0<<COM1A0)|(1<<WGM10);
TCCR1B |=(0<<CS12)|(1<<CS11)|(0<<CS10);
while (1) {
OCR1A=20;
_delay_ms(10000);
OCR1A=70;
_delay_ms(10000);
OCR1A=180;
_delay_ms(10000);
}
return 0;
}

//----------------------------------


Crazy shit yo! Ok, the program makes the servo go left ,wait, then center, wait, and finally right and wait some more. Then all over again. No serious problem here. Let us all dance to the funky tune!
http://www.youtube.com/watch?v=_Lachbg1jcE

>> No.74486

Here is a picaxe program to do the same thing. U Jelly?

main:
servo 1, 100
wait 1
servo 1, 150
wait 1
servo 1, 200
wait 1
goto main

>> No.74495

You bet I am Jelly. Heck, I had a much much easier time with the basic stamp pwm, and that was 10 years ago!

Oh well, I suppose the next step is to add buttons and control the servo with a joystick.