반응형

【 레오나르도활용#1】 아두이노 레오나르도 보드 사용법 #1(Leonardo

▶ 아두이노 Leonardo보드는 아두이노 우노(Uno) 계열의 보드로서, 특징은 PC와 연동하여 활용하기 좋은 보드이다. 기본적인 기능이나 스펙은 우노 보드와 유사하다.  하지만, 우노 보드와 달리 PC와 연결하면 마우스, 키보드와 같은 가상 직렬 포트로 인식되어  PC 제어가 쉬운 특징이 있다.  우노에서의 USB 시리얼 통신(FTDI) 담당 칩인 Mega16u2를 제거하고 그 대신, USB 처리 기능이 있는 프로세서 칩인 ATmega32U4를 사용하였다. 

※ Leonardo는 PC 연결 시, 가상 직렬포트(CDC)로 인식되어, 키보드나 마우스와 같은 HID(Human Interface Device) 장치로 작동 가능한 특징이 있어 키보드 또는 마우스 클래스를 이용하여, PC를 제어하는 용도의 프로젝트에 강점이 있다.

우선, 먼저 레오나르도(Leonardo)에 대해 자세히 알아보고 연결해보도록(드라이버 설치) 하겠다 

아두이노 레오나르도

▶ 레오나르도 사양 :     

Leonardo 상세 사양

▶ 레오나르도 연결(드라이버 설치) :    

 레오나르도를 처음 연결하게 되면 장치가 인식되지 않는데, 
윈도 시작메뉴시작 메뉴로 가서,  제어판 》 장치 관리자 》 기타 장치  쪽을 살펴봐야 한다.

 아래처럼 주의 표시나, 알 수 없는 장치 표시가 뜨게 된다.

그럼 이제 마우스 우클릭하여 드라이버 설치를 진행해보자.

 그럼 아래처럼 드라이브 업데이트 방법에 대한 선택 창이 뜨는데, 
검색으로 찾지 말고, 컴퓨터에서 드라이버 소프트웨어 검색을 눌러준다.

그다음, '찾아보기(R)' 버튼을 눌러,  드라이버의 위치를 아두이노가 설치되어 있는 폴더 아래에 보면 drivers라는 폴더가 있는데, 그 폴더로 선택해준다. (아두이노가 설치된 위치는 다를 수 있음)
 그런데, 이렇게 지정하여도 드라이버 설치가 제대로 안 되는 경우가 있는데, 아두이노 IDE를 너무 오래전 버전을 사용하게 되면 그럴 수 있다.  따라서, 아두이노 사이트에서 아두이노IDE를 최신 버전으로 업데이트해보면 잘 될 것이다. 

 

그러면 드디어 아래처럼, 'Arduino Leonardo(COMxx)' 라며 선명하게 잡히는 것을 볼 수 있을 것이다.


▶ 
레오나르도 특징 :

 아두이노 우노 보드에서는,  보드와 PC 사이 통신(USB to Serial)을 담당해주는 보조 칩인 "mega 16u2"가 따로 존재한다.
하지만, 아두이노 레오나르도 보드에서는 메인칩을 'ATmega32 U4'로 바꾸면서 그 기능까지 담당하게 하였다. 
덕분에 레오나르도 보드의 가격이 우노보다 저렴해진 장점이 있다.  하지만, PC와 연결된 상태에서 리셋 버튼을 누르게 되면 PC와 연결이 끊겼다가 다시 연결되는데, 이 과정에서 장치 목록이 리프레쉬되고 시리얼 통신 중인 연결(데이터)이 끊기게 된다.  별도의 칩이 있어 리셋 버튼에 영향을 받지 않는 우노와 다른 점이다.   
 그래서 
스케치(IDE) 코드를 업로드하거나, 통신을 할 때 영향을 줄 수 있으니 레오나르도 보드를 사용할 때는 약간의 주의가 필요하다.  예를 들면,  레오나르도 보드에서는 PC에서 직렬(Serial) 포트를 열어도 스케치를 다시 시작하지 않는다. 즉, 보드에 의해 PC로 이미 전송된 시리얼 데이터는 (예, Setup { } 문의 내용들) 처음 순간 금방 전송되어 버리고 나면, 다시 확인할 수 없다.  이후 루프(loop { }  ) 안에 있는 내용만 시리얼 창을 통해 확인 가능하게 된다.

 하지만, 큰 장점도 있다. 하나의 메인 CPU로 스케치를 실행하고 USB 연결도 담당하니, 컴퓨터와의 유연성이 증가하게 되고, 펌웨어를 통해서 USB의 다양한 기능을 사용할 수 있어서 강력한 제어가 가능해진다. 

 그리고, 레오나르도 보드의 ATmega32U4 칩에는 D0(RX)핀, D1(TX)핀에서 사용할 수 있는 USB를 통한 UART TTL(5V) 시리얼 통신 기능을 지원한다.  이 것은 PC로 하여금 레오나르도 보드를 USB(2.0) (가상) 장치로 인식할 수 있게 해 준다. 
이는 아두이노(레오나르도) 보드를 이용해서 마우스나 키보드와 같은 기능을 구현할 수 있음을 뜻한다. 

 또한, 물리적인 시리얼 포트와 가상 COM 포트가 분리되어 있기 때문에, RX, TX단자에 블루투스와 같은 통신 모듈을 연결하여 사용하더라도, 스케치에 데이터를 업로드할 때 장치를 분리하지 않고도 업로드가 가능하다. (우노에서는, 블루투스가 연결되어 동작(통신)되고 있는 상태에서는 스케치를 통해서 업로드가 되지 않기 때문에 PC↔우노↔블루투스 형태의 통신을 위해 우노와 블루투스는 일반 포트를 이용한 소프트웨어 시리얼 통신을 이용하게 된다)

또 하나의 장점으로 위 테이블 표에서도 알 수 있듯이, 레오나르도 보드는 소프트웨어적으로 아두이노 보다 더 많은 총, 20 개의 Digital 입출력 핀과,  12개의 Analog 입력 핀을 설정하여 사용할 수 있다.  (물리적인, 핀 수는 우노와 동일하다)

레오나르도 보드의 뒷면을 살펴보라

위 이미지들은 사용할 수 있는 포트를 명기해 놓은 이미지이며, 보기에 편한 이미지를 사용하면 된다. 

많이 복잡해 보여도 실제 코딩에서는 관련 헤더 파일의 함수와 클래스를 이용하면 쉽게 다룰 수 있다.

그럼, 다음 회차부터는 본격적으로 레오나르도 보드를 사용해 재미나는 회로를 만들어 보려고 한다. 

 

반응형
반응형

【 아두이노Proj#6 조이스틱 미니카 만들기~! 

 조이스틱을 이용하여 아두이노 미니카(mini car)를 만들어 보려 한다. 

물론 무선으로 제어가 가능한 방법들도 많이 있지만, 구성이 간단하고 쉽게 조립해서 바로 실행시켜 볼 수 있어 유선으로 제어를 해보려 한다. 아두이노를 배우는 단계에 있다면, 쉬운것 부터 차근 차근 만들어 보는 경험을 쌓는 것이 매우 도움이 되기 때문이다. 또한 조이스틱과 소형의 L9110s 모터 드라이버를 활용해보는 공부도 될 것이다. 

▶ 선수 학습 :

    1. [아두이노 모듈#14] 조이스틱 Joystick 사용하기 #1 ☜ (클릭)

    2. [아두이노 모듈#15] L9110S 모듈 사용하기 #1 (모터 드라이버 참조)  ☜ (클릭)

 

 미니카 제작 재료

 

▶ 실습 목표 :  

 1. [ L9110S 모터 모듈을 활용하는 방법에 대해 이해 할 수 있다.

 2. [ 조이스틱으로 유선 제어를 응용해 볼 수 있다. ]

 3. [ Step up 컨버터를 이용해 낮은 입력 전압을 5V전압으로 승압해 주는 컨버터를 다룰 수 있다. ]

 

▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)

※ 위 회로 연결에서 모터의 회전 방향이 반대가 될 경우 연결선을 서로 바꾸어 주면 된다. 

  (예를 들어, Motor A 가 반대 방향으로 회전 할 경우 A1-A 와 A1-B 에 연결한 선을 서로 바꾸어 연결한다)

 속도제어를 위해서는 디지털 포트 중에서 PWM신호 출력이 가능한 아두이노 포트(숫자앞 '~'표시) 를 연결해야 한다.

 

▶ 실습 절차  : 

 

1.   부품을 준비하여 위와 같은 회로를 구성한다. 

   -  미니카의 베이스 판은 아크릴 판 혹은 MDF 등 주변에서 쉽게 구할 수 있는 것으로 한다.

   -  조이스틱과 연결 되는 케이블은 유연성이 있는 연선(4선 혹은 3선)으로 연결한다.

2.   아래 코드를 작성하고 프로그램을 로딩 후 실행시킨다.(혹은 첨부파일 다운)

3.  코딩1은 조이스틱으로 상하좌우 제어만 가능한 기본 코드로 먼저 적용해 본다.

4.  코딩2는 조이스틱의 대각선 방향을 제어 해볼 수 있는 코드로, 필요한 경우 시리얼모니터링을 통해 데이터 값을 참고하여 코드 속 수치 값을 변경해주거나  자신만의 알고리즘으로 변경해본다. 

 

 

 

※  선수학습 1(조이스틱 편) 을 참고하여, 조이스틱을 상하좌우, 대각선방향 등 작동시켰을 때 나오는 값을 참고 하여, 아래 코딩에서 사용 되는 Jox, Joy의 좌표값을 적당한 값으로 수정할 필요가 있을 수 있다. 

(예를 들어, " if (Joy >= 90 && Jox < 20) ..." 에서  '90' 이나 '20'과 같은 수치 값 조정)

 

▶ 프로그램 코드 및 설명 (코드1) : 

/* 조이스틱 미니카 제어 (방향 : 상하좌우) */

/* L9110s 모터드라이버
   오른쪽모터
   L9110s A_1A 9 
   L9110s A_1B 10 
   왼쪽모터
   L9110s B_1A 5
   L9110s B_1B 6
*/
int A_1A = 9;
int A_1B = 10;
int B_1A = 5;
int B_1B = 6;
int speed = 250;   // speed: 0~ 255

void setup ( ) {  
  //핀을 초기화 하고, 출력설정
  pinMode(A_1A, OUTPUT);
  pinMode(A_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);
  Serial.begin(9600);  
}

void loop ( )  {
  int Jox = map(analogRead(A0), 0, 1023, -100, 100);
  int Joy = map(analogRead(A1), 0, 1023, -100, 100);
  Serial.print(" JoX : ");
  Serial.print(Jox);
  Serial.print("    JoY : ");
  Serial.println(Joy);
   
  if (Jox >= 90 && Joy <= 20 && Joy >= -20)  {
    // 모터 전진
    //모터A
    analogWrite(A_1A, speed);
    analogWrite(A_1B, 0);    
    //모터B
    analogWrite(B_1A, speed);
    analogWrite(B_1B, 0);
  }
  else if (Jox <= -90 && Joy <= 20 && Joy >= -20) {
    // 모터 후진
    //모터A
    analogWrite(A_1A, 0);
    analogWrite(A_1B, speed);    
    //모터B
    analogWrite(B_1A, 0);
    analogWrite(B_1B, speed); 
  }
  else if (Joy >= 90 && Jox < 20)  {
    //모터 우회전
    // 모터A 
    analogWrite(A_1A, 0);
    analogWrite(A_1B, speed);    
    // 모터B 
    analogWrite(B_1A, speed);
    analogWrite(B_1B, 0);
  }   
  else if (Joy <= -90 && Jox < 20) {
    // 모터 좌회전
    // 모터A 
    analogWrite(A_1A, speed);
    analogWrite(A_1B, 0);    
    // 모터B 
    analogWrite(B_1A, 0);
    analogWrite(B_1B, speed);  
  }

    // 모터 정지
  else {
    analogWrite(A_1A, 0);  
    analogWrite(A_1B, 0);    
    analogWrite(B_1A, 0);
    analogWrite(B_1B, 0);
  }
}

 

▶ 프로그램 코드 및 설명 (코드2): 

/* 조이스틱 미니카 제어 (방향 : 상하좌우 & 대각선 제어) */

/* L9110s 모터드라이버 
   오른쪽모터 
   L9110s A_1A 9 
   L9110s A_1B 10 
   왼쪽모터 
   L9110s B_1A 5 
   L9110s B_1B 6 
*/ 
int A_1A = 9; 
int A_1B = 10; 
int B_1A = 5; 
int B_1B = 6; 
int speed = 250;   // speed: 0~ 255 

void setup ( ) {  
  //핀을 초기화 하고, 출력설정 
  pinMode(A_1A, OUTPUT); 
  pinMode(A_1B, OUTPUT); 
  pinMode(B_1A, OUTPUT); 
  pinMode(B_1B, OUTPUT); 
  digitalWrite(A_1A, LOW); 
  digitalWrite(A_1B, LOW); 
  digitalWrite(B_1A, LOW); 
  digitalWrite(B_1B, LOW); 
  Serial.begin(9600);   
} 

void loop ( )  {
  int Jox = map(analogRead(A0), 0, 1023, -100, 100); 
  int Joy = map(analogRead(A1), 0, 1023, -100, 100); 
  Serial.print(" JoX : "); 
  Serial.print(Jox); 
  Serial.print("    JoY : "); 
  Serial.println(Joy); 
    
  if (Jox >= 90 && Joy <= 20 && Joy >= -20)  { 
    // 모터 전진 
    //모터A 
    analogWrite(A_1A, speed); 
    analogWrite(A_1B, 0);     
    //모터B 
    analogWrite(B_1A, speed); 
    analogWrite(B_1B, 0); 
  } 
  else if (Jox <= -90 && Joy <= 20 && Joy >= -20) { 
    // 모터 후진 
    //모터A 
    analogWrite(A_1A, 0); 
    analogWrite(A_1B, speed);     
    //모터B 
    analogWrite(B_1A, 0); 
    analogWrite(B_1B, speed);  
  } 
  else if (Joy>=90 && Jox<20 Jox<=20 && Jox>=-20 && Joy>=90)  { 
    //모터 우회전 
    // 모터A  
    analogWrite(A_1A, 0); 
    analogWrite(A_1B, speed);     
    // 모터B  
    analogWrite(B_1A, speed); 
    analogWrite(B_1B, 0); 
  }    
  else if (Joy<=-90 && Jox<20 Jox<=20 && Jox>=-20 && Joy<=-90) { 
    // 모터 좌회전 
    // 모터A  
    analogWrite(A_1A, speed); 
    analogWrite(A_1B, 0);     
    // 모터B  
    analogWrite(B_1A, 0); 
    analogWrite(B_1B, speed);   
  }

   // 동북방향
  else if ( Jox >= 90 && Joy >= 90 ) {
    analogWrite(A_1A, 120);
    analogWrite(A_1B, 0);    
    analogWrite(B_1A, speed);
    analogWrite(B_1B, 0);  
  }

   // 서북방향
  else if ( Jox >= 80 && Joy <= -80) {    
    analogWrite(A_1A, speed);
    analogWrite(A_1B, 0);    
    analogWrite(B_1A, 140);
    analogWrite(B_1B, 0);  
  }
  
  // 동남방향
  else if ( Jox <= -90 && Joy >= 80) {    
    analogWrite(A_1A, 0);
    analogWrite(A_1B, 120);    
    analogWrite(B_1A, 0);
    analogWrite(B_1B, speed);  
  }
  // 서남방향
  else if ( Jox <= -80 && Joy <= -80) {    
    analogWrite(A_1A, 0);
    analogWrite(A_1B, speed);    
    analogWrite(B_1A, 0);
    analogWrite(B_1B, 140);  
  }

   // 모터 정지
  else { 
    analogWrite(A_1A, 0);   
    analogWrite(A_1B, 0);     
    analogWrite(B_1A, 0); 
    analogWrite(B_1B, 0); 
  } 
}

 

▶ 아두이노 파일다운 :

(다운받아서 압축을 풀어 사용하세요)

# 1.  <코딩 1>

L9110_miniCar_JoyII.zip
0.00MB

# 2.  <코딩 2>

L9110_miniCar_JoyIII.zip
0.00MB

 

조립 과정 및 동작 영상 :

아두이노 미니카 제작 영상

[ ▶ 유튜브에서 보기 ]

https://youtu.be/GbwqPd2gi_s

 

반응형
반응형

【 아두이노모듈#10】 1채널 릴레이(JQC-3FF-S-Z) 사용하기

 

 아두이노를 사용하다보면 대부분 5V~12V 사이의 회로 위주로 제어하게 되는데, 실생활에서 사용되는 선풍기, 등기구 등의 제어를 하고 싶어 질 때가 있다. 이를 가능하게 해주는 부품이 바로 릴레이 이며, 낮은 전압으로 높은 전압을 사용하는 기기 제어가 가능 한 것이 릴레이 사용의 주 목적이다.(코일의 유도전기 원리 이용)

 릴레이 부품을 직접 사용하여도 좋지만, 여기서는 아두이노에서 간단한 핀연결 만으로 사용할 수 있는 릴레이 모듈을 소개하고자 한다. 또한, 1채널(1ch)릴레이에 대해 소개하지만, 2ch 이상의 모듈을 사용하면 동시에 여러가지 기기기를 제어 할 수 있다는 것을 기억하면 도움이 된다. 

 또한, 릴레이를 멀티탭이나 콘센트에 직접 설치하여 제어하게 되면 거의 모든 전기 제품을 제어 할 수 있을 것이다. 

▶ 선수 학습 :

   없음.

▶ 

릴레이모듈 (1ch, JQC-3FF-S-Z) 세부 스팩

 

릴레이 사용법 
 - 릴레이는 코일에 전류를 흘려 코일의 유도 작용에 의해 접점을 On / Off 해주는 스위치이다. 
 - 이를 이용하면, 낮은 전압(예, 5V)으로 220V의 전원을 끊거나 연결시킬 수 있다.
 - 좌측 IN에 HIGH(또는 LOW) 신호가 가해지면 Com단자와 NO 단자가 연결되어 스위치 형태로 작동 된다.
 - NC (Normal Close : 평상시 연결되어 있음)   
 - NO (Normal Open : 평상시 열려 있음, 연결 끊어짐) 

  - NC단자와 Com 단자가 디폴트로 연결 되어 있고, 릴레이가 동작이 되면 이 연결이 끊어지고,
    Com단자가 NO단자와 연결이 됩니다. 이 부분을 전기제품이나 콘센트의 한 쪽 부분의 연결을 끊어 
    스위치 형태로 구성할 수 있다.

 

▶ 실습 목표 :  

  1. [ 릴레이의 사용목적에 대해 이해 할 수 있다. 

 2. [ 릴레이 모듈의 동작 방법에 대해 이해 할 수 있다.]

 3. [ 등기구를 대신한 LED의 On/Off 제어 회로를 이해 할 수 있다.]

 

▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)

 

 

  ※ 부품 목록 :

 

 

▶ 실습 절차  : 

 
1.   부품을 준비하여 위와 같은 회로를 구성한다. 
2.   여기서 소개하는 릴레이가 아니더라도 동일하게 구성하면 되고, 9V, 12V 릴레이 모듈을 사용할 수 있도록 별도 전원연결 형태로 회로를 그렸으나, 5V 릴레이의 경우 릴레이에 별도전원 연결 없이 , 아두이노 전원만으로도 충분히 사용가능하다. (아래 실제 제작 동영상 참조) 

 

3.  아래 코딩을 실행하면 LED가 On 되어 있으며, 푸쉬버튼 스위치를 누르게 되면 LED가 Off 된다. 이와 같이 동작 확인이 되면, 반대로 동작하도록 코딩의 내용을 스스로 변경해보라.

 

 

 

▶ 프로그램 코드 및 설명 : 

 

/* 1채널 릴레이 다루어 보기  */

 

int relay = 7;

int button = 2;

 

void setup ( ) {

  pinMode(relay, OUTPUT); // 릴레이 연결 핀 출력으로 설정

  pinMode(button, INPUT); // 버튼 연결 핀 입력으로 설정

  Serial.begin(9600);

}

 

 

void loop ( )  {

  Serial.println(digitalRead(button));    

  Serial.println(digitalRead(relay));    

  if (digitalRead(button)== HIGH) {

    digitalWrite(relay, LOW);   // 이 부분을 수정하면 반대로 동작

  }

  else {

    digitalWrite(relay, HIGH);  // 이 부분을 수정하면 반대로 동작

  }

}

 

▶ 실행영상 :  

(전체화면 보기로 보세요)

 

(아래는 유튜브로 시청하기)

https://youtu.be/X-cczSjPhtg

 

▶ 아두이노 파일다운 :

 

(다운받아서 압축을 풀어 사용하세요)

relay1.zip
다운로드

 

 

반응형
반응형

【 아두이노모듈#9】 TM1637 & DS1307 리얼타임 시계 만들기


 지난시간 RTC 모듈의 기본사용법에 대해 학습해보았다. 이번 시간에는 이 RTC 모듈의 기록된 시간을 동기화 하여 시계회로의 전원이 차단 되더라도 흘러가는 시간이 유지되는 시계회로를 완성해 보고자 한다. 



▶ 선수 학습 :

   1. [아두이노 모듈#8] DS1307 리얼타임클럭 모듈 ☜ (클릭)

   2. [아두이노 모듈#9] TM1637(시:분) 시계 만들기 ☜ (클릭)


▶ DS1307 세부 스팩 


※ .라이브러리 다운로드

 - DS1307RTC:https://github.com/PaulStoffregen/DS1307RTC

 - RTClib : https://github.com/adafruit/RTClib  


  RTC(리얼 타임 클럭) 모듈은 DS1307과 DS3231 두 종류가 많이 사용된다. 두 모듈의 차이는 DS3231 모듈의 오차가 1년에 수분 정도로 조금 더 정밀도가 높아 진 것인데, DS1307을 사용해도 큰 오차가 나는 것이 아니기에 걱정말고 사용해보자. 
(DS1307 : 한 달 약 5분 미만,  DS3231 : 1년 약 5분 미만 오차)


【 RTC 모듈 시계의 구동원리 】 

: 시계를 만들때 현재의 시간을 맞추어 주어야 하는데, RTC를 가지고 PC와의 시간을 동기화 시키면,그 시간이 RTC모듈의 메모리에 저장되며, 모듈에 있는 베터리로 인해 시계회로에 공급되는 전원이 차단 되어도 메모리에 저장된 기준시간은 유지된되게 된다.  시계회로에서는 이 RTC 모듈에서 보통 1초마다 현재 시간값을 가지고와서 출력(사용)하게 된다. 



▶ 실습 목표 :  

  1. [ RTC 모듈에 대해 이해할 수 있다. 

 2. [ PC의 현재 시간을 RTC모듈에 동기화 시킬 수 있다.]

 3. [ 동기화된 시간을 아두이노 IDE의 시리얼 모니터 창을 통해 출력할 수 있다. ]

 4. [ TM1637 모듈에 14:49 (시 : 분) 형태로 출력해 볼 수 있다. ]

 5. [ 전원이 차단 되어도 시간이 유지되는 것을 확인 할 수 있다 ]

 


▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)



▶ 실습 절차  : 


1.   필요한 라이브러리 등을 '라이브러리 매니저'등을 통해서 설치한다. ( <RTClib.h> , <Wire.h>  )

2.   i2c 통신을 이용하는 모듈이기 때문에 <Wire.h> 라이브러리가 필요하며, 비교적 연결이 간단하고 쉽다. 


3. RTC의 메모리에 현재시간 값을 기록 하기 위해, Set Time 코드를 실행시킨다.(선수학습의 1번 항목 참고1. [아두이노 모듈#8] )

4. 아래의 코드를 실행시켜 시계프로그램을 완성한다. 


▶ 프로그램 코드 및 설명 : 


/* RTC 모듈에 있는 시간 값을 불러와 TM1637로 출력  */


#include <TM1637Display.h> // FND 시계모듈 라이브러리

#include <RTClib.h>     // RTC 기본 라이브러리

RTC_DS1307 RTC;         // RTC 모듈 객체 생성

#define CLK 8

#define DIO 9

TM1637Display display(CLK, DIO);

int Time, Minute;

char daysOfTheWeek[7][12] = {"SUN", "MON", "TUE", "WEN", "THU", "FRI", "SAT"};      //요일 관련 배열 선언 (생략가능)


void setup ( ) {

Serial.begin(9600);  

  display.setBrightness(7);    // 0~7, 밝기 조절

  Serial.begin(9600);

  RTC.begin();

  if (! RTC.begin()) {     // RTC모듈 연결 확인 루틴

    Serial.println("Couldn't find RTC");

    while (1);

  }

  if (! RTC.isrunning()) {

    Serial.println("RTC is NOT running!");

  }

}


void loop ( )  {

  DateTime now=RTC.now(); // RTC에 저장된 값을 불러옴

  Serial.print(now.year(), DEC);

  int Time = now.hour();

  int Minute = now.minute();

  

  int digitoneT = Time / 10;

  int digittwoT = Time % 10;

  int digitoneM = Minute / 10;

  int digittwoM = Minute % 10;


   uint8_t data[] = { 0x0, 0x0, 0x0, 0x0};

   uint8_t segto;

   data[0]=display.encodeDigit(digitoneT); 

   data[1]=display.encodeDigit(digittwoT);

   data[2]=display.encodeDigit(digitoneM); 

   data[3]=display.encodeDigit(digittwoM); 


// 시와 분 사이 ' : ' 출력하고 깜빡임

   segto = 0x80 | display.encodeDigit(digittwoT);

   display.setSegments(&segto,1,1);

   delay(500);   // ' : ' 깜빡임 속도 조절하는 딜레이

   display.setSegments(data);     

   delay(500);   // ' : ' 깜빡임 속도 조절하는 딜레이


// 아래는 시리얼 모니터창에 시간출력(생략 가능) 

  Serial.print(now.year(), DEC);

  Serial.print('-');

  Serial.print(now.month(), DEC);

  Serial.print('-');

  Serial.print(now.day(), DEC);

  Serial.print(" (");

  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);

  Serial.print(") ");

  Serial.print(now.hour(), DEC);

  Serial.print(':');

  Serial.print(now.minute(), DEC);

  Serial.print(':');

  Serial.print(now.second(), DEC);

  Serial.println();

}


▶ 실행영상 :  

(전체화면 보기로 보세요)




▶ 아두이노 파일다운 :

(다운받아서 압축을 풀어 사용하세요)


[ 위 시계 프로그램-아두이노- ]

OK_ds1307_4digit_Watch.zip



[ RTC 타이머에 현재시간 셋팅 프로그램-아두이노-   순서상으로 이걸 먼저하고 바로 위 코드를 다시 업로드 시켜야 합니다.]

(RTC 타이머에 PC로 부터 동기된 현지 시간을 셋팅해주는 프로그램입니다.

따라서 현재시간을 RTC모듈에 이프로그램으로 기록하고 나서, 다시 위 프로그램을 업로드 하면, 

수정된 현지시간으로 시계가 돌아가게 됩니다. )

DS1307_SetTime2.zip


[ 만약 <TM1637Display.h> 관련한 에러가 나는 경우  해당 라이브러리가 설치 되지 않았거나 중복 설치, 잘못된 라이브러리 설치 등의 이유입니다.    해당 라이브러리 설치 안내는 선수학습: https://rasino.tistory.com/209  참고하시고,  별도로 라이브러리는 아래 다시 첨부하니 다운받아 설치해서 다시 실행해보세요 ]  


TM1637Display 라이브러리 다운로드 :  (압축풀지말고 라이브러리 메니저 창에서 zip 형태로 추가하기)

TM1637-master.zip


TM1637 Grove 제품의 경우 핀배열이 Catalex 사와 같을 거예요.  하지만, 핀이 달려있는 위치가 다르니, 역시 핀배열을 잘 확인 하셔야 해요.  Grove 사 모듈을 뒤집어 보면 위에서 부터 GND, VCC, DIO, CLK 이런 순으로 되어 있을 거예요.  그럼 연결만 그 핀에 맞추어 제대로 하면 됩니다. 

그리고 제일 중요한 것, DIO핀과 CLK핀을 아두이노에 연결 한 핀 번호랑, 코드에서 적어준 번호와 일치해야 제대로 동작합니다. 


아래 아두이노 코드는 TM1637 Grove사에서 제공하는 테스트 프로그램 이에요.  아래 코드를 다운받아 핀번호 확인후 업로드해서 실행시켜 보세요.

TM1637_Grove.zip


  


반응형
반응형

【 아두이노에러잡기#3】 버튼 디바운싱 해결하기 (with LCD)


 아두이노 기초 단계에서, 버튼을 사용할 때 기계적 접점의 바운싱 문제 해결을 위해 하드웨어가 아닌 소프트웨어적으로 해결을 해보았습니다.  

여기에 LCD를 연결하면 디바운싱 루틴이 잘 작동하지 않는 사항이 있어, 
해결하는 과정을 영상을 통해 학습해보도록 하겠습니다.   

 간단히 해결 답만 제시해드릴 수도 있지만, 답보다 차근 차근 문제해결하는 능력을 기르는 것이 더 중요하기 때문에, 영상제작에 시간이 걸리지만 제작해서 올려 봅니다. 


▶ 참고 학습 :

   1. [아두이노 기초 #6] 채터링과 디바운스  ☜ (클릭)

  2. [아두이노 기초 #14] 문자LCD 제어 실습 ☜ (클릭)
  3. [아두이노 센서 #14] ...I2C LCD 사용하기 참조 ☜ (클릭)



▶ 트러블 현상 :

  디바운싱 루틴이 시리얼 모니터 창을 통해서는 잘 동작 되었지만, LCD를 연결하면, 잘 작동하지 않는 문제가 발생 하였다.
이에 LCD를 부착한 상태에서도 디바운싱 현상을 해결하고, LCD에 Push, Pull 버튼 표시도 원활히 하고자 한다.

 


▶ 트러블 슈팅 영상 

( 영상에서는 I2C 모듈이 있는 LCD를 사용하였구요, 

I2C 모듈이 없는 LCD 사용할 때는 헤더파일 선언과 객체를 그것에 맞게 적어주시면 되구요, 나머지 부분은 영상과 똑같이 작성하면 됩니다. ) 


(전체화면 보기로 보세요)



아두이노 프로그램 설명


#include <Wire.h>                    //  LCD 관련 추가

#include <LiquidCrystal_I2C.h>     //  LCD 관련 추가

LiquidCrystal_I2C lcd (0x27, 16,2); //  LCD 관련 추가

#define BUTTON 2            // 버튼 입력 핀

#define bounceTimer 50     // 바운싱 카운트를 작게 줄일 것!

u8 keyState = HIGH;          // 버튼의 상태 저장용 변수

u8 bounceCount = 0;         // 바운스 변수 선언


void setup() {

  pinMode(BUTTON, INPUT);  // 버튼(핀)을 입력으로 설정

  digitalWrite(BUTTON, HIGH); 

  Serial.begin(9600);           // 시리얼 통신 시작

  lcd.begin();                   //  LCD 관련 추가

  lcd.clear();                    // LCD 관련 추가  

  lcd.setCursor(0,0);           // LCD 관련 추가

  lcd.print("RasINO Button!"); // LCD 관련 추가

}


void loop() {

  lcd.setCursor(0,1);

  u8 key = digitalRead(BUTTON); // 버튼값 읽어 key변수에 저장

  if(key == LOW)  {                //버튼이 눌러졌다면

    if(keyState == HIGH) {      // 이전의 버튼 상태가 떨어졌다면

          if(bounceCount == 0) { 

            bounceCount = bounceTimer;

            Serial.println("Push"); 

            lcd.print("Push");      // LCD 관련 추가

            keyState = key;

          }  else {

              bounceCount --;  //  바운스 카운트 값 감소

          }      }    }    

   else{                          // 버튼이 안 눌러졌었다면

    if(keyState == LOW)  {    // 이전의 상태가 눌린 상태였다면

      Serial.println("Pull");     // 버튼을 놓은(Pull) 것임     

      lcd.print("Pull");         // LCD 관련 추가

      keyState = key;   }     // 놓은(Pull)버튼 상태 저장.

  }  

}



▶ 아두이노 파일다운 :

(다운받아서 압축을 풀어 사용하세요)

debounceLCD.zip




【 LCD관련 에러나 동작이 안 될 때 】

 LCD관련한 라이브러리 에러나 코드 에러에 대한 안내를 드립니다.  

 크게 아래와 같은 두 가지 형태를 보이는데요, 


▶ 1. 코드를 실행하기전 LiquidCrystal_I2C.h: No such file or directory 에러라고 뜨는 경우!


 이때는 LCD 헤더파일이 설치가 되어 있지 않았을 경우입니다.  아예 관련 라이브러리(해더 파일)가 설치 되지 않은 경우입니다. 

해결법은 바로 아래에 첨부한 라이브러리를 다운받아 압축을 풀지 말고 라이브러리 관리 메뉴에서  .zip 라이브러리 추가 메뉴를 이용해서 추가해주세요.

경로 :  아두이노IDE >  스케치 》 라이브러리 포함하기  .zip 라이브러리 추가...  "다운받은 라이브러리파일 선택"


▶ 2. 또 한가지 LCD관련 에러는 ,  no matching function for call to ‘LiquidCrystal_I2C::begin();   라고 뜨는 경우!

 라이브러리 파일도 똑같은 이름이지만, 제공자에 따라 내부코드가 다른 라이브러리인 경우가 종종 있어요.  그래서 만약 제가 실험에서 사용한 라이브러리가 아닌,  같은 이름이지만 다른 라이브러리를 사용할 경우 위와 같은 에러 표시를 낼 수 있습니다.    라이브러리는 분명 설치되어 있지만 그래서 프로그램이 인지는 하는데, 코드에서 사용한 함수 적용이 되지 않을 때 이런 에러를 띄우게 됩니다.    그럼, 해결책은 실험에 사용한(적용한) 그 라이브러리를 다시 설치해 주어야 하는데요,   이 때 중요한 것은 아두이노에서는 똑 같은 이름의 라이브러리가 두 개 설치될 경우 또다른 중복에러를 띄우게 됩니다.   그러니 잘 못 설치된 라이브러리는 찾아서 반드시 삭제하거나,  다른이름으로 임시 변경해 놓거나,  나중에 다른 프로그램에서 사용해야 할 경우를 대비해서 압축해 놓고 원본은 지워 놓으면 됩니다. 


 그럼 기존 라이브러리를 찾아서 삭제를 하거나 하려면 설치된 라이브러리를 찾아야 겠죠? 

찾는 위치는 보통 아래 두 곳입니다.  (윈도우10 기준이며, 윈도우7도 비슷한 위치) 


두 곳으로 나뉘어 설치되는 이유는 아두이노 IDE의 "라이브러리 관리 메니저" 창을 통해 검색으로 설치되는 기본위치가 있고(아두이노 설치된 경로),   '.zip 라이브러리' 추가로 설치되는 위치가(도큐멘트 문서 저장영역-Doucuments) 따로 있어서 그렇습니다. 


< .zip 라이브러리 추가 메뉴에서 추가한 라이브러리 설치 위치 >

 1. C:\Users\유저-이름\Documents\Arduino\libraries    


 <라이브러리 관리 메뉴창에서 라이브러리 직접 검색으로 설치된 라이브러리 위치 >

 2. C:\Program Files (x86)\Arduino\libraries


위 두 곳에서 찾아서 삭제를 하세요.   (그냥, 폴더 째로 삭제하면 됩니다.)

 그리고 아래 첨부하는 라이브러리를 다운받아  압축파일 그대로 .zip 라이브러리 추가 메뉴로 추가해 주세요. 

만약, 압축파일 그대로 추가할 때 에러가 난다면,  앞축을 풀고  xxxxx.h 가 있는 폴더만 "C:\Users\유저-이름\Documents\Arduino\libraries" 경로에 붙여넣기 하면 됩니다.    이때 아두이노 스케치 IDE는 모두 닫고 재실행 해야 적용 됩니다.


 본 예제에서 사용한 라이브러리 다운로드 받기 :

Arduino-LiquidCrystal-I2C-library-master.zip



  ※ 중요! : 여기에서 제시된 코드로 작성할 경우 반드이 이 라이브러리로 설치하셔야 합니다.   만약, 여러분의 PC에 똑 같은 이름의 라이브러리가 있을 경우 반드시 삭제를 하거나 압축해서 백업을 해 놓으면 충돌이 일어나지 않습니다.!!!

반응형
반응형

【 아두이노모듈#8】 DS1307 (RTC) 리얼타임클럭 모듈 배우기 #1


 지난시간 TM1637 FND 모듈로 시계를 만들어 보았다. 하지만 오차가 0.001 초만 나더라도 시간이 갈 수록 시간 오차가 커질 것이다. 이문제를 해결하기 위해서 좀더 정밀한 클럭을 지닌 RTC 모듈에 시간값을 동기화 시켜서 사용하게되는데,  오늘은 시계를 구성하기에 앞서 이 RTC 모듈에 대해 알아보도록 하자. 



▶ 선수 학습 :

   없음.


▶ DS1307 세부 스팩 



※ .라이브러리 다운로드

 - DS1307RTC:https://github.com/PaulStoffregen/DS1307RTC

 - RTClib : https://github.com/adafruit/RTClib  


  RTC(리얼 타임 클럭) 모듈은 DS1307과 DS3231 두 종류가 많이 사용된다. 두 모듈의 차이는 DS3231 모듈의 오차가 1년에 수분 정도로 조금 더 정밀도가 높아 진 것인데, DS1307을 사용해도 큰 오차가 나는 것이 아니기에 걱정말고 사용해보자.
(DS1307 : 한 달 약 5분 미만,  DS3231 : 1년 약 5분 미만 오차)


【 RTC 모듈 시계의 구동원리 】 

: 시계를 만들때 현재의 시간을 맞추어 주어야 하는데, RTC를 가지고 PC와의 시간을 동기화 시키면,그 시간이 RTC모듈의 메모리에 저장되며, 모듈에 있는 베터리로 인해 시계회로에 공급되는 전원이 차단 되어도 메모리에 저장된 기준시간은 유지된되게 된다.  시계회로에서는 이 RTC 모듈에서 보통 1초마다 현재 시간값을 가지고와서 출력(사용)하게 된다. 



▶ 실습 목표 :  

  1. [ RTC 모듈에 대해 이해할 수 있다. 

 2. [ PC의 현재 시간을 RTC모듈에 동기화 시킬 수 있다.]

 3. [ 동기화된 시간을 아두이노 IDE의 시리얼 모니터 창을 통해 출력할 수 있다. ]

 4. [ 2019/3/15(날짜)와 14:49:12(시간) 형태로 출력해 볼 수 있다. ]



▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)



▶ 실습 절차  : 


1.   필요한 라이브러리 등을 '라이브러리 매니저'등을 통해서 설치한다. ( <RTClib.h> , <Wire.h>  )

2.   i2c 통신을 이용하는 모듈이기 때문에 <Wire.h> 라이브러리가 필요하며, 비교적 연결이 간단하고 쉽다.  브레드보드 없이 직접 연결이 가능하지만, 추후에 FND모듈을 함께 연결하려면 , 필요할 수 있으니 브레드보드를 사용해서 연결해본다. 
3. 시리얼모니터를 통해 설정된 날짜와 시간값을 확인하게 되는데, 에러가 날 경우에는 통신속도(보드레이트)를 서로 같도록 맞추어 주었는지 확인하도록 한다.  


▶ 프로그램 코드 및 설명 : 


/* RTC 모듈에 PC를 이용하여 현재의 일시를 동기화 하기 */


#include <RTClib.h> // RTC 기본 라이브러리

#include <Wire.h>   // i2c 통신 라이브러리

RTC_DS1307 RTC;    // RTC클래스 생성


void setup ( ) {

Serial.begin(9600);  

Wire.begin();

RTC.begin();

RTC.adjust(DateTime(__DATE__,__TIME__));

//연결된 pc의 현재시간을 RTC모듈 기억소자에 동기화 함

//위 동기화 명령라인은 처음 한 번만 실행하고 하고 이후로는 주석처리

}

void loop ( )  {

DateTime now=RTC.now(); // RTC에 저장된 값을 불러옴

// 시리얼 모니터창에 아래의 형식으로 출력함

Serial.print(now.year(), DEC); 

Serial.print('/'); 

Serial.print(now.month(), DEC); 

Serial.print('/'); 

Serial.print(now.day(), DEC); 

Serial.print(' '); 

Serial.print(now.hour(), DEC); 

Serial.print(':'); 

Serial.print(now.minute(), DEC); 

Serial.print(':'); 

Serial.print(now.second(), DEC); 

Serial.println(); 

delay(1000);    //1초마다 현재의 일시를 모니터로 출력.

}


▶ 참고 자료 :  

 없음.

▶ 실행영상 :  

(전체화면 보기로 보세요)



▶ 아두이노 파일다운 :

(다운받아서 압축을 풀어 사용하세요)


반응형
반응형

【 아두이노 센서#26】 IR 적외선 센서 거리 LED 레벨바 만들기

 지난 시간 적외선(IR) 센서인 GP2Y0A41SK의 기본 사용법에 대해 알아 보았다. 이번 시간에는 거리에 따른 LED 레벨바를 만들어 보려 한다.  과거 LED Latch 회로를 다루어 보았는데 IR 센서와 연결하면 간단히 구현가능하다. 


▶ 선수 학습 :

1. (센서)#9 시프트 레지스터 이해하기 1 (Latch 회로이해1 강좌보기클릭  2(센서)#10 나이트라이더 만들어보기 (Latch 회로이해2)   강좌보기클릭  
3(센서)#25 IR적외선 센서 다루기     (IR 센서 기초)     강좌보기클릭  


▶ IR 센서 사양 및 동작 특성


▶ 실습 목표 :  

1. IR 센서의 작동 방식에 대해 이해하고 응용할 수 있다.

2. 센서로 부터 얻어 지는 아날로그 값을 디지털값 및 전압값으로 바꾸어 거리값으로 환산할 수 있다.

3. 얻어진 거리값을 시리얼 모니터와 LED로 표시할 수 있다. 

4. 시프트 레지스터 기능(74HC595) IC를 이용하여 거리에 따라 LED가 켜지도록 레벨바 형태를 구현 할 수 있다.


▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)



▶ 실습 절차  : 


1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    앞선 실습 자료를 참고하여 IR센서로 부터 측정되는 값을 확인 한다음, LED 레벨이 반응하기 원하는 수치값(거리)의 최소값과 최대값을 정한다.(maxVal값  , minVal 값)
3.    프로그램을 동작시켜보고 maxVal값과 minVal값을 조절해 본다.

4.   가까울 수록 LED레벨이 켜지는 것을 멀수록 LED레벨이 켜지도록 프로그램을 수정해본다. 

▶ 프로그램 코드 및 설명 : 

/* 적외선 센서 (IR sensor) LED 레벨바 응용 프로그램       */
/*  by RASIno , http://rasino.tistory.com  */

const int SER=8;   // 시프트 레지스터로 데이터를 입력하는 8번 핀 SER 상수 정의

const int LATCH=9;  //LATCH LATCH 상수 정의

const int CLK= 10;  //CLOCK CLK 상수 정의

const int DIST=0; //아날로그 입력 0번 핀에 연결된 IR 센서의 장애물 거리값

 //LED 거리값 패턴을 저장한 vals 배열 정의

int vals[9]={0,1,3,7,15,31,63,127,255};

int maxVal=600; //IR 센서의 장애물 거리 최대값

int minVal=260;   //IR 센서의 장애물 거리 최소값

//###  IR 센서의 최대, 최소값은 실제 측정해보고 원하는 값으로 수정 필요


void setup( ) {

  Serial.begin(9600); //  시리얼 통신 시작

  pinMode(SER, OUTPUT);

  pinMode(LATCH, OUTPUT);

  pinMode(CLK, OUTPUT);

}


void loop( ) {

  int distance=analogRead(DIST);  //IR 센서에서 장애물 거리값을 읽음

  Serial.println(distance);          // 시리얼 모니터로 IR값을 확인해 본다

  distance=map(distance, minVal, maxVal, 0, 8);

  distance=constrain(distance,0,8); //거리값 범위 조정

  digitalWrite(LATCH,LOW);  //LATCHLOW 입력

  shiftOut(SER, CLK, MSBFIRST, vals[distance]); //거리값에 맞는 데이터전송

  digitalWrite(LATCH, HIGH);  // 거리에 따라 LED가 켜지도록 High 입력함

  delay(10);     // 센서가 장애물을 감지하는 시간 간격 지정

}


▶ 실행영상 :  

(전체화면 보기로 보세요)


▶ 아두이노 파일(실습1. 다운) :

Latch_IR_Sensor.ino


반응형
반응형

【 아두이노 센서#25】 IR 적외선 센서 다루기 ( GP2Y0A41SK )


 대표적인 적외선(IR) 센서인 GP2Y0A41SK를 알아보고 거리값을 시리얼 모니터를 통해 출력해보고자 한다. 


▶ IR 센서 사양 및 동작 특성

위 그래프는 목적물과의 거리에 따른 출력 신호와의 관계 그래프이다.

거리가 4Cm에서 부터 최고치의 출력을 보여주고 있으며, 거리가 멀수록 신호의 출력값은 그래프 처럼 낮아 진다. 또한 목표물의 색이 회색일(어두운색) 경우 반사율이 18%로 낮지만 흰색일수록(가까울 수록) 반사율이 90%로 높다는 것을 알 수 있다.  


▶ 실습 목표 :  

1. IR 센서의 작동 방식에 대해 이해할 수 있다.

2. 센서로 부터 얻어 지는 아날로그 값을 디지털값 및 전압값으로 바꾸어 거리값으로 환산할 수 있다.

3. 얻어진 거리값을 시리얼 모니터와 LED로 표시할 수 있다. 


▶ 실습 회로도면 1 (기본회로):
  (이미지 클릭하면 확대 가능)


▶ 실습 1  : 


1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    DC센서의 아날로그 출력 값에 A/D변환(아날로그를 디지털로)을 위한 값인 '5/1024' 를 곱해준다.(디지털화 된 전압값이 된다) 

3.    디지털 전압값이 나오면 아래 식에 삽입하여 거리값을 구한다.
 (※ 거리값 : 13 x pow(volts, -1)  )

4.   물체와의 거리가 30cm 이하일 때만 시리얼 모니터로 출력 하도록 하다.

▶ 실습1. 프로그램 코드 및 설명 : 

/* 적외선 센서 (IR sensor) 프로그램       */
/*  by RASIno , http://rasino.tistory.com  */

 // 물체와의 거리가 30cm 이하 일 때만 시리얼 모니터로 거리값을 표시하라


#define sensor A0   //  IR 센서의 입력 포트 정의



void setup( )  {

  Serial.begin(9600); //  시리얼 통신 시작

}


void loop( ) {



Serial.print("1.sensor:");  

    Serial.println(analogRead(sensor));  

// A/D 값 변환을 위한 5/1024(분해능)을 곱해준다

    float volts = analogRead(sensor) * 0.0048828125; 


    Serial.print("2.volts:");  

    Serial.println(volts);  

    int distance = 13 * pow(volts, -1); // pow(x,y):x의 y승

    Serial.print("3.distance:");  

    Serial.println(distance);  


  delay(1000);         // 응답시간을 고려하여 시간지연 한다

  if (distance <= 30) {

    Serial.println(distance); 

  } 


}


▶ 실습1. 실행영상 :  

(전체화면 보기로 보세요)



▶ 아두이노 파일(실습1. 다운) :

IR_distance.ino



▶ 실습 회로도면 2 (확장회로):
  (이미지 클릭하면 확대 가능)

 ※ 센서의 선구분은 색깔로 구분하기 쉽다. LED는 기본적으로 저항을 달아주어야 하나, 장시간이 아닌 간단히 테스트 하는 용도로 사용할 때는 그냥 연결하여도 크게 문제가 되지 않는다. 


▶ 실습 2  : 


1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    센서값이 500이상 일때 LED를 끄도록 하고, 40~500 사이 값일 때 아두이노 포트로 출력 조절 가능한 값인 255~0 사이 값으로 맵핑 처리 한다. map(sensor, 40, 500, 255, 0);

3.    LED를 통해 이를 확인하도록 한다. 


▶ 실습2. 프로그램 코드 및 설명 : 

/* 적외선 센서 (IR sensor) 프로그램       */
/*  by RASIno , http://rasino.tistory.com  */

 // 물체와의 거리가 30cm 이하 일 때만 시리얼 모니터로 거리값을 표시하라


const int sensorPin = A0;

const int ledPin = 12;

int sensor = 0;

int value = 0;


void setup( )  {

  Serial.begin(9600);     //  시리얼 통신 시작

  pinMode(ledPin, OUTPUT);

}


void loop( ) {

  sensor = analogRead(sensorPin);

  if (sensor != value) {

    Serial.println(sensor);

 

    value = sensor;

    if (sensor < 40) return;

    if (sensor > 500) {

      digitalWrite(ledPin, LOW);

    } else {

      sensor = map(sensor, 40, 500, 255, 0);

      analogWrite(ledPin, sensor);

    }

  }

  delay(500);

}


▶ 아두이노 파일(실습2. 다운) :

02_IR_LED02.ino


반응형
반응형

【 아두이노 Proj#2】 라인트레이서 자동차 만들기 L298N모듈)

 

 적외선 센서를 이용하여 바닥에 그려진 라인을 따라 이동하는 RC카를 만들어 보자. 

 

▶ 선수 학습 :

1. (기초) #24 DC 모터 제어 하기 4 (L293 & H브릿지 참고 강좌 클릭
2. (센서) #2 적외선(근접)센서 TCRT5000(TCRT5000 참고 강좌 클릭
3. (센서) #24 L298N 모터 모듈활용한... (L298N 모듈 참고 강좌 클릭   
4. (응용) #1 초음파센서로 자동차 만들기 (자동차 구동이해)  강좌 클릭

 

▶ 라인트레이서 완성 모습

 

▶ 라인트레이서 동작 원리

 

 이와 같은 센싱 역할을 하는 센서가 바로 아래 소개 되는 TCRT5000센서이며 이를 사용하기 편하게 모듈화 한 것이다.

 

▶ 실습에 사용되는 부품 스팩 ( TCRT5000)

 

 TCRT 5000은 적외선 방식이어서 적외선 센서로 불리지만, 가깝고 짧은 거리에 사용되기 때문에 근접센서로도 불린다. 

 TCRT 5000 모듈의 상세한 사용 설명은 선수학습 '2.번'을 참고 

 

 

▶ 실습에 사용되는 부품 스팩 ( L298N ) 

 

 모터 모듈의 상세한 사용 설명은 선수학습 '3.번'을 참고
 
 

▶ 실습 목표 :  

1. L298N 모듈에 대해 이해하고 모터를 연결하여 사용하는 방법에 대해 익힌다.

2. 적외선 센서(TCRT5000)의 작동방식과 활용하는 법을 익힐 수 있다.

4. 검은색 라인위를 따라 이동하는 라인트레이서 로봇을 구현할 수 있다. 

 

 

※ 전원 공급은 건전지를 사용할 수도 있지만 , 요즘 많이 보유하고 있는 휴대폰보조베터리를 사용해도 된다.  소형 보조 베터리 사용시 장점은, 건전지보다 장시간 플레이가 가능하며, 언제든 손쉽게 재충전이 가능하여 건전지 교체비용을 줄일 수 있다. 

 

▶ 실습 회로도면 1 (기본회로):

  (이미지 클릭하면 확대 가능)

※ 주의!! 위 이미지에서 아두이노에 연결된 붉은 선이 5V가 아니라 Vin으로 연결 되어야 합니다!!!

※ 실습회로 도면 1에 보면, 9V 건전지는 아두이노쪽에 전원공급용으로 쓰였구요. L298N모듈에 보면, +5V~(모터, 별도전원) 이라고 되어 있는 부분에는 5V이상 되는 전원을 따로 넣어(연결) 주라는 의미에요.   
그래서, 건전지를 두 개(가지) 사용해야 모터가 잘 돌아갑니다. 

 

▶ 실습 회로도면 2 (확장회로):

  (이미지 클릭하면 확대 가능)

 

 ※ 기본 회로로 동작이 확인 되면 위 그림 처럼 마치 자동차의 헤드램프 처럼 라이트가 들어오도록 LED와 저항을 추가 할 수 있으며, RC카의 전원을 켜고 끄기 쉽도록 슬라이드 스위치를 달아 놓았다.  (토글 스위치를 사용하여도 무방)

 

▶ 회로 연결 쉽게 따라하기 (영상) :

 

(영상을 확대해서 플레이해서 보세요)

 

 

▶ 실습 절차  : 

 
1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    DC 모터의 연결선 방향은 우선 연결 후 프로그램으로 작동시켜보고 방향이 반대가 될 경우 다시 바꾸어 연결하면 된다.
3.    만약 가지고 있는 모터의 용량이 비교적 클 경우 아두이노 전원만으로는 동작이 어려울 수 있으니 회로도에서 처럼 별도 전원을 인가해주면 동작이 잘 될 것이다. (※ 모터 관련 회로에서 대부분의 동작 문제는 모터에 공급되는 전력이 충분치 않아 발생한다) 
 
5.   전원 하나로 아두이노와 DC모터를 포함한 L298모듈 둘 다를 돌리기에는 한계가 있다따라서 아두이노와 DC모터 모듈 전원을 각각 공급해주어야 하며이때 그라운드(GND) 공통으로 연결해주면 된다.  (속도가 빠르지는 않지만 휴대폰 보조베터리를 연결하면 하나의 전원으로 구동이 가능하다)
 
6.  모터 모듈 전원은 최소 5V이상, 모터용량에 따라 넣어 주면 되는데, 모터 구동에는 전압보다 전류가 중요한 역할을 하게 된다실험을 해보면모터모듈 전원으로 9V 베터리를 연결 할 때 보다, 1.5V X 4개 (6V)를 연결할 때가 훨씬 잘 동작될 것이다.(4개의 건전지에서 전류가 충분히 공급 되기 때문)
7.   TCRT5000 센서 동작에 문제가 있다면, 센서에 달려 있는 가변저항을 소형드라이버 등으로 돌려서 측정가능한 거리값을 조절 해보기 바란다. 
8. '라인'은 방바닥에 두툼한 검정색 혹은 짙은색 (종이)테이프 등으로 모양을 만들어도 잘 작동한다.
 
 

 

 

▶ 프로그램 코드 및 설명 : 

/* 라인트레이서(Line Tracer) 프로그램       */
/* by RASIno , http://rasino.tistory.com  */


#define IN1 8#define IN2 9#define IN3 10#define IN4 11int leftLineSensor =  12;      // 라인트레이서 왼쪽 센서

int rightLineSensor = 13;      // 라인트레이서 오른쪽 센서

 

void forward() {      // 

전진 : 모터 두 개를 모두 정회전 시킴

      digitalWrite(IN1, HIGH);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, HIGH);

      digitalWrite(IN4, LOW);    }

 

void back() {         // 

후진 : 모터 두 개를 모두 역회전 시킴

      digitalWrite(IN1, LOW);

      digitalWrite(IN2, HIGH);

      digitalWrite(IN3, LOW);

      digitalWrite(IN4, HIGH);   }

 

void left() {         // 

좌회전 : 오른쪽 모터만 정회전 시킴

      digitalWrite(IN1, LOW);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, HIGH);

      digitalWrite(IN4, LOW);  }

 

void right() {      // 

우회전 : 왼쪽 모터만 정회전 시킴

      digitalWrite(IN1, HIGH);

      digitalWrite(IN2, LOW);

 

      digitalWrite(IN3, LOW);

      digitalWrite(IN4, LOW);   }

 

void stop() {       // 

정지 : 2개의 모터 모두 회전 멈춤

      digitalWrite(IN1, LOW);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, LOW);

 

      digitalWrite(IN4, LOW);  }

 

void setup( )  {

  pinMode(IN1, OUTPUT);     // A 모터 1

  pinMode(IN2, OUTPUT);     // A 모터 2

  pinMode(IN3, OUTPUT);     // B 모터 1

  pinMode(IN4, OUTPUT);     // B 모터 2

  pinMode(leftLineSensor, INPUT);

  pinMode(rightLineSensor, INPUT);  

}

 

void loop( ) {

 

// 만약 양쪽 센서가 모두 선 미감지’(반사신호’OK’) 경우 : 전진

if (!digitalRead(leftLineSensor) && !digitalRead(rightLineSensor)) {

  forward();  

 }  

 

// 만약 왼쪽 센서만 선감지(반사신호X)’ 경우 :  좌회전

else if (!digitalRead(leftLineSensor) && digitalRead(rightLineSensor)) {

  left();  

 }   

 

// 만약 오른쪽 센서만 선감지(반사신호X)’ 경우 :  우회전

else if (digitalRead(leftLineSensor) && !digitalRead(rightLineSensor)) {

  right();

 } 

 

  // 만약 양쪽 센서 모두 선감지(반사신호X)’ 경우 :  정지

else if (digitalRead(leftLineSensor) && digitalRead(rightLineSensor)) {

 

  stop();  

 } 

 

}

◈  모터 A, B가 동시에 시계방향으로 돌면 전진, 반시계 방향이면 후진이고, 
한 쪽바퀴만 돌리거나 두 개의 바퀴를 서로 반대로 돌리면 좌회전 혹은 우회전이 된다.  

 이를 함수 형태로 만들고 메인 루프에서 적절히 함수들을 호출해서 사용하도록 하였다.  라인트레이서의 동작을 좀더 다양하게 꾸밀 수 있는데, 바닥의 라인에 따라 되돌아 나오기 등등 여러 형태로 프로그래밍 해 볼 수 있다. 

▶ 실행영상 :  

(전체화면 보기로 보세요)

 

 

 

 

 

 

 

 

▶ 아두이노 파일(다운) :

LineTracerRC-CAR.ino
다운로드

 

 

▶ 동작이 안 될 때 :

아래 사항을 하나씩 살펴보세요. (위 글 내용에도 강조했지만 다시 정리해드리면)

 

1. 회로 연결을 꼼꼼하게 한번더 살펴 보세요. 분명 회로도 보고 하셔도 어디 한 두 군데 잘못연결되면 동작되지 않습니다. 

2. 모터가 들어가는 회로에서 모터 동작이 이상하거나 잘 안되는 원인의 대부분은 전력부족이에요.   전력 중에서도 전류가 충분하게 공급되어야 하죠. (전압보다 전류가 더 중요해요)

실습회로 도면 1에 보면, 9V 건전지는 아두이노쪽에 전원공급용으로 쓰였구요. 
L298N모듈에 보면, +5V~(모터, 별도전원) 이라고 되어 있는 부분에는 5V이상 되는 전원을 따로 넣어(연결) 주라는 의미에요.   그래서, 건전지를 두 개(가지) 사용해야 아마 제대로 돌아갈 거예요. 

건전지 하나로는 보통 겨우 겨우 돌아가거나 제대로 안 돌아 갈 수 있어요. 

그리고, 9V 건전지는 전압은 높아보이지만 전류가 약한 타입이라서 아두이노 본체 전원으로는 좋은데, 모터쪽 전원으로는 부적합해요.  그래서 모터쪽 전원으로는 AA(1.5V)건전지 4개를 직렬연결해서 6V정도로 만들어 공급해주면 좋구요,  아니면, 18650(3.7V) 두 개를 직렬(7.4V) 연결한 걸 공급해주면 됩니다.  얘네들은 전류가 쎈 건전지라서 모터가 잘 돌아가요. 

그리고, 스위치를 추가한 회로 도면 2번(확장회로)에도 1번과 같이 모터쪽 전원과 따로 분리해서 전원을 이중으로 넣어주면 됩니다.

반응형
반응형

【 아두이노 Proj#1】 초음파센서로 자동차 만들기 L298N모듈)

 지난 시간 L298모터 드라이버 모듈을 활용하여 초음파 센서에 반응하여 모터를 구동시키는 실습을 해보았다. 이제 본격적으로 초음파 센싱으로 작동되는 자동차를 만들어보려 한다.  또한 초음파 센서쪽에 서보모터를 부착하여 좌우의 장애물의 유무를 파악하여 장애물이 없는 쪽으로 움직일 수 있도록 하였다. 

▶ 선수 학습 :

1. (기초)#24 DC 모터 제어 하기 4 (L293 & H브릿지 참고)   강좌보기클릭  2(기초)#28 서보(Servo) 모터 제어 하기 1 (서보모터이해)    강좌보기클릭  3(기초)#29 서보(Servo) 모터 제어 하기 2 (서보모터이해)    강좌보기클릭  
4. (센서)#24 초음파센서 경보회로with LCD (초음파 센서이해)    강좌보기클릭


▶ 실습에 사용되는 부품 스팩 ( L298N ) 

 모터 모듈의 상세한 사용 설명은 선수학습 4.번을 참고


▶ 실습 목표 :  

1. L298N 모듈에 대해 이해하고 모터를 연결하여 사용하는 방법에 대해 익힌다.

2. L298N 드라이버 모듈에 별도의 전원이 필요한 경우에 대해 이해 할 수 있다. 

3. 초음파 센서를 비롯한 센서의 신호를 체크하여 N298모듈에 연결된 모터들을 제어 할 수 있다. 

4. 초음파로 장애물을 확인하고 회피기동 프로그램을 작성하여 스스로 움직이는 RC카처럼 구성해볼 수 있다. 


▶ 실습 회로도면 (서보모터 부착회로):

  (이미지 클릭하면 확대 가능)

 ※ 아두이노에 공급되는 전원과 별도로 모터에도 전원을 인가해주면 좋을 것이다.(단일 전원 구성도 가능하나, 바퀴가 힘있게 굴러가지 못하고 작동시간도 매우 짧기 때문에 모터 구동(모듈)쪽에 별도의 전원을 넣어 주는 것이 좋다) 


※ DC(직류) 방식의 모터는 작은 용량(소비전력이 낮은)의 것을 사용하면 되며,  기어가 포함된(기어드) DC 모터를 사용한다면 아두이노의 작은 출력으로도 충분히 제어가 가능하다. 만약 회로연결과 아두이노 프로그램에 문제가 없는데도 동작이 되지 않는 다면, 공급전력에 비해 너무 큰 용량의 DC 모터가 연결된 경우 일 수 있으니,  이런 부분들을 확인 해보면 될 것이다. 이때, 모터드라이버 모듈에 별도의 전원을 넣어주면 해결될 수 있다. 인가 가능한 전원은 5V~36V 사이값 이므로 이를 고려하여 모터를 선택하면 된다.



▶ 실습 절차  : 

1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    DC 모터의 연결선 방향은 우선 연결 후 프로그램으로 작동시켜보고 방향이 반대가 될 경우 다시 바꾸어 연결하면 된다.
3.    만약 가지고 있는 모터의 용량이 비교적 클 경우 아두이노 전원만으로는 동작이 어려울 수 있으니 회로도에서 처럼 별도 전원을 인가해주면 동작이 잘 될 것이다. (※ 모터 관련 회로에서 대부분의 동작 문제는 모터에 공급되는 전력이 충분치 않아 발생한다) 

5.   전원 하나로 아두이노와 DC모터를 포함한 L298모듈 둘 다를 돌리기에는 한계가 있다따라서 아두이노와 DC모터 모듈 전원을 각각 공급해주어야 하며, 이때 그라운드(GND) 공통으로 연결해주면 된다.

6.  모터 모듈 전원은 최소 5V이상, 모터용량에 따라 넣어 주면 되는데, 모터 구동에는 전압보다 전류가 중요한 역할을 하게 된다실험을 해보면, 모터모듈 전원으로 9V 베터리를 연결 할 때 보다, 1.5V X 4(6V)를 연결할 때가 훨씬 잘 동작될 것이다.(4개의 건전지에서 전류가 충분히 공급 되기 때문)
7. 서보모터는 180도 왕복 회전할 수 있는 것을 사용한다.
8.   초음파 센서에 손이나 장애물을 대어 보아서 모터제어가 잘 되는지 확인한다.

▶ 프로그램 코드 및 설명 : 

/*  L298N 모터 모듈을 활용한 초음파 센서 제어 회로 */

int distance;             /*  초음파센서로 모터제어 하기  */

int triggerPin = 13;

int echoPin = 12;

#define IN1 8  // L298모듈의 제어 신호 입력 핀 번호 지정

#define IN2 9

#define IN3 10

#define IN4 11

float distance;          // 초음파 센서 거리값 변수

int servoPin = 2;     // 서보모터 연결 포트

Servo servo;


void forward() {      // L298 제어용 전진 함수

      digitalWrite(IN1, HIGH);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, HIGH);

      digitalWrite(IN4, LOW);    }


void back() {         // 후진

      digitalWrite(IN1, LOW);

      digitalWrite(IN2, HIGH);

      digitalWrite(IN3, LOW);

      digitalWrite(IN4, HIGH);   }


void left() {         // 좌회전(왼쪽모터 멈춤:오른쪽모터 전진)

      digitalWrite(IN1, LOW);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, HIGH);

      digitalWrite(IN4, LOW);  }


void right() {      // 우회전(왼쪽모터 전진:오른쪽모터 멈춤)

      digitalWrite(IN1, HIGH);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, LOW);

      digitalWrite(IN4, LOW);   }


void stop() {       // 정지

      digitalWrite(IN1, LOW);

      digitalWrite(IN2, LOW);

      digitalWrite(IN3, LOW);

      digitalWrite(IN4, LOW);  }


void setup( )  {

  Serial.begin(9600);

  pinMode(triggerPin, OUTPUT);  // 트리거 핀을 출력으로 설정

  pinMode(echoPin, INPUT);          // 에코 핀을 입력으로 설정

  servo.attach(servoPin);               // 서보모터 연결 지정

  servo.write(90);                            // 초기값으로 정면 응시

  delay(1000);               

}


float getDistanceCM() {      // 초음파 센서 거리 측정 함수(단위:cm)

  digitalWrite(echoPin, LOW);

  digitalWrite(trigPin, LOW);

  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);

  delayMicroseconds(10);

  digitalWrite(trigPin, LOW); 

  distance = pulseIn(echoPin, HIGH)  / 58;  //거리값 계산 후 저장

  return distance;

}


// 거리값 정확도를 위한 평균치 계산 함수(1회이상~ 10회미만으로 조정해보기)

float getStableDistanceCM() {

  int CmSum = 0;

  for (int i = 0; i < 8; i++) {

    CmSum += getDistanceCM();  //, 'sum = sum + cm' 동일

   }

  return CmSum / 8;

}


void loop( ) {

   if ( getStableDistanceCM() < 25 ) {  // 25cm이하 장애물 감지

         stop();

         delay(300);     
         servo.write(180);      // 서보모터 좌회전 후 측정 거리값 변수에 저장     

        delay(500);

        int leftDistance = getStableDistanceCM();

        delay(300);

        servo.write(0);           // 서보모터 우회전 후 측정 거리값 변수에 저장

        delay(500);

        int rightDistance = getStableDistanceCM();

        delay(300);

        servo.write(90);        // 서보모터 중앙으로 원위치

        delay(500);

        back();                         // 0.5초간 후진

        delay(500);

       if (leftDistance > rightDistance {

           left();

       } else {

          right();
       } 

      delay(500);

  }   else {                            // 장애물 감지가 안 될 경우 전진

      forward();

      }

   }

◈  모터 A, B가 동시에 시계방향으로 돌면 전진, 반시계 방향이면 후진이고,

  한쪽바퀴만 돌리거나 두 개의 바퀴를 서로 반대로 돌리면 좌회전 혹은 우회전이 된다.   이를 함수 형태로 만들고 메인 루프에서 적절히 함수들을 호출해서 사용하도록 하였다. 또한 거리값을 계산하는 부분을 함수로 만들었다(getDistanceCM()) , 그리고 얻어진 거리값을 초음파로 측정할 때 오류가 날 수 있기 때문에 1~8회 사이 몇 번 측정후 평균을 내면 편차가 큰 오류값은 걸러낼 수 있고 이를 함수로(getStableDistanceCM()) 만들었다.  

 위 프로그래밍에서는 기본 전진 기동을 하다가, 물체가 20cm 이내로 감지되면 정지를 시키고, 초음파 센서에 달린 서보모터를 좌, 우로 돌려보고 거리값을 각각 측정하여 물체가 없거나 물체와의 거리가 더 먼쪽의 방향으로 회전(좌회전 또는 우회전) 하도록 프로그래밍 한 것이다. 


▶ 실행영상 :  

(전체화면 보기로 보세요)


※ 자동차 몸체는 영상에 있는 것이 아니어도 좋다. 두 바퀴를 안정적으로 고정시킬 수 있는 몸체와 앞 뒤로 기울어지지 않게 볼캐스트(볼 베어링)를 종이박스나, 폼보드 등에 부착해서 직접 만들어도 된다. 


▶ 아두이노 파일(다운) :

UltraSonicRC-CAR_Servo.ino






반응형