레이블이 아두이노인 게시물을 표시합니다. 모든 게시물 표시
레이블이 아두이노인 게시물을 표시합니다. 모든 게시물 표시

2012년 6월 26일 화요일

도트매트릭스(dot matrix) 제어 2

 
도트매트릭스(dot matrix) 제어 2
이전글 도트매트릭스(dot matrix) 제어 1: http://eskelt.tistory.com/30
도트매트릭스의 제어를 통해
센서의 입력을 받아 도트매트릭스에 표현해보자
도트매트릭스에 얼굴을 표현하고 마치 말하는 것같은 모습을... 
즉 sound센서의 입력을 받아 
센서값에 따른 얼굴모양이 바뀌도록하여
입을 움직이는 것 처럼 표현해보자.
기본적인 작동은 이전글을 참고하자.
일단 여러가지 얼굴모양을 만들어 배열하고
간단한 수식으로 센서값에 따라 얼굴모양을 선택할 수 있도록 한다.
스케치 소스
-----------------------------------------------------------------------------
/* 말하는 매트릭스*/
int clock = 2;  //74HC595의 클럭핀과 연결
int latch = 3;  //74HC595의 래치핀과 연결
int data = 4;  //74HC595의 데이터핀과 연결
int a;
int dataval[6][8]={
  {0x66,0x99,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x66,0x99,0x00,0x00,0x18,0x00,0x00,0x00},
  {0x66,0x99,0x00,0x00,0x3c,0x24,0x18,0x00},
  {0x66,0x99,0x00,0x00,0x7e,0x42,0x3c,0x00},
  {0x66,0x99,0x00,0x00,0x3c,0x24,0x24,0x18},
  {0x66,0x99,0x00,0x00,0x7e,0x42,0x42,0x3c}};    //6개의 입모양이 다른 얼굴  
int scanval[8] ={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
void setup(){
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
  pinMode(data, OUTPUT);
  Serial.begin(9600);
}
void loop(){
  a = analogRead(A0)/150;   // 사운드 센서의 입력을 받아 값을 6단계로 표현하도록 계산
  if(a>5){a=5;}                    // 총 6개의 모습이므로 5를 넘지 않도록 함.
  for(int i=0; i<8; i++){
    digitalWrite(latch, LOW);   //래치를 내리고
    shiftOut(data,clock,LSBFIRST, scanval[i]); 
    shiftOut(data,clock,LSBFIRST, dataval[a][i]);         // 센서에서 계산된 a값을 통해 입모양 선택
    digitalWrite(latch, HIGH);   //래치를 올린다. 74HC595에서 데이터를  출력함
    delay(2);
    }
digitalWrite(latch, LOW);   
shiftOut(data,clock,MSBFIRST, 0x00); // 매트릭스를 끄는 시간을 줌
shiftOut(data,clock,MSBFIRST, 0x00); 
digitalWrite(latch, HIGH);
delay(3);
}
----------------------------------------------------------------------------------
작동영상
 
 
참조 : http://cafe.naver.com/arduinostory/6869  (카페 : 아두이노 스토리)

도트매트릭스(dot matrix) 제어 1

 
도트매트릭스(dot matrix) 제어 1
LED를 여러개를 묶어 글씨나 간단한 도형을 출력할수 있는 장치다
LED의 수 또 같은 갯수라도 크기에 따라 종류가 다양하다.
여기에서 사용한 것은 
8x8 소형 도트매트릭스 SZ420788K-16P로
총 64개의 LED를 묶어 놓은 것 중 소형매트릭스를 이용하였다.
자세한 사양은
http://www.eleparts.co.kr/front/productdetail.php?productcode=003009003000000007을 참고

핀은 품명이 마킹되어 있는 곳의 맨 왼쪽 핀부터 1번으로 
반시계방향으로 총 16번까지 넘버링된다.

불을 켜는 방법은
13번핀에 +, 9번핀에 -를 연결하면 맨위 왼쪽 led가 불이 들어온다
또 9번핀은 13,3,4,10,6,11,15,16에 연결된 LED의 애노드를 공통으로 묶고 있어
9번핀에 -를 연결한체 13,3,4,10,6,11,15,16에 +를 연결하면 맨 윗줄에 불이 들어온다.
결국 총 16개의 선에 신호를 주면 64개의 LED의 제어가 가능하다.
그러나 아두이노만으로 제어하기에는 16개의 핀이 필요하고
64개의 LED를 켜기위해서는 많은 전류가 소모되므로 
아두이노에 무리가 올 수 있으므로
74hc595 shift register 2개(1개에 8개의 데이터 전송)와
(74hc595의 사용은 http://blog.naver.com/eskelt/120157837942 참고)
ULN2603을 사용하면 아두이노에서 전원을 제외하고
3개의 핀으로 매트릭스 제어가 가능하다.
그림처럼 웃는 모양의 그림을 표시하려면

첫번째 줄
9번핀에 신호를 주고(첫번째 줄 1,0,0,0,0,0,0,0 즉 0x80)
(uln2603을 통해 9번핀에 신호를 주면 9번핀은 GND 처리된다.)
13,3,4,10,6,11,15,16핀에 0,1,1,0,0,1,1,0(즉 0x66)의 신호를 보내면
첫 줄 그림처럼 불이 들어온다.
두번째 줄
14번핀에 신호를 주고(두번째 줄 0,1,0,0,0,0,0,0 즉 0x40)
13,3,4,10,6,11,15,16핀에 1,0,0,1,1,0,0,1(즉 0x99)의 신호를 보내면
두번째 줄 그림처럼 불이 들어온다.
.
.
.
.
.
이런식으로 총 8줄을 짧은 시간간격으로 한줄씩 표현하면
눈으로는 하나의 웃는 모습으로 인식된다.
소스 스케치
-----------------------------------------------------------------------
/* 도트 매트릭스 웃는 얼굴 표현*/
int clock = 2;  //74HC595의 클럭핀과 연결
int latch = 3;  //74HC595의 래치핀과 연결
int data = 4;  //74HC595의 데이터핀과 연결
void setup(){
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
  pinMode(data, OUTPUT);
}
void loop(){
  int dataval[8]={0x66,0x99,0x00,0x00,0x7e,0x42,0x3c,0x00};
  int scanval[8] ={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //줄
  for(int i = 0; i<8; i++){
     digitalWrite(latch, LOW);   //래치를 내리고
     shiftOut(data,clock,LSBFIRST, scanval[i]); //줄 선택
     shiftOut(data,clock,LSBFIRST, dataval[i]); // 선택된 줄에 LED신호
                                                                 // 74hc595에 총scanval과 dataval 16bit를 보내면 
                                                          //8bit는 Q7'핀을 통해 다음 74hc595 data핀으로 밀어낸다.
     digitalWrite(latch, HIGH);   //래치를 올린다. 
     delay(1);
    }
    digitalWrite(latch, LOW);   //래치를 내리고
    shiftOut(data,clock,MSBFIRST, 0x00); 
    shiftOut(data,clock,MSBFIRST, 0x00); //LED를 끄는 시간 필요
    digitalWrite(latch, HIGH);
    delay(1);
}
-------------------------------------------------------------------------------------------
작동 사진

움직이는 입모양을 표현하려면
미리 입모양 표정을 만들어 이차원 배열로 입력하여 출력한다.
스케치 소스
----------------------------------------------------------------
/* 도트매트릭스 움직이는 입모양*/
int clock = 2;  //74HC595의 클럭핀과 연결
int latch = 3;  //74HC595의 래치핀과 연결
int data = 4;  //74HC595의 데이터핀과 연결
void setup(){
  pinMode(clock, OUTPUT);
  pinMode(latch, OUTPUT);
  pinMode(data, OUTPUT);
}
void loop(){
  int dataval[7][8]={
    {0x66,0x99,0x00,0x00,0x3c,0x00,0x00,0x00},  //다문입
    {0x66,0x99,0x00,0x00,0x18,0x18,0x00,0x00},  //조금 벌린입
    {0x66,0x99,0x00,0x00,0x3c,0x18,0x00,0x00},
    {0x66,0x99,0x00,0x00,0x3c,0x24,0x18,0x00},  
    {0x66,0x99,0x00,0x00,0x7e,0x24,0x18,0x00},
    {0x66,0x99,0x00,0x00,0x7e,0x42,0x3c,0x00},
    {0x66,0x99,0x00,0x00,0x7e,0x42,0x66,0x3c}};  //크게 벌린입
  int scanval[8] ={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  for(int j=0; j<7;j++){
    for(int i = 0; i<8; i++){
      digitalWrite(latch, LOW);   
      shiftOut(data,clock,LSBFIRST, scanval[i]); 
      shiftOut(data,clock,LSBFIRST, dataval[j][i]); 
      digitalWrite(latch, HIGH);   
      delay(1);
     }
     digitalWrite(latch, LOW);   
     shiftOut(data,clock,MSBFIRST, 0x00); 
     shiftOut(data,clock,MSBFIRST, 0x00); 
     digitalWrite(latch, HIGH);
     delay(30);
  }
}
-------------------------------------------------------------------------
작동 영상

아두이노간 xbee통신

 

아두이노간 xbee통신

프로그램 버전 : Arduino - 1.0

아두이노끼리 유선은 물론

xbee를 통해 무선통신이 가능하다.

한쪽 아두이노에서 센서 또는 스위치 등으로 신호를 받고

그신호를 다른 아두이노에서 받아 처리하여 출력하는 형식이다.

간단하게

우노에서 스위치를 누르면 숫자 5를 xbee를 통해 날리고

메가에서 숫자5를 받아 출력하는 식으로 구성해보면

우노의 배선

스위치 입력은 11번에 연결하고 

xbee 쉴드 장착

우노의 스케치 소스

-------------------------------------------------------------------------------

#include <SoftwareSerial.h>
SoftwareSerial xbeeS(2,3);   //xbee 통신을 위해 구성
void setup(){
  xbeeS.begin(9600);     //xbee 통신 시작
  pinMode(11,INPUT);    //11번을 스위치 입력
  pinMode(13,OUTPUT);
}
void loop(){
  if(digitalRead(11)==LOW){
    digitalWrite(13,HIGH);
    xbeeS.write(5);      //스위치 입력이 있으면 xbee에 5를 보냄
  }
  digitalWrite(13,LOW);
}

------------------------------------------------------------------------------------

신호를 받을 메가의 배선

메가에서의 스케치 소스

------------------------------------------------------------------------------------

int a;
void setup(){
  Serial.begin(9600);     //시리얼 통신 0번 pc와 통신
  Serial3.begin(9600);   //메가는 하드웨어적으로 시리얼 통신을 0~3번까지 제공하므로

//소프트웨어적으로 시리얼 통신을 구성할 필요 없다.

                                  // 통신할 통신장치를 1~3번에 연결하고 사용하면 된다.

                                  // SoftwareSerial을 구성하면 통신이 잘 안됨???
  pinMode(13,OUTPUT);
}
void loop(){
  if(Serial3.available()>0){
    a = Serial3.read();          //xbee의 값을 저장
    if(a==5){
       digitalWrite(13,HIGH);
       Serial.println(a);          // 값을 시리얼 모니터에 출력
       }
  }
  digitalWrite(13,LOW);
}

---------------------------------------------------------------------------------------

xbee 통신

 

xbee 통신

프로그램 버전 : Arduino - 1.0

사용된 Xbee 모듈은

http://www.sparkfun.com/products/8664 이다

Xbee 모듈의 설정은 

http://www.sparkfun.com/datasheets/Wireless/Zigbee/XBee-Manual.pdf 참고

기본 설정된 값은

Xbee 모듈과 컴퓨터와 UART방식으로 9600bps 로 통신하고

(물론 설정을 변경해 통신속도를 바꿀수 있다. 변경방법은 위 Manual.pdf참고)

Xbee 모듈간은 250000bps로 통신한다.

Xbee라고 다를것 없이 아두이노에서의 스케치는

softwareserial 라이브러리를 이요해서 TX, RX핀을 설정하고

다른 통신모듈과 같이 스케치 하면 된다.

(다른 통신모듈과 통신 거리, 속도, 가격 등이 다르므로

사용 목적에 맞게 선택하면 된다.)

Xbee 모듈 2개, Xbee 쉴드, Xbee explorer 사진이다.

모듈을 쉴드와, explorer에 끼우고

모듈을 장착한 쉴드를 아두이노 UNO보드에 끼운 사진이다.

각각 쉴드가 장착된 아두이노는 com4번과

explorer에 기운 Xbee는 com8번에 연결되었다.

(장치관리자에서 확인)

com4-아두이노-Xbee       <------통신------>       Xbee-com8

결국은 한 컴퓨터의 com4에서 com8번으로 통신을 구현 했지만

이는 통신의 확인을 위한 작업 이고

응용하면

Xbee연결된 아두이노를 센서나 모터를 연결하여 외부에 두고

Xbee를 통해 컴퓨터로 센서 값이나 모터를 제어할 수 있다.

Xbee가 장착된 아두이노와 Xbee가 연결된 pc와의 통신

스케치 소스

-------------------------------------------------------------------------------

/*Xbee가 장착된 아두이노와 Xbee가 연결된 pc와의 통신*/

#include <SoftwareSerial.h>

SoftwareSerial XbeeSerial(2,3);  //아두이노 2,3번 핀을 통해 통신

int a,b; 

void setup(){

  Serial.begin(9600);

  XbeeSerial.begin(9600);

}

void loop(){

  if(Serial.available()>0){    

    a = Serial.read();             // 시리얼 모니터에 입력된 값을 a에 저장

    XbeeSerial.println(a);       // Xbee를 통해 다른Xbee가 연결된 pc에 값 출력

    delay(100);

  }

  if(XbeeSerial.available()>0){

    b = XbeeSerial.read();        // Xbee가 연결된 pc에서 입력한 값 b에 저장

    Serial.println(b);                // Xbee를 통해 아두이노Xbee로 값을 보내고 시리얼 모니터에 출력

    delay(100);

  }

}

-------------------------------------------------------------------

작동영상

(Serial 모니터는 아두이노, 컴포트 마스터는 Xbee-explorer와 연결 되었다.)

스마트폰 + 블루투스 + 아두이노자동차 배선

관련글
블루투스 설정에 관한 글 http://eskelt.tistory.com/14
블루투스 활용에 관한 글 http://eskelt.tistory.com/16
블루투스 자동차 http://eskelt.tistory.com/22
에서 작성된 스마트폰 + 블루투스 + 아두이노자동차 배선도 이다
(모터, 모터드라이버,블루투스,아두이노를 연결)
모터의 출력을 높이기위해 모터 쪽으로 배터리를 따로 연결 하였다.
주의점은 아두이노의 GND와 추가 배터리의 GND를 연결해야 한다.

2012년 6월 24일 일요일

안드로이드 스마트폰 + 블루투스 통신 + 아두이노 자동차


관련글
블루투스 설정에 관한 글  http://eskeltt.blogspot.kr/2012/06/rn-42.html
블루투스 활용에 관한 글  http://eskeltt.blogspot.kr/2012/06/blog-post_4838.html

프로그램 버전 : Arduino - 1.0 

안드로이드 스마트폰과 아두이노를
블루투스 통신으로 연결하여
스마트폰에서 폰의 기울기나 버튼 누름 정보를
아두이노로 받아 처리후 모터를 제어해 보도록 한다.
즉 안드로이드 스마트폰으로 아두이노 자동차를 제어해 보자.

먼저 스마트폰과 아두이노의 블루투스장치를 페어링 시킨다.

다음으로 안드로이드 스마트폰에서
페어링된 블루투스(아두이노)로 정보를 보낼 앱이 필요하다.
(사실 아이폰으로 해보려 했지만 블루투스 통신 방법이 다르고
관련 앱이 흔치 않아 포기했다)

사용한 앱은 BluCar이다.

설치후 실행해 보면


Connect to a device 버튼을 눌러 아두이노 블루투스와 연결한다.
(연결이 되었다는 표시는 각각의 블루투스 모듈에 따라 다르다
사용된 RN-42모듈은 빨간 불에서 파란불로 바뀌며,
한번에 되지 않고 여러번 connect해야 연결되었다.
또, 페어링시킨 후 블루투스의 설정을 변경해야하는 모듈도 있지만
이 모듈은 그런 번거로움 없이 사용된 앱과 연결이 되었다.)

연결되면 블루투스를 통해 아두이노로 값을 날린다.
이 앱은
폰을 왼쪽으로 기울이면 -> 4
오른쪽으로 기울이면 -> 8
Forward 버튼을 누르면 -> 16
Reverse 버튼을 누르면 -> 32
버튼을 누르고 기울이면 각각의 값을 더한 값을 날린다.

이 값을 가지고 스케치 하여 모터를 제어 하면 된다.

앱을 이용해 제어한 자동차는 모터2개, 모터드라이버,
블루투스모듈, 아두이노프로미니를 연결하여 제작하였다.
(자동차라고 까지 부르기에는 조금 미흡한... 그냥 모터달린....)





스케치소스
-------------------------------------------------------------------------------
/*스마트폰으로 제어하는 자동차*/
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3);    //블루투스 모듈 통신 설정
int a = 0;
void setup(){
  BTserial.begin(115200);      //블루투스 모듈 통신 시작
}

void loop(){
    a = BTserial.read();      // 스마트폰에서 블루투스 모듈로 들어오는 신호를 a에 저장
    switch (a){
      case 0:               // 0이면 정지
        analogWrite(8,0);        // 왼쪽 모터 전진 정보 핀
        analogWrite(9,0);        // 왼쪽 모터 후진 정보 핀
        analogWrite(10,0);       // 오른쪽 모터 전진 정보 핀
        analogWrite(11,0);       // 오른쪽 모터 후진 정보 핀
        delay(30); break;
      case 4:               // 4면 제자리 좌회전
        analogWrite(8,0);
        analogWrite(9,250);
        analogWrite(10,250);
        analogWrite(11,0);
        delay(20);
        break;
      case 8:               // 8이면 제자리 우회전
        analogWrite(8,250);
        analogWrite(9,0);
        analogWrite(10,0);
        analogWrite(11,250);
        delay(20);
        break;     
      case 16:               // 16이면 전진
        analogWrite(8,250);
        analogWrite(9,0);
        analogWrite(10,250);
        analogWrite(11,0);
        delay(20);
        break;
      case 20:               // 20이면 좌회전
        analogWrite(8,0);
        analogWrite(9,0);
        analogWrite(10,250);
        analogWrite(11,0);
        delay(20);
        break;
      case 24:                // 24이면 우회전
        analogWrite(8,250);
        analogWrite(9,0);
        analogWrite(10,0);
        analogWrite(11,0);
        delay(20);
        break;
      case 32:                // 32이면 후진
        analogWrite(8,0);
        analogWrite(9,250);
        analogWrite(10,0);
        analogWrite(11,250);
        delay(20);
        break;   
    }
}
------------------------------------------------------------------
(앱에서 블루투스를 통해 보내는 값이 기울기에 따른 변화된 값이 아니라 정해진 값이여서
아날로그출력(PWM)으로 할 필요 없이 디지털 출력으로 모터를 제어하면 될것을.....
조금 더 머리가 좋으면 간략하게 짤수도 있을텐데....)

작동 영상






RC(radio control) + 아두이노 3


RC(radio control) + 아두이노 3 

프로그램 버전 : Arduino - 1.0

저번글에서 RC의 신호를 아두이노에서 받아 보고
신호를 처리해서 모터를 작동시켰다.
이번에는 간단한 자동차를 만들어
실제로  RC 송수신기로 조정하도록 하겠다.


사실 RC카를 어렵게 아두이로로 연결하고 스케치하여 제어할 필요는 없다.
수신기에 모터와 변속기, 각각의 서보 모터를 연결하면
아주 간단하게 RC자동차를 제작 할수 있다.
따라서 RC자동차를 만드는 것이라면 이글을 패스하고
RC사이트를 검색하는 것이....


조립한 자동차는 모터2개와 모터 드라이버를 이용하였고
무게와 크기를 줄이기 위해 아두이노 프로미니와
RC수신기를 이용하여 조립하였다.
차체는 매우 간단하다.



서보모터를 이용하지 않고 좌우 모터의 속도 차이로 방향 조정토록 하고
RC송신기(조정기)의 2개의 채널(스로틀과 에일러론) 신호로 전후좌우를 조정할 수 있도록 스케치 하였다.

스케치 소스
------------------------------------------------------------------
/*rc송신기(조정기)의 신호를 받아 자동차 제어*/
int th,al;       //송신기로 부터 오는 신호를 저장할 변수
int ch1 = 6;    //수신기와 연결된 핀
int ch2 = 7;    //수신기와 연결된 핀
void setup(){
  pinMode(ch1,INPUT);   //송신기에서 신호를 보내면 수신기에서 신호를 받고 수신기에서 아두이노로 신호 입력
  pinMode(ch2,INPUT);   //ch1을 수신기의 스로틀 신호, ch2를 에일러론 신호로 연결함.
}

void loop(){
  th = pulseIn(ch1,HIGH);  //ch1의 펄스폭 저장
  th = constrain(map(th,1100,1900,-255,255),-255,255);   //ch1의 펄스폭1100~1900을 -255~255로 매핑,
                                        //ch1이 스로틀스틱이 중앙일때는 0 위로는 255, 아래로 -255값을 갖도록 함.
  al = pulseIn(ch2,HIGH);
  al = constrain(map(al,1100,1900,-255,255),-255,255);  //ch2의 펄스폭1100~1900을 -255~255로 매핑,
                                        //ch2이 에일러론스틱이 중앙일때는 0 좌로는 255, 우로는 -255값을 갖도록 함.


//모터 드라이브에 연결된 아두이노 핀은 전진시 좌모터 8번, 우모터10번핀
//후진시 좌모터 9번, 우모터 11번

  if(th>0){                      //스로틀 스틱이 위로 움직임 -> 전진
    if(al>0){analogWrite(8,th-al);analogWrite(10,th);} 
                                   //스로틀 스틱이 위로 동시에 에일러론이 좌로 ->좌회전
    if(al<0){al=abs(al);analogWrite(8,th);analogWrite(10,th-al);}     //abs()는 절대값을 취함.
                                   //스로틀 스틱이 위로 동시에 에일러론이 우로 ->우회전
  }
  if(th<0){th=abs(th);               //스로틀 스틱이 아래로 움직임 -> 후진
    if(al>0){analogWrite(9,th-al);analogWrite(11,th);}
                                          //스로틀 스틱이 아래로 동시에 에일러론이 좌로 ->좌후진
    if(al<0){al=abs(al);analogWrite(9,th);analogWrite(11,th-al);}
                                          //스로틀 스틱이 아래로 동시에 에일러론이 우로 ->우후진
  }
}
-------------------------------------------------------------------------------

참고로 RC조정기의 우측 스틱을
위아래 조정을 스로틀
좌우 조정을 에일러론이라 한다.

작동 영상


RC(radio control) + 아두이노 2


RC(radio control) + 아두이노 2 

프로그램 버전 : Arduino - 1.0

사용된 물품
스펙트럼 송신기, 스펙트럼호환 오렌지수신기

이전글에서 아두이노와 RC송수신기를 연결하여
신호를 받는 것에 대해 언급하였고
이번에는 그 신호를 받아 모터를 구동시켜 보자

1번 채널에 의해서는 DC모터를 제어하고(모터 드라이브 회로가 필요)
2번 채널에 의해서는 서보모터를 제어하도록
회로를 구성하고
소스를 스케치하면
---------------------------------------------------
/* rc 송수신기를 통해 신호를 받아 모터와 서보모터 작동 */
int rm1,rm2;
int motorPin = 6;   // 모터 연결( 모터드라이버 필요)
int servoPin = 7;   // 서보모터 연결
int ch1 = 11;   //rc 수신기와 연결
int ch2 = 10;
int refresh = 20;  // 서보모터에 신호를 20ms주기로 보내기위함.
unsigned long lastTime = 0;
void setup(){
  pinMode(servoPin, OUTPUT);
  pinMode(ch1,INPUT);
  pinMode(ch2,INPUT);
}
void loop(){
    rm1 = pulseIn(ch1,HIGH);
    rm1 = map(rm1,1100,2000,0,250); 
        //1번 채널에서 보낸 신호를 모터를 pwm으로 출력하기 위해 0~250으로 범위 제한.
    rm2 = pulseIn(ch2,HIGH);
    rm2 = map(rm2,1100,2000,600,2400); 
        //2번 채널의 신호는 서보모터를 제어하므로 서보모터의 회전값 600~2400으로 제한.(서보모터작동글 확인)
  
    if(millis()-lastTime>=refresh){   //서보모터에 20ms주기로 신호를 주기 위함.
      analogWrite(motorPin,rm1);
      digitalWrite(servoPin,1);
      delayMicroseconds(rm2);    // 서보모터에 HIGH신호를 600~2400마이크로초 폭으로 보냄
      digitalWrite(servoPin,0);
      lastTime = millis();
    }
}
----------------------------------------------------------------------------------------

작동 영상

RC(radio control) + 아두이노 1


RC(radio control) + 아두이노 

프로그램 버전 : Arduino - 1.0

일단 준비물은 서로 바인딩 된 RC송수신기가 필요함.

이전 글에서 키보드 또는 센서에게서 입력을 받아
서보 모터를 작동시켜 보았다.

이번에는 센서나 키보드가 아닌
취미생활로 많이들 즐기는 RC 송신기로 신호를 보내고
RC수신기와 아두이노를 연결하여 신호를 받아
서보모터를 작동시켜 보자.
(RC송수신기의 송수신거리는 1Km 이상이라고 한다
어떤 이의 실험에 의하면 전파의 방해를 받지 않는 넓은 벌판에서
4km까지도 신호를 받는다고 하지만....
고가의 비행기나 헬기를 1km이상 거리에 두고 조정하기에는 분실의 부담이
또 보이지도 않아 조정이 어렵다.)

일단 취미로 비행기나 헬기, 배, 자동차 등을 무선 조정 할수 있는
송수신장치의 작동에 대한 이해가 필요하다.

송신기(조정기)사진을 보면

가운데 두개의 조정스틱이 있는데
이 스틱은 각각 수직방향, 수평방향  총 4채널 조정이 가능하다.
(가변저항으로 말하면 총 4개의 가변저항이 달려 있고
그 위치에 따라 저항값이 다르듯이....이렇게 비교를 해도 되나??)
한번에 4개의 장치를 조정할수 있는 신호를 보낼 수 있다. 
(물론 다른 스위치들을 사용하면 6채널 7채널... 로 늘어난다.)
두 스틱의 위치값을 매 20ms 간격으로 계속 수신기로 신호를 날린다.

조금 더 설명을 붙이면
오른쪽 스틱하나를 위 아래 방향으로 조정할때
아래에서 위로 조금씩 스틱을 올리면
스틱의 위치마다 펄스가 LOW에서 HIGH로 신호가 올라가 HIGH를 유지하는 시간이 다르다.
예로 스틱이 중앙에 있고 중앙에서 펄스를 HIGH로 유지하는 시간이 1500마이크로 초라면
20밀리초에서 1500마이크로 초동안 HIGH로 신호를 보내고
나머지 시간은 LOW를 유지한다.
스틱이 움직임이 없더라도
그 다음 20밀리초에서 또 1500마이크로 초동안 HIGH로 신호를 보내고
나머지시간은 LOW를 유지하며 반복한다.
(작동이 그렇다는 이야기다. 시간값이나 HIGH인지 LOW인지 여타 다른 것들의 정확성에 대해서는 패스...)

수신기와 아두이노의 연결은

수신기에는 각 채널마다 3개의 핀이 있는데 그중 하나는 신호 나머지는 전원이다.


실제 연결 사진



 이신호 값을 확인하기 위해 스케치 해보면
-----------------------------------------------------------------
/*rc송신기(조정기)에거 보낸 신호를 rc수신기를 통해 아두이노에서 받기*/
int ch1,ch2,ch3,ch4;
void setup(){
  Serial.begin(9600);
  pinMode(7,INPUT);  //rc수신기와 아두이노와 연결된 핀 총 4개 4채널
  pinMode(6,INPUT);
  pinMode(5,INPUT);
  pinMode(4,INPUT);
}
void loop(){
  ch1 = pulseIn(7,HIGH);  //수신기를 통해 11번 핀으로 들어오는 신호의 HIGH펄스 폭을 마이크로 초 단위로 저장
  ch2 = pulseIn(6,HIGH);
  ch3 = pulseIn(5,1);    //HIGH나 1이나 같음
  ch4 = pulseIn(4,1);
  Serial.print(ch1);Serial.print("    ");  //HIGH펄스 폭을 출력
  Serial.print(ch2);Serial.print("    ");
  Serial.print(ch3);Serial.print("    ");
  Serial.println(ch4);
}
-------------------------------------------------------------


시리얼 모니터로 값을 확인하면


왼쪽 부터 1번 2번 3번 4번 채널에서 들어온 HIGH신호의 폭이다
1번은 스틱을 가장 아래 최소값으로 조정했고
2번은 가장 위로, 3번과 4번은 중앙 값이다.

이 신호를 받아 처리 하면 모터나 서보모터를 작동 시킬수 있다


아두이노 pro mini소개


아두이노 pro mini

일종의 키트다
.Arduino Pro Mini 5V형
.프로그래밍용 USB 시리얼 변환기
.3색 RGB LED 보드
.사운드 출력용 부저 보드
.광센서 보드
.버튼 보드
.프로토타입(임의 회로 구성용) 보드가 모두 포함되어 있다.

아래 사진과 같다.




일단 모두 하나하나 분리하고 싶지만 
아두이노안에 기본 예제가 프로그래밍 되어 있고 
센서와 아두이노가 연결되어 전원을 넣으면 기본 작동을 한다
가령 라이트센서에 손을 가져가면 RGBLED가 깜박이고,
버튼을 누르면 부저에서 소리를 낸다.
의도한바는 아니겠지만 불량인지 아닌지 확인 가능하다고도 하겠다.

기본 확인이 끝나고 나면 각 부품을 하나씩 떼어 놓고 사용할텐데
센서나 부저는 아두이노 미니 핀에 연결후
연결된 핀을 고려해 스케치하면 되지만
프로그래밍용 USB 시리얼 변환기는 정해진 핀과 연결 해야 한다.
그렇다고 어렵지 않다
처음 분리하기전에 마주보고 있었던 핀순서대로
아두이노 미니와 연결하면 된다.

소스스케치를 하기위해 아두이노 프로그램에서
tool - > board에서 Pro Mini (5V, 16MHz)보드를 선택해야 될것으로 생각되지만
소개 페이지에서는 UNO로 선택하여 업로드 하라고 한다.
실제로 UNO로 선택해야 업로드가 완료 된다.

더 자세한 내용은 아래 참고 페이지를 볼것!!!




LCD모듈과 Serial LCD 사용


프로그램 버전 : Arduino - 1.0

Serial LCD는 일반 LCD모듈 보다 편리하다. 
사실 아무것도 모르고 LCD모듈을 구입한다는 것이 Serial LCD를 구입했고
이것을 사용하기 위해 많은 시간을 소비해야 했다.

사진을 보면 두개중 아래 것이 Serial LCD이다.
앞면


















뒷면


화살표에 (둘중하나)전원과 RX핀 하나만 연결하면 된다.

일반 LCD 모듈을 사용하기 위해서는
아두이노의 LCD라이브러리를 활용하여
소스스케치를 작성하고
아두이노와 LCD모듈을 연결하기 위해서는 
전원을 포함하여 8개이상의 전선을 연결해야한다.

연결그림은 아래와 같다.





제법 연결할 선이 많다.

LCD화면에 "*"를 이동시키는 스케치다.

#include <LiquidCrystal.h>    //라이브러리 활용

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
/* LCD RS pin to digital pin 12
    LCD Enable pin to digital pin 11
    LCD D4 pin to digital pin 5
    LCD D5 pin to digital pin 4
    LCD D6 pin to digital pin 3
    LCD D7 pin to digital pin 2  */

int i=0;

void setup() {
   lcd.begin(16, 2); // LCD창의 크기 선언 16행 2줄
}
void loop() {
   for(i = 0 ; i < 16 ; i++){
      lcd.print("hello, world!");
      lcd.setCursor(i,1);   //커서의 위치 지정
      lcd.print("*");     //LCD에 *표현
      delay(500);
      lcd.clear();    // LCD 깨끗이
   }
}

라이브러리에 등록된 명령으로 LCD를 표현한다.


Serial LCD사용은 매우 간단하다.
다른 Serial 통신기기를 사용하는 것과 같다.
아두이노와 선의 연결도 간단하다.
전원을 넣기 위한 VCC와 GND 그리고 data를 보내기 위한 RX
3개의 선을 연결하면 끝이다.
일반 LCD모듈을 사용하기 위해서는
LiquidCrystal 라이브러리를 이용하지만
SerialLCD는 다른 Serial 통신 장치의 사용처럼
SoftwareSerial 라이브러리를 이용하여 스케치하고
RX선을 이용하 data를 날리면 된다.
SerialLCD의 화면을 지우거나 커서의 위치를 바꾸거나 밝기를 변동하는 등의
제어를 위해서는 이 모듈의 datasheet
언급된 명령을 활용하면된다. 

소스스케치
----------------------------------------------------------------------------------------
/*다음 스케치는 A0에 센서를 연결하여 센서에 읽힌 값을 SerialLCD에 표시*/

#include <SoftwareSerial.h>  //0번과 1번은 usb로 pc와 통신하므로
                                         //0번과 1번포트 이외의 포트를 사용하기 위함.
SoftwareSerial myserial (2, 3);    //2번과 3번을 시리얼통신 TX,RX로 사용하는 myserial라 정의
int sensorPin = A0;
int sensorval = 0;
void setup()  
{
  myserial.begin(9600);    //기계적으로 사용하고자 하는 장치의 bps를 써 넣는다.
//  myserial.write(124);    //SerLCD에 기계적 제어명령을 내림을 알림
//  myserial.write(146);    //SerLCD를 밝기를 조절 128~157 -> 0~100%
/* 밝기 제어는 잘 안됌 SerLCD를 재부탱해야함. 따라서 밝기를 깜박이도록 하기는 힘듬*/
}
void loop()
{
  sensorval = analogRead(sensorPin);
  
  myserial.write(254);     //SerLCD에 제어명령을 내림을 알림
  myserial.write(128);     //SerLCD 16x2화면에 첫줄 첫번째 위치에 커서
                                  //128+(0~15) 값은 첫줄의 1~16번째 항
                                  //128+(64~9) 값은 두번째줄의 1~16번째 항
  myserial.print(sensorval);  //SerLCD에 A0에서 센싱되는 값 표시
  delay(300);
  myserial.write(254);     //SerLCD에 제어명령을 내림을 알림
  myserial.write(1);       //clear display
 
  delay(300);
}
----------------------------------------------------------------------------------------