반응형

【 아두이노에러잡기#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에 똑 같은 이름의 라이브러리가 있을 경우 반드시 삭제를 하거나 압축해서 백업을 해 놓으면 충돌이 일어나지 않습니다.!!!

반응형
반응형

【 아두이노 센서#29】 터치 LED센서( Heltec) Sensor 다루기 


 오늘은 Heltec 의 터치( Touch) LED 센서를 다루어 보고자 한다. 지난시간  터치 센서인 TTP223B를 다루어 보았는데, 이것과의 차이점은 터치 하였을 때 터치판 자체가 LED 불 빛을 내준다는 것이다. 미관적으로 좋고, 제품인테리어를 고려한 부품으로 사용해도 좋을 것이다. 


▶ 선수 학습 :

 없음. 

▶ IR 센서 사양 및 동작 특성




▶ 실습 목표 :  

1. 터치 LED 센서의 기본 작동 방식에 대해 이해하고 스위치 기능으로 사용 할 수 있다.

2. 터치 되었을 때 센서의 출력값을 LED 혹은 멀티테스터 등으로 확인 할 수 있다. 


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

▶ 실습 절차  : 


1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    터치 LED 센서만 연결하여 터치 되었을 때, 센서의 출력 값을 멀티 테스터기로 확인 해본다. . 
3.    LED를 별도로 넣어 LED센서가 터치되었을 때 출력을 LED로 확인 해본다. (센서의 출력 값 3.3v 를 이용한 LED 점등) 

▶ 프로그램 코드 및 설명 : 

/* 터치 LED 센서의 동작확인은 별다른 코드 없이  확인 가능하다.     */

▶ 실행영상 :  

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


1. 블루 불빛 LED 터치 센서의 터치시 출력 전압값을 멀티테스터 측정기로 확인.



2. 레드 불빛 LED 터치 센서의 터치 동작 확인 .



▶ 아두이노 파일다운 :

없음. 




반응형
반응형

【 아두이노 센서#28】 터치 센서( TTP223B) Touch Sensor 다루기 #2


 지난 시간에 이어 터치( Touch) 센서인 TTP223B를 다루어 보려고 한다. 이 터치 모듈은 정전식(사람의 몸에서 발생하는 작은 전기를 이용) 으로서 , 터치 되었을 때 칩 LED가 켜져 터치 되었다는 것을 알려주는 등 아주 사용하기 편하고 쉽다. 이번에는 LED를 13번포트에 직결하고 시리얼 플로터를 통해 터치가 되는지를 간단히 실험해보려 한다. 


▶ 선수 학습 :

 1. (센서)#27 터치센서다루기 #1 (TTP223B 터치센서 이해1 강좌보기클릭


▶ IR 센서 사양 및 동작 특성

▶ 실습 목표 :  

1. 터치 센서의 기본 작동 방식에 대해 이해하고 스위치 기능으로 사용 할 수 있다.

2. 터치 되었을 때 센서로 부터 얻은 값을 시리얼 모니터 혹은 시리얼 플로터 창을 통해 확인 할 수 있다. 

3. LED를 연결하거나 다른 출력으로 사용하여 기기를 작동시킬 수 있음을 이해한다.


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

▶ 실습 절차  : 


1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    시리얼 모니터 창을 열어 터치 유무에 따른 출력 값을 확인 한다. 
3.    시리얼 플로터 창을 열어 터치 유무에 따른 출력 그래프를 확인 한다.
4. LED를 13번포트(LED+단자) 와 인접한 GND(LED-단자)에 바로 직결 연결한다(LED 연결에는 기본적으로 저항을 연결하여야 하나, 이와 같은 회로에서는 아두이노는 충분히 보호된다)

▶ 프로그램 코드 및 설명 : 

/* 터치 센서 (Touch sensor) 사용하기 프로그램       */
/*  by RASIno , http://rasino.tistory.com  */


#define Touch 7  // 터치센서의 핀 정의


void setup( ) {

  Serial.begin(9600);

  pinMode(Touch, INPUT);

  pinMode(13, OUTPUT);  

}


void loop( ) {

  int a = digitalRead(Touch);

  if (a == HIGH) {   digitalWrite(13, HIGH);

    Serial.println(a);    

    delay(1);       // 최소한의 delay 값을 주도록 한다.

    }  else  {  

         digitalWrite(13, LOW);

         Serial.println(a);      

  }

}


▶ 실행영상 :  

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




▶ 아두이노 파일다운 :

TouchSensorLED.ino





반응형
반응형

【 아두이노 센서#27】 터치 센서( TTP223B) Touch Sensor 다루기 #1

 오늘은 터치( Touch) 센서인 TTP223B를 다루어 보려고 한다. 이 터치 모듈은 정전식(사람의 몸에서 발생하는 작은 전기를 이용) 으로서 , 터치 되었을 때 칩 LED가 켜져 터치 되었다는 것을 알려주는 등 아주 사용하기 편하고 쉽다. 


▶ 선수 학습 :

 없음. 

▶ IR 센서 사양 및 동작 특성

▶ 실습 목표 :  

1. 터치 센서의 기본 작동 방식에 대해 이해하고 스위치 기능으로 사용 할 수 있다.

2. 터치 되었을 때 센서로 부터 얻은 값을 시리얼 모니터 혹은 시리얼 플로터 창을 통해 확인 할 수 있다. 


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

▶ 실습 절차  : 


1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    시리얼 모니터 창을 열어 터치 유무에 따른 출력 값을 확인 한다. 
3.    시리얼 플로터 창을 열어 터치 유무에 따른 출력 그래프를 확인 한다.

▶ 프로그램 코드 및 설명 : 

/* 터치 센서 (Touch sensor) 사용하기 프로그램       */
/*  by RASIno , http://rasino.tistory.com  */


#define Touch 9  // 터치센서의 핀 정의


void setup( ) {

  Serial.begin(9600);

  pinMode(Touch, INPUT);

}


void loop( ) {

  int a = digitalRead(Touch);

  Serial.println(a);

  delay(1);   // 최소한의 delay 값을 주도록 한다.

}


▶ 실행영상 :  

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



▶ 아두이노 파일다운 :

TouchSensor.ino




반응형
반응형

【 아두이노 센서#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






반응형
반응형

【 아두이노 센서#24】 L298N 모터 모듈을 활용한 초음파센서 회로#1

 지난 시간까지 초음파 센서를 사용하여 LCD에 표시하는 방법들을 배웠다. 이번에는 초음파 회로에 L298모터 드라이버 모듈을 사용하여 모터가 초음파센서에 반응하는 실습을 진행해보려 한다. 


▶ 선수 학습 :

  1. #24 DC 모터 제어 하기 4 (L293 & H브릿지 참고)   강좌보기클릭

  2초음파 센서 경보회로 with LCD (초음파 센서이해)    강좌보기클릭


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

1. 12V 단자로 7V~35V를 공급할 경우 5V단자를 5V전원으로(출력) 사용할 수 있다.
2. 단 구동전압(모터)12V보다 클 경우 모듈의  레귤레이터 손상을 피하기 위해 외부5V 전원 공급 필요 하다
3. ENA단자가 enable일때 IN1IN2으로 OUT1 OUT2제어
4. ENB단자가 enable일때 IN3IN4으로 OUT3 OUT4제어
5. 동작 온도 : -20~+135
6. 2개의 DC모터를 제어하거나 1개의 스텝모터 제어 가능
7. ENA, ENB 단자에 PWM신호(아두이노의 디지털단자’~’)를 인가하여 모터의 출력(스피드)를 제어 할 수 있다(0~250 : analogWrite() 함수 사용)

8.      ENA 단자를 연결시킬 경우 최대 (속도)255 입력된다.


 실습에 사용되는 모터드라이버 모듈의 핵심 IC는 L298N 이다.  이 IC는 아래 L293D IC와 구조적으로 거의 같다고 보면된다.  IC의 타입(모양)이 다르고 모터를 돌릴 수 있는 출력 전류(전력)가 더 커진 IC이지만 IC의 작동 구조는 아래 L293과 같기 때문에 동작원리 파악을 위해 참고 하면 좋을 것이다.

《참고》

▶ L293D 모터 제어 드라이버 IC :  



H 브릿지 회로가  2개(2채널) 들어가 있으며, IC 이미지에서 처럼 좌우측 으로 구분 되어 있다.  



▶ 실습 목표 :  

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

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

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


▶ 실습 회로도면 :

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

※ 아두이노에 연결한 전원 만으로는 모터가 제대로 작동되지 않을 수 있다.  즉, 모터 쪽은 전력이 약하면 코드에 문제가 없어도 이상 동작을 보이거나 전혀 동작하지 않을 수 있다. 따라서 L298N 모터 드라이버 모듈에 별도의 추가 전원을 연결하고 아두이노 보드에도 전원을 연결해 주는 것이 좋다.  모터 드라이버쪽 전원의 전압은 연결된 모터의 용량이나 크기에 따라 혹은 돌리려는 속도에 따라 스펙상 3V~30V (12V 이하 권장) 적절한 전원을 넣어 주면 된다. 


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



▶ 실습 절차  : 


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


▶ 프로그램 코드 및 설명 : 

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

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

int triggerPin = 13;

int echoPin = 12;

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

#define IN2 9

#define IN3 10

#define IN4 11


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);          // 에코 핀을 입력으로 설정

}


void loop( ) {

  digitalWrite(triggerPin, HIGH); // 트리거핀으로 10us의 펄스 발생

  delayMicroseconds(10);

  digitalWrite(triggerPin, LOW);  //에코 핀의 값을 cm 단위로 계산

  distance = pulseIn(echoPin, HIGH) / 58;

   // 100cm 이상은 모두 100cm로 처리

  distance = distance>100? 100:distance;

  Serial.println("Distance(cm) = " + String(distance));

  if (distance < 20) {    // 20cm 이내 장애물 감지

    stop();

    delay(1000);    // 1초간 정지후 후진

    back();

    delay(2000);    // 2초간 후진

  } else {          //   20cm이내에 벽이 없다면 전진

    forward();     } 

}

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

  한쪽바퀴만 돌리거나 두 개의 바퀴를 서로 반대로 돌리면 좌회전 혹은 우회전이 된다.   이를 함수 형태로 만들고 메인 루프에서 적절히 함수들을 호출해서 사용하도록 하였다. 그리고 메인루프문에서 장애물이 감지 되었을 때 어떻게 동작을 하게 할 것인지를 간단히 프로그래밍 해 주면 된다. 

위 프로그래밍에서는 기본 전진 기동을 하다가, 물체가 20cm 이내로 감지되면 우선 정지(1초) 한 다음, 후진(2초) 하도록 단순하게 작성 하였다.  다음 강의에서는 자동차 처럼 장애물을 회피해서 기동하는 형태로 작성해볼 예정이다.


▶ 실행영상:  

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


※ 센서의 반응에 의한 동작 확인을 위해 영상에서 처럼 모터 및 바퀴를 고정 할 수 있는 알루미늄 몸체를 연결한 모습이다.  만약 이런 바디가 없어도 상관없다. 모터만 연결하여 동작확인을 해보면 된다. 


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

L298N_UltraSonic_Basic.ino





반응형
반응형

【 아두이노 센서#23】 HC-SR04 초음파센서 경보회로2 with i2c LCD

 지난시간 초음파 센서로 접근 경보회로를 구성하면서 LCD(16by02)에 표시하는 실습을 진행해 보았다. 하지만 LCD 핀을 일일이 연결해서 사용하는 것은 번거로움이 있고, 만약 아두이노에 추가적으로 여러가지 부품을 더 연결할 경우 포트에도 여유가 없게 된다. 이럴경우 가장 좋은 해결책은 LCD를 I2C 통신 타입으로 사용하면 쉽게 해결이 된다. I2C 타입 LCD는 온도센서와 습도센서를 다룰 때도 사용을 하였기에, 크게 어렵지 않을 것이다. 다만, I2C 통신에 대한 이해가 필요하다면 아래 선수 학습에서 참고하기 바란다. 


▶ 선수 학습 :

  1. I2C (Inter Integrated Circuit) 통신  강좌보기클릭

  2. I2C LCD로 TMP36 온도센서값 출력하기#3  강좌보기클릭

  3초음파 센서 경보회로 with LCD     강좌보기클릭


▶ 실습에 사용되는 부품 자료 ( HC-SR04 ) 



▶ 실습 목표 :  

1. 초음파 신호의 반사된 시간을 이용해서 물체까지의 거리값을 계산할 수 있다.

2. 물체가 일정거리(40cm) 이하로 감지가 되면 경보음과 함께 LED가 깜빡이게 하고, 가까울 수록 점점 더 빠르게 반응 하도록 프로그래밍 한다. 

3. 하나의 포트로 LED와 스피커(부저) 두 가지를 작동시키게 되면, 출력이 약하여 LED 혹은 스피커 작동이 약할 수 있다. 따라서 LED와 스피커를 분리하여 연결 (포트 추가 필요) 

4. LCD로 거리값을 출력하되, I2C통신 모듈이 달려있는 LCD를 사용함으로 연결 및 사용의 번거로움을 줄이고 아두이노 포트에 여유를 가져 올 수 있다. 


▶ 실습 회로도면 :

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


 ※ 위 회로에서 LED와 아두이노 9번 단자 사이에 100옴~330옴 사이 값 아무값의 저항을 하나를  기본적으로 넣어 주면 좋습니다. 

 아래 영상에 사용된 부저 모듈은 아래 이미지와 같은 3핀 모듈인데요, VCC핀은 +쪽에 ,  GND는 GND에 각각 연결하고,  I/O(신호) 단자를 아두이노의 8번 핀에 연결시켜 주면 됩니다. 이렇게 전원이 따로 분리된 모듈을 사용하면 출력이 좀 더 커지게 되는데요,   그런데, 사실상 아주 큰 소리는 나지는 않으니 참고하세요.

   능동형 부저 :  동작전압(Operating Voltage) : 3.3~5V


※ 아두이노 포트의 작은 출력으로 소리와 함께 LED를 작동 시키기 때문에, 기본적으로 소리가 작게 날 수 있으며, 스피커는 와트(w) 수가 작은 것을 사용해야 들을 수 있다. 또한 진동판을 전류로 울려서 소리를 내는 방식의 스피커 보다는 피에조 타입의(압전) 스피커를 사용하는 것이 좋다.  


▶ 실습 절차  : 

1.    위 회로 연결도를 참고하여 부품들을 연결한다
2.    초음파 센서의 거리 값을 16x2 LCD로 표시하라
3.    LCD에 거리값을 표시 할 경우 큰 수치에서 작은 수치로 줄어들어 이전 수치값이 남아 있어 값을 읽을 때 혼란스러운 현상이 일어난다. 이럴경우 몇가지 방법이 있으나간단한 방법은임의의 공백을 적당(2~10) 딜레이()와 함께 사용하면 해결할 수 있다.
4.    실제 거리와 유사한지 비교해본다


▶ 프로그램 코드 및 설명 : 

/*  초음파 센서를 사용한 거리값을 i2c 타입 LCD에 출력하기 */


#include <Wire.h>

#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd (0x27, 16,2);

int distance;

int alertLED=9; 

int alertBuzz=8; 

int triggerPin = 7;

int echoPin = 6;


void setup( )  {

  Serial.begin(9600);

  pinMode(alertLED, OUTPUT);    // 경보용 LED포트를 출력으로 설정

  pinMode(alertBuzz, OUTPUT);    // 경보용 Buzzer를 출력으로 설정

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

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

  lcd.begin();

  lcd.clear();


}


void loop( ) {

  // 트리거 핀으로 10 us의 펄스를 발생

  digitalWrite(triggerPin, HIGH);

  delayMicroseconds(10);

  digitalWrite(triggerPin, LOW);

  //에코 핀 입력으로부터 거리를 cm 단위로 계산

  distance = pulseIn(echoPin, HIGH) / 58;

  distance = distance>100? 100:distance;


  lcd.setCursor(0,0);

  lcd.print("UltraSonic Ruler");

  lcd.setCursor(0,1);

  lcd.print("distance :");

  lcd.print(distance);

  lcd.print("cm   ");

  if (distance < 40) {    

    digitalWrite(alertLED,HIGH);

    digitalWrite(alertBuzz,HIGH);

    delay(10);

    digitalWrite(alertLED,LOW);

    digitalWrite(alertBuzz,LOW);

    delay(distance); 

  }

  Serial.println(String(distance)+"(cm)");

  delay(50);

 }

}



▶ 실행영상:  

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




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

Ultrasonic_buzzer_i2cLCD.ino



【 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에 똑 같은 이름의 라이브러리가 있을 경우 반드시 삭제를 하거나 압축해서 백업을 해 놓으면 충돌이 일어나지 않습니다.!!!

반응형