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

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

 

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

 

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

 

 

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번 함수를 동시에 동작 할 수 없다는 것이죠.

 

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

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

 

  1. 본명 이수빈 2014.07.05 10:02 신고  Address  Edit/Delete  Reply

    장애인 라이브러리네요. if(millis()%1000){} 이딴게 더 낮겠네요. 무슨 이게 멀티쓰래드죠?? 딜레이 쓰면 기달리고나서 그담에 진행하는게 멀티인가요?

    • Favicon of http://blog.danggun.net BlogIcon 당근천국 2014.07.06 01:32 신고  Address  Edit/Delete

      분석만 읽어보셔도 이런 댓글 안다실텐데 말이죠-_-;;

      어차피 다시 설명해봐야 분석에 있는 내용이랑 다를게 없으니 간단하게 이야기 하자면 아두이노는 loop()를 돌리는 방식이라 자체적으로 쓰래드를 지원하지 않으면 멀티쓰래드를 구현할 수 없습니다.
      그래서 시분활을 할 수 있도록 'ArduinoThread'같은 것을 사용하는 것이죠.
      물론 'ArduinoThread'같은 것을 만들지 않고 클래스안에 'ArduinoThread'와 비슷하게 구현해도 됩니다.
      'ArduinoThread'는 단지 반복적으로 구현해야 할 내용들을 구현해 둔것이죠.
      거기에 정말로 멀티쓰래드처럼 돌아가게 하려면 사용하려는 함수를 포함하는 클래스로 만들어 내부에서 분활반복이 가능하도록 구현해야 합니다.
      그것이 제가 만든 '[Arduino] 한번에 2개 이상의 스테핑 모터를 제어하기'같은 클래스 입니다.
      이 클래스와 'ArduinoThread'를 합쳐서 사용하면 코드도 깔끔해지고 마치 멀티쓰래드같은 착시가 가능합니다.
      이렇게 해야 하는 이유를 다시 한번 설명하자면 아두이노의 구조때문입니다.

      더 궁금한것이 있다면 댓글 남겨주세요~

  2. BlogIcon 조충현 2015.06.09 11:54 신고  Address  Edit/Delete  Reply

    안녕하세요~
    제가 하는 프로젝트에 멀티스레드가 필요한 것같아서 댓글 남깁니다.
    저는 모터가 돌아갈때 네오픽셀링의 led를 시간을 등분할 해서 켜고 싶습니다. 아다푸르트에서 받은 소스코딩을 사용하는데요..코딩자체가 이미 루프로 되어있는던 스레드를 사용할수 있는지 궁금합니다

  3. 아두이노 2015.07.23 10:55 신고  Address  Edit/Delete  Reply

    안녕하세요 저도 지금 제가하는 프로젝트에 아두이노멀티스레드가 필요한시점인데.
    콜백함수에다가 파라미터를 주고싶은데, 헤더파일을 전부다 뜯어 고쳐도 안돼더라구요..
    혹시방법을 알고계십니까?

댓글 작성

이름
패스워드
홈페이지
비밀글

티스토리 툴바