BASIC4MCU | 질문게시판 | 답변 : 외부인터럽트 관련해서 질문드립니다~~~
페이지 정보
작성자 master 작성일2018-10-30 18:29 조회1,034회 댓글2건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=4039
작성일
본문
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2018-10-30 오후 6:34:14// by Ok-Hyun Park//#include <MD_TCS230.h>#include <FreqCount.h>#include <SoftwareSerial.h>#include <DFPlayer_Mini_Mp3.h>#include "ColorMatch.h"//#define BLACK_CAL 0 //검은색 조정#define WHITE_CAL 1 //흰색 조정#define READ_VAL 2 // 읽기#define LEARN_VAL 3 //학습//#define LEARN_MODE 'L' //학습모드#define MATCH_MODE 'M' //동작모드//#define S2_OUT 6 //s2핀#define S3_OUT 13 //s3핀//#define interruptPin1 2 //인터럽트 핀#define in1Pin 10 // 모터1인풋1#define in2Pin 4 //모터1인풋2#define in3Pin 7 //모터2인풋1#define in4Pin 11 //모터2인풋2#define enablePin 9 // enablePin//uint8_t modeOp='M'; //동작모드uint8_t ctIndex;colorData rgb;unsigned long time=0;int count;char runflag=1; //인터럽트MD_TCS230 CS(S2_OUT,S3_OUT);SoftwareSerial mySerial(8,12);//void setup(){Serial.begin(115200);mySerial.begin(9600);CS.begin(); //동작모드시 헤더파일 사용if(modeOp==MATCH_MODE){ CS.setDarkCal(&sdBlack); CS.setWhiteCal(&sdWhite); }mp3_set_serial(mySerial);delay(1);mp3_set_volume(30);pinMode(interruptPin1,INPUT);digitalWrite(interruptPin1,INPUT_PULLUP);attachInterrupt(digitalPinToInterrupt(interruptPin1),toggle,FALLING);pinMode(enablePin,OUTPUT); // enablePin을 출력핀으로 설정합니다.pinMode(in1Pin,OUTPUT); // in1Pin을 출력핀으로 설정합니다.pinMode(in2Pin,OUTPUT); // in2Pin을 출력핀으로 설정합니다.pinMode(in3Pin,OUTPUT); // in3Pin을 출력핀으로 설정합니다.pinMode(in4Pin,OUTPUT); // in4Pin을 출력핀으로 설정합니다.}//인터럽트 함수void toggle(){if(runflag){ mp3_play(2); delay_(3000); }else { mp3_play(0); delay(3000); }runflag=!runflag;}//void Stop(){ // 정지analogWrite(enablePin,255);digitalWrite(in1Pin,0); digitalWrite(in2Pin,0);digitalWrite(in3Pin,0); digitalWrite(in4Pin,0);}//void Foward(int speed,boolean reverse){ // 직진.analogWrite(enablePin,speed);digitalWrite(in1Pin,!reverse); digitalWrite(in2Pin,reverse);digitalWrite(in3Pin,!reverse); digitalWrite(in4Pin,reverse);}//void motor1(int speed,boolean reverse){ //좌회전analogWrite(enablePin,speed);digitalWrite(in1Pin,!reverse); digitalWrite(in2Pin,!reverse);digitalWrite(in3Pin,!reverse); digitalWrite(in4Pin,reverse);}//void motor2(int speed,boolean reverse){ //우회전analogWrite(enablePin,speed);digitalWrite(in1Pin,!reverse); digitalWrite(in2Pin,reverse);digitalWrite(in3Pin,!reverse); digitalWrite(in4Pin,!reverse);}//시리얼의 모든 것을 삭제void clearInput(){ while(Serial.read()!=-1); }//void delay_(int ms){while(count!=ms){ delayMicroseconds(1000); count++; }count=0;}//동작 할 때 필요하지 않으나,다른 함수들에서 사용되기 때문에 넣어놨음//소문자로 받았을 경우char getChar(){ while(Serial.available()==0); return(toupper(Serial.read())); }//char *readASCII(uint8_t size){#define BUF_SIZE(9+1)//시리얼입력 함수static char s[BUF_SIZE];uint8_t i=0; char c;s[0]='\0'; size--;while((i<size)&&(size<BUF_SIZE)){ c=getChar(); if(c=='\n')break; s[i++]=c; s[i]='\0'; }clearInput();return(s);#undef BUF_SIZE}//uint8_t fsmReadValue(uint8_t state,uint8_t valType){ //TCS3200 색 읽는 함수 및 학습모드static uint8_t selChannel;static uint8_t readCount;static sensorData sd;switch(state){case 0:{ // 시작하기 위한 안내문을 보여줍니다:Serial.print(F("\n\n값을 읽는 중: "));switch(valType){case BLACK_CAL: Serial.print(("검정색 영점 조정")); break;case WHITE_CAL: Serial.print(("하얀색 영점 조정")); break;case READ_VAL: Serial.print(("색 맞추기")); break;case LEARN_VAL: Serial.print(ct[ctIndex].name); break;default: Serial.print(F("??")); break;}clearInput();if(valType==LEARN_VAL){ char *p; }else{ Serial.print(("\n시작하려면 어떤 키든 눌러주세요...")); clearInput(); }state++;break;}case 1: CS.read(); state++; break; // 센서 값을 읽기 시작합니다case 2: // 값을 읽어 들일 때까지 기다립니다if(CS.available()){switch(valType){case BLACK_CAL: CS.getRaw(&sdBlack); CS.setDarkCal(&sdBlack); break;case WHITE_CAL: CS.getRaw(&sdWhite); CS.setWhiteCal(&sdWhite); break;case READ_VAL: case LEARN_VAL:{CS.getRGB(&rgb);Serial.print(("\nRGB["));Serial.print(rgb.value[TCS230_RGB_R]); Serial.print((","));Serial.print(rgb.value[TCS230_RGB_G]); Serial.print((","));Serial.print(rgb.value[TCS230_RGB_B]); Serial.print(("]"));break;}}state++;}break;default: state=0; break; // reset fsm}return(state);}//uint8_t colorMatch(colorData *rgb){int32_t d; uint32_t v,minV=999999L; uint8_t minI;for(uint8_t i=0; i<ARRAY_SIZE(ct); i++){v=0;for(uint8_t j=0; j<RGB_SIZE; j++){ d=ct[i].rgb.value[j]-rgb->value[j]; v+=(d*d); }if(v<minV){ minV=v; minI=i; }if(v==0)break;}return(minI);}//void loop(){static uint8_t runState=0,readState=0;if(runflag){switch(runState){case 0: readState=fsmReadValue(readState,READ_VAL); if(readState==0)runState++; break;case 1:{ // 가까운 색을 찾아냅니다:uint8_t i=colorMatch(&rgb);Serial.print(("\n가장 가까운 색은 "));Serial.print(ct[i].name);Serial.print(("입니다"));if(!strcmp(ct[i].name,"빨간색")){ mp3_play(3); delay(300); motor1(255,1); delay(300); motor1(0,0); }else if(!strcmp(ct[i].name,"주황색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"노란색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"초록색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"하얀색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"분홍색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"남색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"보라색")){ mp3_play(1); }else if(!strcmp(ct[i].name,"파란색")){ mp3_play(4); delay(300); motor2(255,1); delay(300); motor2(0,0); }else if(!strcmp(ct[i].name,"검정색")){ Foward(255,1); delay(300); Foward(0,0); }runState++;for(int i=0;i<100;i++){ delay(30); if(!runflag)break; } // 딜레이 도중 빠르게 하기 위해서 사용break;}default: runState=0;}}else Stop(); // 정지}
댓글 2
조회수 1,034아야어여님의 댓글
아야어여 작성일같은 현상이 발생합니다. 모터가 돌고 스위치를 눌러 정지를 하게 되면 바로 정지가 되는게 아니라 모터가 3~4초 정도 돌다가 정지가 됩니다.
master님의 댓글
master
1. 어느 코드 실행일 때 정지 명령이 먹지 않는지 찾아보세요
2. 관성 때문에 어느정도 굴러가다가 섭니다.