Responsive Advertisement

아두이노 우노 DC 모터 방향, 속도 그리고 타이머 설정 ③


아두이노로 DC모터 제어하기
아두이노로 DC모터 제어하기




아두이노로 DC모터 제어하기

어제 그제에 이어 아두이노 우노를 이용한 DC모터 제어 3번째 시간입니다. 오늘은 기존의 회로에 푸시 스위치를 3개를 추가로 장착하여 모터의 회전 시간과 모터가 쉬는 시간을 변경하기 위한 기능을 부여하고자 합니다.


스위치 동작의 정의

스위치는 푸시 타입의 스위치 3개로 구성이 되며, 
1번 스위치를 누르면 시간  A와 B 그리고 C를 설정하기 위해 타이머 대상을 전환하는 기능을 부여하고, (시간 A,B 와 C는 각각 순방향 회전시간, 쉬는 시간, 역방향 회전시간을 의미)
2번 스위치는 1번 스위치로 지정된 타이머의 설정값을 올리는 기능을 부여하며,
3번 스위치는 1번 스위치가 지정된 타이머의 설정값을 내리는 기능을 부여하고자 합니다.

또한 여기에서 스위치를 한번 누를때 변경되는 시간값의 단위는 1초단위로 합니다.,

좀 더 자세히 설명을 하자면,
1번 스위치가 가르키는 값은 A시간으로 정의하고. 프로그램 초기의 설정 시간은 5초에서 시작하도록 정의 합니다.

1번 스위치 기본 값이 A시간을 지정하고 있으니 한번 누르면 B시간을 가리키게 되며, 여기에서 2번 스위치를 누르면 5초가 6초로 설정이 되고 3번 스위치를 누르면 6초가 다시 5초가 되게 하고자 합니다.


푸시 스위치
푸시 스위치




동작 코드


const int motorPin1 = 2;
const int motorPin2 = 3;
const int enablePin = 9;
const int togglePin = 4;
const int potPin = A0;

// 새로운 푸시 스위치 핀 정의
const int switch1Pin = 5;  // 시간 선택 스위치
const int switch2Pin = 6;  // 시간 증가 스위치
const int switch3Pin = 7;  // 시간 감소 스위치

unsigned long timeA = 5000;  // 5초로 초기화
unsigned long timeB = 5000;
unsigned long timeC = 5000;

int mode = 1;
unsigned long previousMillis = 0;
int state = 0;
int motorSpeed = 0;

// 시간 설정을 위한 변수
int selectedTime = 0;  // 0: A, 1: B, 2: C
bool switch1Pressed = false;
bool switch2Pressed = false;
bool switch3Pressed = false;

void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(togglePin, INPUT_PULLUP);
  pinMode(potPin, INPUT);
  
  // 새로운 스위치 핀 설정
  pinMode(switch1Pin, INPUT_PULLUP);
  pinMode(switch2Pin, INPUT_PULLUP);
  pinMode(switch3Pin, INPUT_PULLUP);
  
  Serial.begin(9600);
}

void loop() {
  handleSwitches();
  
  motorSpeed = map(analogRead(potPin), 0, 1023, 0, 255);
  
  if (digitalRead(togglePin) == LOW) {
    mode = 1;
  } else {
    mode = 2;
  }

  unsigned long currentMillis = millis();

  if (mode == 1) {
    if (state == 0 && (currentMillis - previousMillis >= timeB)) {
      motorClockwise();
      previousMillis = currentMillis;
      state = 1;
    } else if (state == 1 && (currentMillis - previousMillis >= timeA)) {
      motorStop();
      previousMillis = currentMillis;
      state = 0;
    }
  } else {
    if (state == 0 && (currentMillis - previousMillis >= timeB)) {
      motorClockwise();
      previousMillis = currentMillis;
      state = 1;
    } else if (state == 1 && (currentMillis - previousMillis >= timeA)) {
      motorStop();
      previousMillis = currentMillis;
      state = 2;
    } else if (state == 2 && (currentMillis - previousMillis >= timeB)) {
      motorCounterClockwise();
      previousMillis = currentMillis;
      state = 3;
    } else if (state == 3 && (currentMillis - previousMillis >= timeC)) {
      motorStop();
      previousMillis = currentMillis;
      state = 0;
    }
  }
}

void handleSwitches() {
  // 스위치 1: 시간 선택
  if (digitalRead(switch1Pin) == LOW && !switch1Pressed) {
    switch1Pressed = true;
    selectedTime = (selectedTime + 1) % 3;
    printSelectedTime();
  } else if (digitalRead(switch1Pin) == HIGH) {
    switch1Pressed = false;
  }

  // 스위치 2: 시간 증가
  if (digitalRead(switch2Pin) == LOW && !switch2Pressed) {
    switch2Pressed = true;
    increaseTime();
  } else if (digitalRead(switch2Pin) == HIGH) {
    switch2Pressed = false;
  }

  // 스위치 3: 시간 감소
  if (digitalRead(switch3Pin) == LOW && !switch3Pressed) {
    switch3Pressed = true;
    decreaseTime();
  } else if (digitalRead(switch3Pin) == HIGH) {
    switch3Pressed = false;
  }
}

void increaseTime() {
  switch (selectedTime) {
    case 0:
      timeA += 1000;  // 1초 증가
      break;
    case 1:
      timeB += 1000;
      break;
    case 2:
      timeC += 1000;
      break;
  }
  printTimes();
}

void decreaseTime() {
  switch (selectedTime) {
    case 0:
      if (timeA > 1000) timeA -= 1000;  // 최소 1초
      break;
    case 1:
      if (timeB > 1000) timeB -= 1000;
      break;
    case 2:
      if (timeC > 1000) timeC -= 1000;
      break;
  }
  printTimes();
}

void printSelectedTime() {
  Serial.print("Selected Time: ");
  Serial.println(selectedTime == 0 ? "A" : (selectedTime == 1 ? "B" : "C"));
}

void printTimes() {
  Serial.print("Time A: ");
  Serial.print(timeA / 1000);
  Serial.print("s, Time B: ");
  Serial.print(timeB / 1000);
  Serial.print("s, Time C: ");
  Serial.print(timeC / 1000);
  Serial.println("s");
}

void motorClockwise() {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, motorSpeed);
  Serial.println("시계 방향 회전, 속도: " + String(motorSpeed));
}

void motorCounterClockwise() {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  analogWrite(enablePin, motorSpeed);
  Serial.println("반시계 방향 회전, 속도: " + String(motorSpeed));
}

void motorStop() {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  analogWrite(enablePin, 0);
  Serial.println("모터 정지");
}



푸시 스위치와 캡
푸시 스위치와 캡





소스코드 설명

이상 언급한 코드는 다음과 같은 기능을 추가합니다:

3개의 새로운 푸시 스위치를 위한 핀을 정의합니다 (5, 6, 7번 핀).
handleSwitches() 함수에서 스위치 입력을 처리하며, 
1번 스위치로 시간 A, B, C를 순환 선택합니다. (시간 A,B 와 C는 각각 순방향 회전시간, 쉬는 시간, 역방향 회전시간을 의미)
2번 스위치로 선택된 시간을 1초 증가시킵니다.
3번 스위치로 선택된 시간을 1초 감소시킵니다.

시간 변경 시 아두이노 우너의 IDE 윈도우에서 Serial 모니터를 통해 현재 설정된 시간을 출력하게 하여 변화되는 상태를 확인할 수 있게 하였습니다.

아두이노 우노의 각 핀에 대한 연결안내입니다.
디지털 핀 5에 1번 스위치 연결 (다른 한 쪽은 GND에 연결)
디지털 핀 6에 2번 스위치 연결 (다른 한 쪽은 GND에 연결)
디지털 핀 7에 3번 스위치 연결 (다른 한 쪽은 GND에 연결)

이렇게 하면 푸시 스위치를 통해 시간 A, B, C를 조절할 수 있는 기능이 구현됩니다. 참고로 실절적인 시간 변경은 밀리초 단위로 지정이 되지만, 사용자에게는 초 단위로 표시됩니다.

다음 시간에는 마지막편으로 OLED LED 디스플레이를 장착하여 구동 상태를 확인할 수 있게 하겠습니다.
















댓글 쓰기