go_away

Author Topic: Hardware timer sourcecode  (Read 1425 times)

0 Members and 1 Guest are viewing this topic.

Offline LaDaDee108Topic starter

  • Beginner
  • *
  • Posts: 3
  • Helpful? 0
Hardware timer sourcecode
« on: September 14, 2010, 08:20:40 PM »
Hi everyone,

I'm new to the world of microcontrollers, so please bear with me.  I'm looking to use a timer capture on an avr chip to control some hardware.  I'm having trouble creating a simple counter using the TCNT0 timer register to use for a sonar.  whatever I've written isn't working.  could any one write up a quick blurb of code for me that I can just paste?  (I get the concept, its really the actual coding that's messing me up)  It was an old chip that someone had lent me, so i'm not entirely sure if its a ATM32 or ATM168...think its the 168 though, if that helps.  please, any help would be much appreciated!

Offline kidwidget

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #1 on: September 15, 2010, 11:45:50 AM »
I would love to help, but I need more information on the hardware you are using, the tool set you're using, language, and exactly how much experience do you have? You stated you were new, how new? Can you make and LED blink? If so what have you accomplished so far. This will give us a base on what kind of advise to give you. Can you post the source code you have so far?

RockON!
World's crappiest website, www.robowidgets.net.
RockON!

Offline RobotFreak

  • Jr. Member
  • **
  • Posts: 17
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #2 on: September 15, 2010, 01:16:41 PM »
I work with LaaDaaDee, so let me help clarify.   I checked, and it is an ATmega168, being programmed in C through WinAVR (PN).  We know C pretty well, its just that we're not familiar with microcontrollers.  Yes, we CAN make an LED blink...:)  So far, i've used the chip to get a servo working (Timer1), now we need to get a sonar working using another timer.  It will eventually be mounted on top of the servo for a sort of scanning obstacle search.  Here is the relevant part of the code:
Code: [Select]


void SonarInitialize(void)
{
     //Set whether pin is input or output using direction registers
    
     //Pin C3 as an input (echo)
     DDRC &= ~0x08;
    
     //Pin B3 as an output (trigger)
     DDRB |= 0x08;
}

void ServoInitialize(void)
{
     //Pin B1 as an output (trigger)
     DDRB |= 0x02;
}


void ServoScan(void)
{
// Set up a PWM channel on Pin B1 (servo)
  TCCR1A = 0;
  ICR1 = 46079; // frequency is every 20ms
  //configure Timer1 for fast PWM mode vai ICR1 with pre-scaling of 8
  TCCR1A = (1 << WGM11);
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
  // Set PB1 and PB2 as outputs
  DDRB |= _BV(1) |  _BV(2);
  TCCR1A |= 2 <<  6;  // enable PWM on port B1 in non-inverted compare mode 2
  TCCR1A |= 2 <<  4;  // enable PWM on port B2 in non-inverted compare mode 2

    while (1)
  {
  for (OCR1A=200; OCR1A < 5000; OCR1A+=100)
  {
delayMs(1);
  }
  LEDBothOn;
  
  for (OCR1A=5000; OCR1A > 200; OCR1A-=100)
  {
delayMs(1);
  }
  }

}

void SonarRanging(void)
{
float Distance_to_obst;
uint16_t delay=0;

//PRITM0 = 0x00; Timer0 on
//PRR = (1 << 5);
//TCCR0B = (0 << WGM02)|(0 << WGM01)|(0 << WGM00);


//Pin B3 is the trigger: Bring it High
     //PORTB |= 0x08;
PORT_ON(PORTB, 3);
     //delay 10 us
     _delay_us(12);
     //Bring Pin B3 low
     //PORTB ^= 0x08;
PORT_OFF(PORTB, 3);

     //wait for it to go high
      do {} while (!(PINC & 0x08));
 
 TCNT0=0x00;
 TCCR0B = START_CLK_N;
 
 do {} while (PINC & 0x08);
 
 TCCR0B = STOP_CLK;
 Distance_to_obst= TCNT0/58;




if (1 < Distance_to_obst < 10)
{
LED1On;
delayMs(500);
LED1Off;
delayMs(500);
}



}

We're just using the LED as a way to get some response from the board without causing any motion yet.  the sonar ranging function is just called repeatedly in a while loop in the main with a delay so as not to create any ghost echoes.  Doesn't seem to be working though?  Can you please instruct us as to how we should modify the code?  Thanks, we really need the help!
« Last Edit: September 15, 2010, 01:24:24 PM by RobotFreak »

Offline LaDaDee108Topic starter

  • Beginner
  • *
  • Posts: 3
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #3 on: September 15, 2010, 01:27:58 PM »
Yep that's right...Thanks RobotFreak...Please help!!

Offline kidwidget

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #4 on: September 15, 2010, 03:11:14 PM »
I don't know C, I program in assembly but let me give this a try.

Let me make sure I understand, the servo rotates back and forth, that part of the code is OK but the sonar part isn't?

If that assumption is true the I have the following suggestion/questions.
Why is
Code: [Select]
     //PRITM0 = 0x00; Timer0 on
     //PRR = (1 << 5);
     //TCCR0B = (0 << WGM02)|(0 << WGM01)|(0 << WGM00);

commented out? Did you do it else where and just wanted to show that it was done? Also wgm01 and wgm00 are not located in register tccr0b, they're in tccr0a.

After that:
Code: [Select]
      do {} while (!(PINC & 0x08));
looks wrong to me (I'm not a c programmer though) but I think what you're trying to say is while the value on PINC is not 0 do nothing but when it is 1 then start the timer. I think (again I'm not a c programmer) the way to do this is do {} while (!(portc& 0x08)) or read the pin this away 'i = pinc' and then replaced i for PINC in your do while statement. The same goes for your other do while statement. Try looking into the WinAVR docs and see how you read a pin.

It looks like your servo code allows a pulse width up to 2.17 ms, some servos won't tolerate a pulse width that long and will behave unpredictably. I found this out with some Traxxas brand RC cars when they used a cheap receiver that would "get out of adjustment" and send out a pulse width signal that high.

Hope this helps.
RockON!
World's crappiest website, www.robowidgets.net.
RockON!

Offline kidwidget

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #5 on: September 16, 2010, 01:54:50 AM »
...One more thing. Timer0 is an 8bit timer. It can only hold values from 0-255. Depending on your prescale and clock rate it may be rolling over several times before the falling edge of the sonar sensor comes back.

RockON!
World's crappiest website, www.robowidgets.net.
RockON!

Offline dunk

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 1,086
  • Helpful? 21
Re: Hardware timer sourcecode
« Reply #6 on: September 16, 2010, 03:31:21 AM »
there's a good article on using AVR timers here:
http://members.shaw.ca/climber/avrtimers.html

dunk.
« Last Edit: October 07, 2010, 02:49:53 AM by dunk »

Offline LaDaDee108Topic starter

  • Beginner
  • *
  • Posts: 3
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #7 on: September 21, 2010, 02:54:55 PM »
Dunk,

Doesn't look like that link is working...Can you please give the right link? Thanks.

Kidwidget-

I'm pretty sure that in the command module manual it says that the state of a pin can be read via the PIN call, and PORT is only used to set the pin to high or low.  But suppose, instead, I did something like this...

Code: [Select]

PORT_ON(PORTB, 3);
_delay_us(12);
PORT_OFF(PORTB, 3);
do {} while PORT_IS_OFF(PORTC, 3);
TCNT0=0x00;
TCCR0B = START_CLK_N;
 
do {} while PORT_IS_ON( PORTC, 3);
 
TCCR0B = STOP_CLK;
Distance_to_obst= TCNT0/58;

Where the functions are defined as...

Code: [Select]
#define PORT_IS_ON( port_letter, number ) ( port_letter & (1<<number) )
#define PORT_IS_OFF( port_letter, number ) (!( port_letter & (1<<number) ))

Should it still work...?

Because it isn't. :(
« Last Edit: September 21, 2010, 02:58:33 PM by LaDaDee108 »

Offline kidwidget

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #8 on: September 23, 2010, 06:17:05 PM »
I'm out of town with work write now and away from my tools and datasheets. When I get back home I'll try to see if I can come up with something that will work for you.
World's crappiest website, www.robowidgets.net.
RockON!

Offline kidwidget

  • Jr. Member
  • **
  • Posts: 7
  • Helpful? 0
Re: Hardware timer sourcecode
« Reply #9 on: September 28, 2010, 06:04:15 PM »
This code works using the simulator in AVR Studio and WinAVR. You will have to change the port and pins to the ones you are using (I used PORTB for testing). I also used the timer in the simplest mode, you may want to change it to an input capture mode. I hope it helps.
Code: [Select]
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRB = 0xff;
volatile unsigned int i, EdgeR, EdgeF, eta;
i = EdgeR = EdgeF = eta = 0;

PORTB = 0x01;
_delay_us(10);
PORTB = 0x00;
DDRB = 0x00;
_delay_us(650);
TCCR1B = (1<<CS00);

while(i == 0)
{
i = PINB;
}
EdgeR = TCNT1;

while(i != 0)
{
i = PINB;
}
EdgeF = TCNT1;
eta = EdgeF-EdgeR;
return 1;
}
RockON!
World's crappiest website, www.robowidgets.net.
RockON!

 


Get Your Ad Here

data_list