Responsive Advertisement

아두이노 우노 DC 모터 제어 OLED 디스플레이 연결 ④


아두이노 우노로 OLED LCD 제어하기
아두이노 우노로 OLED LCD 제어하기



DC모터 제어 OLED디스플레이 연결


아두이노 보드에 연결해서 상태를 확인하는 용도로 사용되는 부품이 몇 가지 있습니다. 그 중 대표적인게 0.91인치 128X32 OLED LCD 입니다. I2C 방식으로 입출력 제어를 하는 LCD이며 아두이노에 직접적으로 연결하여 구동을 할 수 있어 매우 편리하게 사용되는 디스플레이 중 하나입니다.

이 디스플레이에 모터의 현재 상태와 동작할 때의 회전 방향과 동작 타이머의 값을 1초 단위로 표시 해주면 좋을 것 같아 프로그램 소스를 먼저 구현해 보고 자재가 오는대로 제작해 보고자 합니다.


OLED디스플레이 연결방법

0.91인치 128x32 OLED LCD를 I2C 방식으로 연결하여 사용하면 이 디스플레이를 통해 모터의 현재 상태, 회전 방향, 동작 타이머 값 등을 표시할 수 있어 매우 시각적으로 모터를 제어할 수 있다고 봅니다.

LCD 연결 방법입니다

VCC -> 아두이노 5V
GND -> 아두이노 GND
SCL -> 아두이노 A5 (SCL)
SDA -> 아두이노 A4 (SDA)

이제 그동안 작성한 코드에 OLED 디스플레이 기능을 추가하겠습니다. 먼저 필요한 라이브러리를 설치해야 합니다. Arduino IDE에서 "스케치 > 라이브러리 포함하기 > 라이브러리 관리" 메뉴로 이동합니다. 검색창에 "Adafruit SSD1306"을 입력하고 설치합니다. "Adafruit GFX Library"도 함께 설치합니다. 



아두이노 OLED 라이브러리 설치
아두이노 OLED 라이브러리 설치


OLED디스플레이 연결소스


#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET    -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// 기존 핀 정의 및 변수 선언은 그대로 유지

void setup() {
  // 기존 setup 코드

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("Motor Control");
  display.display();
  delay(2000);
}

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

  updateDisplay();  // 디스플레이 업데이트
  if (motorEnabled) {
    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;
      }
    }
  } else {
    motorStop();
    state = 0;
    previousMillis = millis();
  }
}

void updateDisplay() {
  display.clearDisplay();
  display.setCursor(0,0);
  
  // 모터 상태 표시
  display.print("Motor: ");
  display.println(motorEnabled ? "ON" : "OFF");
  
  // 모드 표시
  display.print("Mode: ");
  display.println(mode);
  
  // 현재 선택된 시간 및 값 표시
  display.print("Time ");
  switch(selectedTime) {
    case 0:
      display.print("A: ");
      display.print(timeA / 1000);
      break;
    case 1:
      display.print("B: ");
      display.print(timeB / 1000);
      break;
    case 2:
      display.print("C: ");
      display.print(timeC / 1000);
      break;
  }
  display.println("s");
  
  // 모터 방향 및 속도 표시
  if (motorEnabled) {
    if (state == 1 || state == 0) {
      display.println("Dir: Clockwise");
    } else if (state == 3) {
      display.println("Dir: CounterCW");
    } else {
      display.println("Dir: Stopped");
    }
    display.print("Speed: ");
    display.println(motorSpeed);
  }
  
  display.display();
}

// 기존 함수들 (handleSwitches, increaseTime, decreaseTime 등)은 그대로 유지

void increaseTime() {
  switch (selectedTime) {
    case 0:
      timeA += 1000;
      break;
    case 1:
      timeB += 1000;
      break;
    case 2:
      timeC += 1000;
      break;
  }
  updateDisplay();  // 시간 변경 시 즉시 디스플레이 업데이트
}

void decreaseTime() {
  switch (selectedTime) {
    case 0:
      if (timeA > 1000) timeA -= 1000;
      break;
    case 1:
      if (timeB > 1000) timeB -= 1000;
      break;
    case 2:
      if (timeC > 1000) timeC -= 1000;
      break;
  }
  updateDisplay();  // 시간 변경 시 즉시 디스플레이 업데이트
}



OLED디스플레이 소스 설명

위 소스에는 OLED 디스플레이 초기화 및 설정하는 루틴이 포함되어 있습니다.
그리고 현재 모터의 상태 (ON/OFF) 표시를 해주며, 현재 모드를 표시하며 선택된 시간 (A, B, C) 및 그 값을 표시합니다.

한글이 표시되지 않기에 영문으로만 표시되는데 한글루틴도 넣어 한글로 표시되게 하고 싶지만 너무 길어지니 생략하도록 하겠습니다.

모터 회전 방향 및 속도 표시

시간 값이 변경되는 즉시 디스플레이 업데이트를 합니다. OLED 디스플레이를 통해 모든 중요한 정보를 실시간으로 확인할 수 있게 되는거죠. 시간 값을 변경할 때마다 디스플레이에 즉시 변경사항이 업데이트되어 현재 설정을 바로 바로 확인할 수 있습니다.

프로그래밍시 주의사항

만약, I2C주소가 0x3C가 아닌 경우에는 display.begin() 함수의 두 번째 인자를 알맞은 번지로 수정해야 합니다. OLED 디스플레이 사용시 아두이노의 메모리 사용량이 증가하게 되므로, 혹시 발생할 수 있는 메모리 부족으로 인한 다른 기능의 문제에 배비해야 합니다.
필요한 경우에 코드를 최적화하거나 메모리 사용량을 줄여야 할 필요가 있습니다.

이렇게 OLED 디스플레이를 추가하면 사용자 인터페이스가 크게 개선되어 시스템을 더 쉽게 제어하고 모니터링할 수 있습니다.

배선안내

과거에 fritzing 를 결제를 했었는데 이번에 다시 로그인을 하니 또 결제를 하라고 나오네요. --; fritzing 가 있으면 좀 더 자세한 이미지를 만들어 올릴텐데.. 일반 텍스트,로만 설명 드리는 부분을 이해해 주시기 바랍니다.

기존의 배선 방법에 OLED LCD 디스플레이 연결을 추가하는 방법입니다.

DC 모터 및 L298N 모터 드라이버:
L298N의 IN1 -> 아두이노 디지털 핀 2
L298N의 IN2 -> 아두이노 디지털 핀 3
L298N의 ENA -> 아두이노 디지털 핀 9 (PWM)
L298N의 OUT1, OUT2 -> DC 모터 연결
L298N의 12V, GND -> 외부 전원 공급
모드 전환 토글 스위치:
한 쪽 -> 아두이노 디지털 핀 4
다른 쪽 -> 아두이노 GND
포텐셔미터 (모터 속도 제어용):
왼쪽 핀 -> 아두이노 5V
중앙 핀 -> 아두이노 아날로그 핀 A0
오른쪽 핀 -> 아두이노 GND
시간 선택 푸시 스위치 (스위치 1):
한 쪽 -> 아두이노 디지털 핀 5
다른 쪽 -> 아두이노 GND
시간 증가 푸시 스위치 (스위치 2):
한 쪽 -> 아두이노 디지털 핀 6
다른 쪽 -> 아두이노 GND
시간 감소 푸시 스위치 (스위치 3):
한 쪽 -> 아두이노 디지털 핀 7
다른 쪽 -> 아두이노 GND
모터 ON/OFF 토글 스위치:
한 쪽 -> 아두이노 디지털 핀 8
다른 쪽 -> 아두이노 GND
0.91인치 128x32 OLED LCD (I2C):
VCC -> 아두이노 5V
GND -> 아두이노 GND
SCL -> 아두이노 A5 (SCL)
SDA -> 아두이노 A4 (SDA)

 

배선작업시 주의사항

모든 GND 연결은 아두이노의 GND 핀에 공통으로 연결할 수 있습니다. 아두이노와 L298N 모터 드라이버의 GND는 반드시 연결해야 합니다.
L298N 모터 드라이버와 DC 모터용 외부 전원의 GND도 아두이노 GND와 연결해야 합니다.
I2C 통신을 위한 SDA와 SCL 핀은 아두이노 UNO의 경우 A4와 A5 핀을 사용합니다.

이렇게 연결하면 모든 구성 요소가 제대로 작동할 것입니다. OLED 디스플레이를 통해 모터 상태, 회전 방향, 타이머 값 등을 실시간으로 확인할 수 있으며, 스위치와 포텐셔미터를 통해 시스템을 제어할 수 있습니다.

이상입니다. 긴 글 읽어 주셔서 감사합니다. :)

참고하면 도움이 될 링크











댓글 쓰기