Question

Hy, I have ultrasonic sensor measuring distance and no mather which type is my variable "range" (uint8_t, uint16_t, 32, 64)I always get overflow, and than sensor starts from 0 again..Is there a way that I can limit "range" variable or I must limit that on harder way with pulsewidth... Thanks

SENSOR_DDR |= (1<<TRIGGER_PIN);  
SENSOR_DDR &= ~(1<<ECHO_PIN) & ~(1<<PB3) & ~(1<<PB2) & ~(1<<PB1) & ~(1<<PB0); 
DDRD = DDRD | _BV(4); 
PORTD = PORTD | _BV(4);
ENGINE_DDR = 0xff; 
ENGINE_PORT = 0;

lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_puts("Something wrong...");


while(1)
{

PORTB |= (1<<PB4); //Send Trigger
_delay_us(10);
PORTB &= ~(1<<PB4); //Send trigger


timer0counter=0;
TCNT0=0; //Clear timer
while(bit_is_clear(PINB,5)); //Wait for rising edge
TCCR0 |= (1<<CS02); //Select prescalar 256
TIMSK |= (1<<TOIE0) | (1<<TOIE2); //Enable timer0 overflow interrupt

lcd_clrscr();

while(bit_is_set(PINB,5) && timer0counter<9) //wait for falling edge of echo
{
_delay_us(5);
}
TCCR0 &= ~(1<<CS02); //Stop timer
TIMSK &= ~(1<<TOIE0);
if(bit_is_set(PINB,5))
{
lcd_puts("No OBSTACLE");
}
else
{
range=(256*timer0counter+TCNT0)*32*0.017; //range conversion

lcd_clrscr();
lcd_puts("Distance:");
lcd_puts(itoa(range,buffer,10));
lcd_puts_P("cm");
}
if(range<15){
...

ISR(TIMER0_OVF_vect) 
{
TIMSK &= ~(1<<TOIE0);
TCNT0=0;
timer0counter++;

TIMSK |= (1<<TOIE0);

if(timer0counter>8)
{
TCCR0 &= ~(1<<CS02);
TIMSK &= ~(1<<TOIE0);

}
Was it helpful?

Solution

The calculation

256*timer0counter+TCNT0

saves temporary value in 'default' size int, which on AVR is 16b. so, every time timer0counter is higher than 256 it will overflow regardless of the final type of the variable.

instead of doing

range=(256*timer0counter+TCNT0)*32*0.017;

try going with:

double range_real = 256.0 * (double)timer0counter + (double)TCNT0 * 32.0 * 0.017;
range = (int) range_real;

Being explicit about types can really save your skin.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top