티스토리 뷰

INTRO

Arduino(아두이노)를 이용해서 거실의 커튼을 열고닫는 제어를 해보고 싶다는 생각에서 시작했다.

python을 공부하고 있는 요즘 이녀석을 어디까지 쓸 수 있을 지 고민 중이다.

그 첫걸음에 서서 빛감지 센서와 모터를 구동하는 것을 목표로 정했다.

Arduino에 대한 설명은 위키백과에게 넘기도록 한다. https://ko.wikipedia.org/wiki/%EC%95%84%EB%91%90%EC%9D%B4%EB%85%B8

 

일단 Arduino를 다루는 것부터 시작해보려고 한다.

준비물 : Arduino UNO R3, USB cable, 저항, LED(Light Emitting Diode, 발광 다이오드)

 

 

1. Arduino IDE

https://www.arduino.cc/en/Main/Software#

macosx virsion, 20191024 기준 : arduino-1.8.10-macosx.zip

압축을 해제하고 실행하면 다음과 같이 에디터와 콘솔로 이루어진 것을 확인 할 수 있다.

 

메뉴의 툴에서 보드와 포트를 설정한다.

 

- 에디터 구성

선행처리기 : #include, #define, #error, #if 등의 컴파일 전처리

void setup : 초기화 설정

void loop : 동작 제어부

 

 

 

 

Serial Communication Test : 전송창에 입력된 문자 바이트 단위를 Serial.available()을 통해 전달되어 표시된다.

--Serial Communication Test.ino : Arduino IDE Sketch

// Serial Comunication Test

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print("Hello Arduino UNO R3\n");
  delay(1000);
  Serial.print("Serial Comnunication Test\n");
  delay(1000);
  Serial.print("Serial available Test : ");
  delay(5000);
  Serial.println(Serial.available());
  Serial.println("Test Complete");
  Serial.end();

}

 

 

2. 내장 LED Test

전송창에 1을 입력하면 blink Mode, 2를 입력하면 turn on Mode, 0을 입력하면 Serial Shutdown Mode를 만들어 본다.

 

--blink_test.ino

// 초기값 설정 : inled의 13은 내장LED 번호, sw는 문자열로 표시
int inled = 13;
char sw = '1';

void setup() {
  // Serial.METHOD 형식, begin은 사용, 9600은 baud rate, pinMode 설정
  Serial.begin(9600);
  pinMode(inled, OUTPUT);
  // 동작 설명, Serial.println은 줄바꿈 포함
  Serial.println("Default number is declared by sw = '1' ");
  Serial.println(" '1' is Blink Mode every second for 5 times");
  Serial.println(" '2' is turning on for 5 seconds");
  Serial.println(" '0' is turned off & Serial shutdown");
  Serial.println(" Others are jsut turned off but Serial port on");
}

void loop() {
  // Serial.available은 serail 통신을 수신한 값으로 초기값이 0
  // 전송창에 signal이 입력되면 Serial.available은 1을 가지며 loop를 돈다.
  if(Serial.available() == 0){
    Serial.println("Ready to input number");
    // Serial input이 없을 때, 즉 Serial.available이 0일때 멈춤
    while(!Serial.available());
    Serial.println("");
  }

  // Serial.available이 0보다 크다는 건 입력값이 있을 때 다음 조건문을 실행하겠다는 의미
  if(Serial.available()>0){
    // if(sw가 1일때), 전송창에 입력되는 값을 sw에 저장
    sw = Serial.read();
    if(sw == '1'){
      //if(조건){}else if(조건){}else{} 형태로 else는 if, else if외의 조건
      //if 안에 for 조건문, 반복 변수 i 선언, for(초기값; 조건식; 증감식) 형태로 표시
      int i;
      Serial.println("Blink Mode every a second");
      for(i=1; i<=5; i++){
        Serial.print(" i = : ");
        Serial.println(i);
        digitalWrite(inled, HIGH);
        Serial.println("inled is on");
        delay(1000);
        digitalWrite(inled, LOW);
        Serial.println("inled is off");
        delay(1000); 
      }
      Serial.println("----- Blink Mode End -----");
      Serial.println("");
    }
    else if(sw == '2'){
      int j;
      Serial.println("inled is Turning on for 5 seconds");
      digitalWrite(inled, HIGH);
      for(j=1; j<=5; j++){
        Serial.print(" j = : ");
        Serial.print(j);
        Serial.println(" sec");
        delay(1000);
      }
      Serial.println("----- Turn on Mode End -----");
      Serial.println("");
      digitalWrite(inled, LOW);
    }
    else if(sw == '0'){
      Serial.println("Turn off & Serial shutdown");
      digitalWrite(inled, LOW);
      // Serial.end() 실행 후 전송창에 입력된 값을 통신하지 않음
      Serial.end();
    }
    else{
      digitalWrite(inled, LOW);
    }
  }
}

 

--Arduino Serial Monitor

//최초 upload 후
Default number is declared by sw = '1' 
 '1' is Blink Mode every second for 5 times
 '2' is turning on for 5 seconds
 '0' is turned off & Serial shutdown
 Others are jsut turned off but Serial port on
Ready to input number

//전송창에 1을 입력 시
Blink Mode every a second
 i = : 1
inled is on
inled is off
 i = : 2
inled is on
inled is off
 i = : 3
inled is on
inled is off
 i = : 4
inled is on
inled is off
 i = : 5
inled is on
inled is off
----- Blink Mode End -----

Ready to input number

//전송창에 2을 입력 시
inled is Turning on for 5 seconds
 j = : 1 sec
 j = : 2 sec
 j = : 3 sec
 j = : 4 sec
 j = : 5 sec
----- Turn on Mode End -----

Ready to input number

//전송창에 0을 입력 시
Turn off & Serial shutdown

 

 

 

3. python을 이용한 Serial Monitor 연동

Arduino IDE(Arduino Sketch)에서 C/C++로 작성된 코드를 Arduino로 업로드(upload)하면 Arduino가 동작을 수행하게 된다.

어떤 입력에 따라 수행되는 절차를 정의한 것이 스케치(Arduino Sketch)이고 이에 따라 제어(control)되고 수행(action)을 한다.

코드에 따라 다르겠지만 void loop에서 반복되는 수행과정에서 입력(input)이 필요할 수도 있다.

위에서 작성한 코드는 Serial Monitor에 code에서 정의된 출력(print, ouput)을 하고 전송창 입력(input)에 따라 조건에 맞는 수행을 한다.

 

거실의 커튼 제어를 생각해보면, 열고 닫는 절차를 정의해 놓은 Arduino가 최종 제어할 unit은 모터가 될 것이다.

이를 제어하기 위한 입력은 빛감지 센서가 될 수도 있고, 스위치를 둘 수도, Arduino IDE Serial Monitor 전송창에 입력할 수도 있다.

입출력을 담당하는 Arduino IDE-Serial Monitor의 역할을 python을 이용하는 방법도 있다.

왜? 굳이 python을 이용하려는가에 대한 명쾌한 대답을 아니겠지만, 데이터를 수집하고 시각화하는 코딩이 상대적으로 쉽다는 것이다.

하여 다음은 python을 이용하여 Arduino Serial Monitor에 입출력을 수행하도록 해보려고 한다.

 

먼저 python에서 Arduino Serial 통신에 필요한 library를 설치한다.

$ pip3 install pyserial

sublime text3에서 serial_test.py를 생성한다.

!! 주의사항

 - Arduino IDE Serial Monitor 창을 열어놓으면 sublime text3 *REPL*[python] 실행 시 다음과 같은 오류를 만난다.

   OSError: [Errno 16] Resource busy: '/dev/cu.usbmodem14101'

 - Arduino IDE Serial Monitor 창을 닫고 실행하면 된다.

 - command+shift+B를 이용하여 python을 실행 시 *REPL*[python] 새탭이 열리는데 처음탭에서만 Arduino 연동이 되니 참고하자.

 

--serial_test.py

import serial

serial_port = '/dev/cu.usbmodem14101'
serial_baudrate = 9600
ard = serial.Serial(serial_port,serial_baudrate)

while(1):
  if ard.readable():
    # ard.readline() : Serial Monitor 내용을 한 줄씩 읽어온다.
    smo = ard.readline()
    # ard.decode() : readline을 decoding
    msg = smo.decode()[:len(smo)-1]
    # Arduino Serial Monitor 처럼 print
    print(msg)
    # 필자 코딩 구성 상 마지막 message check를 위함
    pmsg = msg.strip()[0:5]

    if pmsg == 'Ready':
      print('input sw = ', end=' ')
      sw = input()
      print(sw)
      # ard.write()를 이용해 Arduino Serial Monitor 전송창 입력값 전달
      ard.write(sw.encode())

--*REPL*[python]

Default number is declared by sw = '1' 
 '1' is Blink Mode every second for 5 times
 '2' is turning on for 5 seconds
 '0' is turned off & Serial shutdown
 Others are jsut turned off but Serial port on
Ready to input number
input sw =  1
1

Blink Mode every a second
 i = : 1
inled is on
inled is off
 i = : 2
inled is on
inled is off
 i = : 3
inled is on
inled is off
 i = : 4
inled is on
inled is off
 i = : 5
inled is on
inled is off
----- Blink Mode End -----

Ready to input number
input sw =  2
2

inled is Turning on for 5 seconds
 j = : 1 sec
 j = : 2 sec
 j = : 3 sec
 j = : 4 sec
 j = : 5 sec
----- Turn on Mode End -----

Ready to input number
input sw =  0
0

Turn off & Serial shutdown

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함