[아두이노] 초음파센서 제어

IOT/아두이노|2019. 2. 6. 11:01

[아두이노] 초음파센서 제어



오늘은 재밌는 소재로 거리를 측정할 수 있는 초음파센서를 사용하여 실험하는 내용을 다뤄 보겠습니다. 실제 초음파센서를 구매하시면 4핀으로 구성되어 있는데 가상시뮬레이터에서는 초음파센서가 3핀으로 되어서 어떻게 코딩해야하나 혼동 되실 수 있지만 원리는 동일하니깐 어렵게 생각하실 필요는 없습니다.

1. 초음파센서



초음파센서를 부품을 실제 구입하면 1200원정도 하는 초급 초음파센서를 구매하실수 있을꺼에요. 핀은 총 4핀으로 전원(+,-) 2핀, 입력핀, 출력핀으로 구성되어 있습니다. 하지만 가상시뮬레이터에서는 3핀으로 구성되어 있으면 입력/출력을 한핀에서 다 제어해야 합니다.

가상 시뮬레이터 코딩은 이 한핀을 어떻게 제어할지만 생각하시고 표현하시면 됩니다.

2. 초음파센서 계산 공식


  • 공식 : 기본 340 (위 1200원짜리 4핀 초음파센서 초음파속도입니다.)
    거리 = ((초음파속도 * 센서시간값) / 10000) / 2

            ((float)(340 * duration) / 10000) / 2;  
    

초음파속도 : 실제 사용하는 초음파센서 부품의 초음파속도입니다. 즉 초음파센서마다 초음파속도는 다르고 부품을 구매하실때 제공되는 정보를 잘 확인하시면 정교한 계산을 하실 수 있을꺼에요.

센서시간값 : 초음파센서에서 초음파가 나가고 앞에 장애물에 부딪치고 되돌아오는데 까지 걸리는 시간값입니다. 왕복시간값이라고 생각하시면 됩니다. 그래서 마지막에 나누기 2를 함으로써 초음파센서의 위치에서 장애물까지의 거리가 나오게 되는 것이죠.

3. 초음파센서 코딩

  digitalWrite(7, LOW); 
  delayMicroseconds(2); 
  digitalWrite(7,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(7,LOW); 
   
  float duration = pulseIn(6, HIGH);
    
  float distance = ((float)(340 * duration) / 10000) / 2;  
    

7번핀이 출력모드이고 6번핀은 입력모드입니다. 7번핀으로 초음파를 쏘고 되돌아오는 초음파를 6번핀에서 읽게 됩니다. 그 값은 시간값이고 초음파공식에 대입하여 계산하게 됩니다.

  1. 초음파를 쏘기 전 초음파출력핀을 LOW(0)으로 한다. => 초기단계
  2. 딜레이 delayMicroseconds()함수는 시간을 마이크로초로 딜레이 시킬 때 사용. => 대기시간단계
  3. 초음파출력핀을 HIGH(5V)으로 한다. => 초음파를 출력 시작
  4. 딜레이 delayMicroseconds()함수로 대기한다. => 초음파를 쏘는 시간이다.
  5. 초음파출력핀을 LOW(5V)으로 한다. => 초음파 출력 중지

쉽게 말해서 초기상태는 초음파 출력핀 0V 상태로 2마이크로초로 초기상태로 뒀다가 7번핀을 통해 10마이크로초동안 초음파를 쏘고 난뒤에 초음파 출력핀 0V으로 10마이크로초동안만 초음파를 쏜 신호값을 거리계산에 사용한다는 점만 이해하시면 된다.

pulseIn(입력핀, HIGH)함수 : 펄스 신호의 길이를 잴 때 사용합니다. 초음파 되돌아 왔을때 HIGH->LOW가 되는 시점까지의 시간값을 반환하는 함수입니다. 좀 어려울 수 있습니다.
그냥 저 함수로 초음파 거리 시간값을 읽어오는 구나 정도만 처음에 이해하시면 됩니다.

정 모르겠다면 통으로 저 코딩을 외우시면 됩니다. 초음파센서를 사용할때 저 코딩으로 제어하는 구나 정도만 이해하시면 됩니다.

4. 회로도 구성


  • 준비물 : 초음파센서3핀 1개, 아두이노우노

5. 코딩


void setup() {
  Serial.begin(9600);
}
void loop() {   
  pinMode(7,OUTPUT); //출력모드  초음파 출력
  digitalWrite(7, LOW); 
  delayMicroseconds(2); 
  digitalWrite(7,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(7,LOW); 
  
  pinMode(7,INPUT);    //입력모드로 초음파 입력
  float duration = pulseIn(7, HIGH); //초음파 거리 시간값 읽기
  float distance = duration / 57.5;  // ((float)(340 * duration) / 10000) / 2;   

  Serial.println(distance);   
} 

핀의 입력/출력모드 setup()함수에 선언된다고 했는데 여기서는 loop()함수에서 선언하였습니다. 왜 그렇게 했을까요. 그것은 바로 7번핀을 입력모드와 출력모드를 둘 다 사용해야 하기 때문에 계속 핀모드를 변경해야 합니다. 그래서 loop()함수에 선언된거죠.

초음파를 출력하기전에 7번핀을 출력모드로 선언했다가 다시 7번핀을 pulseIn()함수로 입력을 받을때에는 그 앞에 7번핀을 입력모드로 선언해야겠죠. 이런식으로 해서 7번핀으로 입력/출력모드 제어가 가능해 지는 것이죠.

 float distance = duration / 57.5;  // ((float)(340 * duration) / 10000) / 2;   

이식은 공식에서 최대한 줄이고 가상시뮬레이터에서 좀 더 거리가 비슷하게 나타내기 위해서 근사값 57.5로 표현했습니다. 실제로 하실때는 정식 공식을 사용하세요. 가상시뮬레이터에서는 정식 공식으로 대입하면 오차 거리가 좀 크게 나서 일부러 공식을 줄이고 줄인 공식에서 숫자를 앞뒤로 근사값들을 임의로 정해서 여러차례 실험한 뒤에 가장 오차가 적게 나오는 값이 57.5여서 이렇게 식을 만들었습니다.

실제로 하실때에는 정식 공식을 사용하시고 정식 공식을 써도 오차 거리가 발생할때에 그 부품에 맞게 근사값들을 잡아서 오차 거리를 줄이시면 아마 될꺼에요.

시리얼모니터 출력

지난시간에 사용했지만 복습차원으로 다시 설명하자면

아두이노 IDE 시리얼모니터를 사용하기 위해서

void setup()
{
 Serial.begin(9600);
}
void loop(){
Serial.println(distance);   
}

setup()함수에서 시리얼 통신을 시작한다고 선언(Serial.begin) 하고 loop()함수에서 시리얼모니터로 출력(Serial.println) 합니다.

Serial.println(출력값);   

이정도만 우선 알아두세요.

6. 결과

마무리


실제로 한다면 4핀 코딩을 해야하는데 아래와 같이 실험하시면 됩니다.

void setup() {
  Serial.begin(9600);
  pinMode(7,OUTPUT); //출력모드
  pinMode(6,INPUT);    //입력모드
}
void loop() {    
  digitalWrite(7, LOW); 
  delayMicroseconds(2); 
  digitalWrite(7,HIGH); 
  delayMicroseconds(10); 
  digitalWrite(7,LOW); 
   
  float duration = pulseIn(6, HIGH);
  float distance = duration / 57.5;  // ((float)(340 * duration) / 10000) / 2;  

  Serial.println(distance);   
}  

이 초음파센서 하나로 어떤곳에 사용하면 좋을까요 한번 상상의 나래를 펼쳐보세요. 초음파센서가 거리를 측정할 수 있는 재밌는 부품이여서 거리를 측정할 수 있으면 할 수 있는 것들이 참 많습니다. 한번 생각해 보세요.


댓글()

[아두이노] 곰세마리멜로디(피에조부저)

IOT/아두이노|2019. 2. 5. 14:32

[아두이노] 곰세마리멜로디(피에조부저)



1. 악보


2. 멜로디 배열변수 만들기

음계+음길이

위의 악보에서 음계랑 음길이를 메모장에서 간단히 표시해 보자.

도도도도도
4 8 8 4 4
미솔솔미도
4 8 8 4 4
솔솔미솔솔미
8 8 4 8 8 4
도도도
4 4 2

솔솔미도
4 4 4 4 
솔솔솔
4 4 2
솔솔미도
4 4 4 4 
솔솔솔
4 4 2

솔솔미도
4 4 4 4
솔솔솔라솔
8 8 8 8 2
도솔도솔
4 4 4 4
미레도
4 4 2

5옥타브음계

5옥타브 음계 도레미파솔라시도 이것만 이용 합니다.

5옥타브 음계에서 벗어난 음계를 사용할 경우 위 사이트 가셔서 다른 옥타브 음계를 참조하셔서 사용하시면 됩니다. 귀찮은 분들은 전음계를 다 복사해와서 만드셔도 됩니다.

#define NOTE_C5  523   //도
#define NOTE_D5  587   //레
#define NOTE_E5  659   //미
#define NOTE_F5  698   //파
#define NOTE_G5  784   //솔
#define NOTE_A5  880   //라
#define NOTE_B5  988   //시
#define NOTE_C6  1047  //도

멜로디배열변수

계이름을 매크로변수(#define) 이름으로 배열변수에 저장하시면 됩니다. 그냥 도를 523으로 저장해도 되지만 이름으로 표현하시면 음계를 쉽게 구별할 수 있기 때문에 숫자보다는 변수 이름으로 만들어서 코딩하는걸 추천 드려요.

int melody[] = {
NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,               //도도도도도
NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,               //미솔솔미도
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,       //솔솔미솔솔미
NOTE_C5,NOTE_C5,NOTE_C5,                               //도도도
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,                       //솔솔미도
NOTE_G5,NOTE_G5,NOTE_G5,                               //솔솔솔
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,                       //솔솔미도
NOTE_G5,NOTE_G5,NOTE_G5,                               //솔솔솔
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,                       //솔솔미도
NOTE_G5,NOTE_G5,NOTE_G5,NOTE_A5,NOTE_G5,               //솔솔솔라솔
NOTE_C6,NOTE_G5,NOTE_C6,NOTE_G5,                       //도솔도솔
NOTE_E5,NOTE_D5,NOTE_C5                                //미레도
};

멜로디음길이배열변수

각 음계의 음길이가 각기 다르기 때문에 4분음표, 8분음표, 2분음표 등의 박자길이를 숫자로 해서 멜로디음길이배열변수를 만들어서 순차적으로 음계랑 음길이를 나중에 코딩에서 합쳐서 음을 만들어 내기 위해서 배열변수로 해서 음계과 음길이를 따로 만듭니다.

int noteDurations[]={
4,8,8,4,4,
4,8,8,4,4,
8,8,4,8,8,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
8,8,8,8,2,
4,4,4,4,
4,4,2
};

3. 회로도 구성


준비물 : 피에조부저 1개, 아두이노우노


지난 시간의 회로도와 동일합니다.


4. 코딩


지난 시간의 코딩에서 2번의 멜로디를 만든 배열변수를 추가를 하여 약간 코딩을 변경하시면 됩니다.

#define NOTE_C5  523    //도
#define NOTE_D5  587    //레
#define NOTE_E5  659    //미
#define NOTE_F5  698    //파
#define NOTE_G5  784   //솔
#define NOTE_A5  880   //라
#define NOTE_B5  988   //시
#define NOTE_C6  1047 //도


int tonepin = 12;


int melody[] = {
NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,
NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,
NOTE_C5,NOTE_C5,NOTE_C5,

NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_G5,
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_G5,

NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_G5,NOTE_A5,NOTE_G5,
NOTE_C6,NOTE_G5,NOTE_C6,NOTE_G5,
NOTE_E5,NOTE_D5,NOTE_C5
};

int noteDurations[]={
4,8,8,4,4,
4,8,8,4,4,
8,8,4,8,8,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
8,8,8,8,2,
4,4,4,4,
4,4,2
};


void setup() { 
} 
void loop() {
  for (int i = 0; i < 49; i++) {
    
    int Durations = 1000/noteDurations[i];    // 음계의 음길이 계산
    tone(tonepin, melody[i], Durations);    
    int pauseBetweenNotes = Durations *1.3 ;
    delay(pauseBetweenNotes);
    noTone(tonepin);
  }

}

이번에는 loop()에 반복수행하도록 한번 표현해봤습니다.

int Durations = 1000/noteDurations[i];    // 음계의 음길이 계산

음의 출력이 melody[i], noteDurations[i]로 매칭되어 음이 나오게 됩니다.

음길이 계산식이 원래 고정 1000/4여서 외부에 변수로 표현했지만 실제 곰세마리악보에서 보듯이 음길이가 다르기 때문에 melody[i], noteDurations[i]를 맞추기 위해서 for문 안에다 표현을 하였습니다.

그리고 보기 좋게 하기 위해서 따로 Durations로 변수를 만들어서 i번째 음길이를 가져와서 음길이를 계산한 표현을 하였습니다. 물론 tone(tonepin, melody[i], 1000/noteDurations[i])으로 표현해도 되겠지만 코딩은 각각 구분짓고 경계를 나누어 코딩하는게 시각적 가독성이 좋습니다. 그래서 일부로 이건 음길이 계산이다라고 별도로 한줄로 표현한 것이죠.

나머지 코딩부분은 이전 시간의 코딩과 동일합니다. 다른점은 멜로디 음계와 음길이를 별도로 배열변수에 저장했다는 것이죠.

5. 결과

실제로 회로도 구성이 쉬워서

라즈베리파에 설치한 아두이노 IDE 을 통해 바로 아두이노에 프로그램을 이식했습니다.


문제는 동영상 촬영했는데 소리는 원래 크게 들렸는데 녹화시 너무 작게 소리가 들어가서 실제 실험동영상은 올리는 것을 포기 했고 사진만 올립니다.

마무리


사실 tone(), noTone(), delay() 세함수를 제어하는 것일 뿐 별다른게 없습니다. 물론 음길이 공식이 1000/noteDurations와 Durations*1.3 으로 딜레이 시간을 준 공식을 추가된 것은 있지만 함수는 3개뿐이 사용 안했고 응용도 저 세개 함수만 사용한 실험이였습니다.

단지 멜로디를 만들기 위해서 배열변수로 코딩량만 늘어났을 뿐이죠. 코딩량은 늘어났지만 사실 멜로리 코딩은 위 악보에서 음계와 음길이를 추출하는 것은 쉽기 때문에 거기서 실제 배열변수로 만드는것은 어렵지 않게 2번 내용을 보시면 하실 수 있을거라고 생각됩니다.

예전에 자전거 멜로디를 만들어서 실험했지만 최근 음악 관련 포스팅을 할때 곰세마리악보를 이용해서 이번 아두이노에서도 곰세마리악보를 이용해 멜로디를 만들어 봤네요.

한번 다른 악보를 보고 멜로디를 만들어보세요.


댓글()

[아두이노] 피에조부저 제어

IOT/아두이노|2019. 2. 4. 14:54

[아두이노] 피에조부저 제어



1. 회로도 구성


  • 준비물 : 피에조부조 1개, 아두이노우노
  • 내용 : 12번 핀을 주파수 출력핀으로 사용하여 멜로디를 만들어 보자.

회로 구성은 보는것과 같이 간단하다.



2. 코딩


  • 출처 : https://www.arduino.cc/en/Tutorial/toneMelody
  • 함수 : tone(핀번호, 주파수, 출력시간), noTone(핀번호), delay(시간값)
  • 내용 : 주파수 값은 해당 사이트에서 제공되는 값으로 도레미파솔라시도 출력해보자.

#define NOTE_C5  523   //도 (5옥타브 음계 데이터)
#define NOTE_D5  587   //레
#define NOTE_E5  659   //미
#define NOTE_F5  698   //파
#define NOTE_G5  784   //솔
#define NOTE_A5  880   //라
#define NOTE_B5  988   //시
#define NOTE_C6  1047 //도

int tonepin = 12;
int melody[] = { NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_B5, NOTE_C6 }; //도레미파솔라시도
int noteDurations = 1000 / 4; //톤길이(4분음표)

void setup() {
  for (int i = 0; i < 8; i++) {
    tone(tonepin, melody[i], noteDurations);
    int pauseBetweenNotes = noteDurations * 1.30;
    delay(pauseBetweenNotes);
    noTone(tonepin);
  }
}
void loop() {
}

첫번째 :
#define은 매크로 변수로 NOTE_C5란 변수명은 523이란 숫자를 지칭한다. 매크로상수라고만 이해하시면 된다. 523의 별명으로 NOTE_C5라고 불리운다라고 생각하면 될듯요. 각 주파수 값을 숫자로 이게 도인지 솔일지 모르잖아요. 그걸 별명으로 이름을 지어주는 거라고 생각하시면 됩니다.

두번째 :
setup()함수에 로직을 짠 이유는 loop()함수에다가 코딩해도 됩니다. 그런데 멜로디를 무한 반복해서 듣는건 좀 그래서 처음 한번만 수행하는 setup()함수에 1번만 멜로디를 듣도로 실험하기 위해서 setup()에 코딩했습니다. setup()에 코딩해야하는건 아니고 그냥 1회만 멜로디 출력시키기 위해서 이쪽에다 코딩했을뿐 의미가 있는건 아닙니다.

세번째 :
tone()과 notone()은 확실히 음과 음사이를 끊어주기 위한 것으로 하나의 음계의 소리가 귀로 들을때 들리는 음의 구별하기 위해서 처음과 끝을 나타내는 위치로 생각하시면 됩니다.
그리고 그 사이 delay() 함수의 길이가 1.3배함으로 음과 음의소리가 음과 음의길이사이의 딜레이가 발생시키게 합니다. 이걸 구별해서 이해하실려면 1.3대신에 더 큰 숫자를 넣고 돌려보세요. 음을 실제로 들어보면 왜 delay()함수를 넣은지 이해가 되실꺼에요.

melody[] 변수는 배열변수로 하나의 이름으로 여러개의 저장소를 갖는데 int melody[8]로 선언되면 8개의 그릇을 갖게 됩니다. 각 그릇은 다른 값을 저장이 가능합니다. 배열변수는 안에 숫자로 위치를 나타냅니다.
가령 melody[0]=523 , melody[1]=587, .... 이렇게 각 그릇해 주파수 값을 저장되어 있는 것이죠.

for문으로 0~7까지 루프를 돌잖아요.

tone(tonepin, melody[0], noteDurations);

이것은

tone(12, 523, 1000/4);

되는 것이죠.

하나의 음계의 동작은 도라는 음계를 4분음표이고 그걸 피에조부조로 들리게 한다면 아래와 같이 수행되게 됩니다.

tone(핀번호, 523, 1000/4); //도 4분음표
int pauseBetweenNotes = (1000/4) * 1.30; //4분음표 딜레이시간
delay(pauseBetweenNotes);
noTone(핀번호); 

여기서 도레미파솔라시도 총 8번 반복 수행해서 각 melody[i]값이 음계가 출력되는 것이죠.

3. 결과


마무리


오늘은 tone(), noTone()의 함수에 대해 배웠습니다. 이걸 통해서 피에조부저를 통해 멜로디를 만들었습니다.
그러면 한번 곰세마리를 악보를 보고 멜로디를 만들어 보세요.

참고할것은 여기서, 도레미파솔라시도는 4분음표로 고정해서 멜로디를 만들었습니다.
하지만 모든 음악이 4분음표만 있는게 아니죠.

힌트는,
1000/4은 4분음표면 1000/8은 8분음표겠죠. 1000/2은 2분음표이고요.
도레미파솔라시도의 4분음표일때
int noteDurations[]={4,4,4,4,4,4,4,4}; 이렇게 하면 음표 배열을 만들어지겠죠.
Durations=1000/noteDurations[i]으로 하면 해당 음계에 음표를 만들 수 있겠죠.

한번 곰세마리를 만들어 보세요.
내일 곰세마리 멜로디를 올리도 할께요.


댓글()

[아두이노] 스위치 버턴 제어

IOT/아두이노|2019. 2. 3. 10:51


[아두이노] 스위치 버턴 제어




스위치를 누르면 스위치 내부의 선이 연결되어 전류가 공급되고 LED가 켜지게 된다. 이걸 아두이노에서 제어해보도록 하자.

기본 동작



1. 회로도 구성 (풀업, 풀다운)


  • 준비물 : led 1개, 저항 220옴 1개, 10k옴 1개, 스위치 1개, 뻥판, 아두이노우노
  • 내용 : 스위치를 누르면 led의 불이 들어오게 한다.

풀업풀다운
회로도



풀업과 풀다운의 상태 값을 알아야 한다. 내부적인 전류 흐름을 이해해야 하지만 스위치 배치가 풀업과 풀다운으로 상태로만 처음 구별만 하자.
풀업은 전류가 공급되는데 스위치 버턴을 누르지 않은 상태면 7번으로 입력값이 1이 된다. 하지만 스위치를 누르면 전류가 gnd로 낮은 곳으로 흐르기 때문에 7번핀은 입력값이 0이 된다. 풀다운 반대로 스위치를 누르지 않은 상태에서는 전류가 흐르지 않기 때문에 7번핀의 입력값은 0이 되고 스위치를 누르면 전류가 흐르기 때문에 1의 값을 갖게 된다.

그럼 코딩은 살펴보도록 하자.

2. 코딩


void setup()
{
  pinMode(13, OUTPUT);
  pinMode(7, INPUT);
}

void loop()
{
  digitalWrite(13, digitalRead(7));  
}

첫번째 :
led를 켜기 위해서 pinMode()함수로 13번핀을 출력모드로 우선 선언하였다. 그리고 스위치 버턴을 눌렀을때 그 값을 입력을 받기 위해서 7번핀을 입력모드로 선언하였다. OUTPUT 전류를 밖으로 출력하는 것이고 INPUT은 전류를 안으로 입력받는 것이다. OUTPUT/INPUT만 구분하여 이해하면 된다.

두번째 :
led 켜기 위해서 digitalWrite(출력핀, HIGH/LOW)로 불이 들어오게 한다. 이건 지난 시간에 반복해서 실험한 함수이다.
그러면 입력받는것은 digitalRead(7)함수이다. 출력은 Wirte이고 입력은 Read란 단어만 숙지하면 된다.
digitalRead(7)은 7번핀을 전기신호를 입력받겠다는 의미로 이해하시면된다. 그리고 7핀에 들어온 값이 반환값으로 나오게 된다.

쉽게 말해서 임의의 stat변수 그릇이 있다면

state = digitalRead(7);

이러면 7번핀의 입력값이 1 or 0 값중 하나를 반환한다. 가령 전류가 흘러 입력값이 1이 된다면 이 함수를 통해 1이 반환되어서 state=1 이 된다.

풀업 회로도라면
초기 상태는 스위치가 누르기 전 상태는 digitalRead(7)은 1이 되고 digitalWrite(13,1)로 출력되어 led가 켜져있는 상태가 된다.누르면 0이 되어 led가 꺼진다.

풀다운 회로도라면
초기 상태는 스위치가 누르기 전 상태는 digitalRead(7)은 0이 되고 digitalWrite(13,0)로 출력되어 led가 꺼져있는 상태가 된다.누르면 1이 되어 led가 켜진다.

둘의 원리만 이해하면 된다.

3. 저항없이 풀업스위치 회로도 구성



저항이 없을때 INPUT_PULLUP모드로 내부 풀업 저항을 사용하기 위한 배치도 이다.

4. 저항없이 풀업스위치의 코딩

void setup()
{
  pinMode(13, OUTPUT);
  pinMode(7, INPUT_PULLUP);
}

void loop()
{
  digitalWrite(13, digitalRead(7));  
}

PinMode에서 OUTPUT/INPUT 모드 외에 INPUT_PULLUP모드가 있다. 이건 내부 풀업 저항을 사용하겠다는 건데 그냥 저항없이 입력모드로 사용하겠다고 간단히 이해만 하자.

모드만 INPUT_PULLUP만 이해 하면 된다.

5. 고민해야할 것

스위치를 누르면 불이 들어와야 풀업모드를 사용하면 위 코딩에서는 불이 먼저 들어오는게 불편함을 느껴야 합니다.
풀다운으로 해야하는게 아닌가라고요. 사실 풀업을 사용하는 이유는 아두이노 칩 자체가 전류가 공급되면 각 핀에서 소량의 전류가 흐르게 됩니다. 쉽게 말해서 노이즈로 생각하면 될꺼에요. 풀업모드가 이 문제점에 좋다고 하네요. 그래서 스위치 관련 아두이노 소스들을 찾아보시면 거의 다 풀업모드를 사용하더군요.

그런데 중요한것은 스위치를 누르면 불이 들어와야지 하겠죠. 위 코딩은 원리를 이해하기 위한 목적으로 코드를 최소한 한것이고요. 코드를 변경해야겠죠. 즉, 7번의 값으로 led 불이 들어오는 상태를 결정하는 건 동일하지만 누를때 우리가 생각하는 개념으로 불이 들어오게 하기 위해서 하나의 C문법을 배우도록 하죠.

C문법

if(조건문){
  처리문1;
}
else{
  처리문2;
}

예)

if(k>10){
     printf("k가 10보다 크다!\n");
}
else {
     printf("k가 10보다 크다!\n");
}

k가 10보다 크면 처리문1이 수행되고 k가 10보다 작으면 처리문2가 수행됩니다. 참일때 if문의 처리문1이 거짓일때 else의 처리문2가 수행됩니다. 한줄의 코딩일때는 괄호 생략이 가능함.

f(k>10) printf("k가 10보다 크다!\n");
else printf("k가 10보다 크다!\n");

그냥 else 문을 생략가능함

if(k>10) printf("k가 10보다 크다!\n");

k가 10보다 크면 printf문을 수행하고 크지 않으면 if문을 빠져 나온다.

다중 if문은

if(조건1) 처리문1;
elseif(조건2) 처리문2;
else 처리문3;

첫번째 조건1이 참이면 처리문1을 수행하고 끝나지만 조건1이 거짓이면 조건2로 넘어가서 참이면 처리문2를 수행하고 끝나고 거짓이면 else 처리문3문을 수행하고 끝난다. 한줄일때는 괄호를 생략했지만 처리문이 여러 명령문일때는 괄호로 묶어야 한다. 이점만 주의하면 if문을 사용하는데 어려움이 없다.

코딩

int state = digitalRead(7);
if(state ==1) digitalWrite(13, LOW);  
else digitalWrite(13, LOW);  

7번 핀의 초기값이 스위치 누르기 전 값은 1이기 때문에 state 그릇에 1의 값이 저장된다. 조건문에서 스위치를 누르기 전이니깐 led은 LOW가 되어야겠죠. 스위치를 누르면 7번핀은 0이 되고 state = 0으로 조건문은 거짓으로 led은 HIGH가 되면 되겠죠.

원리를 이해하시면 코딩이 바로 안되면 글로써 문장을 만들어보세요.

  1. 스위치를 누르지 않은 상태가 1이니깐 우선 그 값을 변수로 정해서 담아둬야지
  2. state변수가 초기 1의 값이니깐 조건문을 써서 led 불을 꺼진 상태로 둬야지 state==1일때 led 꺼져있어야겠지.
  3. state==0이면 스위치가 눌러지니깐 led 켜야겠지

이걸 문장을 코드로 바꾸시면 되겠죠. 2, 3번은 꼭 if(state==1)을 안해도 됩니다. if(state==0)을 해도 되겠죠. 그러면 명령어 처리문은 반대가 되겠죠.

코딩은 표현하고 싶은데로 자연스럽게 표현 하시면 됩니다.

6. 결과



마무리


간단히 INPUT_PULLUP 모드를 이용한 스위치 버턴 제어를 해 보았습니다.
사실 Led 관련 응용 예제를 오늘 거론하고 싶었지만 약간 프로그램코딩에 치우치는 경향도 있고 둘이상의 부품의 조합을 하는 것들이라서 나중에 거론할까 합니다.
우선은 하나하나의 부품 제어를 통해 부품을 이해하는게 더 중요하다고 생각되어 당분간 부품 제어에 초점을 맞추겠스니다.


'IOT > 아두이노' 카테고리의 다른 글

[아두이노] 곰세마리멜로디(피에조부저)  (0) 2019.02.05
[아두이노] 피에조부저 제어  (0) 2019.02.04
[아두이노] 3색 LED 제어  (0) 2019.02.02
[아두이노] 코딩 구조  (0) 2019.01.31
[아두이노] LED 제어  (0) 2019.01.30

댓글()

[아두이노] 3색 LED 제어

IOT/아두이노|2019. 2. 2. 12:34

[아두이노] 3색 LED 제어




이번 시간에는 3색 Led를 제어하는 시간입니다. 한개의 3색 led를 어떻게 RGB 색으로 나타내는지 실험하도록 하죠.

1. 회로도 구성


  • 구성 : 3색LED 1개, 저항 220옴 3개, 뻥판, 아두이노우노

3색 LED의 각 꼭지점에 마우스를 대면 red, green, blue란 단어가 보여진다. 각각 보기 편하게 전선을 각 색상선으로 바꿔 준다. 저항은 클릭한 뒤에 Ctrl+C로 복사 한 뒤에 원하는 위치에 마우스 대고 Ctrl+V하면 복제가 된다.

그리고 두번째 검정색선(Gnd)로 연결하면 회로도 구성은 끝난다. 그런데 실제 부품은 제품 정보를 보시고 색선을 구별하셔야 합니다.

2. 코딩


  • 함수 : pinMode(핀번호,모드), analogWrite(핀번호, 색값), delay(시간값)
  • 코딩 내용 : R->G->B로 3색을 순차적으로 간단히 출력하는 로직을 짜본다.

int rpin=11;
int gpin=9;
int bpin=10;

void setup()
{
  pinMode(rpin, OUTPUT);
  pinMode(gpin, OUTPUT);
  pinMode(bpin, OUTPUT);
}

void loop()
{
  analogWrite(rpin, 255);
  analogWrite(gpin, 0);
  analogWrite(bpin, 0);
  delay(1000);
  
  analogWrite(rpin, 0);
  analogWrite(gpin, 255);
  analogWrite(bpin, 0);
  delay(1000);
  
  analogWrite(rpin, 0);
  analogWrite(gpin, 0);
  analogWrite(bpin, 255);
  delay(1000);  
}

첫번째 :
변수 선언에서 int은 자료형으로 변수의 그릇의 크기를 나타낸다. rpin, gpin, bpin으로 3개의 변수를 선언하고 그 변수 그릇에 각각 해당핀 값을 저장시켜 놓는다.

두번째 :
setup()함수는 초기화 작업 코딩하는 부분으로 11, 10, 9핀을 OUTPUT(출력모드)로 아두이노에서 외부로 전류를 보내는 출력모드로 사용하겠다는 것이다.
여기서, 주의할 것은 사용된 핀이 다른 디지털핀과 다르다는 것이다. 0~13번 디지털 핀 중에 6개의 핀은 앞에 (~)에 붙은 핀들이 있는데 아두이노우노 보드를 보면 표시 되어 있다. 이것은 아날로그값을 출력으로 내보낼 수 있는 핀이다. 즉 0~255의 전류로 신호를 출력할 수 있는 특수한 핀이다. 실제 아날로그 값이 나가는게 아니라 아날로그 값이 나가는 것처럼 느낌의 전류 신호를 제어해서 내보낼 수 있는 핀으로 생각하면 된다.
3개의 RGB 핀은 각각 0~255의 값의 범위로 해서 다양한 색상을 만들어 낼 수 있다.

3번째 :
loop()함수에서 기존의 digitalWirte(rpin,100)하면 안된다. 디지털출력은 0과 1의 값만 OV와 5V만 존재한다. 즉, 0이 아닌 값은 무조건 5V의 전류가 흐르게 된다. 그렇게 되면 다양한 색을 만들어 낼 수 없다. (~핀)을 사용하기 위해서는 analogWrite(rpin,100)을 해야 합니다. 0~255사이의 전기신호를 보내기 위한 함수 이고 이 함수를 통해서 아날로그 100의 값의 전기신호를 내보내게 된다. 그래서 RGB Led은 rpin을 통해서 100이란 전기신호값의 색밝기로 보여지게 된다.
여기서는 1초 단위로 max 값 255로 R->G->B로 색이 나오도록 출력한 코딩입니다.

rpin을 255의 전기신호를 보내고 gpin, bpin은 0의 전기신호를 보내면 자동으로 Red 색이 출력되겠죠. 함수의 의미만 잘 이해하시면 다양한 색으로 출력이 가능합니다.

3. 고민해야 할 것


여기서 고민을 해야 합니다. 색을 만들기 위해서 analogWrite()함수가 세번 loop()함수에 표현을 해야하는게 불편함을 느껴야 합니다.
여러가지 색을 표현하고자 한다면 매번 3개의 함수를 loop()함수 안에서 코딩으로 표현하는 것은 엄청 비효율적이지요. 그래서 C언어 문법 하나를 배우도록 하죠.

C언어 문법


  • 문법 : 외부사용자함수()

외부사용자함수란 프로그래머가 직접 함수를 만드는 것이죠. 특정 중복되는 동작을 함수로 묶어서 그 함수를 호출하여 해당 동작을 수행할 수 있게 만들 수 있습니다. 즉, pinMode(인자1, 인자2); 이렇게 함수에 2개의 인자값을 넣어서 pinMode()함수 동작을 수행되는데 이런식으로 직접 프로그래머가 함수를 만들어서 RGB 인자값을 넣어서 색을 출력하는 함수를 만들면 간단한 코딩이 되겠죠.
3개의 analogWrite()함수로 RGB led의 색이 결정되는 원리를 배웠습니다. 그러면 이 원리를 이용해서 하나의 새로운 함수를 만들어 보죠.

void Color(int red, int green, int blue)
{
  analogWrite(rpin, red);
  analogWrite(gpin, green);
  analogWrite(bpin, blue); 
}

이렇게 Color라는 함수를 만들면 이 함수를 표현하여 RGB 색을 출력할 수 있게 됩니다. loop()함수 안에다 아래와 같은 방식으로 코딩하면 좀 더 깔끔한 코딩이 되겠죠. 여기서 인자값 (255,0,0)은 (red,green,blue)라는 변수에 저장되게 됩니다. 그 값이 3개의 analogWrite()함수에 각각 인자값이 대입하여 전기 신호를 출력하게 되는 것이죠. 간단한 원리죠.

Color(255,0,0);
delay(1000);
Color(0,255,0);
delay(1000);
Color(0,0,255);
delay(1000);

또, 고민을 해보세요. 지난 시간의 for()문을 이해 했다면 for()문을을 이용해서 RGB의 각 값을 순차적으로 변화시켜서 여러가지의 색을 만들어 볼 수 도 있겠죠.

웹언어를 공부하신분이라면 색을 나타날때 아래 예처럼 16진수로 각각 두자리가 RGB로 3개의 색을 나타내는 것을 알고 있을 겁니다.

예) #ff0000(red), #00ff00(green), #0000ff(blue)

참고 자료를 보시면 색을 좀 더 자세히 나눌 수 있겠죠.
각각 00~ff의 16진수 범위를 10진수 0~255로 색의 범위를 잡아서 색을 정하면 되겠죠.

4. 결과






마무리


RGB led를 한개를 제어해 봤습니다. 이전 led 제어 코딩에서 analogWrite()라는 함수를 새롭게 한개 배웠습니다.
이 함수로 하나의 RGB Led에 원하는 색으로 표현할 수 있게 된 거죠.
그러면 이것을 현실에서 이용하는 것들이 무엇일까요?
가장 가까운것은 현재 당신이 보는 스마트폰이나 pc 모니터를 생각하시면 됩니다. 쉽게 bmp 이미지 파일을 생각하는게 더 이해가 쉬울지 모르겠군요. bmp 이미지 파일은 픽셀단위로 해서 각 픽셀당 RGB색값이 할당 되고 이게 합쳐져서 이미지로 보여줍니다. RGB led 한개를 하나의 픽셀로 생각해 보세요. 수많은 RGB led를 각각 픽셀로 색의 값으로 밝혀진다면 이걸 다 연결하면 하나의 이미지 처럼 픽셀 이미지가 완성 되겠죠.
대충 어떤 느낌이신지 아시겠지요. 실험에 사용한 RGB led은 집중된 밝기가 아니고 분산된 밝기여서 사실상 이미지화 한다는 것이 무척 어렵지만 특수 led의 경우는 가능하겠죠.
네오 픽셀이라는 RGB 색을 만들어 내는 부품이 있습니다. 이걸로 실제 모니터로 구현한 외국인분들도 있습니다.
유사 표현으로는 주변 전광판을 생각하시면 되겠죠.

그리고 상상을 해보세요. RGB led은 3색을 섞어서 다양한 색을 만들어 낼 수 있습니다. 그러면 이걸로 뭘 할 수 있을까 끊임없이 상상해보세요. 0~255까지의 값의 색을 지정할 수 있다. 그러면 센서를 이용해서 그 센서의 값에 따라 밝기를 나타낸다면 뭔가 시각적인 데이터 표현이 가능하겠죠. 그러면 이걸 어떤부품과 연결해서 표현하면 좋을지 상상을 더해 보세요.

원한 하나의 부품을 사용하고 그 원리를 이해하면 단순히 거기서 끝나면 안됩니다.
그 부품이 다른 부품만 결합하면 또 다른 시너지 효과를 발휘 할 수 있으며 또 그 부품의 원리를 잘 이해하면 그 자체의 기능만으로 재밌는 표현이 가능하게 됩니다.

단순히 한개의 RGB를 제어했지만 이걸 어떻게 제어 하느냐에 따라서 표현하고자 하는 목적에 따라 당신이 생각하는 그 이상의 표현을 할 수 있으며 그런 표현들을 현실에서 아두이노를 다루는 분들이 작품으로 만들고 있습니다.
현재의 여러분들이 이걸 통해서 어떤 상상을 하느냐에 따라서 그 가치가 달라지는 점을 유념하세요.

끊임없이 의문을 갖고 생각을 통해 많은것들을 표현하길 바래요.
다음은 이전 시간에 led와 이번시간의 설명한 내용을 기반으로 상상할 수 있는 것들을 이야기 해보도록 하죠.


'IOT > 아두이노' 카테고리의 다른 글

[아두이노] 피에조부저 제어  (0) 2019.02.04
[아두이노] 스위치 버턴 제어  (0) 2019.02.03
[아두이노] 코딩 구조  (0) 2019.01.31
[아두이노] LED 제어  (0) 2019.01.30
아두이노의 기초  (0) 2019.01.27

댓글()

[아두이노] 코딩 구조

IOT/아두이노|2019. 1. 31. 13:46

[아두이노] 코딩 구조




void setup() {
//초기화 작업
}

void loop() {
//수행한 명령어 로직
}


setup()함수와 loop()함수로 구성되어 있는데 아두이노에 전원이 공급되면 처음 한번만 setup()함수가 수행되고 난 뒤 loop()함수가 전원이 공급되는 동안 무한 반복 호출 된다.


그래서 setup()함수에는 한번만 수행할 명령 코드를 이곳에다 표현하고 계속 반복되는 동작의 명령 코드를 loop()함수에 표현하게 된다.

1. 코딩 연습


  • 주제 : 아두이노에서 LED를 깜박이게 하고자 한다.
  • 명령어 : pinMode(), digitalWrite(), delay()함수

원래는 회로를 먼저 설계한 뒤에 설계한 회로가 원하는 동작을 수행하도록 코딩을 그 다음에 한다. 하지만 여기서는 코딩을 연습하는게 목적임으로 코딩하는 법을 먼저 배워보자.

세개의 함수에 대해서 간단히 이해하자.
pinMode(핀번호, 모드)로 아두이노 해당 핀번호를 입력/출력 모드를 지정하는 함수이다. 즉, 해당 핀을 전류를 받는 입력모드로 쓸지 전류를 내보내는 출력모드로 쓸지를 정하는 것이다. 여기서 LED를 깜박이게 하는건 LED로 전류를 보내야 한다. 그렇기 때문에 LED와 연결된 핀을 출력모드로 지정해야 합니다.

만약 13번핀을 이용해서 LED에 전류를 공급하고 싶다면

pinMode(13,OUTPUT); 라고 표현이 됩니다. 13번 핀을 통해서 LED로 전류를 공급하겠다는 의미인거죠.

13번 핀을 출력모드로 준비상태가 되었습니다. 그러면 이제 깜박이게 한다는 것은 전류가 흐를때 LED 불은 켜지고 전류가 흐르지 않을때 LED 꺼지겠지요.
이제 전류를 보내는 명령을 써야겠지요. 13번 핀을 출력모드로 전류를 외부로 보내는 준비 상태였다면 이제 전류를 실제 공급하는 명령어를 표현해야 됩니다.

digitalWirte(13, HIGH); 라고 표현을 하게 되면, 디지털13번 핀을 HIGH로 한다는 명령어 입니다. HIGH은 매크로 상수로 고정 숫자값인데 그 값을 우리가 이해하기 쉬운 네임으로 지정한 것이죠. (HIGH=TRUE=1) 와 (LOW=FALSE=0)의 표현으로 1과 0을 매크로(#define선언 된) 네임으로 생각하시면 됩니다. 여기서 중요한게 아니라 HIGH은 1로 5V의 전류란 의미로 이해하시고 LOW은 0으로 0V의 전류라고 생각하시면 됩니다.
결론은 13번 핀에 5V의 전류를 보내라는 뜻인거죠.

1초 단위로 LED를 깜박이게 하고 싶다고 상상을 해보세요. 13번핀에 5V의 전류가 흘렀다가 1초후 0V로 전류가 안흘렀다가 다시 1초후 5V가 흐르게 하면서 이렇게 반복적인 수행을 하면 1초 단위로 LED를 깜박이게 되겠죠.

delay(1000); 함수는 1000은 1초를 나타납니다. delay=대기 1초간 대기하라는 뜻이죠. LED를 1초 단위로 깜박이고 싶다면 1초동안 켜지고 1초동안 꺼져야 겠죠. 즉, 1초동안 전원이 공급된 상태로 대기해야 한다는 뜻이죠. 그래서 이 함수를 사용하게 됩니다.

이 세개의 함수를 이제 배치를 해야합니다. setup()함수와 loop()함수에 배치해야 하는데 어떻게 해야할까요.
처음 한번만 수행하는 함수는 setup()함수에 코딩한다고 했죠. 13번이라는 핀을 전류를 밖으로 내보내는 출력모드로 사용한다고 했습니다. 그런데 매번 13번을 출력모드를 쓸거야 하고 반복할 필요가 없죠.
그래서

void setup() {
pinMode(13, OUTPUT);
}

이렇게 한번만 수행해도 되니깐 setup()함수에 넣으면 좋겠죠. 다음으로는 LED를 1초 단위로 깜박이는 하는데 한번만 깜박이는게 아니고 계속 반복해서 깜박이잖아요. 그래서 setup()함수에 넣어서 한번만 깜박일 이유가 없죠. loop()함수에서 반복해야지 1초 단위로 깜박이게 되는 것이죠. 그래서 loop()함수에 코딩하는 것이죠.

배치가 가장 중요합니다. 함수의 기능에 대해서 잘 이해하시고 나면 배치가 무난할 거에요.

void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000); 
}

코드를 자세히 보면 13번핀을 HIGH(5V)의 전류을 내보내라고 명령합니다. delay()함수로 1초동안 대기하게 됩니다. 그러면 1초동안 아두이노에서 5V의 전류가 외부로 1초동안 공급하게 됩니다. 다시 13번핀을 LOW(0V)의 전압을 내보내라고 명령합니다. 이말은 0V니 전류가 흐르지 않는 것이죠. delay()함수로 1초동안 대기하게 됩니다. 1초동안 LED에 전류가 공급 안되니 꺼져있겠죠. 반복함수이니 다시 loop() 첫문장 13번에 HIGH(5V)의 전류를 내보내는 명령을 반복 수행합니다.
결론은 1초 단위로 LED는 깜박이게 되는 것이죠.

setup()함수와 loop()함수의 사용 목적을 잘 이해하고 거기에 맞게 명령어를 잘 배치하여 로직을 설계하시면 됩니다.

13번 핀을 출력모드로 지정한 후 13번 핀에 1초동안 5V의 전류를 공급과 0V의 전류 공급을 반복하는 코딩을 해 보았습니다. 핀 모드를 지정하는 법과 디지털핀에 전류를 공급하게 하는 명령어와 대기함수만 잘 사용하면 아두이노를 이미 절반은 배웠다고 생각하시면 됩니다.

2. 회로 설계


  • 재료 : LED 1개 , 저항 220옴 1개, 아두이노보드, 뻥판


3. 결과




실제 시뮬레이터를 돌리면 빨간 LED가 1초 단위로 무한 깜박이게 됩니다.
보는 것 같이 깜박이면 정상적으로 동작된 것이죠. 여기서 유심히 보면 보드 자체에 작은 LED 전구가 깜박이는걸 보실꺼에요.
이건 13번 핀에 보드 자체가 연결되어 있는 LED라서 특이 사항은 아니고 원래 13번 핀 자체가 특정한 목적 기능을 가진 핀이라서 그걸 보드상에서 확인하기 위한 LED라서 나중에 13번을 구지 선택해서 쓸 필요 없고요. 다른 핀으로 실험하시는걸 추천 드려요.

마무리


코딩을 잘 하기 위해서는 C언어의 변수와 상수란 개념과 문법은 IF, FOR, WHILE문의 개념만 잡으시면 왠만한 표현을 자유자재로 표현이 가능합니다. 몇가지 실험을 하다보면은 자연스럽게 해당 문법을 다루다보면 이해가 가게 됩니다. 구지 프로그램언어를 모른다고 해서 코딩을 못하는게 아니고 단순히 블록처럼 함수 단위로 코드를 상상하시면 됩니다.
우리가 일기장에 일기를 쓰듯이 어떤 동작을 글로 써서 그 글에 맞게 명령어함수를 순차적으로 배치만 하시면 됩니다.
코딩은 어렵지 않고 너무 깊은 사고를 요구하지도 않으면 쉽게 상상을 코딩화 하면 됩니다.

'IOT > 아두이노' 카테고리의 다른 글

[아두이노] 스위치 버턴 제어  (0) 2019.02.03
[아두이노] 3색 LED 제어  (0) 2019.02.02
[아두이노] LED 제어  (0) 2019.01.30
아두이노의 기초  (0) 2019.01.27
아두이노 가상시뮬레이터  (0) 2019.01.24

댓글()

[아두이노] LED 제어

IOT/아두이노|2019. 1. 30. 19:45

LED 제어(아두이노)




1. 발광다이오드(LED)



다리가 긴쪽이 +(애노드), 짧은 쪽 -(캐소드) 이다. 애노드와 캐소드 용어로 구지 생각하지 말고 다리길이에 따라 +, -만 구분하시면 된다.

참고로 발광다이오드는 색깔에 따라 필요한 전압이 다릅니다. 일일히 표로 만들기 귀찮아서 괜찮은 표가 있어서 해당 블로그 표를 인용합니다.


출처 : Arduino - LED 저항값 달기
기본적으로 필요 전압이 golsufan09 블로그의 발광다이오드 표를 인용했습니다.

계산법 - 옴의 법칙


V(전압)=I(전류) * R(저항)

R= V/I = (5V-1.8V)/20mA

기본적으로 LED은 표에서 보는 것 처럼 약 2~3V의 전압에 작동을 하는데 아두이노가 5V의 전압을 제공함으로 최소 100옴을 저항이 필요합니다.

그냥 5V의 전압이 공급되면


감당할 수 없는 전압 LED은 그냥 터지고 만다. 그래서 저항을 붙이는데 저항은 흐르는 전류의 양을 조절해주는 수도꼭지 같은 역활을 한다. 즉, 수도꼭지를 돌리면 물의 양을 조절하는 것처럼 저항의 값에 따라서 전류의 양을 조절 가능하다. 그래서 아두이노에서 부품과 모듈을 사용할때에 아두이노의 나오는 전압과 부품과 모듈에서 필요로 하는 전압이 다를때 저항을 사용한다. 특수한 경우를 제외하고는 거의 모듈 형식의 부품을 사용하기 때문에 초보분들은 그렇게 깊게 생각 안하셔도 된다. 그냥 머리속에서 수도꼭지만 생각하시면 된다.

5V의 전압에 저항(220옴)을 붙이면



위 사진과 전류의 변화를 잘 비교하면 된다.

참고로 직접 회로도를 제작하지 않는 이상은 그냥 모듈로 만들어진 부품을 아두이노와 연결해서 자신이 원하는 표현만 잘 해내면 된다.

2. 뻥판



구멍이 촘촘히 뚤려 있다. 여기서 각 점에서 파란선을 주목하길 바란다. 뻥판 내부에 파란선이 그어진 만큼 각 점들은 내부선으로 연결되어 있다. 그래서 LED와 저항을 배치할때에 겹치지 않고 분리 해서 구분하여 배치해야한다.
점들 내부에는 선으로 저런식으로 연결되었구나를 머리속에 담아 놓으시면 됩니다.

실제로


이렇게 연결된 느낌으로 이해하시면 된다. 하지만 이렇게 할려면 각 부품을 납땜해야 한다. 부품마다 분리 되어 있는데 납땜하면 한번 실험하고 말것도 아니고 계속 다양한 실험을 하기 위해서 뻥판을 사용한다. 뻥판에 부품을 꼽기만 하면 납땜을 하지 않아도 부품간 연결을 쉽게 할 수 있어 주로 뻥판을 사용한다.

3. LED 실험



이전 시간에 13번 핀을 출력모드로 깜박이는 실험을 하였다. 아래와 같이 회로도를 배치하고 코딩도 1초 단위로 깜박이는 예제이다.



void setup() {
pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);
delay(1000); 
}


여기서 여러개의 LED를 제어해보자

회로도


  • 준비물 : led 5개, 저항 220옴 5개, 뻥판, 아두이노우노

components 클릭하시면 부품 이미지들이 하단에 나오고 해당 부품을 드래그 하시면 자동으로 불러오게 된다.
그리고 뻥판에 배치하시고 저항값을 지정하고 선은 마우슨 왼쪽으로 클릭해서 선을 연결하시면 됩니다. 자동으로 마우스 왼쪽 버턴을 누르면 해당 위치에 선이 생성되고 다음 마우스 왼쪽 누른 위치에 끝점이 되어 선이 생성된다.

코딩 - 블록 체크되어있는 걸 누르면 해제된다. 순수 코딩창으로 넘어간다.


  • 내용 : 순차적으로 LED 깜박이기



void setup()
{
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
}

13,12,11,10,9번 핀을 출력모드로 선언한다. pinMode()함수는 이전 시간에 공부했기에 출력모드로 5핀을 지정만 해주면 된다.

void loop()
{
  digitalWrite(13, HIGH);
  delay(1000); 
  digitalWrite(13, LOW);
  digitalWrite(12, HIGH);
  delay(1000); 
  digitalWrite(12, LOW);
  digitalWrite(11, HIGH);
  delay(1000); 
  digitalWrite(11, LOW);
  digitalWrite(10, HIGH);
  delay(1000); 
  digitalWrite(10, LOW);
  digitalWrite(9, HIGH);
  delay(1000); 
  digitalWrite(9, LOW);  
}

로직은 13번 핀이 5V가 전류가 공급되고 1초 대기했다가 13번핀을 0V를 보내고 동시에 12번핀에 5V의 전류를 보낸다. 이런식으로 1초 단위로 13번에서 부터 9번핀까지 순차적으로 전류를 공급했다가 끊어주기만 하면 간단한 원리이다.

자세히 보면 뭔가 함수명이 중복해서 코드를 선언하고 실행 명령을 내리는 느낌을 받았을 것이다.10개이상의 LED를 깜박인다고 생각해보자. 10개이상의 핀을 선언하고 10개 이상의 핀을 HIGH, LOW를 시키는 코딩을 일일히 표현해야 한다면 얼마나 비 효율적인 코딩이겠는가 여기서 C언어 문법 하나를 배워서 간단히 코딩을 바꿔 보자.

C언어 문법


  • 구조
    for(초기값1, 조건식2, 증감연산4){
    처리문3;
    }

예) 1부터 10까지 더하기
int i,sum;
sum=0;
for(i=1;i<=10;i++){
sum=sum+i;
}

int i, sum; 에서 자료형 int은 담을 수 있는 그릇의 크기이고, i와 sum은 변수명으로 어떤 값을 저장하는 그릇으로 생각하면 된다.
자료형이랑 작은 접시냐 큰 접시냐로 값을 저장할 수 있는 크기를 결정하는 표현으로 생각하면 된다. i와 sum의 변수의 그릇을 int형 크기의 그릇으로 선언했다는 정도만 지금은 이해하면 된다.

for문은 동작 순서는 1->2->3->4->2->3->4->2->3->4.... 이렇게 순차적으로 반복 수행한다. 2번의 조건식이 참이면 처리문을 반복 수행하고 거짓이면 for문을 빠져나오게 된다.

그래서 for문 i은 1로 초기값을 지정되고 조건식 i<=10로 i가 10보다 작거나같은가 묻는다. 조건식이 참인가 거짓인가 비교하게 된다. 초기값이 1이기 때문에 조건식은 참이 되어 처리문3을 수행한뒤 i++(증감) i=i+1과 같다. 1씩 증가하는 증감연산자이다.
초기값이 1이고 조건식이 참이여서 sum = sum +1이 된다. sum은 초기값이 0이기 때문에 sum=0+1로 sum=1이 된다.
i++로 i은 2가 되고 다시 2은 10보다 작거나같냐고 물으면 참이기 때문에 sum=sum+2로 이전 sum값이 1이기 때문에
sum=1+2로 sum=3이 저장된다.
이런식으로 i는 다시 1이 증가하여 1, 2, 3, 4, 5, 6, 7, 8, 9, 10이 될때까지 반복하게 된다. i가 11이 되면 거짓으로 for문은 더이상 수행하지 않고 빠져나오게 된다.
그래서, 1부터 10까지의 합 55가 최종적으로 sum에 저장된다.

sum = 1+2+3+4+5+6+7+8+9+10; 이렇게 일일히 다 표현한다면 10개니깐 이렇게 했지만 1000까지 합으로 구한다고 생각해보자 1000개의 숫자를 다 코딩한다고 상상해 보자 엄청 힘들고 비효율적이게 된다.
간단히 sum=sum+i로 i를 1000번 반복해서 sum에 누적 합계를 구하면 쉽고 간단하게 코딩으로 해결이 가능하다.

이처럼 아두이노에서 led가 5개면 대충 위 코딩처럼 일일히 표현이 가능하겠지만 10개이상이면 저걸 다 일일히 코딩하는 건 엄청 비효율적이다. 이럴때 for문을 사용한다면 단 몇줄로 쉽게 해결할 수 있게 된다.

int i;
void setup()
{
  for(i=13;i>8;i--){
    pinMode(i, OUTPUT);
  }
}

i 변수가 13으로 초기화 하고 i는 8보다 크다가 조건식이다 참임으로 처리문 pinMode()함수에서 13번 핀을 출력모드로 선언한다. 여기서는 감소연산자 i--은 i=i-1이다. 1씩 감소한다. 즉 다음핀 12번이 8보다 큰가 조건식이 된다. 참임으로 12번핀이 출력모드로 선언된다. 이런식으로 13번핀부터 9번핀까지 출력모드로 선언하게 된다.
pinMode()함수를 중복해서 코딩할 필요 없이 for문으로 5번 반복하게 된다.

이와 같이 5개핀을 이제 깜박이게 하는 원리도 동일하다.

void loop()
{
  for(i=13;i>8;i--){
    digitalWrite(i, HIGH);
    delay(1000); 
    digitalWrite(i, LOW);    
  }
}

동일한 for문으로 13번 핀을 5V전원을 공급하고 1초 대기했다가 13번핀을 0V가 된다. 이때 다시 i가 12로 감소하고 12번핀에 5V의 전원이 공급되고 1초 대기했다가 다시 0V가 된다. 이런식으로 9번핀까지 깜박이고 i가 8이 되면 for문을 빠져나오고 loop()문이 끝나고 다시 재 반복되게 된다. 계속 13번핀에서 9번핀까지 1초 단위로 깜박이게 된다.

4. 결과




마무리


처음 Led 한개를 깜박였다면 순차적으로 5개의 led를 깜박이게 했다. 그러면 한번 상상을 해보자 홀짝으로 깜박이게 한다면 어떻게 해야할지를 핀 값을 홀짝만 나눠서 전원을 공급하면 되겠죠.
5개 핀이니깐 홀수 3개핀 짝수 2개핀으로 정해서 3개핀에 전원을 동시게 5V공급했다가 1초후 전원을 OV로 한뒤에 짝수 2개핀을 5V로 공급하면 되겠죠.
이걸 홀짝으로 나눠서 반복하면 홀짝으로 깜박이게 됩니다.
그럼 다시 정순으로 순차적으로 깜박이게 했는데 정순으로 깜박인 후 다시 역순으로 깜박이게 한다면 로직을 상상해 보세요.
또 다른 방식으로 Led를 깜박이게 상상해보세요.
그리고 led을 깜박이는 원리를 적용가능한 것들을 현실세계에서 찾아보세요.
대표적인 예로 신호등 제어를 들 수 있겠죠.
만약 led를 이용해 신호등을 만든다고 상상해보세요. 신호등의 원리를 이해하면 그 원리에 맞게 led를 깜박이게 하면 되겠죠.
이외도 한번 led를 깜박이게 한다 그러면 현실에서는 어떤 것들이 이와 유사한 것들이 있는지 상상해 보세요.
다음에는 led가 과연 어떠한 표현이 있는지를 살펴보도록 하죠.


'IOT > 아두이노' 카테고리의 다른 글

[아두이노] 스위치 버턴 제어  (0) 2019.02.03
[아두이노] 3색 LED 제어  (0) 2019.02.02
[아두이노] 코딩 구조  (0) 2019.01.31
아두이노의 기초  (0) 2019.01.27
아두이노 가상시뮬레이터  (0) 2019.01.24

댓글()

아두이노의 기초

IOT/아두이노|2019. 1. 27. 15:01

아두이노의 기초



1. 아두이노 구조




      • 상단
        Digital pin : 핀번호 0~13핀으로 구성되었으며 0(0V) 과 1(5V)의 신호를 보내고 받을 수 있다. 여기서 PWM핀은 6개의 핀을 제공하면 아날로그 출력(0~255)를 내보낼 수 있다.
        시리얼통신핀 : TX(출력1번), RX(입력0번)
        GND(핀) : 전류 마이너스(-) 핀

      • 하단
        Power 부분: 하단 왼쪽 POWER(3.3V, 5V, Gnd, Vin)으로 구성되어 있다.
        Analog pin : 아날로그 입력을 받을 수 있는 핀으로 0~1024(2의 10승)값을 받을 수 있다. 총 6개의 핀으로 구성되어 있다. 여기서 디지털핀으로 핀모드를 지정해주면 사용도 가능하다. 핀모드를 지정안해주면 본래 목적으로 아날로그 값을 입력받는데 사용된다.



지금 각 핀에 대해서 이핀은 무슨 핀이고 저 핀은 무슨핀이다라고 설명해 봤자 의미가 없다. 아두이노를 실제로 실험을 하다보면 아 이 핀이 이런 핀이구나라는 걸 이해할 것이다. 단지 여기서는 핀 구성이 대충 이런식으로 되었다는 정도만 머리속에 담아 놓으시면 된다.

2. 아두이노 Atmega328P 구조




전압 = 5V
디지털핀 14핀(6의 PWM핀제공)
아날로그입력핀 6핀
플래쉬메모리 : 32kb
SRAM : 2kb
클럭 속도 : 16MHz


이 Atmega328P는 사용하기 위해 전원 공급과 통신 등 몇가지 기능을 추가하여 덕지 덕지 붙여 놓은게 아두이노우노입니다. 기본적으로 이 칩은 내부 클럭이 최대 8Mhz정도의 클럭속도는 냅니다. 그래서 크리스탈을 붙여 16Mhz의 속도를 낼 수 있게 합니다. 이 칩에 프로그램을 이식할 수 있는게 32kb 만큼의 용량의 프로그램 밖에 이식할 수 없으며 변수공간도 2kb인가로 아주 제한적이여서 사용 용도로도 아두이노는 복잡한 계산 보다는 단순 작업에 사용됩니다.

쉽게 말해서 Atmega328P 칩에 전류를 공급하고 이 칩에 기록된 프로그램 명령어를 전류가 공급되는 동안 칩 핀을 통해서 입력받거나 출력하는 동작을 계속 반복한다고 생각하시면 된다.

칩 각 핀에는 고유의 역할이 있고 그 핀을 통해서 디지털 신호나 아날로그 신호를 받거나 내보내는 작업을 잘 수행하기 위해서 아두이노를 배우는 것이죠. 아두이노는 종류도 다양하고 칩도 다른데 중요한것은 머리속에서 칩에다 전류를 공급되면 칩에 기록된 명령어를 핀을 통해서 수행한다는 개념만 머리속에 담아 놓으시면 기본 베이스는 끝납니다.

그리고 아두이노를 배우는 것은 이 칩에 기록할 명령어 로직을 짜는법을 배우는 것이라는 점만 머리속에 담아 두세요. 여기서 코딩은 어렵지는 않습니다. 과거에는 하나에서 열까지 전부 다 개발자가 머리속에서 짜내어야 했지만 현재는 기본적인 라이브러리가 다 제공되고 엑셀처럼 각 함수의 의미만 잘 이해하면 쉽게 함수(블록)단위로 코딩이 가능합니다. 그래서 예술쪽 있는 분들이 아두이노와의 결합 작품을 많이 시도하고 만들어내는 이유이기도 하죠.


마무리




아두이노를 공부하는 분들은 어느정도 깊게 들어가면 아두이노로 이것저것을 붙여가면서 좀 복잡한 연산 작업을 수행할려고 한다. 뭔가 아두이노로 두뇌 역활을 하는 작업을 수행하려고 배보다 배꼽이 더 큰 모듈들을 붙여가면서 억지로 그 기능을 구현 시키기도 한다.

뭔가 좀 복잡한 연산이나 다양한 기능을 추가하면서 제어를 하고 싶다면 차라리 라즈베리파이와의 연동을 추천 드립니다. 재밌는 것은 라즈베리파이를 배우는 분들은 반대로 단순작업을 수행하는데 라즈베리파이를 이용하는 경우가 많다. 그냥 아두이노로 표현하는게 더 나을 작업을 구지 라즈베리파이로 구현 시킬려는 분들도 많다. 그래서 아두이노를 배우고 나서 라즈베리를 배우는게 가장 이상적이라고 저는 생각되네요.

'IOT > 아두이노' 카테고리의 다른 글

[아두이노] 스위치 버턴 제어  (0) 2019.02.03
[아두이노] 3색 LED 제어  (0) 2019.02.02
[아두이노] 코딩 구조  (0) 2019.01.31
[아두이노] LED 제어  (0) 2019.01.30
아두이노 가상시뮬레이터  (0) 2019.01.24

댓글()

아두이노 가상시뮬레이터

IOT/아두이노|2019. 1. 24. 15:08

아두이노 가상시뮬레이터






https://www.tinkercad.com


tinkercad에 가입하시면 3D 디자인과 Circuits(아두이노가상시뮬레이터)를 이용하실 수 있습니다. 이메일로 회원을 가입하시고 아두이노를 온라인 상에서 무료로 실험하세요.


제가 아두이노를 가상시뮬레이터에서 실험했던 일부 내용들 입니다.




이런 것들을 실제 아두이노를 구입하지 않더라도 편하게 온라인상에서 실험 할 수 있어서 처음 입문하시는 분들에게 많은 도움이 됩니다. 참고로, 처음 공부하시는 분들은 +, - 연결과 핀 연결의 오류가 발생하면 부품 or 아두이노 보드의 손상이 발생 할 수 있는데 가상시뮬레이터에서 충분히 연습하시면 오류를 최대한 줄일 수 있습니다. 


그리고, 실제 제작하는 시간에 비해 가상시뮬레이터 구현이 빠르기 때문에 순간 순간 마다 떠오르는 상상력을 바로 구현하여 결과를 확인 할 수 있어 아두이노 공부하시는 분들에게 큰 도움을 줍니다.


처음에는 많이 연습을 가상시뮬레이터로 하시고 나서 실제로 먼가를 만들고 싶을 때 필요한 부품들만 실제 구매하여 제작하시는 것이 아두이노 제작비를 줄일 수 있습니다. 처음 공부하시는 분들은 키트나 다양한 불필요한 부품들을 다 사서 한번씩 실험하는데 굳이 그럴 필요는 없습니다. 가상으로 기본 베이스 실험을 하고 실제로는 필요한 부품들만 최소 구매하여 실험하시면 됩니다. 그리고 작품을 만들 때 그 때 큰돈을 들여서 뭔가를 만드시면 됩니다.




다음으로, 3D 디자인을 놀이를 이 곳 사이트에서 할 수 있습니다. 은근 중독성이 있고 갤러리를 보시면 다양한 작품들이 있는데 복사해 와서 자신이 직접 수정하거나 보고 따라서 디자인을 할 수 있으니깐 한번 즐겨 보십시오.






'IOT > 아두이노' 카테고리의 다른 글

[아두이노] 스위치 버턴 제어  (0) 2019.02.03
[아두이노] 3색 LED 제어  (0) 2019.02.02
[아두이노] 코딩 구조  (0) 2019.01.31
[아두이노] LED 제어  (0) 2019.01.30
아두이노의 기초  (0) 2019.01.27

댓글()