BASIC4MCU | 질문게시판 | RC카, 초음파를 이용하여 자율주행 질문입니다!
페이지 정보
작성자 seojc 작성일2020-09-09 18:25 조회18,331회 댓글3건본문
안녕하세요 RC카를 초음파 세개를 달아 자율주행하는 것을 하려하는 학생입니다
초음파3개를 터미널값을 받아 CM로 환산하는 것까지는 확인하였습니다
그 이후 모터를 이용하여 자율주행을 하려하는데 계속 원하는데로 IF문도 안되고 switch문도 제대로 되지가 않네요 ㅠㅠㅠ
다음과 같이 터미널로 초음파 값을 받았습니다!
#define F_CPU 8000000UL
#define BAUD 9600
#define U2X_S 2 // U2X 1 or 2
#define MYUBRR ((F_CPU*U2X_S)/(16L*BAUD)-1)
#define sbi(reg, bit) reg |= (1<<(bit))
#define cbi(reg, bit) reg &= ~(1<<(bit))
#include <util/delay.h>
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "USART_ch0.h"
#include "USART_ch1.h"
void timer0_init(void);
void timer2_init(void);
void Go_Straight (void);
void Turn_Left (void);
void Turn_Right (void);
void Back (void);
void Stop (void);
volatile unsigned int buf[8],dist[8],start=0,end=0;
volatile unsigned char cnt=0,flag[8]={0,};
unsigned int domo[10]={0, };
#define DIST 10
ISR(INT0_vect){ if(EICRA==0x03)start=TCNT1; else{ end=TCNT1; buf[0]=end-start; EIMSK=0; flag[0]=1; } EICRA^=0x01; }
ISR(INT1_vect){ if(EICRA==0x0C)start=TCNT1; else{ end=TCNT1; buf[1]=end-start; EIMSK=0; flag[1]=1; } EICRA^=0x04; }
ISR(INT4_vect){ if(EICRB==0x03)start=TCNT1; else{ end=TCNT1; buf[4]=end-start; EIMSK=0; flag[4]=1; } EICRB^=0x01; }
ISR(TIMER1_COMPA_vect) // measurement cycle of 60ms
{
switch(cnt)
{
case 0: PORTA|=0x01; _delay_us(10); PORTA&=~0x01; EICRA=0x03; EICRB=0x00; EIFR=0xFF; EIMSK=0x01; break;
case 1: PORTA|=0x02; _delay_us(10); PORTA&=~0x02; EICRA=0x0C; EICRB=0x00; EIFR=0xFF; EIMSK=0x02; break;
case 2: PORTA|=0x10; _delay_us(10); PORTA&=~0x10; EICRA=0x00; EICRB=0x03; EIFR=0xFF; EIMSK=0x10; break;
}
cnt++;
if (cnt >2)
{cnt=0;}
}
int main(void)
{ int cho;
DDRE = 0x00;//echo
DDRA = 0xFF;//trig
DDRG = 0xFF;
//TCCR1B=0x0C; OCR1A=1840; TIMSK=0x10; //8000000/256/(1+ 1840)=16.9744..==60ms
//HC-SR04 Control
TCCR1B = 0x0A; OCR1A=59999; TIMSK|=0x10;//8000000/8/(1+59999)=16.666Hz=60ms CTC/OCR1A
timer0_init();
timer2_init();
USART0_Init(MYUBRR);
USART1_Init(MYUBRR);
SREG=0x80;
while(1)
{
if(flag[0]){flag[0]=0; dist[0]=(int)((float)buf[0]/58.8);}
if(flag[1]){flag[1]=0; dist[1]=(int)((float)buf[1]/58.8);}
if(flag[4]){flag[4]=0; dist[4]=(int)((float)buf[4]/58.8);} //각각 초음파 3개의 값을 cm값으로 받았습니다
dist[1] -- 왼쪽 초음파 // dist[0] -- 가운데 초음파 // dist[4] -- 오른쪽 초음파
//DIST는 10으로 만들었습니다!
if (dist[1]>=DIST && dist[0]>=DIST && dist[4]>=DIST) //000 전진 10cm내 아무것도 없을 시 전진합니다
{
Go_Straight();
}
else if (dist[1]<=DIST && dist[0]>DIST && dist[4]>DIST) //100 우회전 왼쪽부분 초음파에 10cm내 장애물이 있을시 후진0.5초 정지0.1초 우회전0.5초를 합니다
{
Back(); _delay_ms(500); Stop(); _delay_ms(100);Turn_Right(); _delay_ms(500);
}
else if (dist[1]>DIST && dist[0]<=DIST && dist[4]>DIST) //010 우회전 가운데 부분 초음파에 10cm내 장애물이 있을시 후진0.5초 정지0.1초 우회전0.5초를 합니다
{
Back();_delay_ms(500); Stop(); _delay_ms(100);Turn_Right(); _delay_ms(500);
}
else if (dist[1]>DIST && dist[0]>DIST && dist[4]<=DIST) //001 좌회전 오른쪽부분 초음파에 10cm내 장애물이 있을시 후진0.5초 정지0.1초 좌회전0.5초를 합니다
{
Back(); _delay_ms(500);Stop(); _delay_ms(100);Turn_Left(); _delay_ms(500);
}
else if (dist[1]<=DIST && dist[0]<=DIST && dist[4]>DIST) //110 우회전 왼쪽, 가운데부분 초음파에 10cm내 장애물이 있을시 후진0.5초 정지0.1초 우회전0.5초를 합니다
{
Back(); _delay_ms(500);Stop(); _delay_ms(100);Turn_Right(); _delay_ms(500);
}
else if (dist[1]>DIST && dist[0]<=DIST && dist[4]<=DIST) //011 좌회전
{
Back();_delay_ms(500);Stop(); _delay_ms(100);Turn_Left(); _delay_ms(500);
}
else if (dist[1]<=DIST && dist[0]>DIST && dist[4]<=DIST) //101 후진
{
Back();_delay_ms(1000); Stop(); _delay_ms(100);Turn_Left(); _delay_ms(500);
}
else if (dist[1]<=DIST && dist[0]<=DIST && dist[4]<=DIST) // 111 후진
{
Back();_delay_ms(1000);Stop(); _delay_ms(100);Turn_Left(); _delay_ms(500); 빨간색으로 표시한 부분이 초음파를 이용한 제어부분입니다 ㅠㅠ
}
*/
}
}
void timer0_init(void){TCCR0 = 0b01101100;}
void timer2_init(void){TCCR2 = 0b01101011;}
void Turn_Right(void)
{
sbi(PORTB,4);
sbi(PORTB,2);
cbi(PORTB,3);
sbi(PORTB,7);
cbi(PORTB,0);
sbi(PORTB,1);
}
void Turn_Left(void)
{
sbi(PORTB,4);
cbi(PORTB,2);
sbi(PORTB,3);
sbi(PORTB,7);
sbi(PORTB,0);
cbi(PORTB,1);
}
void Go_Straight(void)
{
sbi(PORTB,4);
cbi(PORTB,2);
sbi(PORTB,3);
sbi(PORTB,7);
cbi(PORTB,0);
sbi(PORTB,1);
}
void Back(void)
{
sbi(PORTB,4);
sbi(PORTB,2);
cbi(PORTB,3);
sbi(PORTB,7);
sbi(PORTB,0);
cbi(PORTB,1);
}
void Stop(void)
{
cbi(PORTB,4);
cbi(PORTB,2);
cbi(PORTB,3);
cbi(PORTB,7);
cbi(PORTB,0);
cbi(PORTB,1);
}
코드는 다음과 같습니다ㅠㅠ
자동차가 10cm 내외 초음파에 걸리는 게없을때 go를 해야하는데 else if문에서 돌기만 하네요ㅠㅠㅠ
전자공작 키드님의 초음파 센서 코딩을 가지고왔씁니다
https://cafe.naver.com/circuitsmanual
댓글 3
조회수 18,331master님의 댓글
master 작성일
초음파 소스가 어느 글인지 전자공작 링크 주소가 명확하지 않습니다.
모터 출력이 포트B인데 DDRB 설정이 빠진 것 같군요.
차근 차근 체크하세요
master님의 댓글
master 작성일
if(flag[0]){flag[0]=0; dist[0]=buf[0]/59;}
if(flag[1]){flag[1]=0; dist[1]=buf[1]/59;}
if(flag[4]){flag[4]=0; dist[4]=buf[4]/59;}
58.8대신 59를 사용하면 오차가 조금 생기겠지만 정수 연산이라서 훨씬 빠르게 계산됩니다.
master님의 댓글
master 작성일답변글에 내용을 조금 더 추가해놓겠습니다.