BASIC4MCU | 질문게시판 | 답변 : 아두이노 프로그램 수정 도움 부탁드립니다
페이지 정보
작성자 master 작성일2018-09-27 23:28 조회7,424회 댓글0건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=5349
본문
여름 때 아두이노 음성 관련해서 질문드렸는데 센서를 하나 추가하는 방식으로 해서 되었습니다.이것을 가지고 수정해서 또 다른 것을 만들어 보고자 하는데현재는 시리얼 모니터로 학습모드와 동작모드 선택 후 동작모드 시에는 엔터를 이용해서음성출력와 색인식이 되었습니다.그리고 수정하고 싶은 것은 시리얼모니터에서 학습모드와 동작모드 선택 없이 바로 색 인식 후음성출력을 해주려고 하고 있습니다.시리얼모니터에서 학습모드와 동작모드 선택없이바로 들어가는 것 까지는 했는데 색인식이 되질 않습니다.시리얼모니터를 누르면 바로 음성출력과 색인식이 되는데 색이 맞질 않습니다.어떻게 해결해야 하나요?--------------------수정파일-----------------------------------------#include <MD_TCS230.h>#include <FreqCount.h>#include <SoftwareSerial.h>SoftwareSerial mySerial(10,11);#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 7#define S3_OUT 6MD_TCS230 CS(S2_OUT,S3_OUT);uint8_t modeOp;uint8_t ctIndex;colorData rgb;unsigned long time=0;//void setup(){Serial.begin(115200);mySerial.begin(9600);mp3_set_serial(mySerial); //set Serial for DFPlayer-mini mp3 moduledelay(1); //wait 1ms for mp3 module to set volumemp3_set_volume(15);}//void clearInput(){ while(Serial.read()!=-1); } // 시리얼 포트에 들어온 데이터들을 모두 읽어 없앱니다://void outputHeader(void){ // 영점 조정한 값들과 컬러를 RGB로 감지한 값들을 헤더 파일에 사용할 수 있게 시리얼 모니터로 출력합니다:Serial.print(("\n // ColorMatch.h 파일에 사용되는 영점 조정과 컬러 값들입니다"));Serial.print(("\n // 이 파일은 ColorMatch 스케치 학습 모드에서 만들어졌습니다"));Serial.print(("\n\n // 영점 조정 데이터: "));Serial.print(("\nsensorData sdBlack={ "));Serial.print(sdBlack.value[0]); Serial.print(F(","));Serial.print(sdBlack.value[1]); Serial.print(F(","));Serial.print(sdBlack.value[2]); Serial.print(F(" }; "));Serial.print(("\nsensorData sdWhite={ "));Serial.print(sdWhite.value[0]); Serial.print(F(","));Serial.print(sdWhite.value[1]); Serial.print(F(","));Serial.print(sdWhite.value[2]); Serial.print(F(" }; "));Serial.print(("\n\n // 색 찾기를 위한 컬러 테이블: "));Serial.print(("\ntypedef struct\n{ \n char name[10]"));Serial.print(("\n\ncolorTable ct[]=\n{ } "));for(uint8_t i=0; i<ARRAY_SIZE(ct); i++){Serial.print(("\n{ \"")); Serial.print(ct[i].name); Serial.print(("\",{ "));Serial.print(ct[i].rgb.value[0]); Serial.print((","));Serial.print(ct[i].rgb.value[1]); Serial.print((","));Serial.print(ct[i].rgb.value[2]); Serial.print(("} },"));}Serial.print(("\n}; \n"));}//uint8_t fsmReadValue(uint8_t state,uint8_t valType){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){}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; } // new bestif(v==0)break; // perfect match,no need to search more}return(minI);}//void loop(){static uint8_t runState=0,readState=0;if(modeOp==LEARN_MODE){ // 학습 모드switch(runState){case 0: readState=fsmReadValue(readState,BLACK_CAL); if(readState==0)runState++; break; // 검정색 영점 조정case 1: readState=fsmReadValue(readState,WHITE_CAL); if(readState==0)runState++; break; // 하얀색 영점 조정case 2:{ // 학습 모드를 위한 준비Serial.println(F("\n\n모든 컬러에 대하여,이름을 넣고 색을 감지합니다"));ctIndex=0; runState++;break;}case 3:{ // 색을 학습합니다.RGB 값을 읽어들여 이를 보관합니다readState=fsmReadValue(readState,LEARN_VAL);if(readState==0){for(uint8_t j=0; j<RGB_SIZE; j++){ ct[ctIndex].rgb.value[j]=rgb.value[j]; }if(++ctIndex>=ARRAY_SIZE(ct))runState++;}break;}case 4: outputHeader(); runState++; break; // 헤더 파일로 사용키 위하여 시리얼 모니터로 출력합니다default: runState=0; // 잘못되었다면 다시 시작합니다}}else{ // 색 맞추기 모드switch(runState){case 0: readState=fsmReadValue(readState,READ_VAL); if(readState==0)runState++; break; // 색의 RGB 값을 읽어들입니다case 1:{ // 가까운 색을 찾아냅니다:uint8_t i=colorMatch(&rgb);Serial.print(("\n가장 가까운 색은 ")); Serial.print(ct[i].name); Serial.print(("입니다"));if (!strcmp(ct[i].name,"빨간색")){ mp3_play(1); delay(100); }else if(!strcmp(ct[i].name,"주황색")){ mp3_play(2); delay(100); }else if(!strcmp(ct[i].name,"노란색")){ mp3_play(3); delay(100); }else if(!strcmp(ct[i].name,"초록색")){ mp3_play(4); delay(100); }else if(!strcmp(ct[i].name,"파란색")){ mp3_play(5); delay(100); }else if(!strcmp(ct[i].name,"남색 ")){ mp3_play(6); delay(100); }else if(!strcmp(ct[i].name,"보라색")){ mp3_play(7); delay(100); }else if(!strcmp(ct[i].name,"검정색")){ mp3_play(8); delay(100); }else if(!strcmp(ct[i].name,"하얀색")){ mp3_play(9); delay(100); }else if(!strcmp(ct[i].name,"분홍색")){ mp3_play(10); delay(100); }runState++;delay(3000);break;}default: runState=0; // 잘못되었다면 다시 시작합니다}}}
////------------------------------------원본파일---------------------------------------------------#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 7#define S3_OUT 6MD_TCS230 CS(S2_OUT,S3_OUT);uint8_t modeOp=0; // 동작 모드uint8_t ctIndex;colorData rgb;unsigned long time=0;SoftwareSerial mySerial(10,11);//void setup(){Serial.begin(115200);mySerial.begin(9600);// 동작 모드를 선택하기 위하여 입력받기while(modeOp==0){Serial.println(("학습모드(L)OR 동작모드(M)"));modeOp=getChar();if(modeOp!=LEARN_MODE&&modeOp!=MATCH_MODE)modeOp=0; else clearInput();}CS.begin();if(modeOp==MATCH_MODE){ // 헤더 파일로부터 영점 조정 데이터를 사용합니다CS.setDarkCal(&sdBlack); CS.setWhiteCal(&sdWhite);}mp3_set_serial(mySerial); //set Serial for DFPlayer-mini mp3 moduledelay(1); //wait 1ms for mp3 module to set volumemp3_set_volume(15);}//char getChar(){ while(Serial.available()==0); return(toupper(Serial.read())); } // 소문자가 들어 올 경우 대비//void clearInput(){ while(Serial.read()!=-1); } // 시리얼 포트에 들어온 데이터들을 모두 읽어 없앱니다://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}//void outputHeader(void){ // 영점 조정한 값들과 컬러를 RGB로 감지한 값들을 헤더 파일에 사용할 수 있게 시리얼 모니터로 출력합니다:Serial.print(("\n // ColorMatch.h 파일에 사용되는 영점 조정과 컬러 값들입니다"));Serial.print(("\n // 이 파일은 ColorMatch 스케치 학습 모드에서 만들어졌습니다"));Serial.print(("\n\n // 영점 조정 데이터: "));Serial.print(("\nsensorData sdBlack={ "));Serial.print(sdBlack.value[0]); Serial.print(F(","));Serial.print(sdBlack.value[1]); Serial.print(F(","));Serial.print(sdBlack.value[2]); Serial.print(F(" }; "));Serial.print(("\nsensorData sdWhite={ "));Serial.print(sdWhite.value[0]); Serial.print(F(","));Serial.print(sdWhite.value[1]); Serial.print(F(","));Serial.print(sdWhite.value[2]); Serial.print(F(" }; "));Serial.print(("\n\n // 색 찾기를 위한 컬러 테이블: "));Serial.print(("\ntypedef struct\n{ \n char name[10]"));Serial.print(("\n\ncolorTable ct[]=\n{ } "));for(uint8_t i=0; i<ARRAY_SIZE(ct); i++){Serial.print(("\n{ \"")); Serial.print(ct[i].name); Serial.print(("\",{ "));Serial.print(ct[i].rgb.value[0]); Serial.print((","));Serial.print(ct[i].rgb.value[1]); Serial.print((","));Serial.print(ct[i].rgb.value[2]); Serial.print(("} },"));}Serial.print(("\n}; \n"));}//uint8_t fsmReadValue(uint8_t state,uint8_t valType){static uint8_t selChannel,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;Serial.print(("\n새로운 이름(<엔터>옛 이름 사용): "));p=readASCII(ARRAY_SIZE(ct[0].name));if(*p!='\0')strcpy(ct[ctIndex].name,p);Serial.print(ct[ctIndex].name);}else{ Serial.print(("\n시작하려면 어떤 키든 눌러주세요...")); getChar(); 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; } // new bestif(v==0)break; // perfect match,no need to search more}return(minI);}//void loop(){static uint8_t runState=0,readState=0;if(modeOp==LEARN_MODE){ // 학습 모드switch(runState){case 0: readState=fsmReadValue(readState,BLACK_CAL); if(readState==0)runState++; break; // 검정색 영점 조정case 1: readState=fsmReadValue(readState,WHITE_CAL); if(readState==0)runState++; break; // 하얀색 영점 조정case 2:{ // 학습 모드를 위한 준비Serial.println(F("\n\n모든 컬러에 대하여,이름을 넣고 색을 감지합니다"));ctIndex=0; runState++;break;}case 3:{ // 색을 학습합니다.RGB 값을 읽어들여 이를 보관합니다readState=fsmReadValue(readState,LEARN_VAL);if(readState==0){for(uint8_t j=0; j<RGB_SIZE; j++){ ct[ctIndex].rgb.value[j]=rgb.value[j]; }if(++ctIndex>=ARRAY_SIZE(ct))runState++;}break;}case 4: outputHeader(); runState++; break; // 헤더 파일로 사용키 위하여 시리얼 모니터로 출력합니다default: runState=0; // 잘못되었다면 다시 시작합니다}}else{ // 색 맞추기 모드switch(runState){case 0: readState=fsmReadValue(readState,READ_VAL); if(readState==0)runState++; break; // 색의 RGB 값을 읽어들입니다case 1:{ // 가까운 색을 찾아냅니다:uint8_t i=colorMatch(&rgb);Serial.print(("\n가장 가까운 색은 ")); Serial.print(ct[i].name); Serial.print(("입니다"));if (!strcmp(ct[i].name,"빨간색")){ mp3_play(1); delay(100); }else if(!strcmp(ct[i].name,"주황색")){ mp3_play(2); delay(100); }else if(!strcmp(ct[i].name,"노란색")){ mp3_play(3); delay(100); }else if(!strcmp(ct[i].name,"초록색")){ mp3_play(4); delay(100); }else if(!strcmp(ct[i].name,"파란색")){ mp3_play(5); delay(100); }else if(!strcmp(ct[i].name,"남색 ")){ mp3_play(6); delay(100); }else if(!strcmp(ct[i].name,"보라색")){ mp3_play(7); delay(100); }else if(!strcmp(ct[i].name,"검정색")){ mp3_play(8); delay(100); }else if(!strcmp(ct[i].name,"하얀색")){ mp3_play(9); delay(100); }else if(!strcmp(ct[i].name,"분홍색")){ mp3_play(10); delay(100); }runState++;break;}default: runState=0; // 잘못되었다면 다시 시작합니다}}}
소스가 길어서 분석을 하는 것은 시간이 걸리고
대충 사용하지 않는 모드를 제거 해드릴텐데
원하는대로 동작하지 않는다면 직접 디버깅해서 만드셔야합니다.
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2018-09-27 오후 11:32:42// by Ok-Hyun Park//#include <MD_TCS230.h>#include <FreqCount.h>#include <SoftwareSerial.h>SoftwareSerial mySerial(10,11);#include <DFPlayer_Mini_Mp3.h>#include "ColorMatch.h"#define BLACK_CAL 0#define WHITE_CAL 1#define READ_VAL 2//#define S2_OUT 7#define S3_OUT 6MD_TCS230 CS(S2_OUT,S3_OUT);colorData rgb;uint8_t ctIndex=0;//void setup(){Serial.begin(115200);mySerial.begin(9600);mp3_set_serial(mySerial); //set Serial for DFPlayer-mini mp3 moduledelay(1); //wait 1ms for mp3 module to set volumemp3_set_volume(15);}//void clearInput(){ while(Serial.read()!=-1); } // 시리얼 포트에 들어온 데이터들을 모두 읽어 없앱니다://void outputHeader(void){ // 영점 조정한 값들과 컬러를 RGB로 감지한 값들을 헤더 파일에 사용할 수 있게 시리얼 모니터로 출력합니다:Serial.print(("\n // ColorMatch.h 파일에 사용되는 영점 조정과 컬러 값들입니다"));Serial.print(("\n // 이 파일은 ColorMatch 스케치 학습 모드에서 만들어졌습니다"));Serial.print(("\n\n // 영점 조정 데이터: "));Serial.print(("\nsensorData sdBlack={ "));Serial.print(sdBlack.value[0]); Serial.print(F(","));Serial.print(sdBlack.value[1]); Serial.print(F(","));Serial.print(sdBlack.value[2]); Serial.print(F(" }; "));Serial.print(("\nsensorData sdWhite={ "));Serial.print(sdWhite.value[0]); Serial.print(F(","));Serial.print(sdWhite.value[1]); Serial.print(F(","));Serial.print(sdWhite.value[2]); Serial.print(F(" }; "));Serial.print(("\n\n // 색 찾기를 위한 컬러 테이블: "));Serial.print(("\ntypedef struct\n{ \n char name[10]"));Serial.print(("\n\ncolorTable ct[]=\n{ } "));for(uint8_t i=0; i<ARRAY_SIZE(ct); i++){Serial.print(("\n{ \"")); Serial.print(ct[i].name); Serial.print(("\",{ "));Serial.print(ct[i].rgb.value[0]); Serial.print((","));Serial.print(ct[i].rgb.value[1]); Serial.print((","));Serial.print(ct[i].rgb.value[2]); Serial.print(("} },"));}Serial.print(("\n}; \n"));}//uint8_t fsmReadValue(uint8_t state,uint8_t valType){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;default: Serial.print(F("??")); break;}clearInput(); 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:{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; } // new bestif(v==0)break; // perfect match,no need to search more}return(minI);}//void loop(){static uint8_t runState=0,readState=0;switch(runState){case 0: readState=fsmReadValue(readState,READ_VAL); if(readState==0)runState++; break; // 색의 RGB 값을 읽어들입니다case 1:{ // 가까운 색을 찾아냅니다:uint8_t i=colorMatch(&rgb);Serial.print(("\n가장 가까운 색은 ")); Serial.print(ct[i].name); Serial.print(("입니다"));if (!strcmp(ct[i].name,"빨간색")){ mp3_play(1); delay(100); }else if(!strcmp(ct[i].name,"주황색")){ mp3_play(2); delay(100); }else if(!strcmp(ct[i].name,"노란색")){ mp3_play(3); delay(100); }else if(!strcmp(ct[i].name,"초록색")){ mp3_play(4); delay(100); }else if(!strcmp(ct[i].name,"파란색")){ mp3_play(5); delay(100); }else if(!strcmp(ct[i].name,"남색 ")){ mp3_play(6); delay(100); }else if(!strcmp(ct[i].name,"보라색")){ mp3_play(7); delay(100); }else if(!strcmp(ct[i].name,"검정색")){ mp3_play(8); delay(100); }else if(!strcmp(ct[i].name,"하얀색")){ mp3_play(9); delay(100); }else if(!strcmp(ct[i].name,"분홍색")){ mp3_play(10); delay(100); }runState++;delay(3000);break;}default: runState=0; // 잘못되었다면 다시 시작합니다}}
댓글 0
조회수 7,424등록된 댓글이 없습니다.