프로그래밍/하드웨어

[Arduino] 아두이노에서 멀티쓰래드사용하기

당근천국 2014. 1. 18. 15:00

아두이노는 자체적으로 멀티쓰래드를 지원하지 않습니다.

그러다 보니 쓰래드 작업을 하고 싶으면 방법이 없죠.

 

결론부터 이야기하자면 아두이노에서 다른 언어의 쓰래드와 같은 동작을 하는 구현은 불가능합니다.

 

지금부터 소개할 라이브러리도 시분할로 쓰래드처럼 보이도록 해둔 것이지 쓰래드라고 볼 수 없죠.

 

 

1. 'ArduinoThread' 프로젝트

깃허브에 'ivanseidel'라는 분께서 만든 프로젝트입니다.

(참고 : github - ivanseidel / ArduinoThread )

 

소스코드를 보면 우리가 생각하는 쓰래드처럼 동작하지 않을 것 같습니다.

구현된 방식이 아두이노의 'loop()'에서 쓰래드 컨트롤러를 지속해서 호출하면서 타이밍 맞을 때 쓰래드로 지정한 함수를 호출하는 방식입니다.

구조만 봐서는 이 라이브러리에서 반복문을 쓰면 안될 거 같네요.

 

 

2. 테스트해보기

테스트 코드도 같이 올라와 있습니다.

우리는 타이머 예제를 사용하겠습니다.

(참고 : github - ivanseidel / ArduinoThread examples )

 

반복문 테스트도 겸할 겸 스탭모터 세팅도 합니다.

 

 

#include <Thread.h>
#include <ThreadController.h>

#include <Stepper.h>

ThreadController controll = ThreadController();

int ledPin = 13;

//My simple Thread
Thread myThread = Thread();
Thread myThread2 = Thread();

int m_nCount = 0;

int m_nTCount1 = 0;
int m_nTCount2 = 0;

Stepper stepper(200, 8, 9, 10, 11);


// callback for myThread
void niceCallback()
{
  ++m_nTCount1;
  Serial.print(" niceCallback : ");
  Serial.print(millis());
  Serial.print(" , ");
  Serial.println(m_nTCount1);
}

void testCallback()
{
  ++m_nTCount2;
  Serial.print(" testCallback : ");
  Serial.print(millis());
  Serial.print(" , ");
  Serial.println(m_nTCount2);

}

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  myThread.onRun(niceCallback);
  myThread.setInterval(500);
  
  myThread2.onRun(testCallback);
  myThread2.setInterval(800);
  
  controll.add(&myThread);
  controll.add(&myThread2);
  
  stepper.setSpeed(30);
}

void loop()
{
  if(Serial.available())
  {
    int c = Serial.read();
    
    if(c == '1')
    {
      stepper.step(200);
    }
  }
  
  // checks if thread should run
  /*if(myThread.shouldRun())
    myThread.run();
    
  if(myThread2.shouldRun())
    myThread2.run();*/
  controll.run();

  // Other code...
  ++m_nCount;
/*
  Serial.print("Main Thread :  ");
  Serial.println(m_nCount);
  
  delay(1000);*/
  
}

 

사실 스텝 모터 대신 그냥 반복문을 많이 돌리셔도 됩니다 ㅡ.-;;;

 

 

3. 테스트

테스트를 위해서 '시리얼 모니터'를 열어 봅시다.

일단 2개의 함수가 정상적으로 돌아가는 것을 볼 수 있습니다.

 

 

 

'1'을 날려보면 잠시 쓰래드가 멈추는 것을 알 수 있습니다.

 

 

 

4. 분석

테스트를 해보면 스텝핑모터가 동작하는 동안 다른 쓰래드까지 멈추는 걸 알 수 있습니다.

우리가 알고 있는 쓰레드 동작이랑 매우 다르죠 ㅎㅎㅎㅎ

 

일단 스텝 모터는 저번에 제가 만든 라이브러리로 해결할 수 있습니다.

(참고 : [Arduino] 한번에 2개 이상의 스테핑 모터를 제어하기)

 

아무래도 'ArduinoThread'를 기반으로 하는 반복문을 위한 클래스를 따로 만들어야겠습니다-_-;

 

마무리

코드를 분석해보면 아두이노의 프로세스를 분할해서 쓰래드처럼 보이도록 하는 것입니다.

(사실 물리적 코어가 하나라면 운영체제에서도 쓰래드 처리를 위해 비슷한 동작을 합니다 ㅎㅎㅎ)

 

이게 아마도 아두이노 자체에서 지원한다면 우리가 원하는 쓰래드가 될 텐데 'loop()'를 이용해야 하니 실행되는 함수 자체를 시분할을 할 수 없다는 문제가 있습니다 ㅡ,.ㅡ;;

그러니 결국 쓰래드 라이브러리에 등록된 함수는 이전함수가 완료되어야 다음 함수로 넘어가는 동작을 하게 됩니다.

1번 함수와 2번 함수를 동시에 동작 할 수 없다는 것이죠.

 

이게 마이크로프로세서의 문제인지 아두이노만의 문제인지는 잘 모르겠네요;;

결국은 그냥은 해결이 안 되겠네요;;