[26호] ICT 융합 공모전 – 적외선 라인트레이서
적외선 라인트레이서
글 | 고려대학교 세종캠퍼스 제어계측공학과 홍태우
1. 작품 개요
· 적외선 센서를 이용하여, 검은 라인과 흰 바탕으로 구성된 맵의 인식기능 구현
· 검은 라인을 따라가며, 주행 중 스스로 라인에 맞춰 진행 방향을 보정기능 구현
2. 작품 설명
2.1. 제작동기
학술동아리 내에서 프로젝트를 진행하기 위해 기본적인 ATmega128 학습을 진행하였습니다. 그 결과 학습한 것이 DC모터의 방향 제어와, 속도 제어를 위한 PWM 파형 출력 방법이었습니다. 그 외에 센서를 활용해보기 위해, 기본적인 센서인 적외선 센서와, 적외선 센서에 적용 할 수 있는 LOW PASS Filter를 학습 했었습니다. 학습해본 것들을 모두 적용하기 적절한 프로젝트를 찾던 중, 라인트레이서가 제일 적합하다 판단되었고, 제작을 진행하게 되었습니다.
2.2. 주요 동작 및 특징
라인 인식 및 위치 인식 비교원리
전면에 장착된 5개의 적외선 센서를 지면 방향으로 배치하여, 검은 라인을 인식하여 본체의 위치를 비교합니다. 라인 위에서의 라인트레이서 본체의 위치를 파악한 뒤, 이 위치에 따라 구동부인 DC모터의 속력을 조절합니다. DC모터는 후면에 두 개가 장착되어 있으며, 방향 조절은 각각 모터의 속도 차이로 조작하게 됩니다. 라인에서 밖으로 나가게 된 경우, 인식 중이던 나가기 직전까지의 방향 및 라인에서의 위치를 피드백 받아, 다시 라인을 찾아 주행을 지속합니다.
센서의 발광부에서 쏴준 적외선 중, 지면에서 반사된 수광부로 받은 신호 중 고주파 신호는 걸러내고, 저주파 신호만 사용하게 하였습니다.
빛의 특성인 검은색에서는 흡수당하고, 흰색에서는 반사당하는 원리를 적외선 센서에도 적용합니다. 적외선을 방출하는 발광부와 적외선을 수신하는 수광부를 나눠 설치하여, 적외선이 반사되는지(검은 라인 위), 반사되지 않는지(흰 바탕 위)를, 적외선의 수신 강도로 판단하며, 이것을 ADC로 디지털화하여 ATmega128이 인식하게 됩니다.
회로도의 캐패시터(47uF)는 고주파는 GND로 빼어내어 저주파만 통과시키는 Low Pass Filter의 실질적인 역할을 합니다. 저항들은 Low Pass Filter의 Fc값을 적절하게 맞춰주기 위하여 맞춤설정한 것입니다. 따라서 ATmega 128의 ADC로 Low Pass Filter에서 걸러진 저주파가 입력되며, 이것을 사용하여 센서는 기능을 수행하게 됩니다.
2.3. 전체 시스템 구성
라인트레이서의 시스템은 위에서 설명했다시피, 크게 DC모터와 적외선 센서로 구현되어 있습니다. 그 외에는 센서 감지여부 디스플레이용 LED가 장착되어 있습니다.
가. DC모터부
DC모터의 방향제어는 74HC132 NAND gate를 사용하여 포트 하나로 양방향 제어를 하였으며, ATmega 128의 Timer를 이용한 PWM을 출력하여, PWM의 듀티비에 따른 속도의 제어를 하였습니다. 모터 드라이버는 통상적으로 많이 쓰이는 드라이버인 L298N을 사용하였습니다.
DC모터부 적용 소자 데이터 시트
74HC132N-2bit quadra gate
L298N 모터드라이버
나. 센서부
적외선 센서의 발광부에는 ULN2003APG를 적용하여 센서의 적외선 출력을 증폭시켜주었습니다. 수광부에는 위의 회로도와 같이 LOW PASS Filter를 적용하여 주었습니다.
적외선 센서 적용 소자 데이터 시트
ULN2003APG
다. LED 디스플레이어
센서가 센싱하는 값인 ADC를 일정한 값으로 나누어 주어, 검은색/흰색의 두가지 경우로 논리를 나눈 뒤, 검은색일 경우에는 LOW(FALSE), 흰색일 경우에는 HIGH(TRUE)를 출력하여, 검은 라인 위에 있는 센서의 해당 LED는 불이 꺼지도록 만들었습니다. LED 디스플레이를 적용하였을 때, 시각 효과로 인하여 센서와 DC모터의 속도값을 보정하는데 큰 도움이 되었습니다.
라. 전원부
ATmega128에 전원을 공급하기 위하여, 전원인 9V DC를 5V DC로 바꿔주는 LM7805를 사용하여, 전원부를 제작하였습니다. DC모터에 강한 출력을 전달해야 하는 L298N을 제외하고는, 모든 하드웨어 모듈이 전원부에서 나오는 5V 출력을 이용하여 동작합니다.
하드웨어 구성 및 신호전달 체계
2.4. 개발환경
라인트레이서에 사용된 MCU는 ATmega128이며, 소스코드 개발은 Code Vision AVR(CV AVR)로 진행하였습니다.
3. 단계별 제작과정
모듈별 제작 및 학습기간(13/10/7~13/11/25)
가. DC모터 속도 제어용 PWM 파형 생성 실험
나. 1차 하드웨어 제작 및 DC모터 방향, 속도제어 실험
다. 적외선 센서 제작 및 작동 실험
라. 2차 하드웨어(완성) 제작 및 LED 디스플레이어 적용, 센서 및 LED 추가
프레임 및 납땜 제작과정
마. 라인 트레이서 작동 확인
4. 기타(회로도, 소스코드)
가. 소스코드
#include <mega128.h>
#include <delay.h>
#include <stdio.h>
#define First 3
#define Second 2
#define Third 1
#define Fourth 0
#define Fifth 4
#define Sixth 7
#define Seventh 5
#define Eighth 6
unsigned int Fi,Se,Th,Fo,Ff,Si,Sv,Ei;
int start,check,a,b,c,d,e,f,g,h;
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (1<<ADLAR))
// Read the 8 most significant bits
// of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
delay_us(10);
ADCSRA|=(1<<ADSC);
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCH;
}
////////////////////////////////발광부 설정
unsigned int sensor(unsigned int si)
{
unsigned int ret;
switch(si)
{
case First:
PORTE.4=0;
delay_us(50);
ret=read_adc(si);
PORTE.4=1;
break;
case Second:
PORTE.2=0;
delay_us(50);
ret=read_adc(si);
PORTE.2=1;
break;
case Third:
PORTE.1=0;
delay_us(50);
ret=read_adc(si);
PORTE.1=1;
break;
case Fourth:
PORTE.0=0;
delay_us(50);
ret=read_adc(si);
PORTE.0=1;
break;
case Fifth:
PORTE.3=0;
delay_us(50);
ret=read_adc(si);
PORTE.3=1;
break;
case Sixth:
PORTE.7=0;
delay_us(50);
ret=read_adc(si);
PORTE.7=1;
break;
case Seventh:
PORTE.6=0;
delay_us(50);
ret=read_adc(si);
PORTE.6=1;
break;
case Eighth:
PORTE.5=0;
delay_us(50);
ret=read_adc(si);
PORTE.5=1;
break;
}
return ret;
}
void main(void)
{
////////////////////모터관련 레지스터 설정
DDRA.0=1;
DDRA.1=1;
DDRB=0xFA;
PORTB=0×00;
TCCR1A=0xA3;
TCCR1B=0×03;
OCR1AH=0×00;
OCR1AL=0×00;
OCR1BH=0×00;
OCR1BL=0×00;
////////////////////센서관련 레지스터 설정
DDRF=0×00;
PORTF=0xFF;
DDRE=0xFF;
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
////////////////////LED관련 레지스터 설정
DDRC=0xFF;
PORTC=0×00;
////////////////////스위치 관련 레지스터 설정
DDRD=0b11111100;
EICRA=0x0a;
EICRB=0×00;
EIMSK=0×03;
SREG=0×80;
/////////////////////////반복문 시작
while (1)
{
///////////////////////센서, 칩 LED 설정
Fi=sensor(First);
Se=sensor(Second);
Th=sensor(Third);
Fo=sensor(Fourth);
Ff=sensor(Fifth);
Si=sensor(Sixth);
Sv=sensor(Seventh);
Ei=sensor(Eighth);
Fi/=55;
Se/=53;
Th/=62;
Fo/=60;
Ff/=50;
Si/=40;
Sv/=40;
Ei/=40;
if(Fi>1)
{PORTD.6=1;a=1;}
else
{PORTD.6=0;a=0;}
if(Se>1)
{PORTD.5=1;b=1;}
else
{PORTD.5=0;b=0;}
if(Th>1)
{PORTD.4=1;c=1;}
else
{PORTD.4=0;c=0;}
if(Fo>1)
{PORTD.3=1;d=1;}
else
{PORTD.3=0;d=0;}
if(Ff>1)
{PORTD.2=1;e=1;}
else
{PORTD.2=0;e=0;}
if(Si>1)
{PORTC.2=1;f=1;}
else
{PORTC.2=0;f=0;}
if(Sv>1)
{PORTC.7=1;g=1;}
else
{PORTC.7=0;g=0;}
if(Ei>1)
{PORTC.4=1;h=1;}
else
{PORTC.4=0;h=0;}
///////////////////////센서, 칩 LED 설정 끝
///////////////////////맵핑 코드 시작
///////////////////////주석의 오차만큼 모터 속도 제어(PWM)
if(a==0&b==0&c==1&d==0&e==0)////////직진
{
PORTA.1=1;
PORTA.0=1;
OCR1AH=0x5E;
OCR1AL=0xAF;
OCR1BH=0xEF;
OCR1BL=0xDF;
}
else if(a==0&b==1&c==1&d==0&e==0)/////////오른쪽오차1
{
PORTA.1=1;
PORTA.0=1;
OCR1AH=0x5D;
OCR1AL=0xAF;
OCR1BH=0xEF;
OCR1BL=0xDF;
}
else if(a==0&b==1&c==0&d==0&e==0)/////////오른쪽오차2
{
PORTA.1=1;
PORTA.0=1;
OCR1AH=0x5D;
OCR1AL=0xAF;
OCR1BH=0xEF;
OCR1BL=0xCF;
}
else if(a==1&b==1&c==0&d==0&e==0)/////////오른쪽오차3
{
PORTA.1=1;
PORTA.0=0;
OCR1AH=0x5E;
OCR1AL=0×00;
OCR1BH=0xFF;
OCR1BL=0x0F;
}
else if(a==1&b==0&c==0&d==0&e==0)/////////오른쪽오차4
{
PORTA.1=1;
PORTA.0=0;
OCR1AH=0x5D;
OCR1AL=0×00;
OCR1BH=0xFF;
OCR1BL=0x0F;
}
else if(a==0&b==0&c==1&d==1&e==0)/////////왼쪽오차1
{
PORTA.1=1;
PORTA.0=1;
OCR1AH=0x5E;
OCR1AL=0xAF;
OCR1BH=0xEE;
OCR1BL=0xDF;
}
else if(a==0&b==0&c==0&d==1&e==0)/////////왼쪽오차2
{
PORTA.1=1;
PORTA.0=1;
OCR1AH=0x5F;
OCR1AL=0xAF;
OCR1BH=0xEE;
OCR1BL=0xDF;
}
else if(a==0&b==0&c==0&d==1&e==1)/////////왼쪽오차3
{
PORTA.1=0;
PORTA.0=1;
OCR1AH=0xFF;
OCR1AL=0xAF;
OCR1BH=0×00;
OCR1BL=0xFF;
}
else if(a==0&b==0&c==0&d==0&e==1)/////////왼쪽오차4
{
PORTA.1=0;
PORTA.0=1;
OCR1AH=0xFF;
OCR1AL=0xAF;
OCR1BH=0×00;
OCR1BL=0xFF;
}
else/////////STOP
{
PORTA.1=0;
PORTA.0=0;
OCR1AH=0×00;
OCR1AL=0x2F;
OCR1BH=0×00;
OCR1BL=0x3F;
}
}
}
////////////////////////////////스위치 인터럽트
interrupt [EXT_INT0] void external_int0(void)
{
start=1;
}
interrupt [EXT_INT1] void external_int1(void)
{
start=0;
}
나. 회로도
1. 모터 드라이버 회로도
2. 센서부 회로도
3. 전원부 회로도
4. 스위치 및 LED 회로도
[26호] ICT 융합 공모전 – 아끼슈
글 | 단국대학교 전자전기공학부 학술동아리 서원호, 김재현, 하원빈, 이지은
환경 보호 차원에서 화장지를 아껴쓰자는 메시지를 전달하기 위해 화장지를 뜻하는 영어단어인 ‘tissue’ 와 우리말 ‘아껴쓰다.’ 을 합쳐 만들어진 작품제목이다.
현대사회에서 환경오염은 불가피하게 되었고 전 세계적으로 환경 문제가 더 이상 선택이 아닌 생존의 문제라는 인식이 고조되고 있다. 하지만 현재 우리 지구의 환경오염 발생 원인은 복잡하게 얽혀 있고, 피해 정도를 정확히 파악할 수가 없는 실정이다. 원상회복에도 많은 시간이 걸릴 것이며, 정치 경제 사회 문화 등 총체적 방법을 강구해야 할 것이다.
이 시점에서 우리는 우리의 생활 속에서 실천할 수 있는 작은 것들이 모인다면 환경문제가 조금씩 해결될 수 있다는 희망을 가지고 매일 가는 화장실에서 흔히 볼 수 있는 두루마리 휴지에서부터 작은 실천을 시작하려고 한다. 화장지의 무분별한 사용을 막기 위해 아이디어를 구상하게 되었고 옆의 첨부 사진들은 수많은 사람들의 다양하고 기발한 아이디어이다.
화장지를 뽑을 때 지구의 색이 초록색에서 검정색으로 바뀜으로써 사용자에게 지구가 병들어 가고 있다는 메시지를 전달하고 있다.
화장지가 뜯겨 나갈 때마다 나무도 함께 잘려나가는 모습을 보여줌으로써 사용자의 화장지 절약의식을 일깨워 주고 있다.
흔히 볼 수 있는 둥글한 심이 아닌 네모난 심을 사용해서 의도치 않은 화장지 과사용을 방지하고 있다.
1. 선행연구
일정 | 내용 | 비고 |
~3.14 | 개별 아이디어 구상 | |
3.15 | 1차 회의 | 아이디어 채택 및 R&R 정하기 |
3.16~3.21 | 요구사항 명세, 분석 | 실패사례 조사하고 분석하기 |
3.22 | 2차 회의 | 구체적 설계, 부품 구매 |
3.23~3.31 | 개발 및 보고서 작성 |
요구사항
요구사항 | 요구사항 내용 | 상세 내용 |
사용자 | 화장지의 적정량만 사용하고 싶다. | 상황에 따른 화장지의 적정량을 알아야한다. |
사용자 | 상황에 따라 버튼을 선택해 눌러서 화장지를 사용하고 싶다. |
외부에 적당한 위치에 스위치를 달아서 사용자가 편리하게 휴지를 뽑아 쓸 수 있도록 한다. |
시스템 | 화장지의 반지름에 따라 모터의 회전이 달라져야한다. |
화장지가 줄어들수록 같은 회전에도 적은양의 화장지가 나오므로 줄어들면 줄어들수록 모터의 회전수가 증가한다. |
시스템 | 화장지의 반지름을 알 수 있어야한다. |
가변저항을 이용하여 화장지의 반지름을 실시간으로 측정한다. 고무줄의 탄성을 이용해서 길이를 조절할 수 있다. |
실패 사례
물가 상승률이 월급 인상률을 넘어서는 일이 잦아지면서 아껴야 잘 산다는 말이 새삼 뼈에 사무치는 시절이다. 1997년 경기 성남시의 이모씨는 우리가 일상생활에서 가장 쉽게 낭비하고 있는 물자의 하나인 두루마리 휴지를 아낄 수 있는 휴지걸이를 개발, 특허를 출원했다. 이 아이템은 기존 휴지걸이의 경우 별도의 제동장치가 없기 때문에 사용자가 휴지의 끝을 잡아당기면 회전력에 의해 필요이상으로 많은 길이가 풀린다는 점에 착안했다. 이에 출원인은 별도의 장치를 통해 휴지걸이의 원통부분이 특정 횟수까지 회전하면 자동으로 멈추도록 설계했다. 이런 방식으로 한 번에 정해진 양만큼만 휴지가 풀리도록 해 낭비를 줄일 수 있다는 게 출원인의 주장이다. 또한 원통의 회전이 정지하면서 자연스럽게 휴지가 끊기므로 현재와 같이 두 손을 모두 사용하지 않고, 한 손으로도 손쉽게 적정량의 휴지를 얻을 수 있어 편의성도 높아진다는 설명이다. 특허청은 참신한 아이디어가 돋보이는 이 특허의 등록을 허락했다. 하지만 출원인의 등록료 불납으로 현재는 권리가 소멸된 상태다. 왜 그랬을까. 아마도 원통의 회전수로 정지 시점을 설정하면 휴지를 쓸수록 그 둘레가 줄어들어 한 번에 손에 쥘 수 있는 양도 줄어드는 한계를 인식한 것이 아닐까.
위 실패 사례를 통해 우리는 원통의 일정한 회전수만으로는 한계가 있다는 것을 알았다. 시시각각변하는 휴지의 반지름을 어떻게 알아낼 것인지가 이번 작품의 가장 큰 논점이 될 것이다.
2. 작품 설명
우리는 특히 화장실에서 사용하는 화장지의 무분별한 사용을 줄여보자는 취지로 작품을 고안하였기 때문에 우리나라 사람들의 평균 화장실 휴지 사용량을 조사결과를 참고하였다.
2.1 주요 동작 및 특징
사용자가 사용 목적에 따라 버튼을 선택하여 누르면 적정량의 휴지만 나오게 함으로써 낭비되는 휴지가 없도록 하였다.
사용할수록 줄어드는 휴지의 반지름을 가변저항으로 측정하여 모터의 회전수와 속도를 조정하였고 일정량의 화장지가 나오도록 설계하였다. 줄어들면서 일정한 양이 나오는데 걸리는 시간이 증가하므로 모터의 회전수를 반지름이 줄어들수록 증가하게 설계하였다.
2.2. 전체 시스템 구성
• 주요 부품 소개
DC모터 : 6V 의 DC 모터를 사용하여 휴지롤을 돌리고자 하였다.
가변저항 : 가변저항을 통해 나오는 값을 아두이노의 ADC를 이용하여 값을 처리하여 휴지의 남은 양을 계산한다.
아두이노 : 아두이노는 ADC input을 반지름 계산 알고리즘을 연산하여 DC MOTOR로 OUTPUT해주는 역할을 한다.
2.3. 개발 환경
Macintosh 및 Arduino IDE환경에서 C언어로 코딩하였다. CAD tool로는 Fritzing을 사용하였고 FlowChart의 경우 yEd를 사용하였다.
3. 단계별 제작 과정
공공장소에서 흔히 볼 수 있는 크기의 화장지케이스를 기준으로 만들었다.
화장지 케이스에 베어링과 합쳐진 모터를 앞 뒤로 단단하게 고정시켰다.
나무 막대기를 제도해서 지지대로 사용(7cm, 8.5cm)
플라스틱 막대기를 연결시켜 휴지를 받히게 했고 막대를 가변저항모양에 맞게 갈아 고정시켰다.
화장지를 끼웠을 때 끝까지 들어가지 않게끔 턱을 만들었다.
4. 반지름 계산 알고리즘
만약 두 측정자의 끼인각이 예각일 경우 반지름은 각도에 따라 선형적으로 증가한다. 하지만 둔각이 될 경우 이는 예각과는 다른 비율로 증가하게 된다. 이는 손쉽게 시리얼 모니터로 확인이 가능하다. 따라서 매핑함수를 이용하여 각각의 경우 다른 반지름으로 초기화를 해준다.
예각인지 둔각인지를 선택하는 것은 OutputValue1, 2중 큰 값을 선택하면 알 수 있다.
outputValue1 = map(sensorValue, 660, 920, 40, 80);
outputValue2 = map(sensorValue, 920, 1020, 81, 145);
예를 들어 딱 90도가 되었을 때 전자의 값은 80, 후자의 값은 81이 되는데 이후로 각도가 늘어날수록 outputValue1의 경우 근소하게 늘어나고 2의 경우는 많이 늘어나기 때문에 이의 차이를 이용하여 현재 예각인지 둔각인지를 판가름 할 수 있다.
또한 휴지롤의 반지름이 작아지면 같은 속도로 모터가 돌아간다고 해도 휴지가 나오는 속도는 차이가 나게 된다. 이를 보정해 주기 위하여 Distance란 파라미터를 정해놓고 반지름에 따라 모터의 PWM을 변화시켜 반지름이 달라지더라도 최종적으로 나오는 휴지의 속도는 모든 반지름일 때 일정하도록 조정해 주었다.
if(outputValue1 > outputValue2)
{
Distance = Speed/outputValue1/10*50;
}
else
{
Distance = Speed/outputValue2/10*50;
}
설계의 한계
우리 설계의 경우 6V짜리 DC모터를 사용한다. 보유하고 있는 모터드라이브를 사용하려고 하였으나 DC모터의 구동 전류가 약 800mA이기 때문에 100mA까지 커버하는 모터드라이브로는 이 모터를 구동할 수 없었다. 하지만 1A이상의 모터드라이브를 사용하면 정확하게 작동할 것이라고 생각한다. 때문에 정확하게 한 시나리오에서 구동하는 모습은 보고서에 담을 수 없었지만 추후에 기회가 된다면 좀 더 완성도 높게 제작할 수 있을 것이다.
5. 기타 (회로도, 소스코드, 참고문헌 등)
• 소스코드
Arduino Code
#define Pwm 5
#define Dir 4
#define Speed 15
#define rpm 3
#define ButtonPin_small 12
#define ButtonPin_Big 11
#define small 2.1
const int analogInPin = A7; // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to
int sensorValue = 0; // value read from the pot
int outputValue1 = 0; // value output to the PWM (analog out)
int outputValue2 = 0;
float Distance = 0; //반지름에 따른 모터의 PWM 변수
void setup() {
Serial.begin(9600);
pinMode(Pwm, OUTPUT);
pinMode(Dir, OUTPUT);
}
void loop() {
sensorValue = analogRead(analogInPin); // ADC값을 sensorValue에 저장.
outputValue1 = map(sensorValue, 660, 920, 40, 80); //반지름에 따른 Value값 매핑
outputValue2 = map(sensorValue, 920, 1020, 81, 145);
if(outputValue1 > outputValue2)
{
Distance = Speed/outputValue1/10*50;
}
else
{
Distance = Speed/outputValue2/10*50; // 어떤 반지름의 경우라도 결과적으로 나오는 속도는 같게 Parameter값 조정
}
// print the results to the serial monitor:
Serial.print(“sensor = “ );
Serial.print(sensorValue);
Serial.print(“\t output = “);
Serial.print(outputValue1);
Serial.print(“ “);
Serial.println(outputValue2);
if (digitalRead(ButtonPin_small) == LOW) //small button의 경우 소변 Big의 경우 대변
{
Motor_GO(Distance/small); // 소변일 경우 PWM을 감소시켜 휴지가 나오는 양을 적게함
delay(rpm*1000)
}
else if (digitalRead(ButtonPin_Big)==LOW)
{
Motor_GO(Distance);
delay(rpm*1000)
}
}
void Motor_GO(float Distance)
{
analogWrite(Pwm ,Distance);
digitalWrite(Dir,HIGH); // Direction = HIGH값일 때 정회전
}
• 참고문헌
http://Arduino.cc
[HNS]디바이스마트 단독이벤트!!IEC Series 베젤타입(B1/B2) 구매시 가격할인!!
[HNS] 디바이스마트 단독이벤트!!
IEC Series 베젤타입(B1/B2) 구매시 가격할인!!