아두이노에서 핀 입력값을 배열에 저장하고 싶습니다.

조회수 6702회

아두이노에서 버튼과 모터를 연결하고 버튼이 순차적으로 눌린 후

모터가 순차적으로 움직이는 것을 하려고 합니다.

예를 들어 버튼 1(모터가 좌로 회전), 2(모터가 우로 회전)가 있고 그에 연결된 모터가 한개 있다고 할 때

버튼을 1, 2, 1, 1, 2로 누른 후 모터가 좌, 우, 좌, 좌, 우의 식으로 움직이는 것을 구현하려고 합니다.

이에 버튼을 누르면 이에 대한 값을 받아 배열에 저장하여 모터를 움직이려고 하는데

핀 입력값을 배열에 저장할 수 있는 방법이 무엇인지 궁금합니다.

3 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    먼저 들어온 명령이 먼저 처리되는 큐(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()를 이용해서 입력을 처리합니다.
    }
    
    • 좋은 답변 감사합니다. 죄송하지만 추가적으로 질문하면, 제가 지금 현재 구현되어 있는 것과는 쫌 달라 적용하기가 힘든데 아래 첨부한 코드를 활용해서 작성할 수 있는 방법이 있는 지 궁금합니다. 감사합니다 ㅠㅠ 우연 2016.5.23 01:32
  • 미리 시퀀스를 입력하고 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를 누른 후에서, 모든 입력 시퀀스까 끝날때까지 새로운 버튼 입력이 안될겁니다.

    • 좋은 답변 감사합니다. 감사합니다 ㅠㅠ 우연 2016.5.24 17:35
  • 현재 아래와 같이 프로그램을 구현하여 순차적인 움직임이 아닌

    누르면 반응하는 형태의 동작을 하고 있습니다.

    올려주신 답변을 토대로 수정해보고 있는데 동작에 관한 부분, 예를 들어

    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

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)