[32호]조립형 Hybrid Wheel Chair
2015 ICT 융합 프로젝트 공모전 참가상
조립형 Hybrid Wheel Chair
글 | 동양미래대학교 임우람
심사평
펌테크 기존의 전동휠체어 제품과 별다른 차이점이 없어 보인다.
JK전자 횔체어의 종류가 다양하고 일반 횔체어에 견고하게 장착을 해서 실제로 사용하려면 수 많은 시행착오와 연구 과정이 필요하겠지만 저렴한 비용으로 일반 횔체어를 전동 횔체어로 변신시켜 줄 수 있는 훌륭한 아이디어다. 어려운 사람을 위한 편의를 제공하겠다는 이런 아이디어를 생각했다는 것만으로도 박수를 쳐주고 싶고, PCB 개발부터, 소프트웨어, 기구부까지 모두 직접 구현한 노력과 열정이 대단하며 본 작품을 구현하면서 정말 많은 것을 배웠으리라 생각이 된다.
뉴티씨 아이디어 및 기술력은 참신하나 완성되지 못한 점이 마이너스 요소이다. 추후 스마트폰 어플리케이션의 연동으로 나오는 결과물이 기대된다.
칩센 기구 구현을 하기 전 레고로 모형 아이디어 구상을 하여 실수를 줄이려고 한 점이 돋보입니다. 아이디어가 타 학생들에 비해 기구물 구현 난이도가 높은 과제인데 이를 해결하기 위한 과정에 대한 자료가 부족하고 일반 전동 휠체어에 비해 하이브리드 휠체어의 차이점에 대한 부분도 부족한 것 같습니다.
위드로봇 기존 제품의 장단점을 분석하고, 아이디어를 낸 후 이를 확인하기 위해 레고와 같이 큰 비용, 시간 부담없이 자신의 아이디어를 확인한 부분은 매우 훌륭하다. PCB를 직접 아트웍한 부분도 학습 관점에서는 매우 잘 한 부분이라 생각한다. 매번 모든 과제의 PCB 아트워크를 할 수는 없겠지만 한 두번쯤은 직접 해 보는 것이 좋다고 생각한다. 아쉬운 부분은 학생이니만큼 배운다는 측면에서 모터 드라이버를 직접 제작해 봤으면 더 많은 것을 얻을 수 있는 과제가 되지 않았을까 싶다. 상용화 측면에서는 바퀴에 동력을 전달하는 부분은 어떤 형태로든 개선이 되어야 가능할 것 같으며 모터 제어에 있어 저크(jerk)를 제거하여 탑승자가 좀 더 부드럽게 움직인다는 느낌을 받게 구현하는 것이 필요해 보인다.
작품 개요
개발동기
기존의 수동휠체어와 전동휠체어의 장단점은 존재한다. 수동휠체어는 경제적이고, 휴대성이 편리하다는 이점이 있는 반면에, 몸이 불편하다는 정도에 따라 사용할 수 있는 사람의 범위가 한정되어 있고, 오르막길 혹은 내리막길 등의 지형적인 요소에 따라서 사용하기가 어렵다는 단점이 존재한다. 전동휠체어는 수동휠체어와는 반대로 사용할 수 있는 사람의 범위가 크고, 여러 지형에 관계없이 사용이 가능하다는 이점이 있는 반면에 휴대성이 불편하고 금액이 상당히 비싸다는 단점이 존재한다. 따라서 이러한 수/전동 휠체어의 단점을 보완하고 장점만을 나타낼 수 있는 제품을 필요로 함에 따라 수/전동 휠체어의 이점을 모두 가질 수 있는 Hybrid Wheel Chair의 제품이 만들어지게 된다. 하지만 기존의 Hybrid Wheel Chair는 보통 바퀴의 회전부 자체에 디스크형 모터를 같이 주문제작을 통해 위치하게 되면서 여기서 경제적인 부분이 많이 증가하게 된다.
이에 따라 우리는 기존의 수·전동화가 가능한 휠체어에 대한 단점을 보완하기 위해 조립형 Hybrid Wheel Chair를 제작하게 되었다.
기존 제품
디스크형 수/전동 휠체어
그림1. 야마하 jwx-1 |
· 수/전동 휠체어의 각 장점을 결합한 휠체어
· 모드 전환을 통해 수동모드, 전동모드 사용가능
· 디스크형 모터를 사용하여 바퀴 탈부착 가능 (편리한 휴대성)
계명대 탈착형 수/전동 휠체어
그림2. 계명대 탈착형 휠체어 |
· 전동키트가 자유롭게 탈착이 가능하도록 설계
· 기존 제품의 경제적인 측면을 보완
· 보조바퀴에 동력을 전달하여 전후진 전동화가 가능 (좌/우 방향전환에 동력을 전달하는 식이 아닌 보조적 기능)
개발 작품 설명
그림3. 레고로 구현한 hybrid wheel chair |
기존의 수동휠체어는 박스형 전동키트의 장착을 통해 전동휠체어가 된다. 탈부착이 가능하도록 하여 필요에 따라 수동, 전동 휠체어 각각의 용도로 사용할 수 있다. 이에 따라 전동휠체어의 역할을 하는 동시에 휴대성 또한 좋아지게 되었다. 모터와 배터리, 메인보드 등의 모터 구동관련 회로의 모든 연결부를 박스 형태의 구조물에 배치하여 수동 휠체어에 이를 탈부착이 가능하도록 제작하였다. 기존 제품과의 경제적인 부분에 차별성을 두고, 양쪽 바퀴 모두에 동력을 전달함으로써 조이스틱 시스템을 통해 전동휠체어와 같은 역할을 할 수 있도록 하였다.
개발과제
기존 수, 전동휠체어의 특징 파악
기존 제품들의 장단점을 정확하게 파악하고 있어야 더욱 발전된 제품을 만들 수 있다.
기구적 아이디어 및 시행착오 필요
기구의 회전부와 전동을 위한 구조물이 제대로 연결이 되어야 동력을 전달할 수 있다. 이에 따른 연결방법에 대한 아이디어 및 더 견고한 틀을 만들 수 있도록 경험적 시행착오가 필요하다.
BLDC 모터 제어
전동휠체어를 구동하기 위해선 모터를 제어할 줄 알아야 하는데, 이에 따른 하드웨어, 소프트웨어 지식을 쉽게 습득하기는 어렵다. 모터제어를 위한 공부를 정말 열심히해야 이 과제를 수행할 수 있을 것이라 생각한다.
하드웨어
메인 컨트롤러 보드
그림4. CPU 보드 | 그림5. BASE 보드 | 그림6. 메인 컨트롤러 보드 |
우리는 작년 7월 BLDC 모터제어에 필요한 회로들이 모인 메인 컨트롤러 보드를 제작하였다. 직접 만능기판에 납땜, 브레드보드를 사용 등의 방법도 있지만, 직접 PCB를 제작하는 방법을 택했다. 먼저 PCB 제작을 위한 기본적인 ORCAD 사용법과 layout 등의 실무적인 기술을 익혔고, 다음으로 작업에 들어갔었다. 이 당시 관련 직종 종사자분께 교육을 받는 영광이 있었고, 이에 따라 PCB 기판을 제작해 볼 수 있는 값진 경험을 하게 되었다.
DC-DC(step down)
입력전원 24V를 5V로 다운시켜서 CPU 전원으로 사용할 수 있도록 했다.
그림7. DC-DC converter (step down) |
CPU Header
ATmega128
그림8. CPU |
그림9. CPU LAYOUT |
그림10. 디지털 in & output |
DAC circuit (MCP 4822)
BLDC모터 드라이버의 0~5V Analog voltage를 제어하기 위해 dac converter 회로를 사용하였다. spi 통신을 통해 해당 데이터를 전송하여 속도제어를 할 수 있다.
그림11. DAC |
Buffer x2
실제 SPI 통신을 통해 데이터를 0~4096까지 보낼 수 있다. 하지만 이를 환산하였을 때 4.096V까지 제어가 되기 때문에 전압을 2배로 올려주는 회로를 배치하였다, 또한, 우리가 필요한 최대전압은 5V 이기 때문에 5V에서 컷팅하여 5V가 최대전압이 될 수 있는 회로를 배치하게 되었다.
그림12. BUFFER |
Circuit For UART
PC interface 및 조이스틱 시스템 구현을 위하여 uart통신이 필요하다. 이에 따라서 uart통신을 위한 회로를 배치하였다.
그림13. PC interface |
Bluetooth FB155BC
스마트폰 app을 통해 무선 조이스틱 시스템을 구현하기 위해 배치하였다.
그림14. bluetooth |
전체 시스템 구성
150W 모터 X2, SBDM-25A 모터 드라이버 X2, 배터리와 조이스틱, 그리고 메인 컨트롤러 보드가 합쳐지게 된다.
그림15. 전체 시스템 구성도 |
기구부
위에서 레고로 구현한 것과 같이 박스형 전동키트를 수동휠체어에 탈부착 가능하도록 제작하려고 하였다. 가장 힘들었던 부분은 뒤에서도 언급하겠지만, 바퀴인 회전부에 동력을 전달하는 것이 정말 어려웠다. 우선적으로 수동휠체어 바퀴부분에 기어를 장착하여 동력을 전달하고 싶었는데, 실제 수동휠체어 바퀴안쪽 사이즈가 우리가 원하는 사이즈로 나온 것이 없었다. 그래서 많은 고생을 하게 됐는데, 현재까지도 이 부분에 대해 큰 해결을 하지 못했다. 지금은 우선적으로 모터의 샤프트와 바퀴표면을 밀착시켜서 표면장력으로 구동할 수 있도록 하였다. 이는 소프트웨어를 먼저 확인해봐야 했기 때문에 어쩔 수 없는 선택이었다.
동력전달부 | 매미고리&합판을 사용한 탈부착 전동키트 |
우선적으로 기어로 동력을 전달하는 과제를 해결하기 이전에 표면장력으로 동력을 전달하는 것을 완벽히 하고자 하는 목표가 있었다. 따라서 처음 생각한 박스형 전동키트를 위해 알루미늄을 주문제작하여 박스키트를 만들려고 했다. 하지만 실제로 사이즈가 조금 차이가 있어서 탈부착을 하지 못했는데, 당장의 구동연습을 위해 다시 합판을 통해 제작하게 되었다.
현재 하드웨어의 문제점 및 과제
메인 컨트롤러 보드 문제점
buffer 회로문제
위에 buffer 회로를 보면 하나의 buffer회로가 핀이 두 개가 잘못 연결되었다. 반전과 비반전회로가 뒤바뀐 것이다. 처음에 왼쪽모터가 제대로 속도제어가 안되고, 자꾸 타는 냄새가 나서 뭐가 문제인지 몰랐는데, 회로도를 유심히 보지 못했던 게 너무 아쉬울 정도로 어처구니 없는 실수를 하고 말았다. 쉽게 찾을 수 있었던 문제에 많은 시간을 쓰게 되었는데, 브레드보드에 직접 회로를 여러번 구성해 보다가 문제점을 찾을 수 있게 되었다. 현재는 우선 pcb제작에 금전적인 문제 때문에 다시 제작은 못하고있고, 우선 기판을 긁어내고 점프선을 띄어 납땜한 상태이다.
그림16. 브레드보드로 회로를 구현, 에러를 찾다. |
UART 회로문제
spi 통신을 통해 모터의 속도제어가 되는 것을 확인한 후에 uart통신을 통해 기본적인 pc인터페이스를 연습하게 되었다. 연습이 한 1~2시간 잘되고 있는 와중에 갑자기 탄 냄새가 나더니 uart 통신이 가끔씩 끊기고 하는 현상이 나타나게 되었는데, 시간이 조금 더 지나고는 아예 작동이 되질 않았다. 이 부분을 거의 2개월간 원인을 찾아보았는데 결론을 확실하게 찾지를 못했다. 하나 마음에 걸리는건 pc인터페이스 연습을 하는 와중 모터드라이버와 메인컨트롤러 간에 선 연결이 한 3군데 잘못 연결되었었는데 그때 전원 차단기를 내리지 못해서 전원이 들어갔었던 적이 있었다. 그것 때문에 uart 회로부분이 문제가 생겼는지도 모르겠다고 생각을 했다. 근데 DMM으로 연결부를 다 찍어보고 회로도 구성해보고 했는데 연결은 잘돼있고, 그냥 다른 동작은 다 잘되는 것을 보면 UART 회로부분만 문제가 생긴 것 같았다. 이 부분은 다시 기판을 제작할 때 좀 더 원인을 찾아봐야 될 것 같다. 현재는 UART통신을 쓸 수가 없고, 디지털 포트 제어부분에 냉납이 심해서 우선 급한대로 인터로크 회로를 기반으로한 4방향 버튼제어로 구동을 해보았다.
그림17. 5V 릴레이를 이용한 인터로크 회로 |
기구적인 문제점
위에 설명한 것처럼, 모터 회전부에 기어를 장착하여 이를 박스형 전동키트를 통해 동력을 전달하는 것이 목표인데, 아직 완성하지 못했다. 사이즈의 문제와 아이디어가 많이 부족했던 것 같다. 현재는 앞쪽으로 표면에 동력을 전달하는 식인데 기어로 하면 뒤쪽으로 키트를 배치해야 할 것 같다.
소프트웨어
개발환경
ATmega128, AVR STUDIO 4, C언어
소스코드
spi 통신을 통한 속도제어
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int i; // 시간세기 변수
unsigned int blink_cnt1=0; // 10ms로 만들어주는 역할 중요.
unsigned int blink_cnt2=0;// 10ms로 만들어주는 역할 중요.
volatile unsigned char timer_flag=0; // 중요하다. 최적화를 하지마라 라는 것.
// 단점은 고정 메모리가1byte를 갖고잇다.
#define SS PB0
#define SCK PB1
#define MOSI PB2
#define MISO PB3
#define LDAC PB4
uint8_t junk ;
void update1(void)
{
PORTB &= ~(1<<SS); // ss핀을 low로하여 슬레이브의 동작을 허용한다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<LDAC; // LDAC set high
SPDR = 0×98; // DACB select + (속도제어)
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
SPDR = 0xFF; //send final 8 data bits , 4.095V 출력
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS; // 전송 완료후 ss신호를 high로 만들어서 송신을 끝낸다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB &= ~(1<<LDAC); //set LDAC low then high to set DAC output
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS | 1<<LDAC;
// 초기화
// add the control values for the chip
// bit 15 ,1 – DACA or DACB Select bit/ DACB Select
// bit 14 ,0 – don’t care
// bit 13 ,0 – Output gain select(x2)
// bit 12 ,1 – Output shutdown control bit(active mode)
}
void update2(void)
{
PORTB &= ~(1<<SS); // ss핀을 low로하여 슬레이브의 동작을 허용한다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<LDAC; // LDAC set high
SPDR = 0×18; // DACA select + (속도제어)
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
SPDR = 0xFF; //send final 8 data bits , 4.095V 출력
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS; // 전송 완료후 ss신호를 high로 만들어서 송신을 끝낸다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB &= ~(1<<LDAC); //set LDAC low then high to set DAC output
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS | 1<<LDAC;
// 초기화
// add the control values for the chip
// bit 15 ,0 – DACA or DACB Select bit/ DACA Select
// bit 14 ,0 – don’t care
// bit 13 ,0 – Output gain select(x2)
// bit 12 ,1 – Output shutdown control bit(active mode)
}
void display10(void)
{
}
ISR(TIMER2_COMP_vect) // 메인 타이머 인터룹트 함수!!! 레지스터 값 지정을 통하여 1msec로 들어온다.
{
timer_flag=1;
// 이 안에는 왠만하면 간단한 것만 넣어야한다!
// flag를 통해 1ms후에 들어오면 1로 표시 해준다. flag는 0,1의 논리값
}
void timer (void)
{
TCCR2 = 0x0B; // timer/counter control register, clk/64 , CTC모드, normal 설정
TCNT2 = 0; // 시작 지정 (실제로 세는것 이것이 카운트된다)
OCR2 = 249; // 0~249로 해서 250번 센다. 1ms 로 만들어 준 것이다.
//즉 tcnt =o cr이되면 딱 1ms이며 이때 인터룹트가 발생되는데 이 모드가 ctc모드이다
TIMSK = 0×80; // T2 OCR2 interrupt 해당지정.
}
void SPI_MasterInit(void) //spi 마스터 레지스터설정
{
//Init Ports
DDRB = 0b00010111;// LDAC,MOSI,SCK,SS 출력 , MISO 입력
PORTB |= 1<<SS;
// SS 비활성화
//Init SPI
SPCR |= 1<<SPE | 1<<MSTR | 1<<SPR1;
// SPI 제어 레지스터이다. SPI활성화, 마스터 설정, 1/64 분주율
// 7bit – spi 인터럽트 활성화 비트 – clear
// 6bit – spi 활성화 비트 – set
// 5bit – 데이터 전송 순서 비트 – msb부터
// 4bit – 마스터/슬레이브 모드 선택 비트 – master set
// 3bit – 클록극성비트 – 데이터가 전송될때 HIGH유지
// 2bit – 클록 위상비트 – 클록의 앞쪽 에지에 데이터를 샘플링한다, cpol비트를 결합하여 결정.
// 송신 데이터 셋업은 하강에지, 수신 데이터 샘플링은 상승에지 이다.
// 1,0bit – 1/64 분주
}
#define forword 0×40
#define stop 0×01
#define Break 0×02
// 드라이버 모드 선택비트
int main (void)
{
// 타이머2 레지스터 설정.;
DDRC = 0xFF;
timer(); // timer2 register set
SPI_MasterInit(); // spi register set
sei(); // global interrupt enable
//set enable interrupt
while(1)
{
PORTC= 0×55;
for(i=0; i<60000; i++){}
for(i=0; i<60000; i++){}
for(i=0; i<60000; i++){}
PORTC= 0xAA;
for(i=0; i<60000; i++){}
for(i=0; i<60000; i++){}
for(i=0; i<60000; i++){}
// LED 확인
if (timer_flag !=0) // 0이 아니라면· { timer_flag=0;// 초기화를 꼭시켜야한다. 이러면 1ms마다 타이머 인터럽트함수가 왓다갓다 실행된다.
cli();// 인터럽트 클리어
update1();
update2();
display10(); sei(); //enable interrupt
}
}
}
uart 통신을 통한 pc인터페이스
#include <avr/io.h>
#include <avr/iom128.h>
#include <avr/interrupt.h>
unsigned int i; // 시간세기 변수
unsigned int blink_cnt1=0; // 10ms로 만들어주는 역할 중요.
unsigned int blink_cnt2=0; // 10ms로 만들어주는 역할 중요.
volatile unsigned char timer_flag=0; // 최적화를 하지말라는 뜻.
// 단점은 고정 메모리가1byte를 갖고잇다.
#define SS PB0
#define SCK PB1
#define MOSI PB2
#define MISO PB3
#define LDAC PB4
uint8_t junk ;
void update1(void)
{
PORTB &= ~(1<<SS);
// ss핀을 low로하여 슬레이브의 동작을 허용한다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<LDAC; // LDAC set high
SPDR = 0×90; // DACB select + data 속도값
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
SPDR = 0xFF; //send final 8 data bits , 4.095V 출력
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS; // 전송 완료후 ss신호를 high로 만들어서 송신을 끝낸다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB &= ~(1<<LDAC); //set LDAC low then high to set DAC output
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS | 1<<LDAC;
// 초기화
// add the control values for the chip
// bit 15 ,1 – DACA or DACB Select bit/ DACB Select
// bit 14 ,0 – don’t care
// bit 13 ,0 – Output gain select(x2)
// bit 12 ,1 – Output shutdown control bit(active mode)
}
void update2(void)
{
PORTB &= ~(1<<SS); // ss핀을 low로하여 슬레이브의 동작을 허용한다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<LDAC; // LDAC set high
SPDR = 0×10; // DACA select + data 속도값
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
SPDR = 0xFF; //send final 8 data bits , 4.095V 출력
while (!(SPSR & (1<<SPIF))); //전송완료 기다림
junk = SPDR;
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS; // 전송 완료후 ss신호를 high로 만들어서 송신을 끝낸다.
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB &= ~(1<<LDAC); //set LDAC low then high to set DAC output
for(i=0; i<1; i++){} //2.5us 지연 시간 설정
PORTB |= 1<<SS | 1<<LDAC;
// 초기화
// add the control values for the chip
// bit 15 ,0 – DACA or DACB Select bit/ DACA Select
// bit 14 ,0 – don’t care
// bit 13 ,0 – Output gain select(x2)
// bit 12 ,1 – Output shutdown control bit(active mode)
}
void display10(void)
{
}
// uart start //
unsigned char get_data(void)
{
while(!(UCSR0A&0×80)); // 수신완료될때까지 대기
return UDR0;
}
void send_data(unsigned char data)
{
while(!(UCSR0A&0×20)); // 송신데이터를 받을 준비가 될때까지 대기
UDR0 = data;
if(data == ‘1’) // 만약 터미널에서 날아온 데이터가 숫자 1 이라면
{
SPDR = 0×90;
}
else if(data == ‘2’) // 만약 터미널에서 날아온 데이터가 숫자 2이라면
{
SPDR = 0×91;
}
else if(data == ‘3’) // 만약 터미널에서 날아온 데이터가 숫자 3이라면
{
SPDR = 0×92;
}
else if(data == ‘4’) // 만약 터미널에서 날아온 데이터가 숫자 4이라면
{
SPDR = 0×93;
}
else if(data == ‘5’) // 만약 터미널에서 날아온 데이터가 숫자 5이라면
{
SPDR = 0×94;
}
else if(data == ‘6’) // 만약 터미널에서 날아온 데이터가 숫자 6이라면
{
SPDR = 0×95;
}
else if(data == ‘7’) // 만약 터미널에서 날아온 데이터가 숫자 7이라면
{
PORTC=0b11001111; //정방향
}
else if(data == ‘8’) // 만약 터미널에서 날아온 데이터가 숫자 8이라면
{
PORTC=0b10001111; //역방향
}
else if(data == ‘9’) // 만약 터미널에서 날아온 데이터가 숫자 9이라면
{
PORTC=0b10011111; //stop
}
else if(data == ‘0’) // 만약 터미널에서 날아온 데이터가 숫자 0 이라면
{
PORTC=0b10001111; //run
}
}
ISR(TIMER2_COMP_vect)
// 메인 타이머 인터룹트 함수!!! 레지스터값지정을 통하여 1msec로 들어온다.
{
timer_flag=1; // 이 안에는 왠만하면 간단한 것만 넣어야한다
// flag를 통해 1ms후에 들어오면 1로 표시 해준다. flag는 0,1의 논리값으로 주로 쓰임
}
void timer (void)
{
TCCR2 = 0x0B; //timer/counter control register, clk/64 , CTC모드, normal 설정
TCNT2 = 0; // 시작 지정 (실제로 세는것 이것이 카운트된다)
OCR2 = 249;
// 0~249로해서 250번 센다. 1ms 로 만들어 준것이다.
// 즉 tcnt =o cr이되면 딱 1ms이며 이때 인터룹트가 발생되는데 이모드가 ctc모드이다
TIMSK = 0×80; // T2 OCR2 interrupt 해당지정.
}
void SPI_MasterInit(void)
//spi 마스터 레지스터설정
{
//Init Ports
DDRB = 0b00010111;// LDAC,MOSI,SCK,SS 출력 , MISO 입력
PORTB |= 1<<SS; // SS 비활성화
//Init SPI
SPCR |= 1<<SPE | 1<<MSTR | 1<<SPR1;
// SPI 제어 레지스터이다. SPI활성화, 마스터 설정, 1/64 분주율
// 7bit – spi 인터럽트 활성화 비트 – clear
// 6bit – spi 활성화 비트 – set
// 5bit – 데이터 전송 순서 비트 – msb부터
// 4bit – 마스터/슬레이브 모드 선택 비트 – master set
// 3bit – 클록극성비트 – 데이터가 전송될때 HIGH유지
// 2bit – 클록 위상비트 – 클록의 앞쪽 에지에 데이터를 샘플링한다, cpol비트를 결합하여 결정.
// 송신 데이터 셋업은 하강에지, 수신 데이터 샘플링은 상승에지 이다.
// 1,0bit – 1/64 분주
}
int main (void)
{ UCSR0A = 0×00; // ready flag clear
UCSR0B = 0×18; // rx, tx enable
UCSR0C = 0×06; // tx data len : 8bit
UBRR0H = 0;
UBRR0L = 51; // boudrate 19200
DDRC = 0xFF;
timer(); // timer2 register set
SPI_MasterInit(); // spi register set
sei();// global interrupt enable
//set enable interrupt
while(1)
{
send_data(get_data());
if (timer_flag !=0) // 0이 아니라면
{
timer_flag=0;
// 초기화를 꼭시켜야한다. 이러면 1ms마다 타이머 인터럽트함수가 왔다갔다 실행된다.
cli();// 인터럽트 클리어
update1();
update2();
display10(); sei();
//enable interrupt
}
}
}
앞으로의 과제
하드웨어의 UART 회로 부분의 에러가 해결이 되면, 제일 먼저 무선 조이스틱 시스템을 위한 PID제어 알고리즘과 XY축의 각각의 위치값을 통해 속도와 방향을 제어할 수 있는 프로그램을 작성해야 한다. 또한 이 과제를 수행한 뒤엔, 스마트폰 APP 개발환경을 구축하여 APP을 이용한 모터제어를 해야 한다.
결론
사실 처음 하이브리드형 휠체어를 만들 계획을 할 때에는 작업이 참 순조롭고 어려움없이 해낼 수 있었던 것 같았다. 하지만 전혀 아니었다. 회로 구성부터 pcb제작 그리고 프로그래밍, 기구부 설계 등등 단 하나도 쉬운 것이 없었다. 평소 학점관리 하면서 공부했던 전공지식만으로는 실무에 가까운 이런 작품 제작과정이 너무 어렵기만 한 것이 사실이었다. 지금 생각해보면 정말 하루하루 애타는 마음을 갖고 작업했던 것 같다. 회로관련 서적과 프로그램관련 서적을 수십 권씩 찾아보고 google 등의 포털 사이트를 통해 정보를 수집하면서 정말 수시로 밤을 샜었는데 정말 좋은 경험이 되었다. 안될 것만 같았던 모터구동도 성공해보고 하니 앞으로 해야 할 것도 꼭 할 수 있다는 자신감도 생기곤 한다.
결론적으로 작품 완성도는 많이 부족한 편이다. 솔직히 지금까지 공부를 해서 제작을 진행했다면 완성했을 것도 같지만, 졸업 후의 여러 개인적 사정과 같이 공부했던 인원들의 스케줄 등이 여유롭지 않아서 작품을 진행하지 못했었다. 하지만 아쉬움이 많이 남는 작품이라서 다시 한번 뭉쳐서 해볼 생각이다. 처음 학교에 입학할 때는 많이 부족해서 옴의법칙도 어려워 했던 본인인데, pcb 제작부터 모터구동 그리고 프로그래밍 기본적인 지식 등을 습득한 것 등의 성과를 냈다는 것만으로도 전기 관련 전공자로서의 길을 걷기위한 첫 번째 단계는 넘었다고 생각을 했다. 그래서 더욱 힘이 나고 학업에 대한 열의를 갖게 해준 좋은 경험이라고 생각한다. 앞으로 더 열심히 공부하고 작업해서 꼭 작품을 완성해보고 싶다.
작업사진
[32호]스마트 가로등 조명제어 시스템
2015 ICT 융합 프로젝트 공모전 참가상
스마트 가로등 조명제어 시스템
글 | 상명대학교 황인철, 유정이, 이정욱, 장삼열, 정희주
심사평
jk전자 중앙 집중식이 아닌 가로등에서 가로등으로 전달되는 방식의 네트워크를 이용하면 보고서의 내용대로 초기 개발과 투자 비용이 절약될수 있을 수 있으나, 개별적인 신호 전달을 통한 방법의 가장 큰 문제점은 중간에 1개의 노드라도 고장이 나거나 문제가 발생했을 경우에 대한 대비가 쉽지 않다는 것이다. 야간에 차량이 빠르게 주행하고 있는데, 여러 가로등 중에서 1~2개가 문제가 생겨 가로등이 1개라도 제대로 켜지지 않으면 위험한 상황이 발생할 수도 있을 것이다.
뉴티씨 차량 정보를 통해 가로등을 제어할 수 있는 점은 꽤 좋은 생각이며 차도에서 이 솔루션을 적용할 경우 단가 절감을 기대할 수 있다. 그러나 인도에서 적용한다면 크게 달라진다. 사람이 걷는 소리는 차량 통행시 발생하는 소음보다 작기 때문이다. 그리고 가로등은 차량보다는 사람의 가시성 확보를 위해 설계된 시설물이니, 이 부분을 보완했다면 좋았을 것 같다.
칩센 스마트 가로등 조명제어 시스템은 이미 2014년도 최원철 학위논문(석사)으로 발표 된 것과 거의 동일함으로 평가 대상자로 적합하지 않다고 본다.
위드로봇 제안한 아이디어의 핵심 요소 기술은 “가로등에 접근하는 물체를 어떻게 인식할 것인가?”와 “가로등끼리 어떻게 통신할 것인가?” 이다. 하지만 보고서에는 전자 기술의 경우 “마이크를 활용하여 차량 이동 시 발생하는 소리 이외에는 제거”라고 간단히 기술되어 있으며, 후자 기술은 “RF 무선 통신 모듈을 활용하여 정보 공유”로만 언급되어 있다. 본 보고서만으로는 구현한 시스템의 기술적인 차별성이나 구현의 완성도를 판단하기 어렵다.
개요
지구 온난화로 인해 세계 각국에서는 효율적 에너지 소비를 위한 에너지 절감 기술 또는 대체에너지에 관한 많은 연구들이 이루어지고 있다. 차량의 유무에 상관없이 항시 점등되어 있는 현재의 가로등 시스템은 과도한 에너지를 소비하는 장치 중 하나로 에너지 절감형 시스템의 도입이 필요하다.
과도한 CO₂ 방출의 폐해로 인해 가로등 시스템 분야에서는 태양광 에너지와, 조명 장치의 전력소모를 줄일 수 있는 LED가 결합된 태양광 LED 가로등 시스템이 각광을 받고 있다. 하지만, 태양광 LED 가로등 시스템은 태양광 패널의 낮은 전기 변환 효율과 축전지 용량의 한계 등으로 상용화에 어려움을 겪고 있다. 국내에서는 수출의 경우 최근 (주)서울마린에서 약 1000기에 해당하는 태양광 독립형 LED 조명 시스템을 해외에 수출 한 것이 전부이며, 내수는 일부 지차체 등에서 시범적인 운용만을 하고 있다. 기존에 공급된 시스템은 태양광 LED은 연속적인 흐린 날씨를 대비하여 태양광 전지 및 배터리 용량을 과도하게 설계되었거나, 야간의 일부시간에만 동작하는 등의 기술적 한계를 갖고 있다. 이런 문제를 극복하기 위해, 차량 운행 정보에 따라 지능적으로 가로등을 제어함으로써 전력사용 효율을 높여 이러한 단점을 극복한다면 태양광 LED 가로등 시스템의 국내 조기 도입 및 해외 수출에 크게 기여할 수 있을 것이다.
또한 현재까지 제시된 가로등의 전력 사용 효율을 높이는 기술 중에는 중앙 집중형 제어 구조를 가지고 있거나 이동 통신망을 활용하는 지능형 가로등 시스템이 있다. 하지만 중앙 집중형 구조가 갖는 고유한 문제인 초기투자 비용이나 이동 통신망을 활용할 경우 발생하는 유지비용등을 고려하면 현재 시장에 도입하기에는 매력적이지 못하다. 또 한, 차량 운행을 감지하는 방법에 대한 구체적 기술이 IP화 및 상품화되어 있지 않다. 도로상의 차량의 소리를 측정하여 차량의 유무를 판별하는 독창적 차량 인식 시스템과, 인식된 차량 정보를 공유하는 무선네트워크 등으로 구성되어 각각의 가로등이 개별적으로 가로등을 제어하는 분산형 태양광 가로등 제어 시스템이다. 분산형 시스템을 적용할 경우 중앙집중형 가로등 제어시스템이 갖는 단점인 초기 투자비 및 운용비를 줄임과 동시에 에너지 효율을 획기적으로 높일 수 있을 것이다. 국가적으로 조성하고 있는 자전거 전용 도로에 설치하기 최적화된 제품이며, 태양광 독립형 LED 조명 시스템뿐 만 아니라 일반 가로등에도 적용할 수 있는 기술로서 제품의 수요처는 무궁무진하다.
본 결과물의 응용분야로는 도로상의 나트륨 가로등, 태양광 LED 가로등 같은 가로등 분야에 직접 적용할 수 있으므로 태양광 LED 가로등의 조기 상용화에 기여를 할 수 있을 뿐 아니라, 비효율적 운용으로 낭비되는 국고와 CO₂발생량을 감소시키는 녹색기술 중 하나이다.
작품 설명
주요 동작 및 특징
본 기술은 자전거 전용도로 혹은 일반 고속도로 등에 설치하여 에너지를 절감하고자 하는 지능형 태양광 LED 조명 시스템이다. 본기술은 태양광 독립형 LED 조명 시스템이나 자전거 전용 LED 조명 그리고 나트륨등을 활용한 조명 시스템에 적용이 가능하다. 또한 이미 설치되어 있는 태양광 가로등 및 기존 나트륨 등에 추가 적용할 수 있다는 장점이 있어, 새로운 태양광 LED 조명의 수요처 뿐 아니라 기존 설치된 가로등 조명 시스템에 추가 공급할 수 있어 시장은 매우 넓다고 할 수 있다. 상기 열거된 조명 시스템에 적용되어 차량 운행 또는 사람의 이동 정보에 따라 지능적으로 가로등을 제어함으로써 에너지 효율을 극대화 할 수 있으며, 중앙 집중형이 아닌 분산형으로 동작함으로써 초기 투자비와 유지비가 과도할 수 있는 중앙 집중형이 갖는 단점을 극복할 수 있다.
그림 1-2. 자전거 전용 도로에 적용 |
이런 장점을 가진 독립형 태양광 LED 시스템에 본 제품이 적용된다면, 열악한 환경(일조량이 매우 적어 충전된 전기를 오랜 시간 사용할 수 없는 환경 등)을 고려하여 과도하게 큰 용량을 가지는 배터리 혹은 태양전지로 인한 가격상승 및 과도한 투자/유지비 등의 단점을 극복하여 태양광 LED 조명의 보급을 촉진 시킬 수 있을 것이다.
본 기술을 활용 예시를 통해 간략히 살펴본다면, 현재 정부와 지자체에서 적극적으로 확충을 추진 중인 자전거 전용도로에 설치되었을 경우 그림 1에서 보는 바와 같이 자전거가 이동할 때 인체 감시 센서 혹은 초음파 센서 등을 활용하여 사람을 인식하고 다음 가로등의 조명을 밝게 하거나 켜고, 지나간 위치의 가로등을 끄는 형태로 지능적으로 동작하여 에너지 효율을 높일 수 있다.
지능형 태양광 LED 조명 시스템이 그림2와 같이 자동차 도로에 적용 된 경우에는 음성 신호처리 기법을 이용하여 바람소리와 같이 정확한 차량인식에 방해가 되는 노이즈 성분을 제거한 후, 음성의 절대적 크기를 감지하고 감지된 크기를 차량 이동이 거의 없는 시간대의 음성신호와 비교하여 차량의 진입여부를 정확히 감지할 수 있다. 감지한 차량의 정보는 무선 센서 네트워크를 구성하여 다음 가로등 시스템에 제어 정보를 전송하고, 전송받은 제어 정보를 통해 가로등의 밝기를 조절하거나 점등/점멸하여 가로등을 제어한다.
아래 그림은 보유기술의 시제품의 가상도로서 보유기술은 세부적으로 차량 혹은 인체를 인식하는 센서부와 무선 센서네트워크를 구성하기 위한 통신부, 그리고 가로등 점멸을 위한 제어부로 구성되어 있다.
그림 3. 지능형 태양광 LED 조명 시스템의 Control Box |
그림 4에서는 본 기술의 개략적인 시스템 구성도를 나타내었다. 그림4에 나타난 것과 같이 전체 시스템은 차량을 감지하는 센서부(20), 가로등 간의 통신이 이루어지는 통신부(30), 가로등을 구동하는 구동부, 이 모든 것을 제어하는 제어부(10)로 이루어져 있으며 차량을 감지하여 가로등 간에 구성된 무선 센서네트워크를 통해 차량 통행 정보를 교환하여 차량 운행에 따라 가로등을 제어한다.
그림 A 전체 시스템의 구성 | 그림 B 센서부의 구성 |
특히 지능형 태양광 LED 시스템에서 핵심적인 역할을 수행하는 차량 인식 모듈인 센서부(20)는 그림 5에서 보는 바와 같이 소리 측정부(22), 속도 측정부(23)와 계산을 하게 되는 계산부(21)로 구성되며 계산부는 다음 가로등의 점멸 시간을 계산할 수 있도록 차량의 통행 유무 또는 속도 등의 차량 정보를 추출해 낼 수 있는 장치이다.
전체 시스템구성
전체 시스템의 동작 순서와 알고리즘은 그림 A에 나타내었다. 그림 6에서와 같이 개발될 시스템은 센서부에서 설정된 기준값과 측정값을 비교하여 차량의 유무를 판별하여 가로등을 제어하게 되고, 각 가로등 간의 통신이 이루어져 유기적인 동작을 하게 된다. 전체 시스템 중 핵심이 되는 센서부의 구체적 알고리즘은 그림 7에서 나타내었다. 차량을 인식하는 과정을 간략히 요약하면, 차량 운행이 없는 상태에서 소리를 측정하여 저장 후 그 값에 대한 평균값을 계산하게 되고, 평균값에 대한 평균값을 다시 계산하는 과정을 반복하여 기준값을 설정하게 된다. 설정된 기준값을 일정 시간이 지나면 재설정하여 그 정확성을 높인다. 차량이 없는 상태의 기준값이 설정되면, 실제 차량의 운행 시 발생되는 소음만을 filtering해서 나온 결과물을 기준값과 비교하여 차량의 통행여부를 판별하고, 차량의 운행 속도 등의 정보를 추출한다.
그림 C. 전체 순서도 | 그림 D. 센서부 순서도 |
구동부
· Atmega16
음성인식부
· 마이크를 활용하여 차량 이동 시 발생하는 소리 이외에는 제거
· 차량의 소리를 인식하여 차량의 유무와 이동방향을 검출
센서부
· 초음파 센서를 활용하여 차량의 속도를 검출
· 자전거 전용도로에 적용하여 자전거를 인식
무선 네트워크부
· RF 무선 통신 모듈을 활용하여 다음 가로등과 정보 공유
개발환경
- | 환경 | 비고 |
CodeViesionAVR | 제어부를 코딩하기 위해 사용 | |
Proteus 8 Professional | 작업 초기 시뮬로 사용 | |
ATmega16 | 제어부로 사용 |
기술 구현
먼저 지능형 태양광 LED 조명 시스템을 활용 예시를 통해 간략히 살펴본다면, 현재 정부와 지자체에서 적극적으로 확충을 추진 중인 자전거 전용도로에 설치되었을 경우 자전거가 이동할 때 인체 감지 센서 혹은 초음파 센서 등을 활용하여 사람을 인식하고 다음 가로등의 조명을 밝히고, 지나간 위치의 가로등을 끄는 형태로 지능적으로 동작하여 에너지 효율을 높일 수 있다.
지능형 태양광 LED 조명 시스템이 <그림 7>과 같이 자동차 도로에 적용된 경우에는 음성 신호처리 기법을 이용하여 바람소리와 같이 정확한 차량 인식에 방해가 되는 노이즈 성분을 제거한 후 음성의 절대적 크기를 감지하고 감지한 크기를 차량 이동이 없는 시간대의 음성 신호와 비교하여 차량의 진입여부를 정확히 감지할 수 있다. 감지한 차량의 정보는 무선 센서 네트워크를 구성하여 다음 가로등 시스템에 제어 정보를 전송하고, 전송받은 제어 정보를 통해 가로등의 조명을 제어한다.
그림7. 자동차 전용도로에 적용 |
<그림 8>에서는 지능형 태양광 LED 조명 시스템의 제어 블록도를 나타내었다. <그림 8>에 나타난 것과 같이 전체 시스템은 가로등의 점등을 제어하는 가로등 구동부(110)와 타 가로등 장치와 통신하기 위한 통신부(120), 특정 방향으로 이동하는 감지 대상체의 이동을 감지하는 대상 감지부(130), 대상 감지부(130)를 통해 감지 대상체의 이동을 감지한 감지 결과에 따라 감지 대상체가 정의된 진입범위 내로 이동한다고 판단되면 이에 대응하여 가로등 구동부(110)를 제어하고 감지 결과에 근거한 점등제어정보를 통신부(120)를 통해 인접한 타 가로등 장치로 제공하는 제어부(140)로 이루어져 있다.
그림 8. 전체 시스템의 제어 블록도 |
지능형 태양광 LED 조명 시스템의 동작은 <그림 9>와 같이 가로등 장치는 감지 대상체의 이동을 감지하여 이동을 감지한 감지 결과, 감지 대상체가 정의된 진입범위 내로 이동한다고 판단되면 이에 대응하여 점등 기능을 제어하고 감지 결과에 근거한 점등제어정보를 인접한 타 가로등 장치로 제공한다. 타 가로등 장치는 제공된 점등제어정보를 토대로 자신의 점등 기능을 제어한다. 예를 들면, 타 가로등 장치는 제공된 점등제어정보로부터 점등대기시간정보를 인지하거나 점등제어정보에 근거하여 자체적으로 점등대기 시간정보를 계산하고, 이러한 점등대기 시간정보에 대응하여 가로등을 점등 또는 점멸할 수 있다.
그림 9. 지능형 태양광 LED 조명 시스템의 흐름도 |
기대효과
■ 태양광 LED가로등의 조기 상용화에 기여
태양광 LED가로등은 태양광전지로 전기를 생산하여 축전지에 저장한 후 야간에 조명을 켜는 차세대 가로등 시스템이다. 하지만, 현재 태양광 전지의 효율 및 축전지 용량 등의 문제와 함께 일조량의 문제로 항상 일정한 에너지를 축적할 수 없는 문제점으로 순수 대체에너지를 사용한 태양광 LED가로등 시스템은 갈 길이 멀다고 할 수 있다. 결과물로 가로등 시스템의 에너지 효율을 획기적으로 증가시킬 수 있다면 상기 단점을 극복할 수 있어 대체 에너지인 태양광을 활용한 가로등 시스템을 조기 도입할 수 있을 것이라 기대된다.
■ 차량 감지를 이용한 효율적 에너지 소비 및 국고 절감효과
야간 도로상의 나트륨 가로등(250W)을 1일 12시간 기준으로, 한 개의 가로등 당 연간 사용소비전력은 1,686.3KW이며, 100개의 가로등 총 사용량은 168,630KW, KW당: 75.50원 가로등 요금을 적용, 산출하면 전체 전기 요금은 12,731,565원이지만 본 사업 아이템을 적용 하여 차량의 유무에 따라 가로등을 제어함으로써 점등시간의 단축으로 인하여 사용소비전력 감소로 효율적 에너지 소비 및 연간 가로등에 사용되었던 예산을 보다 절감함으로써 국가 발전에 이바지 할 수 있다.
■ 유사 제품 대비 낮은 경쟁력
지능형 태양광 LED 시스템의 핵심 모듈 중 하나인 차량 인식부분을 마이크를 활용한 음성 신호처리 기술을 적용함으로써 이는 타 적외선, 레이저 등의 센서 보다 저비용으로 구현이 가능하다. 또한 분산형태의 시스템으로 초기 투자비용 및 유지비용이 저렴하며 현재 시스템에도 바로 적용 가능하므로 본 기술의 가로등 시스템을 조기 도입할 수 있을 것이다.
■ 효율적 에너지 소비로 인한 CO₂발생량 감소
가로등에 많이 사용되는 250W 나트륨등의 경우 12시간 동안 켰을 때 소모되는 전력 1㎾당 420g의 CO₂가 발생이 된다. 이러한 가로등 1만기가 연간 배출하는 CO₂의 양은 5000톤 가까이 되지만 본 사업의 결과물을 도입하면 차량의 유무에 따라 점등이 되므로 즉 점등시간을 단축시킴으로써 전력소비를 줄여 CO₂의 발생량이 감소하는 효과를 기대할 수 있다.
실제사진 |
설계도면 |
|
음성처리 소스코드 일부 |
[32호]비닐하우스 자동 제설 및 자동 습도 조절장치
2015 ICT 융합 프로젝트 공모전 참가상
비닐하우스 자동 제설 및 자동 습도 조절장치
글 | 동아대학교 김준호, 김태구, 천현재
심사평
jk전자 작품의 창의성 면에서 누구나 생각할수 있는 지극히 평범한 아이디어이다. 눈을 쓸어 내리는 방법도 와이퍼를 이용하기 보다는 비닐하우스의 지붕을 이중화 하여 지붕 자체를 개폐하여 눈을 흘러내리도록 하는 방법도 많이 상용화가 되어 있다.
뉴티씨 비닐하우스에 쌓인 눈을 효과적으로 제거할 수 있고, 아무도 생각하지 못한 방법으로 하였기 때문에 창의성 및 완성도에 높은 점수를 주고 싶다. 또한 자동 습도 조절 장치와의 통합을 통해 시스템의 단가를 줄인 것도 하나의 큰 장점이 될 수 있다. 하지만 이런 솔루션을 구축했을 경우 대형화가 걸림돌이다. 스테핑 모터의 경우 토크가 제한되기 때문에, AC모터나 DC기어드 모터 등을 이용한 대형 솔루션으로 방향을 잡고, 이 부분에 대한 향후 업그레이드를 보고서에 설명했다면 어땠을까 하는 생각이 든다.
칩센 비닐하우스 자동제설 및 자동습도조절장치의 자동 제설은 이미 거의 비슷하고 좀 더 효율적으로 적용된 특허가 이미있고, 자동습도조절 장치 또한 이미 많이 보급되어 있는 방식이다. 본제품은 융합이라기보단 이미 있는 특허나 현재 사용중인 제품의 모방이라 볼 수 있어 평가 대상으로 부적합하다고 본다.
위드로봇 저출산 고령화 시대에 농업 경쟁력을 높이기 위하여 농업의 자동화 연구는 최근 많은 관심을 받고 있다. 미니어처에서 가능성을 테스트해 본 것은 좋은 시도이나, 구현한 미니어처가 현장 상황의 핵심 부분을 잘 표현하기는 어려워 보인다. 적설량을 초음파 센서로 계측하는 방법을 시도했는데, 기존에는 어떻게 적설량을 자동으로 계측하고 있는지 조사가 선행되었으면 더 좋은 연구가 되었을 것 같다.
작품 개요
비닐하우스는 채소, 원예, 과일 등의 작물을 재배하거나 닭, 오리 등 가축을 사육하기 위하여 비닐과 설치대를 이용하여 집처럼 만든 것을 말하는 것으로, 햇빛이 쉽게 유입되고 외기를 차단하도록 설치함으로써 내부를 일정 온도로 유지시킨다.
이 프로젝트는 겨울철 폭설로 인해 비닐하우스 지붕에 쌓이는 눈의 하중에 의해 비닐하우스가 훼손되거나 붕괴되어 경작중인 채소, 원예, 과일 등 작물의 피해와 닭, 오리 등의 가축의 폐사를 미연에 방지하여 농가의 피해를 최소화할 수 있는 폭설대비용 비닐하우스에 관한 것이다.
도심 도로에 눈이 쌓이면, 소금이나 염화칼슘, 혹은 모래 등을 사용하여 제설작업을 한다. 그러나 비닐하우스 지붕 위에 제설제를 매번 뿌릴 수는 없는 일이다. 따라서, 겨울철에 비닐하우스 지붕에 쌓이는 눈에 의해 비닐하우스가 붕괴되는 것을 방지하기 위한 여러 방안이 강구되고 있는 실정이다.
현재 가장 간단하면서 보편적으로 행해지는 방법은 비닐하우스 중앙 부위를 받쳐줄 가볍고 튼튼한 받침대를 미리 준비해두었다가 폭설이 내렸을때 받쳐서 사용하는 방법이다. 그러나 이런 방법으로는 붕괴의 위험이 항상 있어 효과적인 폭설대비를 할 수 없다.
한편 일정한 물리적 방법에 의한 제설 방법들이 연구되고 있다. 예를 들면, 비닐하우스 내에 설치된 보일러의 온수를 이용하여 비닐하우스 지붕에 쌓이는 눈을 녹이는 방법이 있다. 그러나 장시간 눈이 오는 경우에는 많은 양의 온수를 확보할 수 없고, 제설을 위해 사용된 온수가 오히려 비닐하우스 주변에 얼어붙는 문제점이 있다.
그래서 사용 방법으로는 비닐하우스 지붕 위에 쌓인 눈을 스테핑 모터를 이용하여 쓸어내리는 방법이다.
작품 설명
주요 동작
① 제설 시스템 동작 원리
일정량 이상의 눈이 비닐 하우스 지붕 위에 쌓이면 설치된 초음파 센서가 감지하게 된다. ATmega128 모듈은 초음파센서 감지 신호를 받고 스테핑모터로 신호를 보낸다. 스테핑모터는 80° 정 회전 후, 160° 역회전 하여 눈을 제거하고, 다시 80° 정회전하여 원래 위치로 이동한다.
② 습도조절 시스템 동작 원리
비닐하우스 내에 온·습도 센서가 위치하고 습도를 감지한다. 온·습도 센서의 습도 감지 값이 일정 값 이하로 하강하면, ATmega128 모듈은 워터펌프로 신호를 보낸다. 워터 펌프는 ON상태가 되어 물을 보내고 비닐하우스 내에 설치된 스프링쿨러에 의해 물이 분사되어 습도를 상승시킨다.
특징(기대효과)
① 폭설이 내렸을 때, 자동으로 제설 와이퍼가 동작하여 비닐하우스 지붕 위의 눈을 쓸어내어 지붕의 붕괴를 막음으로써 폭설 피해 최소화.
② 저 습도시, 자동으로 물이 분사되어 습도를 조절함으로써 비닐하우스의 효율적 운영 가능.
전체 시스템 구성
① 하드웨어 구성
② 비닐하우스 모형 구성
③ 동작 시스템 구현
자동 제설장치
자동 습도 조절 장치
개발 환경(개발 언어, Tool, 사용시스템 등)
① 언어 : C
② Tool : AVRStudio
③ 사용 칩 : ATmega128
단계별 제작 과정
① 동작 원리 구상
② 하드웨어 설계
- 전자기기 구성 설계 : 기타.
③ 회로도 참고.
- 비닐하우스 모형 기구부 설계
기초설계
상세설계
비닐하우스 전면도(단위:mm)
③ 소프트웨어 설계
기타. ② 소스코드 참고.
④ 부품 선정
⑤ 부품 및 기구부 재료 구매
⑥ 비닐하우스 및 초음파센서 감지 탑 모형 제작
⑦ 각 기기 및 모형 조립
기타(회로도, 소스코드, 참고문헌 등)
① 소스코드
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include “dht.h”
#include “ATmega128_v20.H”
unsigned int Humi,Temp;
unsigned int Echo_count;
unsigned int sum;
unsigned char pattern1[8]
= {0x0C, 0×06, 0×03, 0×09, 0x0C, 0×06, 0×03, 0×09};//스테핑모터 정회전 패턴이다.
unsigned char pattern2[8]
= {0×09, 0×03, 0×06, 0x0C, 0×09, 0×03, 0×06, 0x0C};//스테핑모터 역회전 패턴이다.
ISR(INT0_vect)//외부인터럽트 서비스 루틴 함수.
{
Echo_count=TCNT1;// TCNT1을 Echo_count로 변경
}
int8_t dht_getdata(int8_t *temperature, int8_t *humidity)
{
uint8_t bits[5];
uint8_t i,j = 0;
//포트 설정
DHT_PORT |= (1<<DHT_INPUTPIN);
DHT_DDR |= (1<<DHT_INPUTPIN);
//send request
DHT_PORT &= ~(1<<DHT_INPUTPIN); //low
_delay_ms(18);
DHT_PORT |= (1<<DHT_INPUTPIN); //high
DHT_DDR &= ~(1<<DHT_INPUTPIN); //input
_delay_us(40);
if((DHT_PIN & (1<<DHT_INPUTPIN))){
return -1;
}
_delay_us(80);
//check start condition 2
if(!(DHT_PIN & (1<<DHT_INPUTPIN))) {
return -1;
}
_delay_us(80);
//데이터 전송.
uint16_t timeoutcounter = 0;
//5 바이트를 읽는다.
for (j=0; j<5; j++)
{
uint8_t result=0;
//매 비트를 읽는다.
for(i=0; i<8; i++)
{
timeoutcounter = 0;
while(!(DHT_PIN & (1<<DHT_INPUTPIN))) //하이 입력을 기다린다.
{
timeoutcounter++;
if(timeoutcounter > DHT_TIMEOUT){
return -1; }//timeout
}
_delay_us(30);
//만약 30us후에 입력이 하이이면 result를 얻는다.
if(DHT_PIN & (1<<DHT_INPUTPIN)) result |= (1<<(7-i));
timeoutcounter = 0;
while(DHT_PIN & (1<<DHT_INPUTPIN)) //로우 입력을 기다린다.
{
timeoutcounter++;
if(timeoutcounter > DHT_TIMEOUT){
return -1;} //timeout
}
}
bits[j] = result;
}
//체크섬
if((uint8_t)(bits[0] + bits[1] + bits[2] + bits[3]) == bits[4])
{
//온도와 습도를 돌려준다.
*humidity = bits[0];
*temperature = bits[2];
Humi=bits[0];
Temp=bits[2];
return 0;
}
return -1;
Humi=Temp=0;
}
// 온도를 얻는다.
int8_t dht_gettemperature(int8_t *temperature)
{
int8_t humidity = 0;
return dht_getdata(temperature, &humidity);
}
// 습도를 얻는다.
int8_t dht_gethumidity(int8_t *humidity)
{
int8_t temperature = 0;
return dht_getdata(&temperature, humidity);
}
// 온도와 습도를 얻는다.
int8_t dht_gettemperaturehumidity(int8_t *temperature, int8_t *humidity)
{
return dht_getdata(temperature, humidity);
}
// 초음파를 얻는다.
int UltraSonic(char ch){
int range;
switch(ch){
case 0:PORTE|=0×10; // porte=prote or ox10
EIMSK|=0×01; // INT0 허용
break;
default:break;
}
Delay_us(12); // 12us동안 하이 유지
PORTE &= ~0xF0; // 출력을 로우로 만든다.
TCNT1=0;//타이머 0으로 만든다.
EIFR=0;//인터럽드 0으로 만든다.
Delay_ms(50);//INT0 발생
Echo_count -= 1300; //515us 정도 보정
if(Echo_count<180)Echo_count = 180;//하한 제한//180은 대략 3cm
if(Echo_count>36000L)Echo_count = 36000L;//상한 제한 ,Long(32bit)
range=Echo_count/116;//116->cm 단위로 환산
return range;
}
int main()
{
MCU_initialize();// MCU 초기화
LCD_initialize();// LCD 초기화
LCD_string(0×80,” 06-1Group”);//상위 값 지정
LCD_string(0xC0,”Smart House”);//하위 값 지정
TCCR1A = 0×00;//타이머/카운터1A 제어 레지스터 설정
TCCR1B = 0×02;//타이머/카운터1B 제어 레지스터 설정
TCCR1C = 0×00;//타이머/카운터1C 제어 레지스터 설정
TCNT1H = 0×00;//TCNT1 상위비트 초기화
TCNT1L = 0X00;//TCNT1 하위비트 초기화
//하강 에지일 때 인터럽트 발생.
EICRB = 0×88;
DDRD |= 0×10;
sei();//전역 인터럽트 허용
Delay_ms(3000);
int i=0;
int k;
while(1)
{
LCD_string(0×80,” Ultra :”);
LCD_command(0×80+10);
LCD_4d(UltraSonic(0));
LCD_string(0×80+14,”cm”);
if(UltraSonic(0) <=17)//초음파 거리가 17이하일 시 모터 작동.
{
for(k=0;k<45;k++)//81도 정회전
{
_delay_ms(35);
if(++i==8) i=0;
PORTE = pattern1[i];
}
for(k=0;k<90;k++)//162도 역회전
{
_delay_ms(35);
if(++i==8) i=0;
PORTE = pattern2[i];
}
for(k=0;k<45;k++)//81도 정회전(원위치)
{
_delay_ms(35);
if(++i==8) i=0;
PORTE = pattern1[i];
}
}
_delay_ms(500);
dht_getdata(Humi,Temp);
LCD_string(0xC0,”Humidity :”);
LCD_command(0xC0+10);
LCD_4d(Humi);
LCD_string(0xC0+14,”%”);
if(Humi<45)//습도가 45미만일 시 펌프 작동.
{
PORTD |= 0×10;
}
else
{
PORTD &=~ 0×10;
}
}
return 0;
}
② 참고문헌
· Takashi Kenjo, Akira Sugawara, “스테핑 모터&마이컴 제어”, 일진사
· 정용욱, 정구섭 저, “센서 엑츄에이터 공학”, GS인터비전
· http://www.devicemart.co.kr
· http://www.micropik.com/PDF/dht11.pdf
③ 회로도
[32호]프리젠터 장갑
2015 ICT 융합 프로젝트 공모전 참가상
프리젠터 장갑
글 | 충남대학교 김진욱, 박지훈, 이선민
심사평
펌테크 창의적인 아이디어는 좋으나 상품화 측면에서 본다면 프리젠테이션 과정상에 반드시 전용 장갑을 착용해야 하는 과정은 개선이 필요할 것 같다.
JK전자 작품의 향후 계획대로 PC와의 연결을 무선으로 하고 장갑에 연결된 마이크로 프로세서의 크기를 초소형화하고 장갑의 센서를 이용하여 여러가지 제스쳐 동작을 인식하도록 개선한다면 한번쯤은 써볼만한 제품이 나올수도 있겠다.
뉴티씨 간단한 회로를 이용하여 발표용 장갑을 구현했다는 데 의의가 있으며, 이를 최근에 스마트폰과 관련되어 이슈가 되는 블루투스로 통신하여 사용할 수 있도록 한 것이라는 데, 더 의미가 있겠다. 하지만, 기술적인 부분에서 스위치라던가 아이디어 측면에서 좀 더 창의적인 부분들이 있었으면 좋았을텐데 하는 아쉬움이 남는다.
칩센 프리젠테이션 시 두 손을 자유롭게 하는 점은 아이디어는 좋으나, 장갑을 이용한다는 점이 오히려 불편할 수 있다고 생각된다. 실용적으로 생각하여서 외관도 잘 꾸며져야 한다.
위드로봇 가속도 센서를 이용하여 모션 인식을 통한 데모가 추가되었다면 완성도가 더 높은 작품이 되었을 것입니다. 제출한 보고서만으로는 스위치 입력으로 동작하는 부분만 구현된 것으로 보이며, 가속도 센서 인식 부분이 아직 구현이 안되었다 하더라도 어떻게 구현하겠다는 계획이라도 나와 있었으면 좋았을 것 같다.
작품 개요
필요성
요즘에는 혁신적인 아이디어도 중요하지만 그만큼 그런 아이디어를 대중들에게 알려주는 프리젠테이션 능력도 중요하게 여겨지고 있다. 그리고 프리젠테이션이 제품을 발표하는 자리 이외에도 학교 수업, 설명회 등등에서 실용되고 있다. 발표를 할 때는 말 이외에도 신경을 써야할 부분이 바로 비언어적 요소들이지만 대부분 발표자들을 보면 한 손에는 마이크를, 한 손에는 무선 프리젠터를 들고 발표한다.
발표자들의 양손에 무언가 쥐어져 있다면 이런 비언어적 요소들을 사용할 수 없게 되므로 발표의 수준이 떨어지게 된다. 이 프리젠터 장갑을 만들어서 발표자의 손을 보다 더 자유롭게 해주고자 한다.
주요 기능 간략 설명
1) 레이저 ON/OFF
2) 슬라이드 전, 후 이동
3) LCD에 발표 진행 시간, 해당 슬라이드의 주요 멘트 표시
기대효과
1) 비언어적 요소 사용 증가로 청중들의 이해도 증가
2) 발표자의 손이 자유로워서 자연스러운 발표 가능
3) LCD에 나오는 시간으로 발표 시간을 즉각적으로 볼 수 있어서 시간 관리 편리
4) LCD에 주요 멘트가 표시되어 꼭 전달해야 될 내용을 까먹지 않고 전달함
작품 설명
주요 동작 및 특징
1) 주요 기능
· 슬라이드 제어 기능 : PPT 슬라이드를 전후로 이동 가능 [버튼 input 방식 / 가속도 센서로 손 동작 인식 방식 2가지로 작동]
· 레이저 ON/OFF 기능
· LCD 디스플레이에 발표 진행 시간, 각 슬라이드의 주요 멘트 표시
2) 기능 상세 설명
· 슬라이드 제어 기능 : 중지, 약손가락 끝에 있는 버튼을 누르게 되면 발표자료를 앞뒤로 이동시킨다. 또, 버튼을 사용하지 않고 가속도 센서로 손의 동작을 인식해서 버튼처럼 사용한다. [버튼 input 방식 / 가속도 센서로 손 동작 인식 방식 2가지로 작동]
· 레이저 ON/OFF 기능 : 검지에 있는 버튼을 누르면 레이저가 켜지고, 한 번 더 누르면 레이저가 꺼진다.
· LCD 디스플레이에 발표 진행 시간, 각 슬라이드의 주요 멘트 표시
3) 특징
장갑위에 버튼과 LCD를 부착해야 되는데 아두이노에 맞는 부품을 사야해서 전선도 달리고 좀 거추장스러워 보이지만, 장갑 외부에 부착을 했기 때문에 착용을 해보면 그렇게 많이 무겁지도 않고, 사용하는데 불편하지 않습니다. 또한 뒤에 나오는 사진들은 아두이노로 만든 제품이라 프로토타입 단계이다. 향후 지원을 받아서 시제품으로 개발이 된다면 장갑 내부에 버튼, LCD 등을 넣어 방수기능과 무게를 줄 일 예정이다.
전체 시스템 구성
· 회로도
· 순서도(알고리즘)
개발 환경(개발 언어, Tool, 사용시스템 등)
· 개발 환경 : Arduino IDE (C언어 기반)
· 아두이노 레오나르도 사용 (HID 사용)
단계별 제작 과정
·제작 일정
· 활동 사진
1) 버튼 & 초음파 센서 실습 | 2) 레이저 작동 실습 |
3) 버튼으로 레이저 ON/OFF 제어 | 4) 버튼으로 레이저, backspace, 마우스 오른쪽버튼 활용 실습 |
5) 장갑에 버튼 부착 (1차 작품) | 6) LCD 작동 연습 |
7) 3D프린터로 아두이노 케이스 제작 | 8) 완성품 – A |
8) 완성품 – A |
향후 계획
1) 블루투스 모듈을 연결해서 아두이노와 컴퓨터 무선 연결 구현
2) 가속도 센서를 사용해서 정밀한 손동작 인식
· 손동작으로 슬라이드를 넘기는 기능 추가
· 발표 중 특정 사진을 이동, 확대 등 실시간으로 발표자료 변경 가능
3) 파워포인트 이외에도 프레지, 키노트에도 적용
기타
소스코드
#include <Wire.h> //변수 및 라이브러리 선언
#include <Time.h>
#include <LiquidCrystal_I2C.h>
#define LASER 11
#define BUTTON 6
LiquidCrystal_I2C lcd(0×27,16,2);
int buttonState = 0;
int num=0;
const int mouseButton = 4;
int val = 0;
int old_val = 0;
int state = 0;
void setup(){ //아두이노 초기화
pinMode(LASER,OUTPUT);
pinMode(BUTTON,INPUT);
pinMode(mouseButton, INPUT);
lcd.init();
Mouse.begin();
pinMode(8, INPUT_PULLUP);
Keyboard.begin();
setTime(0,0,0,5,3,15);
void loop(){ //초기화 한뒤 무한 반복되는 구간
ButtonSwitch();
MouseControl();
KeyControl();
LcdControl();
digitalClockDisplay();
}
void digitalClockDisplay(){ //LCD위에 시간을 표시하는 함수
lcd.setCursor(0,1);
lcd.print(“TIME “);
lcd.print(hour());
printDigits(minute());
printDigits(second());
delay(100);
}
void printDigits(int digits){ //슬라이드 번호 출력을 10의 자리 보정 함수
lcd.print(“:”);
if (digits < 10)
lcd.print(‘0’);
lcd.print(digits);
}
void LcdControl() { //버튼 input정보에 따라 LCD에 슬라이드 번호 출력
buttonState = digitalRead(mouseButton);
lcd.backlight();
lcd.setCursor(0,0);
lcd.print(num);
if (buttonState==LOW){
lcd.setCursor(0,0);
lcd.clear();
num++;
lcd.print(num);
delay(100);
}
}
void KeyControl(){ //버튼에 Backspace 기능을 구현하는 함수
while (digitalRead(8) == LOW) {
Keyboard.press(KEY_BACKSPACE);
lcd.setCursor(0,0);
lcd.clear();
num–;
lcd.print(num);
delay(100);
}
Keyboard.releaseAll();
}
void MouseControl(){ //버튼으로 마우스 오른쪽을 클릭하게 하는 함수
int clickState = digitalRead(mouseButton);
if(clickState == LOW){
if(!Mouse.isPressed(MOUSE_LEFT)){
Mouse.press(MOUSE_LEFT);
}
}
else{
if(Mouse.isPressed(MOUSE_LEFT)){
Mouse.release(MOUSE_LEFT);
}
}
delay(10);
}
void ButtonSwitch(){ //버튼으로 레이저를 ON/OFF하는 함수
val = digitalRead(BUTTON);
if((val==HIGH) && (old_val == LOW)){
state = 1 - state;
delay(10);
}
old_val = val;
if(state == 1){
digitalWrite(LASER,LOW);
} else {
digitalWrite(LASER,HIGH);
}
}
참고 문헌
· Make: 아두이노 DIY 프로젝트 (키모 카르비넨, 테로 카르비넨 저)
· 손에 잡히는 아두이노(마시모 밴지 저)
· 핵심 예제로 배우는 아두이노 프로그래밍(허경용 저)
· http://cafe.naver.com/arduinostory (아두이노 네이버 카페)
사용 부품 모델명
· Arduino Leonardo (ATmega32u4)
· 아두이노 LCD 모듈 (LCD 1602)
· keyes button 모듈 (3개)
· keyes Laser 모듈
[32호]너무 쉬운 아두이노 DIY ④ – 정원등과 공중회전그네
글 | 신상석 ssshin@jcnet.co.kr
이 강의는 아두이노를 가지고 간단하게 생활에 필요한 용품을 만들어 보는 강의입니다. 뚝딱뚝딱 뭔가 자신만의 DIY 용품을 만들어 보는 쏠쏠한 재미가 있는 강의라고나 할까요? 이미 주변에 아두이노와 관련한 많은 책이 출간되었고 카페나 블로그를 통하여 강의가 진행된 경우도 꽤나 많이 있는데도 불구하고, 이 지면을 통하여 강의를 개설한 이유는 다음과 같습니다.
1. 아두이노의 초보자들을 위한 쉽고 재미있는 강의가 거의 없는 것 같아, 가능하면 초등학생(?)까지도 함께 해 볼 수 있는 그런 강의를 한 번 해보고 싶어서…
2. 아두이노를 가지고 뭔가 조금은 다른, 자신만의 창의적인(?) DIY를 할 수 있는 자리를 만들어주고 싶어서…
3. 디바이스마트매거진은 임베디드와 관련된 독자들이 많고, 발행 부수도 많아, 저와 제가 속한 회사(제이씨넷) 그리고 임베디드홀릭 카페의 홍보에 도움이 될 것 같아서…
현재 구상하고 있는 회차별 내용을 간략하게 정리해 보면 다음과 같습니다. (변경될 수 있습니다.)
회차 | 내용 |
1 | 3색 신호등 만들기 |
2 | 카멜레온 반지, 스위치를 이용한 신호등 게임기 |
3 | FND로 만드는 디지털전압계, 카운트다운 계수기 |
4 | 어두워지면 켜지는 정원등, 공중회전그네 |
5 | 캐롤송 카드, 컬러링 온도계 |
6 | 스마트폰으로 조정하는 스마트카 |
앞으로 즐겁고 알찬 강의가 될 수 있도록 최선을 다할 것을 약속 드리며, 이 강의를 보는 독자들도 메일이나 카페를 통하여 Q&A(Question & Answer)나 피드백을 주셔서, 함께 정감을 나눌 수 있는 계기가 되기를 기대해 봅니다.
여러분, 안녕하세요. 항상 환한 강사 신상석입니다.
지난번 주제였던 [시한폭탄 카운트다운 계수기] DIY는 한 번 만들어 보셨나요? 양방향 대화가 아니어서 질문하는 것이 조금 멋적긴 하지만, “그래도 한 열 분 정도는 시도해보지 않았을까?” 라고 나름 생각하면서 즐겁게 계속 진도 나갑니다.
오늘은 [어두워지면 저절로 켜지는 정원등]과 [공중회전그네]를 만들어 볼까 합니다.
어둑어둑 해질 무렵의 놀이동산, 노오란 정원등이 하나 둘씩 저절로 켜지고 내가 좋아하는 공중회전그네가 빙글빙글 돌아가는 풍경… 많이 비슷하게는 안되겠지만 기분이라도 이렇게 낭만적으로 상상하면서 한 번 가보도록 하지요.
■ 광센서 ■
어두워지면 저절로 켜지는 정원등을 만들려면, 일단 어두워졌다는 사실을 알아야 합니다. 즉, 빛의 밝기를 측정할 수 있는 센서가 있어야 하는데, 이러한 센서를 광센서라고 합니다. 보통 광센서는 아래와 같이 생긴 황화카디늄(CdS) 센서를 많이 사용하는데, 이것은 황화카디늄(CdS) 성분이 빛이 밝아지면 전기저항값이 작아지고, 빛이 어두워지면 전기저항값이 커지는 성질이 있기 때문입니다. 오~ 저항값이 변한다면 가변저항의 역할을 할 수 있다는 것이므로 이 성질을 잘 이용하면 뭔가 해답이 나올 것 같지요? 세부적인 방법은 잠시 후에 기본 회로를 꾸며가면서 살펴보기로 하고 일단은 빛과 광센서에 대하여 먼저 알아보겠습니다.
빛의 밝기는 룩스(LUX)로 측정이 되는데, 엄밀한 정의는 이해도 어렵고 필요도 없으므로 룩스 값에 따른 예를 보면서 이해하는 것이 더 좋을 것 같습니다. 아래를 보시지요.
사람마다 느끼는 것이 다르겠지만 우리는 위의 표와 같이 조금 어두워지는 것 같다고 느껴지는 저녁 황혼의 밝기인 10 룩스 정도에서 정원등이 켜지도록 하겠습니다.
이제 빛의 빛의 밝기에 따라 변하는 광센서의 저항값을 알아봅시다. 아래는 CdS 광센서중의 하나인 GL5537 광센서의 모습과 규격 일부입니다.
우리가 측정하고자 하는 빛의 밝기인 10 LUX는 정도에서 약 20~50KΩ 정도의 저항값을 갖는 것으로 되어 있습니다. 조금은 틀려도 크게 문제는 없을 것이기에 우리는 이 때의 대표 저항값을 중간값인 35 KΩ 라 생각하고 진행하는 것으로 하지요.
■ 아날로그 센서 측정을 위한 기본 회로 ■
결국 광센서는 빛의 밝기에 따라 저항값이 변하는 가변저항의 역할을 하는 것이고, 우리의 아두이노는 아날로그 입력으로 전압값을 측정할 수 있는 능력이 있으므로 이 광센서의 저항값이 변함에 따라 특정 지점의 전압이 변하도록 회로를 꾸미면 아두이노로 광센싱이 가능하겠습니다. 지난번에 과제로 내주었던 [FND-과제-2]와 비슷한 회로가 될 것 같은데…
아래와 같이 회로를 꾸며 보도록 하지요.
이렇게 연결한 후 (?V)로 표기된 부분을 아두이노의 아날로그 입력(A0~A5) 핀 중 하나에 연결하고(우리는 A1에 연결) 전압을 측정하면 현재 빛의 밝기를 알 수 있겠습니다. 즉, 광센서의 저항값을 R1, 여기에 직렬로 연결한 저항값을 R2(고정값)으로 설정하고, 양단에 전압 +5V를 인가하면 이 회로에 흐르는 전류(I)는,
5 = R1 x I + R2 x I 에서,
I = 5 / (R1+R2)가 되므로
아날로그 입력(A1)에서 측정한 전압값(?V)은
?V = I x R2 = (5 / (R1+R2)) x R2 가 됩니다.
R2는 고정값인 상수이므로 측정된 전압값(?V)를 알면 결국 R1 값을 구할 수 있고, R1 값을 알면 GL5537의 규격표에서 이에 대응되는 현재 빛의 밝기를 알 수 있게 되는 것이지요.
아하~ 그렇구나~
■ 어두워지면 저절로 켜지는 정원등
자, 이제 기초적인 원리는 이해가 되었으니 오늘의 주제 중 하나인 [어두워지면 저절로 켜지는 정원등]을 만들어 봅시다. 항상 그렇듯이 일단, 어떤 것을 만들 것인지 기능 규격부터 정해볼까요?
[기능 규격]
· 주변이 10 룩스 정도 밝기로 어두워지면 저절로 켜지는 정원등 제작
· LED를 정원등이라고 생각하고 LED의 ON/OFF 제어
※ 실제 정원등을 제어하려면 AC 전원이 연결된 정원등 스위치를 ON/OFF 하여야 하는데 이것은 릴레이로 스위치를 대신하고 이 릴레이를 제어하면 되므로, 여기서는 그냥 원리만을 알아보는 차원에서 정원등을 DC 5V에 대응되는 LED라고 가정하고 진행합니다.
기능 규격을 보니 우리가 공부한 기본 원리를 이용하면 바로 구현이 가능할 것 같습니다. 아래와 같이 하면 되겠네요.
[아두이노 연결]
· GL5537의 규격이 4KΩ ~ 2MΩ 정도의 범위에서 변하므로, 로그 스케일로 그 중간 정도에 있는 값인 200KΩ(또는 그 근처 저항)을 고정저항(R2)으로 선정
· [+5V --- GL5537 광센서 --- 200 KΩ 저항 --- GND] 형태로 회로를 구성하고 GL5537과 200KΩ 저항이 만나는 지점을 아두이노 A1 아날로그 핀에 연결(노란색 도선)
· 아두이노 D3핀(디지털출력, 녹색 도선)에 LED(직렬 저항 포함) 연결
10룩스일 때의 GL5537은 데이터시트에 보면 20~50 KΩ 으로 나타나므로 중간값인 35 KΩ 으로 추정하였을 때 위에서 공부한 이론을 적용하여 10룩스일 때의 전압값(?V)을 계산하여 보면, ?V = (5 / (R1+R2)) x R2 = (5 / (35 + 200)) x 200 = 5 x 200 / 235 이 됩니다. 5V에 대응되는 아날로그로 값은 1024이므로 위의 전압에 해당되는 아날로그 값을 계산하면 5 : 1024 = 5 x 200 / 235 : ?V 의 식으로 표현되므로 ?V 에 해당되는 값을 구하면 ?V = 5 x 200 x 1024 / 235 / 5 = 871 이 되겠습니다.
결론적으로, 위와 같이 연결한 회로에서 10룩스의 밝기가 되면 A0 핀으로는 871값이 읽히게 되므로, 읽은 값이 이 값 보다 작거나 같으면 정원등(LED)을 ON하고, 그렇지 않으면 정원등(LED)를 OFF하도록 스케치 프로그램을 작성하여야 하겠습니다.
[스케치 프로그램]
이제 모든 것이 결정되었으니 프로그램 작성이 가능하겠죠? 바로 갑니다.
const int LED=3; const int CDS=1; #define CDS_10 871 // 200/(35+200) * 1024, 10룩스일 때의 CDS 저항값인 35KΩ에 대응되는 아날로그 값 void setup() void loop() |
에러가 없다면 바로 업로드를 실행한 후 광센서(GL5537) 앞쪽으로 손바닥을 가깝게 가져갔다가 멀리했다가 하는 동작을 반복해 봅시다. 손바닥이 가까이 가면 빛을 차단하게 되므로 어두워져서 빛의 밝기가 10룩스 아래로 내려가게 되어 LED가 켜질 것이고, 다시 멀리하면 빛의 밝기가 10룩스 위로 올라가게 되어 LED가 꺼지게 되겠습니다. 동영상과 같이 된다면 이번 DIY도 성공이네요. 와우~~~
한가지 더 알려드리고 싶은 것은, 시중에 나와 있는 센서는 광센서와 같이 가변저항의 성질을 이용한 것이 상당히 많다는 사실입니다. 예를 들어 온도센서는 주변 온도에 따라 저항값이 변하는 성질을 이용하며, 압력센서의 경우는, 압력에 따라 저항값이 변하는 성질을 이용하는 것입니다.
이러한 종류의 센서는 지금까지 사용한 방법과 비슷한 방법으로 쉽게 구현할 수 있으므로 이번 예를 잘 응용한다면 앞으로의 다른 DIY 작업도 식은 죽 먹기로… (윽. 너무 오버?)
자, 그러면 첫번째 DIY는 이쯤에서 마치고 잠시 후에는 오늘의 메인 DIY인 공중회전그네 제작에 도전해 보도록 하겠습니다. 조금은 쉬었다 가야겠지요? 모두 10분간 휴식~~~
…(1분)
…(2분)
…(3분)
…(4분)
…(5분)
…(6분)
…(7분)
…(8분)
…(9분)
…(10분)
편안한 휴식이 되셨나요? 그러면 이제 오늘의 메인 DIY인 공중회전그네에 도전해 봅시다.
처음으로 움직이는 작품을 만들어 볼 기회가 되겠네요.
우리가 할 수 있는 것 중에서 단순하면서도 재미있는 것을 이것 저것 생각하다가 찾은 것이 공중회전그네입니다. 이름이 정확한지는 잘 모르겠는데, 롯데월드에 제가 생각한 것과 비슷한 것을 하나 찾았습니다.
버섯처럼 생긴 부분이 돌아가면 거기에 매달려 있는 그네가 공중에 붕 떠서 도는 것이지요. 저도 타보지는 않았지만 요것, 일반 그네보다는 훨씬 재미있을 것 같으니 여러분도 기회가 되면 꼭 한 번 타보시기 바랍니다.
■ 모터 ■
어떤 물건을 움직이려면 동력을 발생시키는 주체가 있어야 하는데, 이것이 모터입니다. 모터의 쓰임새는 거의 무한이어서, 자동차 바퀴, 선풍기 날개, 믹서기 커터, 비행기 프로펠러 등등 그 쓰임새는 셀 수가 없을 정도입니다. 그리고 꼭 회전이 아니더라도 자동문, 도어락, 포크레인 집게 등 생명체가 아니면서 움직이는 것의 대부분은 모터에 의한 것이라고 봐도 과언이 아니지요.
그러니까, 우리도 일단 공중회전그네를 만들기 전에 모터에 대하여 조금은 알고 넘어가는 것이 좋을 듯 합니다.
모터(Motor)는 우리말로 전동기라고 하는데, “전류가 흐르는 도체가 자기장 속에서 받는 힘을 이용하여 전기에너지를 역학적에너지로 바꾸는 장치”입니다. 뭔가 좀 어려운 설명인데, 우리는 그냥 “전기를 넣어주면 축을 중심으로 회전하는 것이 모터”다 라고 알아두면 되겠습니다.
어떤 전류를 사용하느냐에 따라 건전지 같은 전원을 사용하면 DC(Direct Current, 직류) 모터, 220V 같은 콘센트 전원을 사용하면 AC(Alternating Current, 교류) 모터로 구분합니다. 또한, 사용하는 형태에 따라서도 일반 모터, 서보(Servo) 모터, 스테핑(Stepping) 모터로 나눌 수가 있는데, 일반 모터는 그냥 왱~ 하면서 돌아가는 모터구요. 서보 모터는 일정한 각도 만큼만 회전하는 모터로 차단기, 자동문 등에 사용하는 모터입니다. 또한, 스테핑 모터는 아주 정밀한 각도를 움직일 수 있도록 만든 모터가 되겠습니다.
우리는 DC 모터를 사용할텐데, DC 모터는 보통 2개의 단자를 가지고 있고 이 단자의 양단에 모터의 정격에 알맞은 전압을 가하면 회전하게 됩니다. 또한, 일반적으로 2단자의 극성을 바꾸면 반대방향으로 회전하게 되지요.
그러면 이제 아두이노에 모터를 연결하는 방법에 대하여 간단히 알아보겠습니다.
요렇게 연결하면 될까요? (M 표시가 있는 것은 모터 심볼입니다.)
아두이노의 핀 하나(OUT1)를 모터의 한쪽에 연결하고, 모터의 다른 한쪽은 GND에 묶어 놓으면, 아두이노에서 제어가 가능할 것 같습니다. OUT1 = 1이면 모터가 돌고, OUT1 = 0 이면 모터가 정지하겠네요.
음. 한번에 완성?
반대 방향으로도 돌려야 할 필요성도 있겠네요. 모터는 보통 양단의 극성을 바꾸어 전원을 공급하면 반대 방향으로 회전하므로 아래쪽에도 GND 대신 포트를 하나 할당하는 것이 좋겠습니다. 값을 1, 0 마음대로 바꿀 수가 있으니까요. 아래와 같이 연결해 보지요.
오, 이렇게 되면, OUT1= 1, OUT2 = 0 인 경우는 모터가 정방향으로 돌고, OUT1 = 0, OUT2 = 1 이렇게 만들면 모터가 역방향으로 돌고… OUT1 = 0, OUT2 = 0 또는 OUT1 = 1, OUT1 = 1 이면…
OUT1 및 OUT2 양단 사이에 전위차가 없으니 모터가 정지할 것 같습니다. 괜찮은 설계가 된 것 같네요.
모두 만족? 음. 약간 부족한 것 같네요. 몇가지 더 생각할 게 있어요.
모터라는 녀석은 힘으로 먹고 사는 녀석이어서… 모터가 도는 힘에 비례하여 전류를 많이 소모합니다. 모터마다 5V-1A, 12V-2A, …, 이런 식으로 규격이 정해져 있지요. 요점은 OUT1 ▶ 모터 ▶ OUT2 방향으로 많은 전류를 흐르게 할 수 있는 지의 여부입니다. 예를 들어 1A의 전류를 모터로 흘려보내야 한다면 그 전류를 아두이노의 출력핀에서 공급하는 것이 가능한지를 살펴보아야 합니다. 오우~ NO! 아두이노 디지털출력핀은 전류를 많이 공급하지 못하네요. 기껏해야 한 신호당 약 40mA 정도가 최대랍니다. 엄청나게 모자라네요.
그렇다면 불가능할까요?
아니겠죠? 다른 방법이 당연히 있습니다.
이렇게 많은 양의 전류를 흘려야 하는 경우에는 전류를 아두이노 출력핀에서 직접 공급하지 않고 간접적으로 흐르게 하는 방법을 사용하여야 하는데, 이런 경우 가장 많이 사용하는 방법은 바로 트랜지스터를 이용하는 것입니다.
트랜지스터는 PNP형과 NPN형이 있는데 여기서는 NPN형을 기준으로 한 번 설명해 보겠습니다. 아래와 같이 생겼습니다.
여기서 B는 베이스(Base), C는 컬렉터(Collector), E는 에미터(Emitter)인데 아래와 같은 특징이 있습니다. (엄밀한 의미로는 틀릴 수 있는 내용이지만 여기서는 쉽게 설명하기 위하여 개념을 간략화 합니다.)
1. B-E(베이스-에미터)간 전압이 0.7V 이상 순방향으로 걸리면 트랜지스터는 턴-온(Turn-On)되었다고 하고, 이 때 C-E(컬렉터-에미터)는 서로 직접 연결된 것으로 간주합니다. (물론 0.2V 정도의 전위차가 있긴 하지만 그냥 직접 연결되었다고 생각해도 무방합니다.)
2. B-E(베이스-에미터)간 전압이 0.7V 이하이면 트랜지스터는 턴-오프(Turn-Off)되었다고 하고, 이 때 C-E(컬렉터-에미터)는 연결이 끊어진 것으로 간주합니다.
3. 턴-온 되는 경우 B-E 경로로는 수 mA 정도만 흘러도 C-E 경로로는 B-E 전류의 10~1000배 정도의 전류, 즉 수십 mA ~ 수 A 정도의 전류를 흘릴 수 있습니다. (그렇게 흘러도 아무런 문제가 되지 않습니다. 즉, 트랜지스터가 그 정도의 전류를 견디어 냅니다.)
PNP형의 경우는 NPN의 경우와 반대라고 생각하고, B-E간의 전압이 역방향으로 걸리면 턴-온 된다고 생각하면 됩니다.
그러면, 이제 이 트랜지스터를 이용하여 우리의 모터 연결을 수정하여 보겠습니다.
트랜지스터가 방향성을 가지므로, 정방향, 역방향을 모두 수용하려면 아래와 같이 2개의 경우가 생기겠네요. 왼쪽의 경우는 OUT1 = 1, OUT2 = 0 이면 Q1, Q2 트랜지스터가 모두 턴-온되어 모터가 회전하고, 오른쪽의 경우는 OUT1 = 0, OUT2 = 1 이면 Q3, Q4 트랜지스터가 모두 턴-온되어 모터가 회전하겠습니다.
이미 눈치 채신 분이 있으시겠지만 이 경우 트랜지스터는 턴-온, 턴-오프 상태를 갖는 스위치의 역할을 하게 되며, OUT1, OUT2 출력 신호는 아두이노가 생성할 수 있고, 모터에 흐르는 전류는 모두 VCC ▶ 트랜지스터 ▶ 모터 ▶ 트랜지스터 ▶ GND(접지) 로 흐르므로 모터의 전류 용량도 무난히 소화할 수 있겠습니다. 한가지 더 주의 깊게 보아야 할 것은 VCC로 표시된 전압은 +5V가 아니어도 괜찮다는 것입니다. 즉, OUT1이나 OUT2를 결정하는 로직 레벨과 무관하게 모터(M)의 정격에 알맞은 전압(예를 들어 3V~24V)을 걸어주면 된다는 것이지요. 오, 전류도 맘대로 되고, 전압도 맘대로 할 수 있으니, 일거양득(一擧兩得)! 신세대 은어로는 개이득이네요.
다시 돌아가서, 한 개의 모터를 가지고 위 2가지의 경우에 모두 적용되어야 하므로 이제 2개의 회로를 합쳐서 그려보겠습니다. 아래와 같이 될 것 같습니다. 모습이 H 형태와 비슷하다고 하여 이 회로의 이름을 ‘H-브릿지’라고 부릅니다.
일단, 맞는지 잘 확인해 보시지요. (특히, Q1, Q1, Q3, Q4 위치)
똑같죠? 왠지 멋져 보입니다.
그럼, 최종 점검해 보겠습니다.
OUT1 = 1, OUT2 = 0 이면 Q1 = ON, Q2 = ON, Q3 = OFF, Q4 = OFF이므로 아래 그림과 같이 VCC ▶ Q1 ▶ 모터(M) ▶ Q2 ▶ GND 방향으로 전류가 흘러서 모터가 순방향으로 회전합니다.
OUT1 = 0, OUT2 = 1 인 경우는 Q1 = OFF, Q2 = OFF, Q3 = ON, Q4 = ON 이므로 모터로 흐르는 전류 방향이 반대가 되므로 역방향으로 회전하겠네요. (여러분이 한번 전류 흐름을 그려보세요.)
또한, OUT1 = 1, OUT2 = 1 이거나, OUT1 = 0, OUT2 = 0 이면 VCC 쪽이거나 GND 쪽에 연결된 트랜지스터가 OFF 되어 모터로 전류가 흐르지 않으므로 모터는 정지하겠습니다.
이것이면 완전 끝인가요?
아쉽게도 좀 더 세부적으로 들어가면, 모터의 정격 전압, 전류 등에 대하여 제대로 알아야 하구요. 이를 구동할 트랜지스터의 타입, 전류 구동 능력, 관성 다이오드(flywheel diode)의 규격 및 이들의 상관 관계 등 세부적인 계산 방법은 간단하지가 않습니다. 또한, 잘못 연결하거나 맞지 않는 규격을 사용할 경우 모터나 트랜지스터에 손상을 일으킬 여지도 있어, 실제로 모터를 동작시킬 때에는 회로를 직접 꾸미기 보다는 이미 잘 동작하도록 제작된 전용 드라이버 칩 또는 이러한 칩을 사용하여 제작한 모듈을 사용하는 경우가 대부분입니다.
그러므로 우리는 기본 원리를 이해하는 정도에서 만족하고, 실제 DIY에서는 전용 모터드라이버 모듈을 사용하도록 하는 것으로 방향을 잡겠습니다.
■ 모터 드라이버 : JMOD-MOTOR-1 ■
모터드라이버는 앞에서 이야기한대로 모터를 쉽게 구동할 수 있도록 트랜지스터와 저항, 관성다이오드를 내장함은 물론 모터가 도는 방향도 선택하여 제어할 수 있는 구조를 가진 모듈을 의미하며, 시장에는 여러 종류의 모터드라이버가 출시되어 있습니다. 여기서는 우리의 목적에 적합한 모터드라이버로 제이씨넷 사의 JMOD-MOTOR-1이라는 모터드라이버를 사용하여 설명하도록 하겠습니다. (물론, 규격에 알맞은 다른 모터 드라이버를 사용하셔도 됩니다.)
JMOD-MOTOR-1 은 TB6612FNG 칩 기반의 2채널 DC 모터 드라이버입니다. 4.5V~13.5V 범위의 DC 모터를 사용할 수 있고 채널당 최대 1.2A 까지의 전류를 공급할 수 있으며 다른 모터드라이버에 비하여 효율이 상당히 높다는 장점을 가지고 있습니다. 2.54mm 핀헤더 타입 및 2×5 박스헤더 타입의 인터페이스를 함께 제공하여, 아두이노나 AVR 모듈 등과의 연결이 편리한 아래와 같이 생긴 제품(http://www.devicemart.co.kr/1160053)입니다.
세부 구조 및 핀 배치는 다음과 같습니다.
이론적으로 공부한 H-브릿지 드라이버와 실제 드라이버와의 매핑을 해보면 아래와 같이 됩니다. 한가지 다른 점은 TB6612에는 PWMA 라는 신호가 하나 더 있는데, 이것은 제어 입력인 AIN1, AIN2이 회전하는 경우 속도를 제어하기 위한 제어 신호로 PWMA가 High인 경우만 AIN1, AIN2 신호가 AO1, AO2로 그대로 전달되고, PWMA가 Low인 경우는 전달되지 않는다고 생각하시면 되겠습니다.
그렇다면 PWMA를 High로 했다가 Low로 했다가… 를 적당한 길이로 조정하면 모터가 돌다가 쉬다가… 할테니 속도를 조절할 수가 있겠습니다. 쉽게 설명하려고 했는데 설명이 더 어려운 것 같기도 하고…
어쨌든 결과적으로, 우리가 제어하여야 할 핀은 PWMA, AIN1, AIN2의 3핀이고, 이 3핀의 값에 따라 AO1, AO2가 결정되어, 결국 모터가 정회전(CW, ClockWise, 시계방향), 역회전(CCW, CounterClockWise, 반시계방향), 정지(Break, Stop) 기능을 아래 표와 같이 수행하게 됩니다. 조금 장황한 듯 하지만 결국 3개의 신호선만 우리가 원하는 대로 알맞게 출력해 주면 모터는 동작하는 것이지요.
마지막으로, 모터 전원의 경우는 외부에서 따로 제공하여야 하며, +5V 전원이라 할지라도 아두이노에서 사용하고 있는 +5V 전원과는 다른 전원을 사용하는 것이 좋습니다. 왜냐하면 모터는 기본적으로 전류용량이 커서 최소 수백 mA 이상을 사용하며, 또한 모터 기동시에는 이것의 2-3배 정도의 전류가 더 필요하게 되므로, USB 케이블을 통하여 아두이노에 제공되는 전류 용량(보통 500mA)만으로는 부족한 경우가 많아 모터가 동작하지 않거나 아두이노가 리셋이 되는 경우 등 오동작하는 경우가 발생할 수 있기 때문입니다.
■ 간단한 선풍기 ■
자, 이제 이론적인 준비가 끝났으니 DIY 작품을 만들어 보도록 하지요. 공중회전그네를 만들기 전에 먼저 간단한 선풍기를 만들어보겠습니다. 선풍기를 만든 다음에 요것을 변신시켜서 공중회전그네를 만들거랍니다.
기본 재료인 모터는 3V DC 모터인 WRE-260을, 소형프로펠러는 아래와 같이 생긴 프로펠러를 사용하도록 하겠습니다. 다른 이유는 없고 그저 값이 싸다는 이유이므로, 다른 모터를 사용하여도 되고, 프로펠러는 그냥 간단히 스카치테이프나 색종이 등을 모터 축에 오려 붙여서 만들어도 되겠습니다.
다행이도 프로펠러는 모터에 꼭 맞네요.
[기능 규격]
· 소형 DC 모터에 모형 날개를 달고 아두이노로 제어하여 간단한 선풍기 제작
· 5초간 정회전, 2초간 정지, 3초간 역회전, 2초간 정지를 반복 실행
[알고리즘]
정리된 알고리즘은 아래와 같습니다.
· 위의 표에서 정회전, 역회전, 정지에 해당되는 PWMA, AIN1, AIN2 값을 정해진 시간 동안 차례로 출력
[아두이노 연결]
PWMA는 아두이노 5번핀에 할당하고, AIN1과 AIN2는 각각 7번핀, 8번핀에 할당
※ 참고 : 모터 전원용으로 배터리(팩)를 연결할 때 배터리의 (+)는 JMOD-MOTOR-1의 VCC에 직접 연결하고 GND는 아두이노의 GND에 연결하면 추가 배선없이 연결됩니다. 모터가 3V용이어서 1.5V 건전지 2개를 직렬로 연결하여 모터 전원(VCC)에 공급하면 됩니다.
[스케치 프로그램]
자, 이제 연결은 되었으니, 프로그램해서 돌려 봅시다.
장황하게 왔는데, 프로그램은 항상 너무 간단하죠.
const int MOTOR_PWM = 5; // 모터 PWM 입력핀, PWM핀으로 할당 const int MOTOR_IN1 = 7; // 모터 IN1 입력핀 const int MOTOR_IN2 = 8; // 모터 IN2 입력핀 void setup() void loop() |
으, 별 것 없죠?
실행 결과은 어떻게 되었나요?
아래 동영상처럼 잘 돌아가나요? 작은 선풍기인데 생각보다는 꽤 쌩쌩~~~ 도네요.
■ 공중회전그네 ■
자, 이제 드디어 마지막 목적지인 공중회전그네 DIY 입니다. 앞에서 제작한 선풍기를 약간 개조하여 공중회전그네를 만들어 보겠습니다. 아마도, 어떻게 만들지 벌써 감을 잡으신 분들이 대부분이겠지요?
선풍기를 꺼꾸로 매달아 공중회전그네의 동력으로 쓰고, 선풍기 날개 끝에 구멍을 뚫어 그네를 매달아 회전을 시키는 형태로 하면 될 것 같습니다. 사용하고 싶은 재료를 자유롭게 골라서 만들면 될 것 같구요. 저는 그네줄은 점퍼케이블로 구현하고, 그네는 그냥 클립으로 찝어 그네라고 우기면서 간단히 꾸며려 합니다.
놀이기구이니까 그냥 도는 것 보다는 회전 속도와 회전 방향을 랜덤하게 하면 좀 더 재미가 있을 것 같으니 그렇게 한 번 해보지요.
[기능 규격]
· 여러명의 사람을 태울 수 있는 공중회전그네
· 한 번은 시계 방향, 한 번은 반시계 방향 회전하며 회전 후에는 2초간 정지
· 한 번 회전시 1~9초간 랜덤 시간 회전
· 저속, 중속, 고속의 랜덤 속도로 회전
[필요 함수]
randomSeed(seed)
· 난수 초기화 함수
· seed : 난수 초기화를 위한 초기값
랜덤한 값을 만들어 내기 위한 초기값을 결정하는 함수로 seed값에 따라 랜덤한 값의 시작점이 달라짐. seed값도 랜덤하게 하기 위하여 이 값을 analogRead(A0) 를 수행한 값으로 하면 임의의 랜덤값을 얻을 수 있음
random(min, max) 또는 random(min)
· 난수값 생성 (리턴값)
· min : 난수값의 최소값 (범위 포함)
· max : 난수값의 최대값 + 1 (범위 불포함)
랜덤한 값을 만들어 내는 함수로 min, max 값을 주어 랜덤값의 범위를 결정함
[알고리즘]
정리된 알고리즘은 아래와 같습니다.
여기서 주의하여야 할 점은 2가지입니다.
하나는 난수 생성을 어떻게 하는가 하는 것인데, 앞에서 배운 것처럼, 난수를 발행하려면 초기값을 생성해 주어야 하며 이 함수는 random(seed)입니다. 여기서 seed 값에 따라 난수표의 초기 위치가 결정되므로 seed 값도 random으로 입력할 수 있으면 진정한 난수가 될 수 있겠지요. 그래서 보통 사용하는 방법은 이 seed 값을 analogRead(0), 즉 아날로그 포트 0에 아무 것도 연결하지 않은 상태를 읽는 방법을 사용합니다. 포트 0에 신호를 연결하지 않고 그냥 읽으면 일반적으로 0~1023 사이의 랜덤한 값이 읽히게 되는 전기적인 현상을 이용하는 것이지요.
두번째는 속도를 결정하여 이것을 출력하는 것인데, PWM핀에 출력할 때는 이전 예제와는 다르게 digitalWrite( ) 함수를 사용하면 안되고 analogWrite( ) 함수를 사용하여야 한다는 점입니다.
즉, 고속, 중속, 저속의 3가지 경우에 각각 적당한 0~1023 사이의 PWM 값을 결정하여 analogWrite(PWM포트, PWM값)의 형태로 사용하여야 하겠습니다. (실제로는 돌려보고 적당한 값으로 튜닝하는 것이 맞겠네요.)
프로그램은 선풍기 프로그램을 기본으로 난수 발생 함수만 잘 요리하면 되겠습니다. 혼자서도 하실 수 있는 분들은 아래를 보기 전에 먼저 혼자 해 보시구요.
아래와 비슷하게 되겠네요.
const int MOTOR_PWM = 5; // 모터 PWM 입력핀, PWM핀으로 할당 const int MOTOR_IN1 = 7; // 모터 IN1 입력핀 const int MOTOR_IN2 = 8; // 모터 IN2 입력핀 #define PWM_HIGH 320 // 빠른 속도, 그네 무게에 따라 조정 필요 void setup() void loop() |
돌려 본 결과는 아래와 같습니다.
빌빌빌… 돌기도 하고, 약간 썡~ 돌기도 하네요.
어쨌든 제가 원했던 공중회전그네와 비슷합니다. 저는 만족!
만들고 시험하노라면 시간이 조금 많이 걸리기는 하는데… 그래도 나름 재미있는 DIY를 해 본 것 같습니다.
저는 사실 조금 게을러서… 꾀를 내어 간단히 만들어 보았지만 여러분은 좀 더 멋있게 정말 공중회전그네처럼 만들어서 동작시켜 보시기를 기대해 보겠습니다.
여기까지 함께 하시느라 고생하셨구요.
다음에는 좀 더 즐겁고 재미있는 내용으로 환하게 다시 만나겠습니다! 모두모두, 안녕~~~