레이블이 시리얼통신인 게시물을 표시합니다. 모든 게시물 표시
레이블이 시리얼통신인 게시물을 표시합니다. 모든 게시물 표시

2015년 5월 22일 금요일

아두이노 시리얼 통신 예제들

시리얼 통신 두 번째 예제

 두 번째 예제로 이번에는 PC에서 문자 하나를 받아서 그것이 ‘0’이면 LED를 끄고 ‘1’이면 LED를 켜는 프로그램을 작성해 보자. 이 경우 아두이노는 데이터가 사용자로부터 들어올 때 까지 대기 상태로 있다가 데이터가 읽히면 거기에 맞는 동작을 수행해야 한다.

#define LED 13
void setup() {
 pinMode(LED, OUTPUT);
 Serial.begin(9600);
}
void loop() {
 if ( Serial.available() ) {
   char command = Serial.read();
   if (command == '0') {
     digitalWrite(LED, LOW);
     Serial.println("LED off.");
   }
   else if (command == '1') {
     digitalWrite(LED, HIGH);
     Serial.println("LED on.");
   }
     else {
     Serial.print("Wrong command :");
     Serial.println(command);
     }
 }
}

이 예제에서는 다음과 같은 함수들이 사용되었다.

   int Serial.available() 함수
  • 전송되어 내부버퍼(64바이트)에 저장된 데이터의 개수를 반환한다.
  • 입력인수는 없다.

   int Serial.read() 함수
  • 전송되어 내부 버퍼(64바이트)에 저장된 데이터 중 가장 첫 번째 데이터(ASCII코드)를 읽어서 반환한다.
  • 이 함수가 수행되면 내부 버퍼의 크기는 하나가 줄어든다.
  • 내부 버퍼가 비었다면 -1을 반환하다.

   int Serial.println() 함수
  • 출력 문자열의 끝에 줄바꿈 기호 ‘\r\n’ 가 자동으로 붙는다는 점 외에는 Serial.print()함수와 동일한 동작을 수행한다.

이 예제에서는 USRT 통신기의 내부 버퍼의 개념을 이해할 필요가 있다. 내부 버퍼란 전송된 데이터가 일시적으로 저장되는 내부 메모리를 말하며 데이터가 전송된 순서대로 저장된다. 아두이노의 내부 버퍼의 크기는 64바이트이다. 전송되어 저장된 데이터를 사용하려면 내부 버퍼에서 이 데이터를 읽어내야 하는데 이때 사용되는 함수가 Serial.read()함수이다. 가장 먼저 전송된 데이터 하나를 읽어낸 후 그 데이터는 버퍼에서 삭제되며, 만약 버퍼가 비었다면 -1을 반환한다. 따라서 버퍼에 읽어낼 데이터가 있는지 없는지를 먼저 검사하는 것이 일반적이고 이때 사용되는 함수가 Serial.available()이다. 이 함수는 버퍼에 저장된 데이터의 개수를 반환하며 따라서 버퍼가 비어있다면 0을 반환한다.

 이런 사항들을 이해하였다면 두 번째 예제를 이해하는데 어려움이 없을 것이다. 데이터가 전송되어 오면 그것을 읽어들여서 ‘1’이면 LED를 켜고, ‘0’이면 끈다. 그 이외의 데이터에 대해서는 잘못된 명령이라는 문자열을 출력한다.

시리얼 통신 세 번째 예제

 세 번째로 11번 핀에 부저가 연결되었다고 가정하고 명령어를 하나 받아서 다음과 같은 동작을 수행하는 예제를 작성해 보도록 하겠다.

       - ‘0’ : LED를 끈다.
       - ‘1’ : LED를 켠다.
       - ‘2’ : 부저를 짧게 한 번 울린다. (삑)
       - ‘3’ : 부저를 짧게 두 번 울린다.(삐삑)
       - 그 외의 명령어들은 잘못된 것이라는 메세지를 출력한다.

이 예제의 경우는 처리해야 될 경우의 수가 많기 때문에 if-else 명령보다는 switch-case 명령이 더 효율적이다.

#define LED 13
#define BUZ 11

void setup() {
 pinMode(LED, OUTPUT);
 pinMode(BUZ, OUTPUT);
 Serial.begin(9600);
}

void loop() {
 if ( Serial.available() ) {
   char command = Serial.read();
   switch(command) {
     case '0':
       digitalWrite(LED, LOW);
       Serial.println("LED off.");
       break;
   case '1' :
     digitalWrite(LED, HIGH);
     Serial.println("LED on.");
     break;
   case '2' :
     digitalWrite(BUZ, HIGH);
     delay(50);
     digitalWrite(BUZ, LOW);
     break;
   case '3' :
     digitalWrite(BUZ, HIGH);
     delay(50);
     digitalWrite(BUZ, LOW);
     delay(50);
     digitalWrite(BUZ, HIGH);
     delay(50);
     digitalWrite(BUZ, LOW);
     break;
   default:
     Serial.print("Wrong command :");
     Serial.println(command);
   }
 }
}


2015년 5월 4일 월요일

아두이노Due와 Scilab의 시리얼 통신

  아두이노Due 와 Scilab 사이에 baudrate 250000 속도로 안정적으로 통신이 됨을 실험으로 확인하였다. Scilab의

    아두이노Due : Serial.begin(250000)
    Scilab : h=openserial(7,"250000,n,8,1")

아두이노Due에서는 50msec 마다 데이터를 보내도록 하였는데도 데이터 처리가 밀리지 않고 잘 수행되었다. 사실 Scilab쪽에서는 계산보다는 통신하는데 더 시간이 많이 소요되기때문에 고속으로 통신을 수행하는 것이 복잡한 연산이 필요한 경우 무척 중요해질 것 같다.

보레이트를 460800 으로 높여도 안정적으로 통신이 됨을 확인했다. 아래 그림은 아두이노Due 와 Scilab을 연결하여 이 속도로 로터리 엔코더의 각도값을 실시간으로 받아오는 화면을 캡쳐한 것이다.


아래는 아두이노Due 쪽의 소스코드이다.

[edit]