KEYPAD를 이용한 모터 제어
- 왼쪽 회전, 정지, 오른쪽 회전 3개의 키에 의해 모터 동작
- Keypad ISR과 Motor Task간 큐를 이용하여 데이터 전달
< ITC1.c >
#include <FreeRTOS_AVR.h>
// 모터, 키패트 핀 정의
const int MT_P = 10;
const int MT_N = 9;
const int LeftKey = 2; // 0번 인터럽트 사용
const int StopKey = 3; // 1번 인터럽트 사용
const int RightKey = 21; // 2번 인터럽트 사용
// Task간 데이터 전달을 위해 전역으로 큐를 선언
QueueHandle_t xQueue;
// 키패트 ISR -> Queue로 데이터를 전달
void LeftKeyControl(){
uint16_t sendValue = 1;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void RightKeyControl(){
uint16_t sendValue = 2;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void RightKeyControl(){
uint16_t sendValue = 3;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void MotorTask(void *arg){
uint16_t receiveValue = 0;
while(1){
// Queue로부터 데이터 수신을 대기
if(xQueueReceive(xQueue, &receiveValue, 0)){
// Left state
if(receiveValue==1){
digitalWrite(MT_P, LOW);
digitalWrite(MT_N, HIGH);
}
// Stop state
if(receiveValue==2){
digitalWrite(MT_P, LOW);
digitalWrite(MT_N, LOW);
}
// Right state
if(receiveValue==3){
digitalWrite(MT_P, HIGH);
digitalWrite(MT_N, LOW);
}
}
}
}
void setup(){
pinMode(MT_P, OUTPUT);
pinMode(MT_N, OUTPUT);
pinMode(LeftKey, INPUT);
pinMode(StopKey, INPUT);
pinMode(RightKey, INPUT);
// 인터럽트 설정
attachInterrupt(0, LeftKeyControl, RISING); // Left키패드 입력은 Rising 조건일때 0번 인터럽트
attachInterrupt(1, StopKeyControl, RISING);
attachInterrupt(1, RightKeyControl, RISING);
// ITC를 위한 큐 생성
xQueue = xQueueCreate(3, sizeof(uint16_t)); // 버퍼의 아이템수가 3인 큐 생성
if(xQueue!=NULL){ // 큐가 생성된 경우 Motor Task를 생성하고 스케쥴링 실행
xTaskCreate(MotorTask, NULL, 200, NULL, 1, NULL);
vTaskStartScheduler();
}
}
void loop(){}
KEYPAD를 이용한 모터 속도 제어
- 왼쪽 or 오른쪽 회전은 25% 회전
- 버튼 2개를 추가하여 속도를 제어
- 한 번 누를때마다 50 -> 75 -> 100 -> 50으로 속도 제어
< ITC2.c >
#include<FreeRTOS_AVR.h>
const int MT_P =10;
const int MT_N =9;
const int LeftKey =2; // 0번 인터럽트
const int StopKey =3; // 1번 인터럽트
const int RightKey =21; // 2번 인터럽트
const int LeftSpeedKey =20; // 3번 인터럽트
const int RightSpeedKey =19; // 4번 인터럽트
// 255기준 Duty-cycle 정의
const int val[4] = {127, 190, 255, 190};
// ITC을 위한 전역 큐
QueueHandle_t xQueue;
int count1, count2 = 0;
// 키패트 ISR -> Queue로 데이터를 전달
void LeftKeyControl(){
uint16_t sendValue = 1;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void StopKeyControl(){
uint16_t sendValue = 2;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void RightKeyControl(){
uint16_t sendValue = 3;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void LeftKeySpeedControl(){
uint16_t sendValue =4;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void RightKeySpeedControl(){
uint16_t sendValue =5;
xQueueSendFromISR(xQueue, &sendValue, 0);
}
void MotorTask(){
uint16_t recievevalue = 0;
while(1){
if(xQueueReceive(xQueue, &receiveValue, 0)){
// Rotate Left
if(receiveValue==1){
analogWrite(MT_P, 0);
analogWrite(MT_N, 64);
}
// STOP
else if(receiveValue==2){
analogWrite(MT_P, 0);
analogWrite(MT_N, 0);
}
// Rotate Right
else if(receiveValue==3){
analogWrite(MT_P, 0);
analogWrite(MT_N, 64);
}
// Left Rotation Speed up
else if(receiveValue==4){
analogWrite(MT_P, 0);
analogWrite(MT_N, val[count1]);
count1 = (count1+1) % 4;
}
// Right Rotation Speed up
else if(receiveValue==5){
analogWrite(MT_P, val[count2]);
analogWrite(MT_N, 0);
count2 = (count2+1) % 4;
}
}
}
}
void setup() {
// Set pin Mode
pinMode(MT_P, OUTPUT);
pinMode(MT_N, OUTPUT);
pinMode(LeftKey, INPUT);
pinMode(StopKey, INPUT);
pinMode(RightKey, INPUT);
pinMode(LeftSpeedKey, INPUT);
pinMode(RightSpeedKey, INPUT);
// 인터럽트 추가
attachInterrupt(0, LeftKeyControl, RISING);
attachInterrupt(1, StopKeyControl, RISING);
attachInterrupt(2, RightKeyControl, RISING);
attachInterrupt(3, LeftKeySpeedControl, RISING);
attachInterrupt(4, RightKeySpeedControl, RISING);
// 큐 생성
xQueue = xQueueCreate(5, sizeof(uint16_t));
if(xQueue !=NULL) {
xTaskCreate(MotorTask, NULL, 200, NULL, 1, NULL);
vTaskStartScheduler();
}
}
void loop(){}