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++