[아두이노] 아두이노 선풍기 만들기

IOT/아두이노|2019. 7. 22. 09:00


[아두이노] 아두이노 선풍기 만들기



오늘은 일상에서의 주제를 찾다가 여름이고 해서 선풍기를 주제로 아두니로를 실험을 해 보았습니다. 선풍기의 동작을 관찰하고 각 특징을 기록하고 그 특징들을 아두이노 시각으로 정리 하여 아두이노 상에서 선풍기의 원리를 최대한 유사하게 표현하여 실험을 진행했습니다. 실제로 제작하지 않았고 가상시뮬레이터에서 여러분들도 같이 체험할 수 있게 가상시뮬레이터에서 실험이 이루어집니다.

자! 아두이노 상에서 선풍기를 한번 실험해 볼까요.

1. 선풍기의 동작 관찰


우선 선풍기를 아두이로 만들려면 선풍기의 특징들을 우선 알아야 합니다.

간단히 선풍기의 특징을 정리해 볼까요.


  • 선풍기는 각 단계별로 바람의 세기를 조절 할 수 있다.
  • 선풍기는 180도 정도의 각으로 좌/우 회전을 시킬 수 있다.
  • 선풍기는 동작을 제어하는 스위치버턴이 있으며 현재 상태를 LED로 표시하는 선풍기가 있다.

3가지 특징으로 접근해 보면, 선풍기의 바람(DC모터)을 단계 별로 세기를 조절하는 스위치버턴와 좌/우회전(Servo모터) 시키는 스위치버턴 그리고 스위치를 누를 때 스위치 상태를 7-Segment Display로 표현하면 대충 선풍기의 느낌으로 제작이 가능해 집니다.

2. 아두이노 선풍기 회로도


  • 준비물 : DC모터, 서보모터, 저항 1K옴 1개, 저항 220옴 1개, npn 1개, 다이오드 1개, 스위치버턴 2개, 7-Segment Display 1개, 아두이노우노, 외부전원
  • 내용 : 5번핀이 DC모터 제어핀으로 사용, 9번핀은 서보모터 제어핀으로 사용, 스위치버턴은 2,3번을 사용, 7-Segement Display 4,6,7,8,10,11,12 핀으로 제어하게 됩니다.


위 그림과 같은 느낌으로 제어를 한다는 가정하에서 회로도를 만들면 다음과 같습니다.


좀 복잡하실꺼에요. 아래 코딩에 사전학습 post들을 보시고 개별적으로 해당 부품에 대한 이해하시고 회로도를 보시면 회로도가 어느정도 이해하실 거라 생각됩니다.

3. 코딩



실험에 사용되는 부품들에 대한 사전학습이 필요합니다.

  • 스위치버턴 - 인터럽트함수를 이용하여 제어하게 됨
  • 7 Segment LED - 선풍기 바람의 세기의 단계를 숫자로 표시
  • 서보모터 : 몸체의 회전
  • DC모터 : 바람의세기 제어

기본적으로 위 내용을 우선 원리를 이해하셨으면 본격적으로 코딩에 들어갑시다.

1)선풍기 바람 세기 제어


DC모터 속도를 제어 합니다.

int motorPin = 5;
...
pinMode(motorPin, OUTPUT); 
...
analogWrite(motorPin, 속도);

DC모터는 5번핀을 이용하고 핀모드는 출력 모드입니다. 그리고 analogWrite()함수로 DC모터의 속도를 조절할 수 있습니다.

0,1,2,3 단계로 4개의 상태로 나눠서 바람의 세기를 제어를 하면 아래와 같습니다.

  switch(step){
    case 0:
     analogWrite(motorPin, 0);
     break;
    case 1:
     analogWrite(motorPin, 85);
     break;
    case 2:
     analogWrite(motorPin, 170);
     break;
    case 3:
     analogWrite(motorPin, 255);
     break;
  }

step은 단계 변수로 step의 값에 따라서 DC모터의 세기가 결정됩니다.

바람의 세기버턴을 누르면 step의 값이 0,1,2,3으로 변환하게 하려면 아래와 같이 코딩하면 됩니다.

attachInterrupt(digitalPinToInterrupt(interruptPin1), exchange1, FALLING);
void exchange1() {
  step++;
  if(step==4) step=0;
    
     switch(step){   
       ... 생략
     }  
}

스위치 버턴은 인터럽트함수를 이용하여 인터럽트 스위치 버턴을 누르면 현재 선풍기의 바람의 세기를 변경할 수 있게 됩니다.

2) 바람의 세기 단계를 7-Segment Display(애노드형) 출력


현재 step 단계를 7-Segment Display로 출력하면 됩니다.

해당 숫자를 출력하기 위해서 0.1.2.3 숫자의 패턴을 만들어야 합니다. 애노드형이니깐 아래와 같이 표현할 수 있습니다.

int segValue[4][7] = {
  {0,0,0,0,0,0,1}, //0
  {1,0,0,1,1,1,1}, //1
  {0,0,1,0,0,1,0}, //2
  {0,0,0,0,1,1,0}, //3
};

이 패턴을 가지고 step의 숫자가 출력되는 위치는 어디 일까요. 바로 스위치가 눌러질 때 그 때가 바로 숫자가 변경되는 시점이 됩니다.

void exchange1() {
  step++;
  if(step==4) step=0;
  for(int j=0;j<7;j++){ //setp 숫자 출력
     digitalWrite(segPin[j], segValue[step][j]);        
  }

3) 좌/우 회전시키기


서보모터로 좌/우 회전을 시키기 위해서는 어떻게 해야 할까요. 대충 0~180도 사이를 왔다 갔다 회전을 시키면 됩니다. 회전 최소 간격을 10도기준 0.1초로 해서 회전시키는 방식을 취했습니다.

    if(millis()-timeVal>=100){
        angle=angle+addAngle; //angle(각) 변화값 
        if(angle==180){ 
          addAngle=-10;
        }
        else if(angle==0){
          addAngle=10;
        }  
        servo1.write(angle); //회전각
        timeVal = millis();
    }

위 코딩을 자세히 보시면 addAngle이 초기값으로 10도로 세팅되어 있고 10도씩 0.1초 간격으로 증가하게 됩니다. 이때 180도가 되면 addAngle은 -10으로 바뀌고 -10도씩 0.1초 간격으로 감소하게 됩니다. 이때 0도가 되면 다시 addAngle은 10으로 바큅니다. 0~180도 사이를 왔다 갔다 회전을 하게 하는 동작 코딩이 됩니다.

그러면, 회전을 시킬려면 스위치 버턴을 누르면 회전을 시킬지 정지할지를 정하면 됩니다. 이경우도 인터럽트함수를 이요합니다. 왜냐면 어떤 명령을 수행중에 특정 상태로 강제로 변환 시키기 위해서는 인터럽트함수만한게 없습니다. 회전을 하는 중에서도 강제로 중단시켜야 할 때 유영하게 사용 할 수 있기 때문입니다.

attachInterrupt(digitalPinToInterrupt(interruptPin2), exchange2, FALLING);
void exchange2() {
  sw_state=!sw_state;
  timeVal = millis();
}

인터럽트스위치버턴이 눌러지먼 sw_state가 반전시킵니다.

void loop(){
  if(step>0 && sw_state==true){
    회전명령;
  }
}   

이렇게 코딩하면 sw_state 상태값에 따라서 서보모터의 회전을 결정하게 됩니다.

추가로"step>0" 이 표현이 넣었습니다. 그 이유는 회전은 선풍기가 돌때만 회전되어야지 돌지도 않는데 선풍기화 회전할 필요는 없겠죠. 그래서 선풍기 바람의 세기가 0일때는 회전 할 필요가 없다는 의미로 추가했습니다.

결론은 선풍기 바람의 세기가 0이상이고 선풍기회전스위치버턴이 눌러서 sw_state가 true일때마 회전하라는 의미입니다.

종합해 보면,

#include <Servo.h> 

Servo servo1; 
int servoPin1 = 9;
int motorPin = 5;

unsigned long timeVal = 0; //이전시간

int segValue[4][7] = {
  {0,0,0,0,0,0,1}, //0
  {1,0,0,1,1,1,1}, //1
  {0,0,1,0,0,1,0}, //2
  {0,0,0,0,1,1,0}, //3
};
int segPin[8]={4,6,7,8,10,11,12}; //a,b,c,d,e,f,g 핀


int interruptPin1 = 2; //바람 세기 스위치버턴
int interruptPin2 = 3; //회전 스위치버턴
int step = 0; //바람의세기 단계
boolean sw_state = false; //회전스위치 상태값
int angle = 0; //회전각
int addAngle = 10; //회전조절각

void setup() 
{ 
  pinMode(motorPin, OUTPUT); //DC모터
  servo1.attach(servoPin1); //서보모터
    
  for(int i=0;i<7;i++){ //7-Segment Display핀 모드를 선언과 동시체 초기 0단계 표시
    pinMode(segPin[i], OUTPUT);
    digitalWrite(segPin[i], segValue[0][i]);
  }
  
    //인터럽트함수 선언
  pinMode(interruptPin1, INPUT_PULLUP);
  pinMode(interruptPin2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), exchange1, FALLING); 
  attachInterrupt(digitalPinToInterrupt(interruptPin2), exchange2, FALLING);
  

  //초기 세팅
  analogWrite(motorPin, 0); //바람세기 = 0
  servo1.write(angle); //회전각 = 0
  delay(1000);
}

void loop() 
{   
  if(step>0 && sw_state==true){
    if(millis()-timeVal>=100){
        angle=angle+addAngle;
        if(angle==180){
          addAngle=-10;
        }
        else if(angle==0){
          addAngle=10;
        }  
        servo1.write(angle);        
        timeVal = millis();
    }
  }   
}
void exchange1() {
  step++;
  if(step==4) step=0;
  for(int j=0;j<7;j++){
     digitalWrite(segPin[j], segValue[step][j]);        
  }
  switch(step){
    case 0:
     analogWrite(motorPin, 0);
     break;
    case 1:
     analogWrite(motorPin, 85);
     break;
    case 2:
     analogWrite(motorPin, 170);
     break;
    case 3:
     analogWrite(motorPin, 255);
     break;
  }
}
void exchange2() {
  sw_state=!sw_state;
  timeVal = millis();
}

4. 결과



위그림에서 회전과 바람세기 스위치버턴을 누르면 아래 동영상처럼 동작을 하게 됩니다.


한가지 특수 기능을 표현했습니다. 단순하게 회전과 바람세기을 명령을 내리는 것이 아니라 둘간의 상황이 잘 어울리게 코딩을 했습니다. 바람의 세기가 0일때는 회전상태일지라도 정지가 되고 바람의 세기가 0이 아닌 1이상일 때는 회전정지 상태가 아니면 회전되게 코딩을 표현 했는데 최대한 진짜 선풍기처럼 표현한 부분입니다.

if(sw_state==true){
  선풍기회전;
}

위 코딩에서 "step>0"이란 조건문 한개로 방금 말한 특수 기능을 수행합니다.

if(step>0 && sw_state==true){
  선풍기회전;
}

단순한 한개의 조건을 체크 했을 뿐인데 재밌는 기능을 수행하게 되었네요.

마무리


오늘은 아두이노 가상시뮬레이터에서 코딩적 관점에서 회로도를 만들고 실험이 이루어졌습니다. 실제로 선풍기를 제작한다면 DC모터로 선풍기를 만들지 않고 AC모터로 만들고 좀 더 큰 사이즈의 형태로 실제 선풍기와 같은 형태로 제작을 했다면 좀 더 멋졌겠지만 그러지는 못했네요.

오늘 실험은 일상에서 흔히 볼 수 있는 특정 사물 동작 하나를 관찰하고 그것을 아두이노 시각으로 풀이해 보았습니다. 여러분들도 이런 실험을 한번 해보세요. 이런 학습을 하다보면 처음에는 모방 실험이 되겠지만 그 노하우가 쌓이면 사물의 관찰에서 인간과 같은 생물의 동작을 관찰하고 그것을 아두이노 시각으로 풀이해 낼 수 있게 됩니다. 즉, 상상이 현실이 됩니다. 단지 여러분들에게 필요한 것은 상상입니다.

오늘 실험에서 리모콘이나 Bluetooth를 연동하면 추가로 원격 제어를 할 수 있기 때문에 한번 상상코딩을 해보셨으면 합니다. 리모콘과 Bluetooth를 그동안 자주 거론되고 실험에 사용한 부품입니다. 그리고 라이브러리를 이용하면 간단히 제어를 할 수 있습니다. 함수 몇개만 사용하시면 쉽게 제어가 되니깐 위 코딩에서 어떻게 이 부품들을 적용할지만 코딩 로직만 잘 상상하시면 됩니다 한번 도전해 보세요. 그리고 하실 수 있으시다면 DC모터가 아닌 AC모터를 이용해서 실제 선풍기처럼 제작을 해보셔도 됩니다. AC모터와 AC모터를 제어할 모터쉴드를 구하시고 아두이노로 AC모터를 제어코딩만 하시면 실제 선풍기를 만드실 수 있을 꺼에요.


댓글()