Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
daniel's
PostPosted: Jul 11, 2012 - 09:41 PM
Newbie


Joined: Jul 11, 2012
Posts: 4


Hi everyone !!!

I'm new here and new to programming ... I have a problem with adding support for the servo

Below Timer1 settings for 12MHz

Code:

        ICR1 =  3750;
   // Center outputs (1.5ms)
   OCR1A = 1500; 
   // Timer 1 fast PWM mode 14
   // Clear on compare, set at TOP
   // /8 prescaler
   TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
   TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11);
 


and Timer0 settings
Code:

   TCCR0A |= (1<<WGM01);
   TCCR0B |= (1<<CS00);
   TIMSK |= (1<<OCIE0A);
   OCR0A = F_CPU/1024/100 - 1; //Tick 1ms



how to send a PWM signal to PD.1 ???
and to cause the servo leaned one way, depending on the dip switch settings, connected to the PB ???

LEDs are working properly and with the servo I have a big problem

Also sorry for my English - unfortunately not the best...
 
 View user's profile Send private message  
Reply with quote Back to top
metron9
PostPosted: Jul 12, 2012 - 03:44 AM
Resident


Joined: Aug 25, 2005
Posts: 911
Location: U.S.A

PB3 is your output pin for timer 1 OCR1A

You also should design for 20 mS delay between pulses.

http://www.diydrones.com/forum/topics/m ... -pwm-pulse
 
 View user's profile Send private message  
Reply with quote Back to top
Visovian
PostPosted: Jul 12, 2012 - 07:28 AM
Posting Freak


Joined: Aug 07, 2007
Posts: 1477
Location: Czech

You need
ICR1 period = 20 ms
OCR1A = 1 ms -> servo left
OCR1A = 1.5 ms -> servo in center
OCR1A = 2 ms -> servo right

The formula for fast pwm is
register_value = (F_CPU[MHz] * time[us] / prescaler) - 1

ICR1 = ( 12 * 20000 / 8 ) - 1 = 29999

For servo left
OCR1A = ( 12 * 1000 / 8 ) - 1 = 1499

For servo in center
OCR1A = ( 12 * 1500 / 8 ) - 1 = 2249

For servo right
OCR1A = ( 12 * 2000 / 8 ) - 1 = 2999

The output is on PB3 (cannot be changed).
Do not forget to set portb.3 as output.
 
 View user's profile Send private message  
Reply with quote Back to top
Visovian
PostPosted: Jul 12, 2012 - 07:44 AM
Posting Freak


Joined: Aug 07, 2007
Posts: 1477
Location: Czech

Quote:
and to cause the servo leaned one way, depending on the dip switch settings, connected to the PB ???
Code:
 while(1)
 {
   //step up
   if(bit_is_clear(PINB, 1) // if buton1 pressed
   {
      if (OCR1A < 2990)
      {
         OCR1A = OCR1A + 10;
         _delay_ms(20);
      }
   }

   
   //step down
   if(bit_is_clear(PINB, 2) // if buton2 pressed
   {
      if (OCR1A > 1510)
      {
         OCR1A = OCR1A - 10;
         _delay_ms(20);
      }
   }
 }
 
 View user's profile Send private message  
Reply with quote Back to top
daniel's
PostPosted: Jul 13, 2012 - 12:06 PM
Newbie


Joined: Jul 11, 2012
Posts: 4


Hi !

Thanks for fast response ...

It's my simple code to test servo and unfortunately does not work ... Did I forget something? Sorry - this is for you can very easy - very difficult for me ...

Code:

#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdio.h>

#define F_CPU 12000000

#include <util/delay.h>



int main(void)
{
//Configure TIMER1
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); //NON Inverted PWM
TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11);
ICR1=29999; //fPWM=50Hz (Period = 20ms Standard).

DDRB|=(1<<PB3)|(1<<PB4); //PWM Pins as Out

while(1)
{

OCR1A=1499;
_delay_ms(1000);

OCR1A=2249;
_delay_ms(1000);

OCR1A=2999;
_delay_ms(1000);
}
}


Last edited by daniel's on Jul 13, 2012 - 01:41 PM; edited 4 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 13, 2012 - 12:23 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62337
Location: (using avr-gcc in) Finchingfield, Essex, England

Mode 14 looks like a good choice for servos.

Setting the OCR to be between 5% and 10% (1500 and 3000) of the 30000 counting range also looks good for setting a pulse to be between 1ms and 2ms in a 20ms frame.

You didn't say what speed the AVR is running at but let's see if I can work it out.

You are saying you want the counter to count 30,000 in 20ms so the timer itself will "tick" at a period of 20ms/30000. That is 0.6us. But then you also specify a prescaler of /64 so the CPU must have a clock period of 0.6us/64 so this would seem to imply that the AVR is running at 96MHz?

Maybe it'd be best if you just say what the AVR clock speed is then you can get some sensible numbers but I'll bet /64 prescaling does not figure in the answer if you really want to get the finest granularity possible out of 16 bits.

By the way in avr-gcc the prototype for main() is:
Code:
int main(void);

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
daniel's
PostPosted: Jul 13, 2012 - 01:37 PM
Newbie


Joined: Jul 11, 2012
Posts: 4


sorry - my mistake with the "int main (void)", but it does not change anything

F_CPU = 12MHz
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 13, 2012 - 03:36 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62337
Location: (using avr-gcc in) Finchingfield, Essex, England

96MHz = 12MHz * 8. The implication of this is that all you need is /8 not /64 prescaling. That would be just CS11 instead of CS11 and CS10.

But wait a minute - that's what the code above now shows? I could have sworn (as I typed in my previous reply) you had CS11 and CS10 set. Have you changed the code? If so is it now working?
Quote:
but it does not change anything

Actually it does - you are now getting one less warning that you were. But more to the point did the change to /8 make it work?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
daniel's
PostPosted: Jul 13, 2012 - 05:13 PM
Newbie


Joined: Jul 11, 2012
Posts: 4


fact I found some "stupid" bugs and corrected code

Still don't work ... also checked the two servos and both are doing nothing - they are "soft" - the engine does not block them ...

... all of fusebits and etc. is correct ...
 
 View user's profile Send private message  
Reply with quote Back to top
Visovian
PostPosted: Jul 13, 2012 - 08:51 PM
Posting Freak


Joined: Aug 07, 2007
Posts: 1477
Location: Czech

The code is right.
Even if the pulses had wrong time, the servo must react.
Put an earphone on OC1A pin against ground. You should hear a sort of 50 Hz tone.
If so, test your hardware. Use an extra supply for servo, (dry cells 4.5-6V, minus to avr gnd).
Check if the servo pins are right connected.
Plus of battery is on the middle pin on a common servo.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits