Utilizing the Ultrasonic Sensor HC-SR04 on Atmel Studio with Arduino Uno (C++)

  arduino, atmel, atmelstudio, avr, c++

I was curious as to how I can utilize Atmel studio for the Ultrasonic Sensor HC-SR04. Thus far, I created my own timer to pulse every ten microseconds to get the distance with a separate counter.

However, this didn’t work, so I spent last afternoon attempting to find header files utilize the Ultrasonic library the arduino utilizes. Of course, this didn’t really work, so I am all out of ideas.

I’m unsure what I am doing wrong in my code, if anyone could take I look I would greatly appreciate it!

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL

#include <avr/delay.h>
#define triggerPin PIND3
#define echo PIND2

//variable corresponding to port numbers in port b
const unsigned char redOut         = 0x20;//bit 5
const unsigned char yellowOut    = 0x10;//bit 4
const unsigned char greenOut        = 0x08;//bit 3
const unsigned char servo        = 0x02;//bit 1
const unsigned char buzz            = 0x01;//bit 0
//variables for port d
const unsigned char ultraTrig    = 0x08;//bit 3
const unsigned char ultraEcho    = 0x04;//bit 2
const unsigned char Time_out     = 30000; // 5 m

int TimerOverflow = 0;

//delay functions
void delayfiveMS();//generates a delay of 5 ms
void delaytenUS();//generates a delay of 10 us
void servoDelay();//delay of 32 seconds to allow for driver to enter garage
//functions to manipulate I/O
long timeOut();//function to find the duration to use in the lightDistance function
void useServo();// activates servo to close door
void lightDistance(double dist);//function to do the range math and activates pins and buzzer. will also call servo in red

unsigned long read_pulse(int pin)
{
    static unsigned long rising_time;  // time of the rising edge
    static int last_state;             // previous pin state
    int state = PORTD;      // current pin state
    unsigned long pulse_length = 0;    // default return value

    // On rising edge: record current time.
    if (last_state == 0 && state == 1) {
        rising_time = micros();
    }

    // On falling edge: report pulse length.
    if (last_state == HIGH && state == LOW) {
        unsigned long falling_time = micros();
        pulse_length = falling_time - rising_time;
    }

    last_state = state;
    return pulse_length;
}

long timing()
{
    PORTD &= ~(ultraTrig);
    _delay_us(2);
    PORTD |= (ultraTrig);
    delaytenUS();
    PORTD &= ~(ultraTrig);
    long duration = pulseIn(Echo_pin,HIGH,Time_out);
    if ( duration == 0 ) {
    duration = Time_out; }
    return duration;
}

ISR(TIMER1_OVF_vect)//interrupt function to help find the distance
{
    TimerOverflow++;    /* Increment Timer Overflow count */
}

int main(void){
    
    long count;
    double dist;
    
    DDRB    = 0x3B;//instantiates ports for output
    DDRD    = 0x0C;
  
    sei();            /* Enable global interrupt */
    TIMSK1 = (1 << TOIE1);    /* Enable Timer1 overflow interrupts */
    TCCR1A = 0;        /* Set all bit to zero Normal operation */
    //distance_cm = duration /29 / 2 ;
    while(1)
    {
        count = timing();
        dist = (double)count/29 / 2;//should be meters
        lightDistance(dist);
        
        /* Give 10us trigger pulse on trig. pin to HC-SR04 
        PORTD |= (1 << triggerPin);
        delaytenUS();
        PORTD &= (~(1 << triggerPin));
        
        
         16MHz Timer freq, sound speed =343 m/s 
        count = timeOut();
        dist = (double)count/932.9455;//should be meters
        lightDistance(dist);*/
        
        }
}

void delayfiveMS() {//may need to change to timer2 to prevent conflict with main function
    TCNT1    = 0;
    OCR1A    = 1250-1;
    TCCR1A    = 0b0;
    TCCR1B    = 0b1011;
    while ((TIFR1 & (1 << OCF1A)) == 0);
    TCCR1B    = 0;
    TIFR1    = (1 << OCF1A);
}

void delaytenUS(){//normal mode timer0 delay
    TCNT0 = 256-160;
    TCCR0A = 0b0;
    TCCR0B = 0b1;
    while ((TIFR0 & 0x01) == 0);
    TCCR0B    = 0;
    TIFR0    = (1 << TOV0);
}

void lightDistance(double dist){
       if (dist < 2){
       PORTB = redOut;
       PORTB = buzz;
       }else if(dist < 4){
           PORTB = yellowOut;
       }else if(dist < 6){
           PORTB = greenOut;
       }else{
           PORTB = greenOut + redOut + yellowOut;
       }
    
}

long timeOut(){
    TCNT1 = 0;    /* Clear Timer counter */
    TCCR1B = 0x41;    /* Capture on rising edge, No prescalar*/
    TIFR1 = 1<<ICF1;    /* Clear ICP flag (Input Capture flag) */
    TIFR1 = 1<<TOV1;    /* Clear Timer Overflow flag */

    /*Calculate width of Echo by Input Capture (ICP) */

    while ((TIFR1 & (1 << ICF1)) == 0);/* Wait for rising edge */
    TCNT1 = 0;    /* Clear Timer counter */
    TCCR1B = 0x01;    /* Capture on falling edge, No prescalar */
    TIFR1 = 1<<ICF1;    /* Clear ICP flag (Input Capture flag) */
    TIFR1 = 1<<TOV1;    /* Clear Timer Overflow flag */
    TimerOverflow = 0;/* Clear Timer overflow count */

    while ((TIFR1 & (1 << ICF1)) == 0);/* Wait for falling edge */
    return ICR1 + (65535 * TimerOverflow);    /* Take count */
}

}


Apologies for the longhand code. I attempted to use a predefined library code for the timeout function but I fear I implemented it poorly. Any help at all would be appreciated!

Source: Windows Questions C++

LEAVE A COMMENT