2015년 9월 26일 토요일

RF 리모컨 기반 서보 모터 제어

오늘은 간단히 FS-TH9X RF송수신기를 이용한, 서보모터 제어 방법을 간단히 알아보도록 하겠다.

1. 조립
조립은 매우 쉽다. 송신기는 다음 왼쪽 그림과 같이 생겼다. 수신기는 다음 오른쪽과 같이 작은 박스처럼 생겼다(적색 표시된 안테나가 달려 있다).


이 수신기는 아래와 같이 각 핀이 배터리 연결부를 제외하고는 8개 채널이 있다. 즉, 모터를 8개 별개로 제어할 수 있다.

전원을 수신기에 연결하기 위해 수신기의 BIND라고 표시된 채널의 3개의 핀에서, 신호핀을 제외한 양극+, 음극- 핀에 배터리를 다음과 같이 연결한다. 그리고, 서보 모터를, 채널 1과, 채널 3에 다음 그림과 같이 연결한다


2. 테스트
송신기 전원을 키고, 조정기를 좌우상하로 움직여 본다. 그럼, 이 동작에 따라, 서보모터가 원격으로 움직일 것이다.


동작 영상은 다음과 같다.


3. 결과
서보 모터와 같이, 모터를 제어할 수 있는 신호선이 있다면, 수신기에 직접 연결해서, 모터를 바로 제어할 수 있다. 만약, 신호선이 없는 DC 모터인 경우에는, 수신기에 입력되는 신호에 따라, DC모터에 PWD로 전압을 조정해 제어할 수 있는 회로를 덧붙여 연결해야 한다. 만약, 아두이노를 이용한다면, 이 회로는 간단히 프로그램으로 코딩하면 된다.
참고로, 수신기에서 특정 채널에 신호를 주면, 송신기의 신호선에 전압의 변화가 일어나게 된다. 이 전압의 변화는 송신기의 조작에 따라 전압이 올라가기도하고, 내려가기도 하는 데, 이를 이용해, 아두이노에서 전압의 변화에 따라, DC모터에 PWD제어를 하면 DC모터를 쉽게 제어할 수 있다.

참고 내용은 다음과 같다.

1. FS-TH9X 설정 방법

2. FS-TH9X

Turnigy 9X Configuration for Aux Channel Gimbal and Servo Control 



3. FS-TH9X 메뉴얼


2015년 9월 12일 토요일

Dynamixel XM-430 설정

이 글에서는 로보티즈의 다이나믹셀 XM-430 설정 방법을 정리한다.

1. 개요
최근에 출시된 XM-430 설치 방법을 정리한다. 기존 모델에 비해, 알루미늄 재질로 튼튼하게 마무리되어 있으며, 그래픽카드와 유사한 메모리 주소 기반 제어를 지원한다.

2. 설정
다음과 같은 순서로 액추에이터를 인식하고, 각종 파라메터(아이디)를 설정한다. 아두이노와 유사한 OpenCM으로 제어를 할 수 있다.










3. 마무리
간단한 설정과 아두이노와 유사한 개발환경 제공은 매우 편리하다. 다만, ROS와 같은 미들웨어에서 제공되는 아직 예제가 그리 많지 않다는 것은 아쉽다.

2015년 9월 6일 일요일

태양광 에너지 충전 방법

센서 등을 동작할 때, 배터리 없이, 자가 발전을 하기 원할 때가 있다. 이 경우에 사용할 수 있는 태양광 기반 에너지를 충전하는 방법을 정리한다.

1. 태양 전지 연결
태양 전지를 구입하였다면, 사용 전압에 맞게 태양 전지를 적절히 연결해야 한다. 연결하는 방법은 다음과 같다.


직렬로 연결하면, 전압이 증가되고, 병렬로 연결하면, 전류양이 증가한다.

2. 배터리 연결
이제, 태양 전지와 배터리를 연결해야 한다. 양쪽 모듈을 같은 극성끼리 연결하되, 태양 전지의 양극에서 배터리의 양극선 사이에, 다이오드를 다음 그림과 같이 연결한다. 그렇지 않으면, 전류가 배터리방향으로만 흐르지 않으므로, 전기 충전이 안된다.

회로 기호는 이 링크를 참고한다.

3. 테스트
실제로 잘 동작되는 지 테스트해보자. 테스트에 사용한 태양전지는 한장에 2.7V를 출력하며, 많은 전류를 얻기 위해, 병렬로 결선하였다. 사용된 충전지는 니켈 카드뮴 배터리(N-270AA)로, 1.2V 두개를 직렬연결해, 2.4V로 만들었으며, 용량은 270mAh를 갖는다. 야외에서 태양전지를 소형 모터에 연결해 본다. 큰 문제 없으면, 다음과 같이 잘 동작한다.


충전지에 충전을 해 본다. 다음은 충전하기 전의 충전지 전압이다.


야외에서 충전을 해 본다. 회로 결선은 앞의 설명대로 연결한다.


야외에서 약 30분 정도 충전을 시킨다. 그리고, 다시 전압을 측정해 본다.


충전지와 소형모터를 연결해 본다. 다음과 같이 소형모터를 회전할 만한 전압과 전류가 있다는 것을 확인할 수 있다.


약 1분 정도 소형모터를 동작시킨 후, 전압을 다시 측정해 본다. 다음과 같이, 전압 소모가 일어났음을 알 수 있다.


LED를 연결해 본다. 다음과 같이 잘 동작한다.


4. 응용 사례
다음은 태양전지 기반 아두이노이다. 아두이노에 필요한 전류를 태양전지에서 충전된 충전지로 부터 얻는다.


OpenCM 기반 엑추에이터 제어

이 글에서 OpenCM 9.04 기반 엑추에이터 제어 방법을 정리한다.

1. 개요
OpenCM은 아두이노 호환 보드로, 로보티즈에서 개발한 오픈소스 엑추에이터 전용 개발보드이다. 로보티즈에서 개발한 다이나믹셀을 제어하는 데 주로 사용한다.

2. 설치
아래의 링크에서 파일을 다운로드 받아, 드라이버를 설치해야 한다.
그리고, ROBOTIS_OpenCM 파일을 실행하면, 아두이노 IDE와 유사한 프로그램이 실행된다. 시리얼포트와 보드종류를 설정한 후, OpenCM 예제파일을 로딩해, 펌웨어를 빌드해본다. 그리고, 보드로 다운로드해 본다.

3. 마무리
다이나믹셀은 스마트 액추에이터로 알려져 있을 만큼, 구동부에 필요한 센서 등이 포함되어 있고, 많은 다이나믹셀을 편리하게 연결할 수 있도록, 데이지체인 방식의 연결을 지원한다.

무선 조정용 FlySky TH9X

1. 소개
무선으로 액추에이터에 신호를 전달하기 위해서는 무선 조정 장치가 필요하다. FlySky TH9X는 저렴하면서, 기능이 많은 9채널 무선 조정기이다. 이 조정기를 이용하면, 매우 간단하게, 액추에이터를 제어할 수 있다.



각 채널은 조정기의 스위치 등을 이용해, 무선으로 신호를 전달할 수 있다. 전달 받은 신호는 액추에이터를 구동하기 위한 시그널로 입력된다.

2. 사용팁
처음 조정기를 시작할 때, switch error가 날 경우가 있다. 이 경우에는 모든 switch를 backside로 젖히고, 다시 전원 버튼을 누르면 된다. 아래 영상을 참고하라.


에너지 절약 캠패인을 위한 스마트 홈 원리에서 응용한 프로세싱(Processing) 및 아두이노

이 글은 스마트 홈 원리 교육을 위한 프로세싱(Processing)와 아두이노 활용 방법에 대해서 다룬다. 이 내용은 다음 글을 참고하였다.
실제로 에너지 절약 캠페인을 위해, 스마트 홈이란 주제로 전시한 메이커 페어 참가 프로젝트의 상세 내용은 다음 링크를 참고하길 바란다. 메이커 페어 때 작업한 스마트 홈 관련 디자인, 소스코드 및 관련 참고 자료가 포함되어 있다 (전체 구현 내용은 매우 많으므로, 이 글에서 제공하지 않는다).

1. 프로세싱 개요
프로세싱은 미디어아트에 많이 활용되는 저작 도구이다. Java기반으로 스크립트를 개발하여, 데이터를 가시화한다. 매우 많은 수의 라이브러리와 예제를 프로세싱 홈페이지 및 관련 사이트에서 제공한다. processing.js를 사용하면, 웹기반으로 동작한다.

2. 프로세싱 사용 사례
프로세싱으로 개발한 작품을 확인해 보자.


이와 같이 전문가적인 컴퓨터 그래픽스를 만들 수 있다.

3. 프로세싱 코딩
프로세싱을 이용해, 센서 데이터를 취득하고, 이를 가시화하는 다음 그림과 같은 데쉬보드를 개발해 본다.


센서 데이터는 serial 통신으로 부터 획득한다. 조도, 온도, 습도, 전류 센서를 아두이노에 연결하여, 초당 2회씩 데이터를 프로세싱으로 보낸다. 이를 가시화한다.

데이터베이스에 센서 데이터를 저장하는 원리를 간단히 보여주기 위해, sensor.txt, energy.txt 파일 두개를 사용하였다(물론, MySQL과 같은 DB를 사용할 수 있으나, 교육적 원리를 전달해 주면 충분하므로 작업이 쉬운 방법으로 처리한다). 아울러, 센서 저장 및 그래픽 출력 간격을 교육적 효과를 얻을 수 있도록 매우 짧게 설정하였다.

다음은 관련 주요 코드이다(bar chart, pie chart 및 building 그래픽은 소스에 포함하지 않았음. 앞의 링크 참고.).

/** 
 * Smart home
 */ 
import java.util.Iterator;

PFont font = createFont("Arial", 30, true);
Chart[] charts = new Chart[2];
Bar[] bars = new Bar[2];
building[] buildingz; 

PApplet pg;

void setup() {
  size(1024, 768, P3D);
  smooth();
  noStroke();
  colorMode(RGB);  // colorMode(HSB, TWO_PI, 1, 1, 1);
  
  setup_arduino();  
  
  for(int i = 0; i < charts.length; i++)
    charts[i] = new Chart();
  charts[0].initChart("Year", width * 0.8, height * 0.2, 180.0);  
  charts[1].initChart("Month", width * 0.8, height * 0.5, 180.0);  

  for(int i = 0; i < bars.length; i++)
    bars[i] = new Bar();
  bars[0].initBar("Sensor", "sensor.txt", "sensor_data.txt", width * 0.05, height * 0.62, 400, 300);
  bars[1].initBar("Energy", "energy.txt", "energy_data.txt", width * 0.55, height * 0.62, 400, 300);

  initBuilding();  
}

void draw() {
  update_arduino();
  
  background(230, 150, 30);  
  
  textFont(font);  
  String str = "Smart Home Dashboard";
  fill(0);
  text(str, width / 2, 50);  
  
  for(int i = 0; i < charts.length; i++)
    charts[i].drawChart();

  for(int i = 0; i < bars.length; i++)
    bars[i].drawBar();
    
  fill(32, 128, 32, 128);
  house(20, 300, 250, 150);
  fill(32, 128, 32, 196);  
  house(220, 200, 320, 250);  
  
  translate(90, -20);  
  for(int a=0;a<buildingz.length;a++){
    buildingz[a].dessine( );
  }  
  translate(0, 0);  
}

void initBuilding()
{
  buildingz = new building[0];  
  float decx = 270; 
  float decy = 270;
  
  float bx = 270;
  for (int b = 0; b < 4; b++){
    float mindy = 0;
    for (int a = 0; a < 4;a++){
      float x = decx; 
      float y = decy + mindy;
      new building(x, y);

      decx = decx - 76;
      mindy += 25;
    }
    decy = decy + 30;
    decx = bx + 30; 
    bx = decx;
  } 
}

void house(float x, float y, float W, float H) {
  noStroke();
  rect(x, y, W, H);
  triangle(x, y, x + W / 2, y - H / 2, x + W, y);
}

웹서버에 개발된 코드를 동작시키려면, 다음과 같이 시도해 본다.
1. 웹서버를 설치한다 (python 서버, locally).
2. processing.js 등을 다운로드 받는다.
3. index.html 파일을 다음과 같이 만든다.
<html>
<head>
<title>Hello Web</title>
<script src="processing.js"></script>
</head>
<body>
<h1>Processing.js</h1>
<p>web-based sketch:</p>
<canvas data-processing-sources="your_processing-1.pde your_processing-2.pde ..."></canvas>
</body>
</html>

4. 웹서버를 실행한다.
5. chrome에서 localhost:8080을 입력한다.

만약, 프로세싱 스케치가 로딩되지 않아, 그래픽이 표시되지 않으면, 프로세싱 파일을 하나로 합쳐본다. 이렇게 해도 로딩이 잘 안되면, 다른 종류의 웹서버를 설치해 시도해 본다.


4. 아두이노 연결
아두이노에서는 센서 데이터를 취득하거나, 릴레이와 같은 액추에이터를 제어한다.

릴레이에는 5V LED가 연결되어 있어, 간단한 스마트 전등을 구현하고 있다.
에너지 소모 데이터는 전류센서로 부터 얻도록 되어 있다. 기타, 스마트 홈에서 가전기기 조절에 필요한 온도, 습도, 조도 센서도 아두이노와 연결한다.

이렇게 연결된 센서 데이터는 energy.txt, sensor.txt로 구분해 파일로 저장하고, 이 데이터를 정해진 시간 단위로 읽어, 앞의 프로세싱으로 코딩한 스마트 홈 데쉬보드에 컴퓨터 그래픽으로 출력한다. 이런 방식으로 스마트 홈의 기본적인 기능들을 만들고, 보기 쉬운 그래픽으로 표현하여, 에너지의 중요성에 대한 교육적인 효과를 전달한다.

아래 코드의 적색 부분에서 센서값을 프로세싱과 시리얼포트로 주고 받는다.
참고로, 아두이노에서 사용한 코드들은 앞의 압축파일 링크에서 '1.공부'폴더에 저장된 참고자료들을 사용해, 적절히 조합한 것이다.

상세 코드는 다음과 같다.

// include the library code:
#include <LiquidCrystal.h>
#include <DHT.h>

// Relay pin
const int relay_pin = 7;
boolean relay_state = false;

// Define measurement variables
float amplitude_current;
float effective_value;
float effective_voltage = 230; // Set voltage to 230V (Europe) or 110V (US)
float zero_sensor;

// DHT instance
#define DHTPIN 6
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(10, 11, 2, 8, 4, 9);

// Variables to be exposed to the API
int temperature;
int humidity;
int light;
int effective_power;

void setup() {
  // Start Serial
  Serial.begin(9600); // 115200);
  
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  pinMode(relay_pin, OUTPUT);
  zero_sensor = getSensorValue(A1);
}

void loop() {
  // Measure from DHT
  temperature = dht.readTemperature(); // / 30.0;  // 4.7k Ohm. Calibration factor.
  humidity = dht.readHumidity(); // / 20.0;
  
  // Measure light level
  float sensor_reading = analogRead(A0);
  light = sensor_reading / 1024*100;

  // Perform power measurement
  float sensor_value = getSensorValue(A1) - zero_sensor; 

  // Convert to current. (ACS712T). http://arduinosensors.com/index.php/tag/allegro-acs712/
  float sensor_voltage = sensor_value * 10.0 / 1023.0;
  amplitude_current = (sensor_voltage - 2.5) / 0.186;
  effective_value = amplitude_current / 1.414;
  effective_power = abs(effective_value * effective_voltage / 1000); 

  String data;
  data = data + temperature + ", " + humidity + ", " + light + ", " + effective_power;
  Serial.println(data);

  // If the light level is less than 50 %, switch the lights off
  if (light < 50) 
  {
    digitalWrite(relay_pin, HIGH);
    relay_state = true;  
    lcd.begin(16, 2);
  }
  else
  {
    digitalWrite(relay_pin, LOW);
    relay_state = false; 
    lcd.begin(16, 2);
  }  
  
  // Display temperature
  lcd.setCursor(0,0);
  lcd.print("T:");
  lcd.print((int)temperature);
  lcd.print((char)223);

  lcd.setCursor(6,0);
  lcd.print("P:");
  lcd.print(effective_power);
  lcd.print("W     "); 

  lcd.setCursor(11,0);
  lcd.print("");
  lcd.print(sensor_voltage);
  lcd.print("V   "); 

  // Display humidity
  lcd.setCursor(0,1);
  lcd.print("H:");
  lcd.print(humidity);
  lcd.print("%");
  // Display light level
  lcd.setCursor(6,1);
  lcd.print("L:");
  lcd.print(light);
  lcd.print("%");  


  delay(200);
}

// Get the reading from the current sensor
float getSensorValue(int pin)
{
  int sensorValue;
  float avgSensor = 0;
  int nb_measurements = 100;
  for (int i = 0; i < nb_measurements; i++) {
    sensorValue = analogRead(pin);
    avgSensor = avgSensor + float(sensorValue);
  }
  avgSensor = avgSensor / float(nb_measurements);
  return avgSensor;
}


5. 마무리
프로세싱은 시리얼 장치, 센서, 카메라, 키텍트 등과 같은 다양한 입출력 장치 및 관련 라이브러리를 지원할 뿐만 아니라, javascript기반 node.js를 이용해, 웹 상에서 스마트폰 같은 다양한 장치를 통해, 작품을 렌더링할 수 있는 강력한 도구이다. 이를 잘 활용하면, 매력적인 그래픽스 영상을 개발할 수 있다.

상보필터(Complementary Filter) 기반 IMU 값 보정

이 글은 상보 필터를 이용해 IMU 값을 보정하는 방법을 정리한 것이다. 이 글은 다음 글을 참고하였다.

1. 개념
MPU-6050 가속도와 자이로(각속도) 센서는 이론적으로는 각 값을 누적한다면, 거리와 각도를 알 수 있어야 한다. 하지만, 센서에 노이즈가 포함되어 있어, 누적하면 할 수록 참값과는 멀어져 버려, 발산해 버리고 만다. 그러므로, 노이즈를 필터링해, 에러를 제거해 주어야 한다. 이런 기법 중 유명한 것이, 상보 필터(Complementary Filter)와 칼만 필터(Kalman Filter)이다. 이 글에서는 상보 필터를 다룬다.

2. 내용
상보 필터는 각도를 계산할 때, 단순히, 자이로값(각속도값)만 적분(합산)하지 않는다. 가속도 센서값을 함께 고려해, 에러값을 보정한다. 이 내용을 수식으로 표현하면 다음과 같다.

angle = 0.98 * (angle + gyroscope_data + delta_t) + 0.02 * (accelerometer)

여기서, 0.98과 0.02 상수값을 변경해, 필터를 얼마나 적용할 지 여부를 설정할 수 있다. 상세한 소스는 이 링크를 참고한다.

3. 마무리
다음 영상은 가속도 적분, 각속도 적분, 상보필터기반 적분 결과를 보여주는 영상이다. 상보필터가 적용되지 않은 결과들은 시간이 지나면서, 오차가 누적되는 것을 확인할 수 있다.


상보 필터는 칼만 필터에 비해, 간단하며, 아두이노와 같은 저성능 보드에서도 잘 동작하는 가벼운 알고리즘이다. 이런 필터들은 드론, 로봇, 무인 자율 주행 장치 등에 많이 활용되고 있다.