0

I came across a project where I want to print the distance measured from an ultrasonic sensor to a LCD. The schematic of the design is as follows:

Schematic

The corresponding code:

    /*
C Program for Distance Measurement using Ultrasonic Sensor and AVR Microocntroller
 */ 

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000
#include <util/delay.h>
#include <stdlib.h>

#define enable            5
#define registerselection 6

void send_a_command(unsigned char command);
void send_a_character(unsigned char character);
void send_a_string(char *string_of_characters);

static volatile int pulse = 0;
static volatile int i = 0;

int main(void)
{
    DDRA = 0xFF;
    DDRB = 0xFF;
    DDRD = 0b11111011;
    _delay_ms(50);

    GICR|=(1<<INT0);
    MCUCR|=(1<<ISC00);

    TCCR1A = 0;

    int16_t COUNTA = 0;
    char SHOWA [16];


    send_a_command(0x01); //Clear Screen 0x01 = 00000001
    _delay_ms(50);
    send_a_command(0x38);
    _delay_ms(50);
    send_a_command(0b00001111);
    _delay_ms(50);

    sei();

    while(1)
    {
        PORTD|=(1<<PIND0);
        _delay_us(15);
        PORTD &=~(1<<PIND0);

        COUNTA = pulse/58;
        send_a_string ("CIRCUIT DIGEST");
        send_a_command(0x80 + 0x40 + 0);
        send_a_string ("DISTANCE=");
        itoa(COUNTA,SHOWA,10);
        send_a_string(SHOWA);
        send_a_string ("cm    ");
        send_a_command(0x80 + 0);

    }
}

ISR(INT0_vect)
{
    if (i==1)
    {
        TCCR1B=0;
        pulse=TCNT1;
        TCNT1=0;
        i=0;
    }
    if (i==0)
    {
        TCCR1B|=(1<<CS10);
        i=1;
    }
}

void send_a_command(unsigned char command)
{
    PORTB = command;
    PORTD &= ~ (1<<registerselection);
    PORTD |= 1<<enable;
    _delay_ms(8);
    PORTD &= ~1<<enable;
    PORTB = 0;
}

void send_a_character(unsigned char character)
{
    PORTB = character;
    PORTD |= 1<<registerselection;
    PORTD |= 1<<enable;
    _delay_ms(8);
    PORTD &= ~1<<enable;
    PORTB = 0;
}
void send_a_string(char *string_of_characters)
{
    while(*string_of_characters > 0)
    {
        send_a_character(*string_of_characters++);
    }
}

The design specs and code were taken from here: https://circuitdigest.com/microcontroller-projects/distance-measurement-using-hc-sr04-avr

I am confused about the ISR part of this code .The way it is coded here, when the echo from the sonar goes from HIGH to LOW, timer gets started again, since it goes to the second if block too, which i thought was unnecessary. But the simulation behaves strangely and gives incorrect and changing outputs if I just put the second if block as an else if which should have been fine.

ISR(INT0_vect)
{
    if (i==1)
    {
        TCCR1B=0;
        pulse=TCNT1;
        TCNT1=0;
        i=0;
    }
    else if (i==0)
    {
        TCCR1B|=(1<<CS10);
        i=1;
    }
}

This change produces erratic and changing output like this:

Wrong output

It seems here for it to work properly when i = 1 the code has to jump to the second block too. Why does using the else if produce incorrect results? Any help would be much appreciated.

1 Answers1

0

A few points:

  • The ISR from the original code doesn't make sense to me. Your changes should result in the intended behavior.

  • i can be uint8_t instead of int

  • pulse should be uint16_t instead of (signed) int

  • Since pulse is a multi-byte variable and it is accessed from ISR and from main(), interrupts should (have to) be disabled while accessing it from the "main thread".

Like this:

cli();
COUNTA = pulse/58;
sei();

or even better use the macros from "util/atomic.h"

ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
     COUNTA = pulse/58;
}

Otherwise you can get wrong results during access.

Rev
  • 5,827
  • 4
  • 27
  • 51
  • applied all the changes mentioned.Still it doesnt work with the else if block. The distance gets increased on each iteration – Abhik Bhattacharjee Jun 06 '18 at 07:50
  • Increased? Even if you don#t change the actual distance? Does the original code without the "else" run without problems? Something seems weird. – Rev Jun 06 '18 at 10:24
  • Yes. It gets increased without changing the actual distance. The original code with the two "if " blocks works flawlessly – Abhik Bhattacharjee Jun 06 '18 at 14:48