본문 바로가기

이론/AVR

무이메이커스_[arduino]아두이노에서 멀티태스킹 사용하기 / FreeRTOS를 이용한 멀티태스킹 (2/2)

안녕하세요 허니컴의 무이메이커스입니다.

저번시간은 아두이노를 사용하면서 Delay()로 인해 발생할 수 있는 문제점과 해결책을 알아보았습니다. 오늘은 FreeRTOS헤더파일 없이 멀티태스킹을 진행해보겠습니다.

 

< 문제점 >

아두이노는 싱글스레드로 동작합니다. 스레드는 프로세서를 수행하는 하나의 흐름을 말합니다.

스레드가 하나라는 것은 한번에 한가지 일만 할 수 있다는것을 의미합니다.

그렇기 때문에 delay()를 사용하게되면 코드전체가 뒤로 밀리는 현상이 발생합니다.

또, delay()가 사용되어야만 하는 모듈과 다른주기적인 동작이 병행되어야 할 때에도 문제가 발생합니다. 때문에 이번시간에는 아두이노를 이용해 멀티태스킹을 진행해보도록 하겠습니다.

< 아두이노 멀티태스킹 회로도 >

- 사용부품 : 360도 Servo motor2개, LED2개

 

< 아두이노 멀티태스킹 연결방법 >

5V

2개 servo motor의 +

GND

2개 servo motor의 -, 2개 LED의 -

13

LED1의 +

12

LED2의 +

10

servo motor1의 신호선

9

servo motor2의 신호선

< 아두이노 멀티태스킹 소스코드 >

#include <Servo.h>

class Flasher

{

int ledPin;

long OnTime;

long OffTime;

int ledState;

unsigned long previousMillis;

public:

Flasher(int pin, long on, long off)

{

ledPin = pin;

pinMode(ledPin, OUTPUT);

OnTime = on;

OffTime = off;

ledState = LOW;

previousMillis = 0;

}

void Update()

{

unsigned long currentMillis = millis();

if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))

{

ledState = LOW; // Turn it off

previousMillis = currentMillis; // Remember the time

digitalWrite(ledPin, ledState); // Update the actual LED

}

else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))

{

ledState = HIGH; // turn it on

previousMillis = currentMillis; // Remember the time

digitalWrite(ledPin, ledState); // Update the actual LED

}

}

};

////////////////////////////////////////////////////////////////////////////

class Sweeper

{

Servo servo; // the servo

int pos = 90; // current servo position

int increment; // increment to move for each interval

int updateInterval; // interval between updates

unsigned long lastUpdate; // last update of position

public:

Sweeper(int interval, int incr)

{

updateInterval = interval;

increment = incr;

}

void Attach(int pin)

{

servo.attach(pin);

}

void Detach()

{

servo.detach();

}

void Update()

{

if((millis() - lastUpdate) > updateInterval) // time to update

{

lastUpdate = millis();

pos += increment;

servo.write(pos);

if ((pos >= 180) || (pos <= 90)) // end of sweep

{

increment = -increment;

}

}

}

};

Flasher led1(12, 100, 400);

Flasher led2(13, 350, 350);

Sweeper sweeper1(15, 2);

Sweeper sweeper2(25, 2);

void setup()

{

sweeper1.Attach(9);

sweeper2.Attach(10);

}

void loop()

{

led1.Update();

led2.Update();

sweeper1.Update();

sweeper2.Update();

}

< 소스&동작 설명 >

Flasher라는 class를 생성해 줍니다. 이 클레스는 LED를 조절할 때 쓰입니다.

이 class를 사용하려면 Flasher led1(핀번호, led 켜있는시간, led 꺼있는시간) 이렇게 인스턴스를 만든 후 loop문에서 led1.Update();로 동작시키면 됩니다.

서보모터를 동작하기 위해서도 마찬가지로 Sweeper라는 class를 생성한 후 Sweeper sweeper1(핀번호, 모터속도 증분)을 통해 인스턴스를 만듭니다. 마지막으로 loop문에 sweeper1.Update()로 동작합니다.

< 동작영상 >

 

 

 

........

시제품 제작 문의