본문으로 바로가기
728x90
728x90
더보기

1. 젤리비 AGV 핀 맵 (바퀴 모터와 IR 센서)

 

 

 

2. 젤리비 AGV 핀 맵 (메인 보드)

 

 

 

3. 젤리비 AGV 핀 맵 (Pin 번호 순서)

 

 

4. 젤리비 AGV LIFTER

 

(1) 서보 모터 (Servo Motor) 종류

 

모터와 이를 구동 제어하는 회로나 컨트롤 보드를 포함하는 개념으로DC 모터, AC 모터, BLDC 모터, 리니어 모터 등의 모터 자체만으로 서보 모터라고 하지 않습니다.

 

(2) 펄스로 제어하는 서보 모터의 각도

 

 

[참고] 저가의 서보 모터에서는 양쪽 끝의 각도인 0도와 180도 근처로 회전각을 설정하면 불안정한 떨림 현상이

         발생할 수 있으므로, 양 끝 10(0~10, 170~180) 정도는 사용하지 않는 것이 좋습니다.

 

 

(3) 서보와 기어로 리프터를 위아래로 움직이는 구조

 

 

 

 

 

5. 리프터 올리고 내리기

 

(1) 서보 모터를 제어하여 Lifter 올리고 내리기

 

////////////////////  AGV 리프터(Lifter) 서보 모터 제어

#include <Servo.h> 

#define SERVO_DOWN  90-10-20 // Down 위치 (10 정도 더 아래)
#define SERVO_UP    180-10  // Up 위치 (떨림 방지)
#define SERVO_DEF   SERVO_DOWN   // 기본 위치

#define pinServo   9   // 리프터(서보)모터 핀 번호

Servo servo;   // 리프터용 서보 모터 인스턴스 선언

void  LifterUp()
{
  servo.attach( pinServo ); // 서보 연결
  delay( 10 );

  servo.write( SERVO_UP );  // 리프터 위로 올림
  delay( 300 );

  servo.detach(); // 서보 연결 해제
  delay( 10 );  
}

void  LifterDown()
{
  servo.attach( pinServo ); // 서보 연결
  delay( 10 );
  
  servo.write( SERVO_DOWN ); // 리프터 아래로 내림
  delay( 300 );

  servo.detach(); // 서보 연결 해제
  delay( 10 );  
}

////////////////////  메인 프로그램 (setup & loop)

void setup()
{
  LifterUp();     // 리프터를 위로 올림
  delay( 3000 );

  LifterDown();   // 리프터를 아래로 내림
}

void loop()
{
}

 

 

(2) [실습 준비] JellibiPCUSB로 연결하고 보드 및 포트 선택

   (보드: Arduino Nano, 프로세서: ATmega328, 포트: COM 번호)

 

(3) [작업 과정]

  • 아두이노 소프트웨어 [파일] 메뉴에서 해당 소스 파일 열기
  • 툴바에서 업로드 아이콘을 클릭하여 컴파일 및 업로드

 

 

 

[추가 실습] 점선의 코드loop 함수 안에 넣고 다시 실행해봅니다. LifterDown(); 아래에 delay(3000);을 추가합니다.

 

 

6. 전원을 켤 때 리프터가 올라가는 현상의 처리

 

전원을 켰을 때 setup() 함수에서 리프터 내리기를 실행합니다.

 

(1) 리프터 제어에 필요한 코드 추가

 

 

 

(2) setup() 함수에서 리프터를 내리는 함수 호출

 

 

 

로봇의 전원을 켤 때마다 리프터가 약간씩 올라가는 현상이 나타날 수 있습니다.

 이런 현상이 나타난다면 다음과 같이 처리합니다.

  • 실습 프로그램 소스에 왼쪽 코드를 추가하고(Jellibi-AGV-02-01-Lifter-Basic.ino 소스 참고)
  • setup() 함수에서 리프터를 아래로 내리는 함수 호출

 

 

7. Digital 출력 제어 실습

 

부저(Buzzer)도레미파솔멜로디를 재생할 수 있습니다.

 

////////////////////  부저 핀 번호

#define pinBuzzer     3 // 부저 핀 번호

void  PlayMelody()
{
  tone( pinBuzzer, 262 );  // 도(4옥타브 C)
  delay( 500 );
  tone( pinBuzzer, 294 );  // 레(4옥타브 D)
  delay( 500 );
  tone( pinBuzzer, 330 );  // 미(4옥타브 E)
  delay( 500 );
  tone( pinBuzzer, 349 );  // 파(4옥타브 F)
  delay( 500 );
  tone( pinBuzzer, 392 );  // 솔(4옥타브 G)
  delay( 500 );
  noTone( pinBuzzer );     // 음소거(mute)  
}

////////////////////  메인 프로그램 (setup & loop)

void  setup() {
  pinMode( pinBuzzer, OUTPUT ); // 출력 핀으로 설정  
  noTone( pinBuzzer );  // 스피커 끄기(음소거)  

  PlayMelody();
}

void  loop() {
}

 

아래의 그림은 부저의 핀구조를 나타낸 것입니다.

 

 

[ 주요 사용 함수 ]

tone(핀번호, 주파수) : 주파수 음을 지정 핀으로 출력
noTone() : 주파수 신호 출력 중지 (음소거)
 

 

8. Digital 출력 제어 실습 :  [추가 실습] 부저로 음악 연주하기

 

다음 악보를 연주하는 프로그램을 만들어 보세요.

 

 

//////////////////// 부저 핀 번호
#define pinBuzzer 3

//////////////////// 음계(4옥타브 기준)
#define C4 262
#define D4 294
#define E4 330
#define F4 349
#define G4 392
#define A4 440
#define REST 0

//////////////////// 템포 설정
const int quarter = 500;            // 4분음표 길이(ms)  (120BPM 기준)
const int gap     = 50;             // 음 사이 짧은 공백(ms)

//////////////////// 반짝반짝 작은 별 (4/4)
int melody[] = {
  // 도 도 솔 솔 라 라 솔(2분)
  C4, C4, G4, G4, A4, A4, G4,
  // 파 파 미 미 레 레 도(2분)
  F4, F4, E4, E4, D4, D4, C4,

  // 솔 솔 파 파 미 미 레(2분)
  G4, G4, F4, F4, E4, E4, D4,
  // 솔 솔 파 파 미 미 레(2분)
  G4, G4, F4, F4, E4, E4, D4,

  // 도 도 솔 솔 라 라 솔(2분)
  C4, C4, G4, G4, A4, A4, G4,
  // 파 파 미 미 레 레 도(2분)
  F4, F4, E4, E4, D4, D4, C4
};

// 각 음의 길이(4분음표/2분음표)
int noteDur[] = {
  // C C G G A A G(2분)
  quarter, quarter, quarter, quarter, quarter, quarter, quarter * 2,
  // F F E E D D C(2분)
  quarter, quarter, quarter, quarter, quarter, quarter, quarter * 2,

  // G G F F E E D(2분)
  quarter, quarter, quarter, quarter, quarter, quarter, quarter * 2,
  // G G F F E E D(2분)
  quarter, quarter, quarter, quarter, quarter, quarter, quarter * 2,

  // C C G G A A G(2분)
  quarter, quarter, quarter, quarter, quarter, quarter, quarter * 2,
  // F F E E D D C(2분)
  quarter, quarter, quarter, quarter, quarter, quarter, quarter * 2
};

void playSong() {
  int n = sizeof(melody) / sizeof(melody[0]);

  for (int i = 0; i < n; i++) {
    int freq = melody[i];
    int dur  = noteDur[i];

    if (freq == REST) {
      noTone(pinBuzzer);
      delay(dur);
    } else {
      tone(pinBuzzer, freq);
      delay(dur);
      noTone(pinBuzzer);
    }
    delay(gap); // 음 사이 공백
  }
}

void setup() {
  pinMode(pinBuzzer, OUTPUT);
  noTone(pinBuzzer);

  playSong();   // 전원 켜지면 1번 연주
}

void loop() {
  // 반복 재생하고 싶으면 아래처럼:
  // playSong();
  // delay(1000);
}

 

 

 

다음은 다양한 효과음을 만들어 보고 출력하는 예제입니다. 예제 이외에도 적절한 효과음을 만들어 사용해 보시기 바랍니다.

 

/*
  [부저 경고음 통합 예제]
  - 질문에서 준 멜로디(작은별/학교종 느낌) 1회 재생
  - 작업 이벤트용 경고음 함수들(발견/단계완료/전체완료/경고/오류/위험/확인요청/시작)
  - setup()에서 순서대로 테스트 재생

  BUZZER_PIN = 5
*/

#include <Arduino.h>

//////////////  부저
#define BUZZER_PIN            3

// 음계(질문 예제 + 확장)
#define OCTAVE_4_DO           262
#define OCTAVE_4_RE           294
#define OCTAVE_4_MI           330
#define OCTAVE_4_SOL          392
#define OCTAVE_4_LA           440
#define OCTAVE_4_TI           494
#define OCTAVE_5_DO           523

#define C4  262
#define D4  294
#define E4  330
#define F4  349
#define G4  392
#define A4  440
#define B4  494
#define C5  523
#define E5  659
#define G5  784

// 박자(질문 예제)
#define WHOLE_NOTE            1300
#define HALF_NOTE             (WHOLE_NOTE/2)
#define QUATER_NOTE           (WHOLE_NOTE/4)
#define DOTTED_QUATER_NOTE    (WHOLE_NOTE*3/8)
#define EIGHTH_NOTE           (WHOLE_NOTE/8)
#define SIXTEENTH_NOTE        (WHOLE_NOTE/16)
#define SHORT_DELAY           10

// 경고음용 gap
#define GAP_SHORT 20
#define GAP_MED   80
#define GAP_LONG  200


// ===== 공통 유틸 =====
void beep(int freq, int dur, int gap = GAP_SHORT) {
  tone(BUZZER_PIN, freq);
  delay(dur);
  noTone(BUZZER_PIN);
  delay(gap);
}

void beepSeparated(int freq, int dur, int gap = GAP_SHORT) {
  noTone(BUZZER_PIN);
  delay(10);
  tone(BUZZER_PIN, freq);
  delay(dur);
  noTone(BUZZER_PIN);
  delay(gap);
}

// ===== 작업 이벤트용 경고음 패턴들 =====

// 1) 작업 시작
void soundStart() {
  beep(C4, SIXTEENTH_NOTE);
  beep(E4, SIXTEENTH_NOTE);
  beep(G4, EIGHTH_NOTE, GAP_MED);
}

// 2) 특정한 것 발견
void soundFound() {
  beepSeparated(E5, SIXTEENTH_NOTE);
  beepSeparated(E5, SIXTEENTH_NOTE, GAP_MED);
}

// 3) 단계 완료/성공
void soundStepDone() {
  beep(C4, EIGHTH_NOTE);
  beep(E4, EIGHTH_NOTE);
  beep(C5, QUATER_NOTE, GAP_LONG);
}

// 4) 전체 작업 완료
void soundAllDone() {
  beep(C4, EIGHTH_NOTE);
  beep(G4, EIGHTH_NOTE);
  beep(C5, EIGHTH_NOTE);
  beep(G4, EIGHTH_NOTE);
  beep(C5, QUATER_NOTE, GAP_LONG);
}

// 5) 주의/경고(짧-짧-길 x3)
void soundWarning() {
  for (int i = 0; i < 3; i++) {
    beep(A4, SIXTEENTH_NOTE);
    beep(A4, SIXTEENTH_NOTE);
    beep(A4, EIGHTH_NOTE, GAP_MED);
  }
  delay(GAP_LONG);
}

// 6) 오류/실패(하강 + 길게)
void soundError() {
  beep(C5, EIGHTH_NOTE);
  beep(G4, EIGHTH_NOTE);
  beep(E4, HALF_NOTE, GAP_LONG);
}

// 7) 긴급/위험(사이렌 느낌)
void soundDanger() {
  for (int i = 0; i < 6; i++) {
    beep(G5, SIXTEENTH_NOTE, GAP_SHORT);
    beep(E5, SIXTEENTH_NOTE, GAP_SHORT);
  }
  delay(GAP_LONG);
}

// 8) 사용자 확인 필요
void soundNeedConfirm() {
  beep(F4, EIGHTH_NOTE, GAP_MED);
  beep(F4, EIGHTH_NOTE, GAP_LONG);
}

void setup() {

  // 아래는 테스트용: 이벤트 경고음들을 순서대로 들려줌
  soundStart();       delay(1000);
  soundFound();       delay(1000);
  soundStepDone();    delay(1000);
  soundWarning();     delay(1000);
  soundError();       delay(1000);
  soundDanger();      delay(1000);
  soundAllDone();     delay(1000);
  soundNeedConfirm(); delay(1000);

  // 끝
  noTone(BUZZER_PIN);
}

void loop() {
  // 실제 프로젝트에서는 여기서 조건에 따라
  // soundFound(), soundError() 같은 함수를 호출하면 됩니다.
}

 

728x90
728x90