BASIC4MCU | 질문게시판 | 답변 : atmega128fh 라인트레이서 제작중 방향 문제에 관해서
페이지 정보
작성자 master 작성일2018-12-19 20:14 조회6,419회 댓글0건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=7073
본문
// MCU BASIC: https://www.basic4mcu.com// 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=30000; speed_R=50000; state=1; } //Left Cornerelse if(L>800 && C>550 && R<500){ speed_L=35000; speed_R=50000; state=2; } //Leftelse if(L<500 && C<550 && R>800){ speed_L=50000; speed_R=30000; state=3; } //Right Cornerelse if(L<500 && C>550 && R>800){ speed_L=50000; speed_R=35000; state=4; } //Rightelse if( C>800 ){ speed_L=50000; speed_R=50000; state=5; } //Straightelse { 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=0; i<=4; i++){ String[i]=0x30+(dec%10); dec/=10; }for(i=4; i>=0; i--)Txd0Byte(String[i]);}//void Txd1Dec(int dec){char i,String[5];for(i=0; i<=4; i++){ String[i]=0x30+(dec%10); dec/=10; }for(i=4; i>=0; i--)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=0xFF; PORTC=0xFF;DDRE=0xFF;DDRD=0xFF; PORTD=0xFF;//UCSR0B=0x08; UBRR0L=25; // 38400UCSR1B=0x08; UBRR1L=25; // 38400//TCNT1=speed_R; TCCR1B=1; TIMSK=4;TCNT3=speed_L; TCCR3B=1; ETIMSK=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=30000; speed_R=50000; state=1; } //Left Cornerelse if(L>800 && C>550 && R<500){ speed_L=35000; speed_R=50000; state=2; } //Leftelse if(L<500 && C<550 && R>800){ speed_L=50000; speed_R=30000; state=3; } //Right Cornerelse if(L<500 && C>550 && R>800){ speed_L=50000; speed_R=35000; state=4; } //Rightelse if( C>800 ){ speed_L=50000; speed_R=50000; state=5; } //Straightelse { speed_L=0; speed_R=0; state=6; } //Stop}하나는 정지, 다른 하나는 전진 해야지 회전을 합니다.
하나는 2ms, 다른 하나는 1ms로 하면 회전 반경이 커질 수 밖에 없겠죠
//
speed_L=30000; speed_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){ // RCLcase 0b000: break;case 0b001: break; //Left Cornercase 0b011: break; //Leftcase 0b100: break; //Right Cornercase 0b110: break; //Rightcase 0b010: break; //Straightcase 0b111: break; //Straightcase 0b101: break; //Straight}}Set_Speed 함수에서 센서를 이런식으로 체크 할 수도 있겠죠
//void R_up(){ if(++count_R>7)count_R=0; PORTB=right_motor[count_R]; }void L_up(){ if(++count_L>7)count_L=0; PORTC=right_motor[count_L]; }//void R_dn(){ if(--count_R<0)count_R=7; PORTB=right_motor[count_R]; }void L_dn(){ if(--count_L<0)count_L=7; PORTC=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){ // RCLcase 0b000: break; // stopcase 0b001: L_dn(); R_up(); break; // Left Corner 제자리 회전case 0b011: R_up(); break; // Leftcase 0b100: L_up(); R_dn(); break; // Right Corner 제자리 회전case 0b110: L_up(); break; // Rightcase 0b010:case 0b111:case 0b101: L_up(); R_up(); break; // Straight}}모터를 돌리고 안돌리고는 이렇게 처리하면 됩니다
// MCU BASIC: https://www.basic4mcu.com// 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=0; i<=4; i++){ String[i]=0x30+(dec%10); dec/=10; }for(i=4; i>=0; i--)Tx0_Char(String[i]);}//void Txd1Dec(int dec){char i,String[5];for(i=0; i<=4; i++){ String[i]=0x30+(dec%10); dec/=10; }for(i=4; i>=0; i--)Tx1_Char(String[i]);}//void R_up(){ if(++R_cnt>7)R_cnt=0; PORTB=R_motor[R_cnt]; }void L_up(){ if(++L_cnt>7)L_cnt=0; PORTC=R_motor[L_cnt]; }//void R_dn(){ if(--R_cnt<0)R_cnt=7; PORTB=R_motor[R_cnt]; }void L_dn(){ if(--L_cnt<0)L_cnt=7; PORTC=R_motor[L_cnt]; }//ISR(TIMER0_COMP_vect){ // 1mschar s=0;if(adBuf[1]>700)s|=1;if(adBuf[2]>700)s|=2;if(adBuf[3]>700)s|=4;//switch(s){ // RCLcase 0b000: state=0; break; // stopcase 0b001: L_dn(); R_up(); state=1; break; // Left Corner 제자리 회전case 0b011: R_up(); state=2; break; // Leftcase 0b100: L_up(); R_dn(); state=3; break; // Right Corner 제자리 회전case 0b110: L_up(); state=4; break; // Rightcase 0b010:case 0b111:case 0b101: L_up(); R_up(); state=5; break; // Straight}}//SIGNAL(ADC_vect){adBuf[ADMUX]=ADC;if(++ADMUX==4)ADMUX=1;ADCSRA|=0x40; // ADSC}//int main(void){DDRA=0XFF;DDRB=0xFF;DDRC=0xFF; PORTC=0xFF;DDRE=0xFF;DDRD=0xFF; PORTD=0xFF;//UCSR0B=0x08; UBRR0L=25; // 38400UCSR1B=0x08; UBRR1L=25; // 38400//TCCR0=0x0D; OCR0=124; TIMSK=2; //16000000/128/(1+124),1ms//ADMUX=1; ADCSRA=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 0: Tx1_Str("Stop\n"); break;case 1: Tx1_Str("Left Corner\n"); break;case 2: Tx1_Str("Left\n"); break;case 3: Tx1_Str("Right Corner\n"); break;case 4: Tx1_Str("Right\n"); break;case 5: Tx1_Str("Straight\n"); break;}}}
댓글 0
조회수 6,419등록된 댓글이 없습니다.