All About Circuits Forum  

Go Back   All About Circuits Forum > Software, Microcomputing, and Communications Forums > Embedded Systems and Microcontrollers

Notices

Embedded Systems and Microcontrollers Discussion forum for projects and working with embedded systems and microcontrollers (FPGAs, PICs, AVRs). Get help with hardware issues and embedded programming.

Reply   Post New Thread
 
Thread Tools Display Modes
  #1  
Old 03-29-2013, 04:43 PM
thinkanish thinkanish is offline
New Member
 
Join Date: Mar 2013
Posts: 8
Default Measuring width of a pulse using avr capture

Hi,
I want to interface a ultrasonic sensor to attiny2313. The code I developed using avrgcc. I used capture interrupt of the avr to capture the rising and falling edge of the pulse and calculate the time elapsed in doing so. In this process, after capturing the falling edge of the pulse, the timer is switched of and again it is switched on only after triggering the sensor. The code below works fine but when the distance is low (say 10cm), timer overflows and everything stops. But by seeing the speed of the avr core and timer, it has no chance to overflow. I cannot sort it out.
Code:
#include "avr/io.h"
#include "avr/interrupt.h"
#define F_CPU 8000000
#include "util/delay.h"
 
volatile unsigned int pulseStart;
volatile unsigned int pulseEnd;
volatile unsigned int pulseInUs = 2013;
volatile unsigned char edge =0;
volatile unsigned int success = 0;
volatile unsigned int failure = 0;
 
#define START_TIMER TCCR1B |= ((1 << CS11) | (1 << CS10))
#define STOP_TIMER TCCR1B &= ~((1 << CS11) | (1 << CS10))
void pulseSensor(void){
   PORTB |= (1 << 0);
   _delay_us(10);                        
   PORTB &= ~(1 << 0);                    
}
 
void initialisePorts(void){
   DDRD &= ~(1 << 6);                  //PORTD.6 = INPUT
   DDRB |= (1 << 0) | (1 << 1) | (1 << 2);   //PORTB.0 = PORTB.1 = OUTPUT
}
 
void blinkLED(unsigned int port){
   DDRB |= (1 << port);
   PORTB ^= (1 << port);
   _delay_ms(200);
}
 
 
int main(void){
   initialisePorts();
   TIMSK |= ((1 << ICIE1)| (1 << TOIE1));   //Set capture interrupt
   sei();                           //Set global interrupt
   TCCR1B |= (1 << ICES1);               //Set capture rising edge
   pulseSensor();
   START_TIMER;
   for(;;){
     
      if(success){
         success = 0;
         if(pulseInUs <= 200)         //Obstacle in range  
            PORTB |= (1 << 1);
         else
            PORTB &= ~(1 << 1);         //Obstacle not in range
         pulseSensor();
         START_TIMER;
      }
      if(failure){
         failure = 0;
         PORTB |= (1 << 2);
      }
   }
   return 0;
}
 
ISR(TIMER1_CAPT_vect){
   if(edge == 0){
      pulseStart = ICR1;               //copy capture value
      TCCR1B &= ~(1 << ICES1);         //toggle capture edge
      edge = 1;                    
   }
   else{
      pulseEnd = ICR1;               //copy capture value
      TCCR1B |= (1 << ICES1);            //toggle capture edge
      edge = 0;
      STOP_TIMER;
      TCNT1 = 0;  
      pulseInUs = pulseEnd - pulseStart;
      success = 1;
   }
}
 
ISR(TIMER1_OVF_vect){
   failure = 1;
   TCCR1B |= (1 << ICES1);
   STOP_TIMER;
   TCNT1 = 0;
   edge = 0;
}
Select All
What is the problem in this code which makes the timer overflow?
Thanks.
Reply With Quote
  #2  
Old 03-31-2013, 12:00 AM
Motardo Motardo is offline
Junior Member
 
Join Date: Sep 2011
Location: Apex, NC, USA
Posts: 17
Default

Most ultrasonic ping sensors need a minimum distance of 7-10cm to work. If the distance is less than that, the sensor doesn't receive the echo, so it doesn't interrupt the uC, and the uC timer overflows. Which ultrasonic sensor are you using, and do you have a link to the datasheet?
Reply With Quote
  #3  
Old 03-31-2013, 05:31 PM
Bhavin Tailor Bhavin Tailor is offline
New Member
 
Join Date: Mar 2013
Posts: 3
Default

As per reply from Motardo, make ensure that are getting pulse from sensor.
Do you have any LED or display device...?
So, first make ensure you are getting rising & falling both edge from sensor. Just increment one variable on rising & falling edge & display value on LCD.
So, make ensure you are getting pulse or not from your sensor.
Reply With Quote
  #4  
Old 03-31-2013, 08:36 PM
thinkanish thinkanish is offline
New Member
 
Join Date: Mar 2013
Posts: 8
Default

Hi, thanks for your replies, i am using this 4 pin ultrasonic sensor : HC-SR04

The minimum resolution is 2cm but timer overflows even at 10 / 15cms

But the sensor works well with arduino pulseIn function up to (1 cm)

I have designed the program such that, if there is obstacle within some 20cm range, the LED in PORTB.1 glows. else it switches off. Also, an led is connected to PORTB.2 to indicate timer overflow. PORTB.0 is used to ping the sensor and PORTD.6 is the capture input.

Thanks.
Reply With Quote
  #5  
Old 03-31-2013, 09:15 PM
kubeek's Avatar
kubeek kubeek is offline
Senior Member
 
Join Date: Sep 2005
Location: Prague, Czech Rep
Posts: 3,490
Default

I am not quite sure why you do it the way you do. If I were doing this, I would reset the count on the timer and start it on the rising edge, then capture the value from the timer on the falling edge.
Reply With Quote
  #6  
Old 04-01-2013, 01:59 AM
thinkanish thinkanish is offline
New Member
 
Join Date: Mar 2013
Posts: 8
Default

Quote:
Originally Posted by kubeek View Post
I am not quite sure why you do it the way you do. If I were doing this, I would reset the count on the timer and start it on the rising edge, then capture the value from the timer on the falling edge.
I tried even this method. Doesnt seem to work
Even in the above method, the timer overflows when distance is short. I think the controller is failing to capture the falling edge?
In that case what can be done?
Reply With Quote
  #7  
Old 04-01-2013, 10:56 AM
kubeek's Avatar
kubeek kubeek is offline
Senior Member
 
Join Date: Sep 2005
Location: Prague, Czech Rep
Posts: 3,490
Default

Do you have an oscilloscope to crack this? I would toggle a pin to see for example when you enter and leave the ISR and use the other channel on the echo wire.
Reply With Quote
The Following User Says Thank You to kubeek For This Useful Post:
thinkanish (04-01-2013)
  #8  
Old 04-01-2013, 03:55 PM
thinkanish thinkanish is offline
New Member
 
Join Date: Mar 2013
Posts: 8
Default

Quote:
Originally Posted by kubeek View Post
Do you have an oscilloscope to crack this? I would toggle a pin to see for example when you enter and leave the ISR and use the other channel on the echo wire.
Hmm. I dont have a scope. I ll try this at my college and see.
Thanks for the tip
Reply With Quote
  #9  
Old 04-01-2013, 05:04 PM
Bhavin Tailor Bhavin Tailor is offline
New Member
 
Join Date: Mar 2013
Posts: 3
Default

Just for time being don't configure interrupt. As you are saying, timer overflow so there is enough time to sense. So, just make one WHILE loop to sense pin which is connected with sensor. Observe below logic,............

Code:
PORTB.1 = 0;            // LED1 Off
PORTB.2 = 0;            // LED2 Off
while(PORTB.0==0);           // Wait here until you found High State from Sensor
PORTB.1 = 1;           // You come here when you will get rising edge from sensor, 
while(PORTB.0==1);           // Wait here until you found High State from Sensor
PORTB.2 = 1;           // You come here when you will get falling edge from sensor,
Select All

So, if your both LED will glow it means, you are getting pulse from sensor and you have to look at in your code. Here, i assume that, by default state at your pin is LOW, Sensor will give High pulse & then it will maintain low state at pin.

Last edited by bertus; 04-01-2013 at 06:00 PM. Reason: used code tags
Reply With Quote
  #10  
Old 04-01-2013, 10:21 PM
djsfantasi's Avatar
djsfantasi djsfantasi is offline
Senior Member
 
Join Date: Apr 2010
Location: Northeast US
Posts: 1,039
Blog Entries: 1
Default

Code:
while(PORTB.0==1); // Wait here until you found Low State from Sensor
Select All
I think you meant Low state in your comment.
__________________
- Δj' fαπταi
Reply With Quote
Reply   Post New Thread

Tags
, , , ,


Similar Threads
Thread Thread Starter Forum Replies Last Post
Worksheets Help Pulse width convertor ratheepkrk General Electronics Chat 1 06-19-2012 07:48 AM
how to measure pulse width via AVR? eric_s88 Homework Help 1 03-15-2012 01:22 AM
PWM to RC servo pulse width Simon0362 The Projects Forum 3 09-21-2011 11:51 PM
control pulse width of a -15vdc pulse train @ 20khz fringe General Electronics Chat 2 01-23-2011 10:46 PM
LM555 Timing and Pulse Width Modulation 1337Hendrix The Projects Forum 6 12-02-2009 07:40 PM

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 03:41 PM.


User-posted content, unless source quoted, is licensed under a Creative Commons Public Domain License.
Powered by vBulletin
Copyright ©2000 - 2014, vBulletin Solutions, Inc.