아두이노에서 핀 입력값을 배열에 저장하고 싶습니다.
조회수 6702회
아두이노에서 버튼과 모터를 연결하고 버튼이 순차적으로 눌린 후
모터가 순차적으로 움직이는 것을 하려고 합니다.
예를 들어 버튼 1(모터가 좌로 회전), 2(모터가 우로 회전)가 있고 그에 연결된 모터가 한개 있다고 할 때
버튼을 1, 2, 1, 1, 2로 누른 후 모터가 좌, 우, 좌, 좌, 우의 식으로 움직이는 것을 구현하려고 합니다.
이에 버튼을 누르면 이에 대한 값을 받아 배열에 저장하여 모터를 움직이려고 하는데
핀 입력값을 배열에 저장할 수 있는 방법이 무엇인지 궁금합니다.
3 답변
-
먼저 들어온 명령이 먼저 처리되는 큐(Queue)라는 자료구조를 사용해야 합니다. 아래는 MAX(3)개의 input을 저장할 수 있는 큐를 구현하는 코드입니다. MAX의 숫자는 원하는대로 수정해서 사용하시면 됩니다.
#include <stdio.h> #define MAX 3 #define BLANK -1111111 #define LEFT -1 #define RIGHT 1 int queue_array[MAX]; int rear = 0; //Position to write int front = - 1;//Position to read int nextPosition(int position){ return (position+1)%MAX; } void insert(int add_item) { if(queue_array[rear]==BLANK) { if (front == - 1) { front = 0; } queue_array[rear] = add_item; rear = nextPosition(rear); printf("insert %d\n",add_item); } else{ printf("insert %d ignored\n",add_item); } } int read() { if(front>=0){ if(queue_array[front]!=BLANK){ int ret = queue_array[front]; queue_array[front] = BLANK; front = nextPosition(front); printf("Read %d\n",ret); return ret; } } printf("Nothing to read\n"); return BLANK; } void reset(){ rear = 0; front = - 1; for(int i=0;i<MAX;i++){ queue_array[i]=BLANK; } } int main() { reset(); insert(LEFT); printf("(%d,%d)\n",front,rear); insert(LEFT); printf("(%d,%d)\n",front,rear); insert(RIGHT); printf("(%d,%d)\n",front,rear); insert(LEFT); read(); read(); read(); read(); insert(RIGHT); read(); for(int i=0;i<MAX;i++){ printf("%d(%d,%d)\n",queue_array[i],front,rear); } return 0; }
위의 코드로 구현된 큐를 이용해서 loop에서 입력이 있으면 큐에 넣고, 또 read를 이용해서 명령을 순서대로 처리하면 되겠네요.
void loop() { leftButtonState = digitalRead(leftButtonPin); if (leftButtonState != lastLeftButtonState) { insert(LEFT); } //right에 대해서도 똑같이. 입력을 insert해 줍니다. //read()를 이용해서 입력을 처리합니다. }
-
미리 시퀀스를 입력하고 OK를 누를 때 동작시키는 것이 목표라면...
// 전,후,좌,우에 대한 액션 상태 정의 #define FORWARD 1 #define BACKWARD 2 #define LEFT 3 #define RIGHT 4 void setup() { // 초기화 // 큐 초기화 } void loop() { // 버튼(들) 상태 읽기 if( 전진 버튼이면 ) { // 큐에 FORWARD 추가. 큐는 환영큐를 만들어 쓰거나, 정두식님의 큐 구현을 써보세요. // 다음 예는 정두식님의 큐 구현을 기준으로 설명했습니다. insert(FORWARD); } else if ( 후진 이면 ) { insert(BACKWARD); } else if( 왼쪽이면 ) { insert(LEFT); } else if( 오른쪽이면 ) { insert(RIGHT); } // 마지막으로 OK 를 눌렀을 때, 실제로 액션을 취하세요. else if( OK 버튼이 눌렸으면 ) { while( (action = read()) != BLANK ) // 큐가 비어 있지 않으면 계속함. { if( action == FORWARD ) { // 모터 동작 - 전진. } else if( action == BACKWARD ) { // 모터 동작 - 후진. } else if ( action == LEFT ) { // 모터 동작 - 왼쪽 } else if ( action == RIGHT ) { // 모터 동작 - 오른쪽 } } // 끝나면 큐를 리셋. reset(); } }
위와 같이 하면 될 것 같습니다.
다만 위는 OK를 누른 후에서, 모든 입력 시퀀스까 끝날때까지 새로운 버튼 입력이 안될겁니다.
-
현재 아래와 같이 프로그램을 구현하여 순차적인 움직임이 아닌
누르면 반응하는 형태의 동작을 하고 있습니다.
올려주신 답변을 토대로 수정해보고 있는데 동작에 관한 부분, 예를 들어
digitalWrite(in1pin, HIGH); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, HIGH);
가 모터가 한쪽은 앞으로 돌고 한쪽은 뒤로 돌아 오른쪽으로 회전하는 부분인데
위 코드를 참조하여 수정하기가 힘듭니다...ㅠㅠ
현재 구현한 전체코드
const int buttonPin0 = 7; //시작 버튼 const int buttonPin1 = 8; //앞 버튼 const int buttonPin2 = 9; //뒤 버튼 const int buttonPin3 = 10; // 오른쪽버튼 const int buttonPin4 = 11; // 왼쪽버튼 const int in1pin = 2; //왼쪽모터 const int in2pin = 3; //왼쪽모터 const int in3pin = 4; //오른쪽모터 const int in4pin = 5; //오른쪽모터 int buttonStateOK = 0; int buttonStateGO = 0; int buttonStateBACK = 0; int buttonStateLEFT = 0; int buttonStateRIGHT = 0; void setup() { pinMode(buttonPin0, INPUT); pinMode(buttonPin1, INPUT); pinMode(buttonPin2, INPUT); pinMode(buttonPin3, INPUT); pinMode(buttonPin4, INPUT); pinMode(in1pin, OUTPUT); pinMode(in2pin, OUTPUT); pinMode(in3pin, OUTPUT); pinMode(in4pin, OUTPUT); Serial.begin(9600); } void loop() { buttonStateOK = digitalRead(buttonPin0); buttonStateGO = digitalRead(buttonPin1); buttonStateBACK = digitalRead(buttonPin2); buttonStateLEFT = digitalRead(buttonPin3); buttonStateRIGHT = digitalRead(buttonPin4); if (buttonStateGO == HIGH) { digitalWrite(in1pin, HIGH); digitalWrite(in2pin, LOW); digitalWrite(in3pin, HIGH); digitalWrite(in4pin, LOW); delay(1500); digitalWrite(in1pin, LOW); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, LOW); } else if(buttonStateBACK == HIGH) { digitalWrite(in1pin, LOW); digitalWrite(in2pin, HIGH); digitalWrite(in3pin, LOW); digitalWrite(in4pin, HIGH); Serial.println("back!"); delay(2000); digitalWrite(in1pin, LOW); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, LOW); } else if(buttonStateLEFT == HIGH) { digitalWrite(in1pin, LOW); digitalWrite(in2pin, HIGH); digitalWrite(in3pin, HIGH); digitalWrite(in4pin, LOW); delay(995); digitalWrite(in1pin, LOW); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, LOW); } else if(buttonStateRIGHT == HIGH) { digitalWrite(in1pin, HIGH); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, HIGH); delay(995); digitalWrite(in1pin, LOW); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, LOW); } else { digitalWrite(in1pin, LOW); digitalWrite(in2pin, LOW); digitalWrite(in3pin, LOW); digitalWrite(in4pin, LOW); } }
감사합니다.
- 입력과 동시에 움직이지 않고, 미리 시퀀스를 입력하고 나중에 동작하는 것을 원하는건가요? (가령. 전->좌->전->우 와 같이 버튼 입력 후, OK 버튼을 눌렀을 때 움직이는) 허대영(소프트웨어융합대학) 2016.5.24 16:48
- 네 맞습니다 ㅠㅠ 아두이노를 처음 접하는 것이라 생각보다 쉽디가 않네요... 우연 2016.5.24 17:06
댓글 입력