I have an ultrasonic sensor measuring distance and no matter which type my variable "range" is (uint8_t, uint16_t, 32, or 64), I always get an overflow, and then the sensor starts from 0 again... Is there a way that I can limit the "range" variable, or must I limit that on harder way with the pulsewidth?
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 a rising edge
TCCR0 |= (1<<CS02); // Select prescaler 256
TIMSK |= (1<<TOIE0) | (1<<TOIE2); // Enable timer0 overflow interrupt
lcd_clrscr();
while(bit_is_set(PINB, 5) && timer0counter<9) // Wait for the alling 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);
}
The calculation
256*timer0counter + TCNT0
saves a temporary value in a 'default' size int, which on AVR is 16 bits. 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.