극한의 아두이노 DIY생활 - NFC RC카9
안녕하세요 Jimae입니다.
setup 함수를 보았으면 이제 loop 함수차례인대
void loop()
{
//RFIDRead();
//Serial.println(RFIDIdCompare()); //RFID 테스트
/*
unsigned char num = 0; //LED 테스트
for(num = 1; num < 5; num++)
{
LEDSelect(num);
delay(500);
}
*/
/*
MotorDirection(ADVANCE); // 모터 움직임 테스트 전진,후진,왼쪽,오른쪽 순으로
MotorAction(STRAIGHTANGLE,500);
delay(5000);
MotorDirection(BACK);
MotorAction(STRAIGHTANGLE,500);
delay(5000);
MotorDirection(LEFT);
MotorAction(ROTATIONANGLE,500);
delay(5000);
MotorDirection(RIGHT);
MotorAction(ROTATIONANGLE,500);
delay(5000);
*/
RCCarProgram(); // 실제 프로그램
}
제가 디버깅하면서 냅둔 프로그램들이 있내요.
원래는 삭제해야했지만 주기적으로 확인을 해야 했기에 그냥 주석처리를 했습니다.
RC카의 핵심 프로그램은 결국
RCCarProgram() 함수입니다.
이함수 내부에 돌아가는 프로그램순서들이
enum{COMMANDREAD = 0,COMMANDANALYSIS,CHANGENFCREAD,CHANGELED,MOTORDRIVING,MOTORNFCREAD,COMPLETEANSWER}; // 프로그램 동작순서
COMMANDREAD
COMMANDANALYSIS
CHANGENFCREAD
CHANGELED
MOTORDRIVING
MOTORNFCREAD
COMPLETEANSWER
이런식으로 일련의 과정들을 나열을 해보았는대요.
블루투스를 통해 제어 명령어를 받고, 그 명령어를 분석하고 NFC 데이터를 읽어보고, LED를 바꾸고, 모터를 움직이고, 모터를 움직인뒤 NFC를 읽어보고, 목적지에 도착했다는 답변을 보내주는 순서입니다.
void RCCarProgram(void)
{
unsigned char num = 0;
switch(programStep)
{
case COMMANDREAD:
if (BTSerial.available()) // 컨트롤러에서 들어오는 데이터가 있을때
{
commandBugffer[commandBufferAddress++] = BTSerial.read(); // 데이터를 읽고
//Serial.println(commandBugffer[commandBufferAddress++],HEX);
if(commandBufferAddress >= 3) // 3개 이상의 데이터가 들어왔을때
{
commandBufferAddress = 0;
programStep = COMMANDANALYSIS; // 데이터를 분석하는 구역으로 변경
break;
}
}
break;
case COMMANDANALYSIS: // 데이터 분석
if(commandBugffer[0] == 0xAA && commandBugffer[1] == 0xAA && commandBugffer[2] == CAHNGE) // 특수코드 LED 및 ID 변환하는 명령어가 들어올때
{
programStep = CHANGENFCREAD; // 변환하는 구역으로 변경
break;
}
else if(commandBugffer[0] == rcCarID) // 그게아니라 모터움직이는 명령어가 들어올때
{
programStep = MOTORDRIVING; // 모터 움직이는 구역으로 변경
break;
}
programStep = COMMANDREAD; // 그게아니면 다시 읽기
break;
case CHANGENFCREAD: // ID,LED 변경하기전 NFC값 읽기
if(RFIDRead() == MI_OK) // 우선 NFC 값을 읽는다
{
nfcNumber = RFIDIdCompare(); // 읽은 NFC값을 위에 아이디 배열과 비교해서 가공하여 번호로 저장
programStep = CHANGELED; // LED 변경 및 보낼데이터 정하는 구역으로 변경
}
break;
case CHANGELED: // LED 변경 및 보낼데이터 정하기
rcCarID = LEDDataChange(nfcNumber); //NFC 값 14 = 1,15 = 2,16 = 3,17 = 4 의 값으로 나와서 저장
LEDSelect(rcCarID); // LED 변경
answerData[0] = rcCarID; // 보낼데이터 ID값 저장
answerData[1] = 0xAA; // 특수코드
answerData[2] = COMPLETE; // 확인명령어
programStep = COMPLETEANSWER; // 컨트롤러로 데이터 보내는 구역으로 전환
break;
case MOTORDRIVING:
MotorDirection(commandBugffer[2]); // 명령어에 3번째 데이터 가야할 방향으로 모터 셋팅
if(commandBugffer[2] == ADVANCE || commandBugffer[2] == BACK) MotorAction(STRAIGHTANGLE,500); // 전진, 후진 모터 움직임
else MotorAction(ROTATIONANGLE,500); // 회전 모터 움직임
timeFlag = START; //타이머 시작
programStep = MOTORNFCREAD; //모터 움직이고난후 NFC데이터 확인하는 구역으로 변경
break;
case MOTORNFCREAD:
if(RFIDRead() == MI_OK) //NFC 값을 읽은후
{
nfcNumber = RFIDIdCompare(); // 비교하고
answerData[0] = rcCarID; // 현재 RCcar의 ID 저장
answerData[1] = nfcNumber; // 현재 NFC 위치
answerData[2] = ARRIVE; // 도착한 명령어
programStep = COMPLETEANSWER; // 컨트롤러로 데이터 보내는 구역으로 전환
}
else
{
if(delayCount >= 2) // 2초 대기 NFC값 안읽힐 경우 무시하고 움직이기 위한 루틴
{
answerData[0] = rcCarID; // 현재 RCcar의 ID 저장
answerData[1] = commandBugffer[1]; // 아까 명령어로 읽어들여온 가야할 NFC 위치
answerData[2] = ARRIVE; // 도착한 명령어
timeFlag = STOP; // 타이머 스탑
delayCount = 0;
programStep = COMPLETEANSWER; // 컨트롤러로 데이터 보내는 구역으로 전환
}
}
break;
case COMPLETEANSWER: //블루투스 쪽 응답
for(num = 0; num < 3; num++)
{
BTSerial.write(answerData[num]); // 데이터 3개 보낸다
answerData[num] = 0; // 보낸 데이터 초기화
commandBugffer[num] = 0; // 들어온 데이터 초기화
}
programStep = COMMANDREAD; // 다시 처음으로 명령어를 읽기위해 돌아감
break;
default:
break;
}
}
위의 설명을 한 프로그램이 이정도인대..
다음 부터는 이걸 각각 분석을 해보도록 하죠.
다들 좋은하루 되세요.
극한의 아두이노 DIY생활 - NFC RC카1
극한의 아두이노 DIY생활 - NFC RC카2
극한의 아두이노 DIY생활 - NFC RC카3
극한의 아두이노 DIY생활 - NFC RC카4
극한의 아두이노 DIY생활 - NFC RC카5
극한의 아두이노 DIY생활 - NFC RC카6
극한의 아두이노 DIY생활 - NFC RC카7
극한의 아두이노 DIY생활 - NFC RC카8
[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.