Society of Robots - Robot Forum

Electronics => Electronics => Topic started by: rox2007 on January 18, 2008, 10:11:38 AM

Title: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 10:11:38 AM
Once again, please help, please
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: robonoob on January 18, 2008, 10:31:30 AM
u only have a chip? or a whole controll board?
if u have a controll board then search internet for how to make a circuit board with your atmega as its brain and then you can connect ur servos there.
else if u have a control board then where is the problem? just connect the servos where needed and programme it and you are all done :)
but if u know all the hardware thing(like where to connect it and stuff) and you have done this all (like connecting and powering servo) but you only have problems with servo control code, then you should read some examples of servo controll and read tutorials about controlling the servo with the code you want to use.
anyway internet is a good friend of yours :) use it
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 18, 2008, 11:01:56 AM
Can you tell us what you have working and what isn't working?

The $50 Robot will tell you exactly how to do it.

Are you sure you have 16MHz?
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 11:39:09 AM
Well, this is what i have done.

--i have my mcu board which runs my line detecting code
--i modified my servo for continuous rotation using the admin tutorial. it worked. servo stopped at 1.5ms

this is what i used for delay
courtesy sparkfun blink_iMhz code

//General short delays
void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 90 ; y++){
      for ( z = 0 ; z < 6 ; z++){
        asm volatile ("nop");
      }
    }
  }
}

--but i added an oscillator t(16mhz and set the fuse bits) to my mcu after . my code ran perfectly but faster, which is what i wanted
--but now when i try to control the servo with 1.5ms using the above code, it doesnt stop instead it moves slower
--so if anyone can help me with a servo control code, i'll be really grateful
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 11:56:25 AM
actually it reverses when it gets that 1.5ms
maybe it recaliberated itself
i should probably run a code from 0ms to 2ms to find the new stop point
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: airman00 on January 18, 2008, 12:46:11 PM
perhaps when you added on the 16mhz oscillator you messed up the pulse.

A program that controls a servo @ 4mhz will not work correctly control a servo @ 16mhz

But that is based on my experience in assembly and BASIC , though not in C , thats just a guess.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 12:50:21 PM
yeh, i guess so
i'll just run a code that runs the servo from 0ms to 2ms, and find that centerpoint
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rgcustodio on January 18, 2008, 12:50:38 PM
check you F_CPU settings make sure you've set it up properly for the new oscillator, then don't forget to recompile your code.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: airman00 on January 18, 2008, 12:50:53 PM
at what oscillator speed did the servo work correctly?
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 12:55:55 PM
at 4mhz i think
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 12:56:42 PM
check you F_CPU settings make sure you've set it up properly for the new oscillator, then don't forget to recompile your code.

where do i find this
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rgcustodio on January 18, 2008, 12:58:06 PM
check you F_CPU settings make sure you've set it up properly for the new oscillator, then don't forget to recompile your code.

where do i find this

it should be a define in one of your source or header files.

you should find something like:
Code: [Select]
// make sure the following is the CPU frequency in Hertz
#define F_CPU 1600000UL
in your code.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: airman00 on January 18, 2008, 01:03:32 PM
at 4mhz i think

so try to send it a pulse of 6 ms( 4 times 1.5ms)  in your confused code. Once upon a time , I ran servo code at 8 mhz instead of the 4mhz which worked before. So all I did was double the 1.5  ms pulse , so the microcontroller though it was sending a 3ms pulse , but since it was at 8mhz it ended up giving 1.5 ms.


P.S. If you try to do the 6 ms pulse , have an on/off switch for the power supply , because if you leave it on and it gives a real 6ms pulse i think the servo will turn to the extreme angle and the gears will grind. or maybe the servo won't accept the pulse at all.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 01:39:30 PM
this just might work thanx.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: airman00 on January 18, 2008, 03:00:34 PM
well did it work?
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 03:24:32 PM
nope, dont know what happened.....is it possible to loop through numbers and find the right milliseconds for stopping it
actually i think i was running it at 1mhz
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 03:36:13 PM
how do you modify the delay_cycles code from atmega8 to atmega16

about the fcpu thing, i dont have it declared anywhere. shouldi declare it?
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 04:30:53 PM
it looks like for any value 10ms and above the servo doesnt move, ignore this...it doesnt work
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 18, 2008, 04:40:26 PM
Wait . . . atmega16 or atmega168?

Anyway, you don't have to modify the delay code, its exactly the same.

What changes is the frequency you are running at . . . does your hardware have a crystal built in? Are you using the Arduino or the $50 Robot? What are your fuse frequency settings? Are you using AVRlib?

Here is a great way to determine your frequency for servo use (if you don't have an oscilloscope):
Code: [Select]
turn on LED
loop 10 times:
  delay_cycles(65500);
turn off LED
loop 10 times:
  delay_cycles(65500);
repeat

Now this means that 65500*10*2 cycles occur for every flash of the LED.

Now get out your watch and count the number of times your LED turns on in one minute.

Lets say its 30 times, count.

That means:
65500*10*2*count/(60 seconds) = cycles per second

or

655000 cycles/second

but what you want is to know how many cycles it takes for 1.5ms - the servo control time . . .

so:

655 cycles/ms   ->   655*1.5=982.5

so to get your servo to stop moving, you'd want to send a signal of 1.5ms long, or 982.5:

turn servo on
delay_cycles(982);
turn servo off

Your servo moving one direction would be 655*1 (for 1ms), and the other way is 655*2 (for 2ms).
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 04:43:31 PM
i'll try this..

Thanx alot admin, you are still the best
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 18, 2008, 04:46:57 PM
thanks :)

I think Ill turn that last post into a tutorial . . . it saved me tons of timing frustration when I figured that out last summer . .  .
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 04:53:31 PM
that wont be a bad idea
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 04:55:49 PM
-----i am using a 16mhz external crystal with an atmega168

-------built like the $50 Robot

fuse frequency settings= i got this from sparkfun

----avrdude -p m168 -P com1 -c ponyser -U lfuse:w:0xE6:m
i am using AVRlib?

admin, one question:
loop 10 times:
turn on
loop 10 times:
turn off

do you mean i should run it in a for loop like

for (j = 0; j < 10; j++)
      {
          PORTC = 0xFF;
         PORTB = 0xFF;
         PORTD = 0xFF;
         
           delay_cycles(65500);
         PORTC = 0x00;
         PORTB = 0x00;
         PORTD = 0x00;
         loop 10 times:
           delay_cycles(65500);
      }


OR

   for (j = 0; j < 10; j++)
      {
          PORTC = 0xFF;
         PORTB = 0xFF;
         PORTD = 0xFF;
      }   
      for (j = 0; j < 10; j++)
      {
         delay_cycles(65500);
         PORTC = 0x00;
         PORTB = 0x00;
         PORTD = 0x00;
         
         delay_cycles(65500);
      }
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rgcustodio on January 18, 2008, 05:14:50 PM
regarding the F_CPU thing nope i guess it isn't needed in your case, i think you're not using avrlibc. you can ignore the F_CPU thingy.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 18, 2008, 05:52:35 PM
you want to do that first for loop you posted, but probably just for your LED pin . . . I'm also doing 16MHz on another AVR, so if you did your fuse settings properly, you will find your delay should be around ~800.

since its just a quickie test, I just do:

Code: [Select]
while(1)
{
LED_on();
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
LED_off();
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
delay_cycles(65500);
}
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 06:03:23 PM
i got 521, with the code i wrote. i'll try what you wrote. and was this correct for a 16mhz external oscillator

avrdude -p m168 -P com1 -c ponyser -U lfuse:w:0xE6:m
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 06:10:43 PM
maybe i didnt do the fuse settings right, how can i do it right
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 18, 2008, 06:22:30 PM
Read Osc.Calibration Byte successful: 0xA8 (168)

i got 22 counts
i checked my fuse bits and they are correct

    *  CKDIV8 = 1
    * CKOUT = 1
    * SUT1 = 1
    * SUT0 = 0
    * CKSEL3 = 0
    * CKSEL2 = 1
    * CKSEL1 = 1
    * CKSEL0 = 0
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 19, 2008, 08:31:47 AM
Quote
maybe i didnt do the fuse settings right, how can i do it right
I use AVR Studio to do my fuse settings.

Quote
i checked my fuse bits and they are correct

    *  CKDIV8 = 1
    * CKOUT = 1
    * SUT1 = 1
    * SUT0 = 0
    * CKSEL3 = 0
    * CKSEL2 = 1
    * CKSEL1 = 1
    * CKSEL0 = 0
how do you know thats correct? are you sure you want to divide the clock by 8 (making it 1/8th the speed)? ;)
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 19, 2008, 09:21:28 AM
actually, i got that from sparkfun. I am using the serial dongle and thats what i saw on sparkfun's tutorial. well i just skimmed through the tutorial, maybe i missed something. I dont know how to do it with AVR though. If you could help me out that would be great.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 19, 2008, 10:16:40 AM
nevermind about what I said earlier about the fuses, having a 0 makes it divide by 8 . . . oops . . .

anyway, if you have the serial dongle, you can't use AVR Studio to do the fuses . . . I'm guessing you are using ponyprog, right?

try the delay code yet?
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rgcustodio on January 19, 2008, 10:35:23 AM
Quote
-----i am using a 16mhz external crystal with an atmega168

-------built like the $50 Robot

fuse frequency settings= i got this from sparkfun

----avrdude -p m168 -P com1 -c ponyser -U lfuse:w:0xE6:m
i am using AVRlib?

you're using avrlibc? are you sure? AVRlibc is a small C library comparable to glibc. glibc is used in full-blown Linux systems mainly while AVRlibc is designed specifically for use with the Atmel AVR series of MCUs.

if you are using AVRlibc, your code and/or Makefile must have F_CPU defined. verify that all values match before recompiling.

whose code are you using? if you're using the $50 Robot code, the F_CPU definitions are in a file named global.h. find the file and select the F_CPU value that matches your setup.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 19, 2008, 10:57:47 AM
i am using avrlib by procyon not avrlibc. FCPU is defined in the make file as 16mhz. maybe i did not set the fuse bits right. does anyone now how to set the fuse bits for an external 16mhz clock for an atmega168 with pony prog. i am using my own code based on the $50 robot but modified extensively
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rgcustodio on January 19, 2008, 11:24:35 AM
i also use procyon's libraries. procyon also uses F_CPU. it can also be defined in the Makefile or in the globals.h file.

make sure first that the correct F_CPU is not commented out. from one of my globals.h file:

Code: [Select]
// project/system dependent defines

// CPU clock speed
//#define F_CPU        20000000                         // 20MHz processor
//#define F_CPU        16000000                         // 16MHz processor
//#define F_CPU        14745000                         // 14.745MHz processor
#define F_CPU        8000000                            // 8MHz processor
//#define F_CPU        7372800                          // 7.37MHz processor
//#define F_CPU        4000000                          // 4MHz processor
//#define F_CPU        3686400                          // 3.69MHz processor
#define CYCLES_PER_US ((F_CPU+500000)/1000000)  // cpu cycles per microsecond

yes you can see F_CPU as 16MHz but it is not used because it is commented out using C++ style comments. to enable the correct F_CPU value just remove the "//" in front of the definition.

Code: [Select]
#define F_CPU        16000000                         // 16MHz processor
//#define F_CPU        14745000                         // 14.745MHz processor
//#define F_CPU        8000000                            // 8MHz processor

how did you connect your oscillator to the MCU? did you precisely follow the requirements/recommendations on page 31 and 32 of the ATmega168 data sheet? personally, the fuse settings that you are using seems to be correct based on the information that you have provided so far.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 19, 2008, 11:34:01 AM
i did connect the oscillator right. i used two capacitors (22pf) connected to the oscillator to xtal pins.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rgcustodio on January 19, 2008, 12:03:44 PM
i'am, at this point, all out of any constructive suggestions. the only thing i can suggest is to go and double, maybe even triple check your settings and setup.
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 19, 2008, 12:27:12 PM
ok, thanks for your help
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 19, 2008, 10:05:17 PM
solved it with PWM wooohooo.

Code: [Select]
// Servo test program
// Put your name here
// Put the date here
//----- Include Files ---------------------------------------------------------
#include <avr/io.h>
// include I/O definitions (port names, pin names, etc)
#include <avr/signal.h>
// include "signal" names (interrupt names)
#include <avr/interrupt.h>
// include interrupt support
#include "global.h"
// include our global settings
#include "timer.h"
// include timer function library (timing, PWM, etc)
#include "pulse.h"
// include pulse output support
#include "servo.h"
#include "iocompat.h" 
int i;
// include RC servo support
//----- Function Declarations--------------------------------------------------
void init(void);
//----- Begin Code ------------------------------------------------------------
int main(void)
{
init();
// initialize everything
while(1)
{
for (i = 0; i < 255; i++)
{
servoSetPosition(0, i);
PORTD = 0x00;
timerPause(3000);
//servoSetPosition(0,0);
PORTD = 0xff;
timerPause(3000);
}
}
return 0;
}
// end main()
void init(void)
{
// initialize our libraries
timerInit();
// initialize the timer system
servoInit();
// initialize the servo system
// Setup I/O
DDRC = 0;
// Set PORTA to all inputs
PORTC = 0xff;
// Turn on pullup resistors
DDRD = 0xff; // Set PORTD to all outputs
PORTD = 0xff;
// Set PORTD outputs to high
}
// end init()
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: rox2007 on January 19, 2008, 10:17:00 PM
the code above works according to avrlib
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: Admin on January 26, 2008, 08:14:12 PM
I finally wrote that tutorial on calculating delay_cycles . . .
http://www.societyofrobots.com/microcontroller_time_cycles.shtml
Title: Re: Please, how do i control my servo with an ATMEGA 168, 16Mhz MCU
Post by: GUmeR on January 27, 2008, 10:28:52 AM
Isn't it simpler:

http://mil.ufl.edu/~achamber/servoPWMfaq.html