질문게시판 > 답변 : atmega128fh 라인트레이서 제작중 방향 문제에 관해서

인기검색어 > 아두이노 센서 ATMEGA128

최신글 질문게시판 동영상강좌 가입하기

▼ BASIC4MCU 후원업체 신제품 정보 ▼

▲ BASIC4MCU 후원업체 신제품 정보 ▲

BASIC4MCU > 질문게시판

답변 : atmega128fh 라인트레이서 제작중 방향 문제에 관해서

페이지 정보

작성자 master 작성일18-12-19 20:14 조회3,794회 댓글0건

본문

 

// DateTime : 2018-12-19 오후 7:44:58
// by Ok-Hyun Park
//
안녕하세요 라인트레이서 제작중인 학생입니다.
서툴지만 직진은 가능하나 좌우회전이 안됩니다.
돌아도 크게 돕니다.다음은 사용중인 코드인데
어느 부분을 수정하면 좋을지 조언부탁드립니다.
참고로 발광센서는  쌍을 사용중입니다.
//
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL // 16 MHz
#include <util/delay.h>
//
typedef unsigned int  WORD;
typedef unsigned char BYTE;
//
#define SenserNum  3
//
WORD speed_L,speed_R;
WORD ADC_Data[SenserNum+1]={0,};
//
int state=0,count_R=0,count_L=0,CrossCount=0,StopState=0;
//
unsigned char left_motor[8] ={0x99,0x88,0xcc,0x44,0x66,0x22,0x33,0x11};
unsigned char right_motor[8]={0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99};
//
void Set_Speed(void){
  int L,C,R;
  L=ADC_Data[1]; C=ADC_Data[2]; R=ADC_Data[3];
  if     (L>800 && C<550 && R<500){ speed_L=30000speed_R=50000state=1; } //Left Corner
  else if(L>800 && C>550 && R<500){ speed_L=35000speed_R=50000state=2; } //Left
  else if(L<500 && C<550 && R>800){ speed_L=50000speed_R=30000state=3; } //Right Corner
  else if(L<500 && C>550 && R>800){ speed_L=50000speed_R=35000state=4; } //Right
  else if(         C>800         ){ speed_L=50000speed_R=50000state=5; } //Straight
  else                            { speed_L=0;     speed_R=0;     state=6; } //Stop
}
//
unsigned char Rxd0Byte(){ while(!(UCSR0A&0x80)); return UDR0; }
unsigned char Rxd1Byte(){ while(!(UCSR1A&0x80)); return UDR1; }
//
void Txd0Byte(char d){ while(!(UCSR0A&0x20)); UDR0=d; }
void Txd1Byte(char d){ while(!(UCSR1A&0x20)); UDR1=d; }
//
void Txd0String(char *s){ while(*s)Txd0Byte(*s++); }
void Txd1String(char *s){ while(*s)Txd1Byte(*s++); }
//
void Txd0Dec(int dec){
  char i,String[5];
  for(i=0i<=4i++){ String[i]=0x30+(dec%10); dec/=10; }
  for(i=4i>=0i--)Txd0Byte(String[i]);
}
//
void Txd1Dec(int dec){
  char i,String[5];
  for(i=0i<=4i++){ String[i]=0x30+(dec%10); dec/=10; }
  for(i=4i>=0i--)Txd1Byte(String[i]);
}
//
SIGNAL(TIMER1_OVF_vect){
  PORTB=right_motor[count_R]; if(++count_R>7)count_R=0;
  Set_Speed();
  
}
//
SIGNAL(TIMER3_OVF_Vect){
  PORTC=left_motor[count_L]; if(++count_L>7)count_L=0;
  Set_Speed();
  TCNT3=speed_L;
}
//
SIGNAL(ADC_vect){
  ADC_Data[ADMUX++]=ADC;
  ADMUX%=SenserNum+1;
  ADCSRA|=0x40// ADSC
}
//
int main(void){
  DDRA=0XFF;
  DDRB=0xFF;
  DDRC=0xFFPORTC=0xFF;
  DDRE=0xFF;
  DDRD=0xFFPORTD=0xFF;
  //
  UCSR0B=0x08UBRR0L=25// 38400
  UCSR1B=0x08UBRR1L=25// 38400
  //
  TCNT1=speed_RTCCR1B=1TIMSK=4;
  TCNT3=speed_LTCCR3B=1ETIMSK=4;
  //
  ADCSRA=0xCF;
  //
  SREG=0x80;
  for(;;){
    _delay_ms(100);
    Txd1Dec(ADC_Data[3]); Txd1Byte(' ');
    Txd1Dec(ADC_Data[2]); Txd1Byte(' ');
    Txd1Dec(ADC_Data[1]); Txd1Byte(' ');
    // Txd1Dec(ADC_Data[4]); Txd1Byte(' '); Txd1Dec(ADC_Data[5]); Txd1Byte(' ');
    Txd0Dec(ADC_Data[3]); Txd0Byte(' ');
    Txd0Dec(ADC_Data[2]); Txd0Byte(' ');
    Txd0Dec(ADC_Data[1]); Txd0Byte(' ');
    // Txd0Dec(ADC_Data[4]); Txd0Byte(' '); Txd0Dec(ADC_Data[5]); Txd0Byte(' ');
    if     (state==1)Txd1String("Left Corner");
    else if(state==2)Txd1String("Left");
    else if(state==3)Txd1String("Right Corner");
    else if(state==4)Txd1String("Right");
    else if(state==5)Txd1String("Straight");
    else             Txd1String("Stop");
    Txd1Byte('\n');
  }
  return 0;
}

 

void Set_Speed(void){
  int L,C,R;
  L=ADC_Data[1]; C=ADC_Data[2]; R=ADC_Data[3];
  if     (L>800 && C<550 && R<500){ speed_L=30000speed_R=50000state=1; } //Left Corner
  else if(L>800 && C>550 && R<500){ speed_L=35000speed_R=50000state=2; } //Left
  else if(L<500 && C<550 && R>800){ speed_L=50000speed_R=30000state=3; } //Right Corner
  else if(L<500 && C>550 && R>800){ speed_L=50000speed_R=35000state=4; } //Right
  else if(         C>800         ){ speed_L=50000speed_R=50000state=5; } //Straight
  else                            { speed_L=0;     speed_R=0;     state=6; } //Stop
}

하나는 정지, 다른 하나는 전진 해야지 회전을 합니다.

하나는 2ms, 다른 하나는 1ms로 하면 회전 반경이 커질 수 밖에 없겠죠

 

//

 speed_L=30000speed_R=50000 

5000 이든 3000 이든 변경하지말고 한 값으로 고정시키면

타이머는 1개만 있으면 되겠죠

 

void Set_Speed(void){
  char s=0;
  if(ADC_Data[1]>700)s|=1;
  if(ADC_Data[2]>700)s|=2;
  if(ADC_Data[3]>700)s|=4;
  //
  switch(s){ // RCL
    case 0b000: break;
    case 0b001: break//Left Corner
    case 0b011: break//Left
    case 0b100: break//Right Corner
    case 0b110: break//Right
    case 0b010: break//Straight
    case 0b111: break//Straight
    case 0b101: break//Straight
  }
}

Set_Speed 함수에서 센서를 이런식으로 체크 할 수도 있겠죠

 

 

//
void R_up(){ if(++count_R>7)count_R=0PORTB=right_motor[count_R]; }
void L_up(){ if(++count_L>7)count_L=0PORTC=right_motor[count_L];  }
//
void R_dn(){ if(--count_R<0)count_R=7PORTB=right_motor[count_R]; }
void L_dn(){ if(--count_L<0)count_L=7PORTC=right_motor[count_L]; }
//
SIGNAL(TIMER1_OVF_vect){
  char s;
  TCNT1=50000;
  //
  s=0;
  if(ADC_Data[1]>700)s|=1;
  if(ADC_Data[2]>700)s|=2;
  if(ADC_Data[3]>700)s|=4;
  //
  switch(s){ // RCL
    case 0b000:                 break// stop
    case 0b001: L_dn(); R_up(); break// Left Corner 제자리 회전
    case 0b011:         R_up(); break// Left
    case 0b100: L_up(); R_dn(); break// Right Corner 제자리 회전
    case 0b110: L_up();         break// Right
    case 0b010:
    case 0b111:
    case 0b101: L_up(); R_up(); break// Straight
  }
}

모터를 돌리고 안돌리고는 이렇게 처리하면 됩니다

 

 

// DateTime : 2018-12-19 오후 8:19:22
// by Ok-Hyun Park
//
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL // 16 MHz
#include <util/delay.h>
#include <stdio.h>
//
typedef unsigned int  U16;
typedef unsigned char U08;
typedef   signed char S08;
//
U16 adBuf[4]={0,};
U08 str[50];
S08 state=0,R_cnt=0,L_cnt=0;
//
unsigned char L_motor[8]={0x99,0x88,0xcc,0x44,0x66,0x22,0x33,0x11};
unsigned char R_motor[8]={0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99};
//
char Rx0_Char(){ while(!(UCSR0A&0x80)); return UDR0; }
char Rx1_Char(){ while(!(UCSR1A&0x80)); return UDR1; }
//
void Tx0_Char(char d){ while(!(UCSR0A&0x20)); UDR0=d; }
void Tx1_Char(char d){ while(!(UCSR1A&0x20)); UDR1=d; }
//
void Tx0_Str(char *s){ while(*s)Tx0_Char(*s++); }
void Tx1_Str(char *s){ while(*s)Tx1_Char(*s++); }
//
void Txd0Dec(int dec){
  char i,String[5];
  for(i=0i<=4i++){ String[i]=0x30+(dec%10); dec/=10; }
  for(i=4i>=0i--)Tx0_Char(String[i]);
}
//
void Txd1Dec(int dec){
  char i,String[5];
  for(i=0i<=4i++){ String[i]=0x30+(dec%10); dec/=10; }
  for(i=4i>=0i--)Tx1_Char(String[i]);
}
//
void R_up(){ if(++R_cnt>7)R_cnt=0PORTB=R_motor[R_cnt]; }
void L_up(){ if(++L_cnt>7)L_cnt=0PORTC=R_motor[L_cnt];  }
//
void R_dn(){ if(--R_cnt<0)R_cnt=7PORTB=R_motor[R_cnt]; }
void L_dn(){ if(--L_cnt<0)L_cnt=7PORTC=R_motor[L_cnt]; }
//
ISR(TIMER0_COMP_vect){ // 1ms
  char s=0;
  if(adBuf[1]>700)s|=1;
  if(adBuf[2]>700)s|=2;
  if(adBuf[3]>700)s|=4;
  //
  switch(s){ // RCL
    case 0b000:                 state=0break// stop
    case 0b001L_dn(); R_up(); state=1break// Left Corner 제자리 회전
    case 0b011:         R_up(); state=2break// Left
    case 0b100L_up(); R_dn(); state=3break// Right Corner 제자리 회전
    case 0b110L_up();         state=4break// Right
    case 0b010:
    case 0b111:
    case 0b101L_up(); R_up(); state=5break// Straight
  }
}
//
SIGNAL(ADC_vect){
  adBuf[ADMUX]=ADC;
  if(++ADMUX==4)ADMUX=1;
  ADCSRA|=0x40// ADSC
}
//
int main(void){
  DDRA=0XFF;
  DDRB=0xFF;
  DDRC=0xFFPORTC=0xFF;
  DDRE=0xFF;
  DDRD=0xFFPORTD=0xFF;
  //
  UCSR0B=0x08UBRR0L=25// 38400
  UCSR1B=0x08UBRR1L=25// 38400
  //
  TCCR0=0x0DOCR0=124TIMSK=2//16000000/128/(1+124),1ms
  //
  ADMUX=1ADCSRA=0xCF;
  //
  SREG=0x80;
  for(;;){
    _delay_ms(100);
    sprintf(str,"%04d %04d %04d ",adBuf[3],adBuf[2],adBuf[1]); Tx0_Char(str); Tx1_Char(str);
    //
    switch(state){
      case 0Tx1_Str("Stop\n");         break;
      case 1Tx1_Str("Left Corner\n");  break;
      case 2Tx1_Str("Left\n");         break;
      case 3Tx1_Str("Right Corner\n"); break;
      case 4Tx1_Str("Right\n");        break;
      case 5Tx1_Str("Straight\n");     break;
    }
  }
}

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

댓글 : 0

조회수 : 3,794

등록된 댓글이 없습니다.

게시물 검색

BASIC4MCU > 질문게시판 목록

제목 날짜
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은… 스태프  19-01-15
공지 사이트 이용 안내 댓글[25] master  17-10-29
질문 ESP32-C3 리튬폴리머 ADC 전압 체크 관련 문의… 댓글[3] cansad 새글 13:06
질문 ESP32-C3 리튬폴리머 ADC 전압 체크 관련 문의 댓글[3] cansad 새글 11:32
질문 빵판없이 디스플레이 넣을 수 있을까요? 댓글[2] 첨부파일오소로롯 새글 22-06-29
질문 라즈베리파이4 신형 선택문제 댓글[1] maximum  22-06-26
질문 음전압 ADC 댓글[2] 412904  22-06-26
질문 아두이노 센서값 출력 질문입니다! 댓글[1] 아궁2  22-06-24
질문 ATmega128, ATmega28 RS232통신 첨부파일Moon4201  22-06-24
답변 답변 : ATmega128, ATmega28 RS232… 댓글[1] master  22-06-25
질문 서보모터, 온습도센서 코드 질문 댓글[2] 첨부파일kshdlfaldfh  22-06-22
답변 답변 : 서보모터, 온습도센서 코드 질문 댓글[15] master  22-06-22
질문 steppermulti5 질문 응애  22-06-21
답변 답변 : steppermulti5 질문 댓글[1] master  22-06-22
질문 atmega128 avr usart 질문 snoflak  22-06-21
답변 답변 : atmega128 avr usart 질문 댓글[5] master  22-06-21
질문 사용자 정의 함수 변환 하는 방법 댓글[2] 첨부파일da0800  22-06-21
질문 atmega128 댓글[1] 양의노래  22-06-20
질문 아두이노 동시동작 재질문 댓글[9] 첨부파일죠르디  22-06-20
질문 초음파센서로 dc모터 제어하기 댓글[1] 첨부파일난쟁2  22-06-20
질문 아두이노 동시동작 댓글[7] 죠르디  22-06-19
질문 ATMEGA128 UART,FND 연동 질문 JMOD  22-06-19
답변 답변 : ATMEGA128 UART,FND 연동 질문 댓글[1] master  22-06-20
질문 atmeg128 질문이요 댓글[1] 첨부파일공대생er  22-06-18
질문 atmega128 초음파 센서로 신호등 시간초 늘리기 서동씨  22-06-18
답변 답변 : atmega128 초음파 센서로 신호등 시간초… 댓글[1] master  22-06-18
질문 atmega128 댓글[2] 망경이  22-06-18
질문 앱인벤터 이용해서 수동 자동 할라고하는데 ..잘안됩니다… 댓글[1] 따랑해영  22-06-18
답변 질문 : 앱인벤터 이용해서 수동 자동 할라고하는데 ..… 댓글[1] 첨부파일따랑해영  22-06-19
답변 질문 : 앱인벤터 이용해서 수동 자동 할라고하는데 .… 첨부파일따랑해영  22-06-19
게시물 검색


Privacy Policy
MCU BASIC ⓒ 2017
PC버전