본문 바로가기

아두이노우노 R4

시각 장애인을 위한 점자 디스플레이 시스템 개발 2

반응형

 

시각장애인을 위한 점자 디스플레이 장치 개발 프로젝트를 도와드리겠습니다. 42개의 스텝모터를 제어하는 것은 복잡한 작업이므로 체계적인 접근이 필요합니다.

 

점자 디스플레이 게발에 관한 게시물

 

시각 장애인을 위한 점자 디스플레이 개발 1 

시각 장애인을 위한 점자 디스플레이 개발 2 

시각 장애인을 위한 점자 디스플레이 개발 3 

시각 장애인을 위한 점자 디스플레이 개발 4 

스테퍼 모터와 아두이노 - 완벽한 가이드, 점자 구현 참고

시각 장애인을 위한 점자 디스플레이 시스템 개발 5 - Gemini

 

 

시스템 구성 개요

주요 구성요소:

  • Arduino Mega 2560 (I/O 핀 부족 문제 해결)
  • A4988 스텝모터 드라이버 42개
  • 스텝모터 42개 (NEMA 17 권장)
  • 멀티플렉서 (74HC4067 또는 CD74HC4051)
  • 전원 공급 장치 (12V/24V, 최소 10A)
  • 점자 핀 메커니즘

 

하드웨어 구성도

 

 

위 이미지 코드는 아래와 같다.

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>점자 디스플레이 하드웨어 구성도</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            margin: 20px;
            background-color: #f5f5f5;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        .title {
            text-align: center;
            color: #2c3e50;
            margin-bottom: 30px;
            font-size: 24px;
            font-weight: bold;
        }
        .diagram {
            display: flex;
            flex-direction: column;
            gap: 30px;
        }
        .section {
            border: 2px solid #3498db;
            border-radius: 10px;
            padding: 15px;
            background: #ecf0f1;
        }
        .section-title {
            font-weight: bold;
            color: #2980b9;
            margin-bottom: 10px;
            font-size: 16px;
        }
        .component {
            background: #fff;
            border: 1px solid #bdc3c7;
            border-radius: 5px;
            padding: 10px;
            margin: 5px;
            display: inline-block;
            text-align: center;
            min-width: 120px;
        }
        .arduino {
            background: #27ae60;
            color: white;
        }
        .driver {
            background: #e74c3c;
            color: white;
        }
        .motor {
            background: #f39c12;
            color: white;
        }
        .multiplexer {
            background: #9b59b6;
            color: white;
        }
        .power {
            background: #34495e;
            color: white;
        }
        .connection {
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 10px 0;
        }
        .arrow {
            font-size: 20px;
            margin: 0 10px;
            color: #7f8c8d;
        }
        .grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 10px;
            margin: 15px 0;
        }
        .pin-info {
            background: #e8f6f3;
            border: 1px solid #1abc9c;
            border-radius: 5px;
            padding: 10px;
            margin: 10px 0;
        }
        .specs {
            background: #fdf2e9;
            border: 1px solid #e67e22;
            border-radius: 5px;
            padding: 15px;
            margin: 20px 0;
        }
        .warning {
            background: #fadbd8;
            border: 1px solid #e74c3c;
            border-radius: 5px;
            padding: 10px;
            margin: 10px 0;
            color: #c0392b;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="title">점자 디스플레이 하드웨어 구성도 (42개 스텝모터)</div>
        
        <!-- 전체 시스템 개요 -->
        <div class="section">
            <div class="section-title">📋 시스템 개요</div>
            <div class="connection">
                <div class="component power">전원 공급장치<br>12V/24V 10A</div>
                <div class="arrow">→</div>
                <div class="component arduino">Arduino Mega 2560<br>메인 컨트롤러</div>
                <div class="arrow">→</div>
                <div class="component multiplexer">멀티플렉서<br>74HC4067 x6</div>
                <div class="arrow">→</div>
                <div class="component driver">A4988 드라이버<br>x42</div>
                <div class="arrow">→</div>
                <div class="component motor">스텝모터<br>NEMA 17 x42</div>
            </div>
        </div>

        <!-- Arduino Mega 2560 핀 배치 -->
        <div class="section">
            <div class="section-title">🔌 Arduino Mega 2560 핀 할당</div>
            <div class="pin-info">
                <strong>디지털 핀 사용:</strong><br>
                • 핀 2-13: 멀티플렉서 제어 (S0, S1, S2, S3) x 3개<br>
                • 핀 22-53: STEP 신호 출력 (32개 핀)<br>
                • 핀 A0-A15: DIR 신호 출력 (16개 핀)
            </div>
            <div class="grid">
                <div class="component">핀 2-5: MUX1 제어</div>
                <div class="component">핀 6-9: MUX2 제어</div>
                <div class="component">핀 10-13: MUX3 제어</div>
                <div class="component">핀 22-37: STEP 1-16</div>
                <div class="component">핀 38-53: STEP 17-32</div>
                <div class="component">A0-A9: STEP 33-42</div>
                <div class="component">A10-A15: DIR 1-6</div>
            </div>
        </div>

        <!-- 멀티플렉서 구성 -->
        <div class="section">
            <div class="section-title">🔄 멀티플렉서 구성 (74HC4067)</div>
            <div class="grid">
                <div class="component multiplexer">MUX 1<br>DIR 신호 1-16</div>
                <div class="component multiplexer">MUX 2<br>DIR 신호 17-32</div>
                <div class="component multiplexer">MUX 3<br>DIR 신호 33-42</div>
            </div>
            <div class="pin-info">
                <strong>74HC4067 핀 연결:</strong><br>
                • S0, S1, S2, S3: 채널 선택 (Arduino 디지털 핀)<br>
                • EN: GND (항상 활성화)<br>
                • VCC: 5V, GND: GND<br>
                • SIG: Arduino 디지털 핀<br>
                • C0-C15: A4988 DIR 핀들
            </div>
        </div>

        <!-- A4988 드라이버 구성 -->
        <div class="section">
            <div class="section-title">⚡ A4988 드라이버 연결</div>
            <div class="specs">
                <strong>각 A4988 드라이버 연결:</strong><br>
                • VDD: 5V (로직 전원)<br>
                • GND: 공통 접지<br>
                • VMOT: 12V/24V (모터 전원)<br>
                • 1A, 1B, 2A, 2B: 스텝모터 4선<br>
                • STEP: Arduino 디지털 핀<br>
                • DIR: 멀티플렉서 출력<br>
                • MS1, MS2, MS3: 마이크로스테핑 설정<br>
                • RST, SLP: 5V (항상 활성화)<br>
                • EN: GND 또는 제어 핀
            </div>
        </div>

        <!-- 전원 공급 -->
        <div class="section">
            <div class="section-title">🔋 전원 공급 시스템</div>
            <div class="connection">
                <div class="component power">AC 220V</div>
                <div class="arrow">→</div>
                <div class="component power">SMPS<br>24V 15A</div>
                <div class="arrow">→</div>
                <div class="component power">DC-DC 컨버터<br>24V→5V 3A</div>
            </div>
            <div class="specs">
                <strong>전원 분배:</strong><br>
                • 24V: A4988 VMOT (모터 전원)<br>
                • 5V: Arduino, A4988 VDD, 멀티플렉서<br>
                • 각 모터 최대 소비전류: 1.5A<br>
                • 총 예상 소비전력: 약 300W
            </div>
        </div>

        <!-- 점자 메커니즘 -->
        <div class="section">
            <div class="section-title">⚙️ 점자 핀 메커니즘</div>
            <div class="grid">
                <div class="component">스텝모터</div>
                <div class="component">리드 스크류<br>또는 캠</div>
                <div class="component">점자 핀</div>
                <div class="component">리미트 스위치<br>(선택사항)</div>
            </div>
            <div class="specs">
                <strong>메커니즘 사양:</strong><br>
                • 점자 핀 높이: 0.6-0.8mm<br>
                • 응답 시간: 100ms 이하<br>
                • 정밀도: 0.1mm<br>
                • 내구성: 100만회 이상
            </div>
        </div>

        <!-- 주의사항 -->
        <div class="warning">
            <strong>⚠️ 주의사항:</strong><br>
            • 전원 공급 시 과전류 보호 회로 필수<br>
            • 방열판 설치로 A4988 발열 관리<br>
            • 공통 접지 확실히 연결<br>
            • 노이즈 필터링을 위한 커패시터 추가 권장
        </div>
    </div>
</body>
</html>

 

 

## 소프트웨어 구현

 

다음으로 Arduino 코드 예시를 제공하겠습니다:

 

/*
 * 42개 스텝모터 점자 디스플레이 제어 시스템
 * Arduino Mega 2560 + A4988 드라이버 + 멀티플렉서
 */

#include <AccelStepper.h>

// 멀티플렉서 제어 핀 정의
const int MUX1_S0 = 2, MUX1_S1 = 3, MUX1_S2 = 4, MUX1_S3 = 5;
const int MUX2_S0 = 6, MUX2_S1 = 7, MUX2_S2 = 8, MUX2_S3 = 9;
const int MUX3_S0 = 10, MUX3_S1 = 11, MUX3_S2 = 12, MUX3_S3 = 13;

// 멀티플렉서 SIG 핀
const int MUX1_SIG = A10;  // DIR 신호 1-16
const int MUX2_SIG = A11;  // DIR 신호 17-32
const int MUX3_SIG = A12;  // DIR 신호 33-42

// STEP 핀 배열 (42개)
const int stepPins[42] = {
  22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,  // 1-16
  38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,  // 17-32
  A0, A1, A2, A3, A4, A5, A6, A7, A8, A9                           // 33-42
};

// 멀티플렉서 제어 핀 배열
const int mux1Pins[4] = {MUX1_S0, MUX1_S1, MUX1_S2, MUX1_S3};
const int mux2Pins[4] = {MUX2_S0, MUX2_S1, MUX2_S2, MUX2_S3};
const int mux3Pins[4] = {MUX3_S0, MUX3_S1, MUX3_S2, MUX3_S3};

// 점자 상태 배열 (42개 점자 셀)
bool brailleState[42] = {false};
bool targetState[42] = {false};

// 모터 설정
const int STEPS_PER_REV = 200;  // 1.8도 스텝모터
const int MICROSTEPS = 16;      // A4988 마이크로스테핑
const int BRAILLE_HEIGHT_STEPS = 32;  // 점자 높이에 해당하는 스텝 수
const int MAX_SPEED = 1000;
const int ACCELERATION = 500;

// 스텝모터 객체 배열
AccelStepper steppers[42];

void setup() {
  Serial.begin(115200);
  Serial.println("점자 디스플레이 시스템 초기화...");
  
  // 멀티플렉서 제어 핀 초기화
  for(int i = 0; i < 4; i++) {
    pinMode(mux1Pins[i], OUTPUT);
    pinMode(mux2Pins[i], OUTPUT);
    pinMode(mux3Pins[i], OUTPUT);
  }
  
  // 멀티플렉서 SIG 핀 초기화
  pinMode(MUX1_SIG, OUTPUT);
  pinMode(MUX2_SIG, OUTPUT);
  pinMode(MUX3_SIG, OUTPUT);
  
  // 스텝모터 초기화
  for(int i = 0; i < 42; i++) {
    steppers[i] = AccelStepper(1, stepPins[i], -1); // DRIVER 타입
    steppers[i].setMaxSpeed(MAX_SPEED);
    steppers[i].setAcceleration(ACCELERATION);
    steppers[i].setCurrentPosition(0);
  }
  
  Serial.println("초기화 완료!");
}

void loop() {
  // 시리얼 명령 처리
  if(Serial.available()) {
    processSerialCommand();
  }
  
  // 모터 실행
  updateMotors();
  
  delay(1);
}

// 멀티플렉서 채널 선택
void selectMuxChannel(int muxNum, int channel) {
  int* pins;
  
  switch(muxNum) {
    case 1: pins = (int*)mux1Pins; break;
    case 2: pins = (int*)mux2Pins; break;
    case 3: pins = (int*)mux3Pins; break;
    default: return;
  }
  
  digitalWrite(pins[0], channel & 0x01);
  digitalWrite(pins[1], (channel >> 1) & 0x01);
  digitalWrite(pins[2], (channel >> 2) & 0x01);
  digitalWrite(pins[3], (channel >> 3) & 0x01);
}

// DIR 신호 설정
void setDirection(int motorNum, bool direction) {
  if(motorNum < 0 || motorNum >= 42) return;
  
  if(motorNum < 16) {
    // MUX1 사용 (모터 0-15)
    selectMuxChannel(1, motorNum);
    digitalWrite(MUX1_SIG, direction);
  }
  else if(motorNum < 32) {
    // MUX2 사용 (모터 16-31)
    selectMuxChannel(2, motorNum - 16);
    digitalWrite(MUX2_SIG, direction);
  }
  else {
    // MUX3 사용 (모터 32-41)
    selectMuxChannel(3, motorNum - 32);
    digitalWrite(MUX3_SIG, direction);
  }
  
  delayMicroseconds(1); // 신호 안정화
}

// 점자 패턴 설정
void setBraillePattern(int cellNum, bool state) {
  if(cellNum < 0 || cellNum >= 42) return;
  
  targetState[cellNum] = state;
  
  // 방향 설정
  bool direction = state; // true = 올라감, false = 내려감
  setDirection(cellNum, direction);
  
  // 목표 위치 설정
  int targetPos = state ? BRAILLE_HEIGHT_STEPS : 0;
  steppers[cellNum].moveTo(targetPos);
}

// 전체 점자 패턴 설정
void setBrailleText(String pattern) {
  if(pattern.length() != 42) {
    Serial.println("오류: 패턴 길이는 42자여야 합니다.");
    return;
  }
  
  for(int i = 0; i < 42; i++) {
    bool state = (pattern.charAt(i) == '1');
    setBraillePattern(i, state);
  }
}

// 모터 업데이트
void updateMotors() {
  for(int i = 0; i < 42; i++) {
    if(steppers[i].distanceToGo() != 0) {
      steppers[i].run();
    }
  }
}

// 시리얼 명령 처리
void processSerialCommand() {
  String command = Serial.readStringUntil('\n');
  command.trim();
  
  if(command.startsWith("SET:")) {
    // 예: SET:111000111000111000111000111000111000111000
    String pattern = command.substring(4);
    setBrailleText(pattern);
    Serial.println("패턴 설정 완료");
  }
  else if(command.startsWith("CELL:")) {
    // 예: CELL:5:1 (5번 셀을 1로 설정)
    int firstColon = command.indexOf(':');
    int secondColon = command.indexOf(':', firstColon + 1);
    
    if(firstColon != -1 && secondColon != -1) {
      int cellNum = command.substring(firstColon + 1, secondColon).toInt();
      int state = command.substring(secondColon + 1).toInt();
      
      setBraillePattern(cellNum, state == 1);
      Serial.println("셀 " + String(cellNum) + " 설정: " + String(state));
    }
  }
  else if(command == "STATUS") {
    printStatus();
  }
  else if(command == "HOME") {
    homeAllMotors();
  }
  else if(command == "STOP") {
    stopAllMotors();
  }
  else {
    Serial.println("알 수 없는 명령: " + command);
    Serial.println("사용 가능한 명령:");
    Serial.println("  SET:<42자리 패턴> - 전체 패턴 설정");
    Serial.println("  CELL:<번호>:<상태> - 개별 셀 설정");
    Serial.println("  STATUS - 현재 상태 출력");
    Serial.println("  HOME - 모든 모터 홈 위치");
    Serial.println("  STOP - 모든 모터 정지");
  }
}

// 상태 출력
void printStatus() {
  Serial.println("=== 점자 디스플레이 상태 ===");
  for(int i = 0; i < 42; i++) {
    Serial.print("셀 ");
    Serial.print(i);
    Serial.print(": ");
    Serial.print(brailleState[i] ? "올림" : "내림");
    Serial.print(" (위치: ");
    Serial.print(steppers[i].currentPosition());
    Serial.print(", 목표: ");
    Serial.print(steppers[i].targetPosition());
    Serial.println(")");
  }
}

// 모든 모터 홈 위치로
void homeAllMotors() {
  Serial.println("모든 모터를 홈 위치로 이동 중...");
  
  for(int i = 0; i < 42; i++) {
    setDirection(i, false); // 내려가는 방향
    steppers[i].moveTo(0);
    brailleState[i] = false;
    targetState[i] = false;
  }
  
  // 모든 모터가 멈출 때까지 대기
  while(true) {
    bool allStopped = true;
    for(int i = 0; i < 42; i++) {
      if(steppers[i].distanceToGo() != 0) {
        steppers[i].run();
        allStopped = false;
      }
    }
    if(allStopped) break;
  }
  
  Serial.println("홈 위치 이동 완료");
}

// 모든 모터 정지
void stopAllMotors() {
  for(int i = 0; i < 42; i++) {
    steppers[i].stop();
  }
  Serial.println("모든 모터 정지");
}

// 점자 문자 변환 함수 (추가 구현 가능)
void displayBrailleChar(char ch, int startCell) {
  // 점자 문자 매핑 테이블을 구현하여
  // 각 문자에 해당하는 6점 패턴을 설정
  // 예: 'A' = 100000 패턴
  
  // 이 부분은 점자 문자 체계에 따라 구현
}

/*
 * 사용 예시:
 * 1. 시리얼 모니터에서 "SET:111000111000111000111000111000111000111000" 입력
 * 2. 개별 셀 제어: "CELL:5:1"
 * 3. 상태 확인: "STATUS"
 * 4. 홈 위치: "HOME"
 */

 

 

구현 시 고려사항

1. 전원 관리

  • 42개 모터 동시 구동 시 큰 전류가 필요합니다
  • SMPS 24V 15A 이상 권장
  • 각 A4988마다 방열판 부착 필수

2. 성능 최적화

  • 모든 모터를 동시에 움직이지 말고 순차적으로 제어
  • 멀티플렉서 채널 전환 시 지연시간 고려
  • 인터럽트 기반 스테핑으로 성능 향상 가능

3. 기계적 설계

  • 점자 핀 높이: 0.6-0.8mm (표준 점자 규격)
  • 점자 셀 간격: 2.5mm (가로), 2.8mm (세로)
  • 리드 스크류 피치 최적화로 정밀도 확보

4. 소프트웨어 확장

  • 한글/영문 점자 변환 라이브러리 추가
  • USB/블루투스를 통한 PC 연동
  • 점자 새로고침 속도 조절 기능

5. 안전 기능

  • 과전류 보호 회로
  • 모터 온도 모니터링
  • 비상 정지 기능
  • 점자 핀 위치 피드백 (엔코더 또는 리미트 스위치)

이 설계를 기반으로 단계적으로 구현하시면 됩니다. 먼저 소수의 모터로 프로토타입을 만들어 테스트한 후 전체 시스템으로 확장하는 것을 권장합니다.

추가로 궁금한 점이나 특정 부분에 대한 상세한 설명이 필요하시면 언제든 문의해 주세요!

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^