October 24, 2021

디바이스마트 미디어:

[66호] 원하는 색상으로 제어가 가능한 아두이노 IoT 스마트 무드등 키트 -

2021-06-25

★2021 ICT 융합 프로젝트 공모전 결과 발표! -

2021-05-12

디바이스마트 국내 온라인 유통사 유일 벨로다인 라이다 공급! -

2021-02-16

★총 상금 500만원 /2021 ICT 융합 프로젝트 공모전★ -

2021-01-18

디바이스마트 온라인 매거진 전자책(PDF)이 무료! -

2020-09-29

[61호]음성으로 제어하는 간접등 만들기 -

2020-08-26

디바이스마트 자체제작 코딩키트 ‘코딩 도담도담’ 출시 -

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

[60호]초소형 레이더 MDR, 어떻게 제어하고 활용하나 -

2020-06-30

[60호]NANO 33 IoT보드를 활용한 블루투스 수평계 만들기 -

2020-06-30

라즈베리파이3가 드디어 출시!!! (Now Raspberry Pi 3 is Coming!!) -

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

디바이스마트 레이저가공, 밀링, 선반, 라우터 등 커스텀서비스 견적요청 방법 설명동영상 입니다. -

2015-06-09

디바이스마트와 인텔®이 함께하는 IoT 경진대회! -

2015-05-19

드디어 adafruit도 디바이스마트에서 쉽고 저렴하게 !! -

2015-03-25

[29호] Intel Edison Review -

2015-03-10

Pololu 공식 Distributor 디바이스마트, Pololu 상품 판매 개시!! -

2015-03-09

[칩센]블루투스 전 제품 10%가격할인!! -

2015-02-02

[Arduino]Uno(R3) 구입시 37종 센서키트 할인이벤트!! -

2015-02-02

[M.A.I]Ahram_ISP_V1.5 60개 한정수량 할인이벤트!! -

2015-02-02

[64호]Dollying

64 ict dollying (1)

ICT 융합 프로젝트 공모전 장려상

Dollying (휴대폰 어플리케이션과 연동 가능한 영상 촬영 장비)

글 | 전남대학교 조유진, 이예찬

1. 심사평
칩센 사회적 트렌드를 이해하고, 그것에 적합한 작품을 목표로 한 창의성이 매우 대단해 보입니다. 목표로 한 결과에 얼마나 근접하였는지에 관한 물음이 생겨 실제 구동 화면이 궁금해지네요. 작품에서 스마트폰 어플을 이용하여 구동을 조작하도록 하였으나, 이 부분을 리모콘의 형태로 만들어 쉽게 제어 및 조작을 할 수 있다면 더 좋을 듯 합니다.
펌테크 세심한 관찰력과 아이디어가 반영된 실생활과 밀접한 작품이라고 생각합니다. 단 출품작의 경우 스마트폰용 APP 구현내용은 확인이 되었으나 스마트폰을 고정하고 구동하게될 하드웨어관련 부분은 초기개발 단계로 판단됩니다. 추후 보완을 통해 상업적으로도 충분한 가치가 있는 제품이 되리라 생각됩니다.
위드로봇 실제 촬영한 수준이 어떠한지 확인할 수 있으면 더 좋은 보고서가 될 것 같습니다.

2. 작품 개요
2.1. 개발배경

64 ict dollying (2)

대한민국 기준, 하루 평균 유튜브 시청 시간은 58.8분으로 다른 프로그램에 비해 사용 시간면에서 월등히 높다. 유튜브 영상 수요의 증가로 유튜브 영상 업로드 시간이 5년 사이에 약 10배 증가하였으며, 업로드 되는 영상 중 42%는 People 카테고리로 Vlog와 같은 개인의 일상에 관련되는 내용을 담고 있다. 이러한 1인 영상 매체가 성장하며 개인 방송장비 매출도 2년 사이에 540% 증가하였다.

2.2. 전동달리

64 ict dollying (1)

영화 촬영 시 사용하는 장비를 최근 소형화, 전동화 시켜서 1인 영상 촬영에 사용되고 있다. 현재 시중에 사용되는 제품은 움직임 설정에 정교함이 없기 때문에 휴대폰 어플을 통해서 섬세한 제어와 다양한 움직임을 가능하게 하는 전동달리 제작을 목표로 하였다.

3. 작품 설명
3.1. 주요 동작 및 특징
외관

64 ict dollying (2)

- 앞바퀴는 방향을, 뒷바퀴는 전진과 후진 기능을 수행한다.
- 윗면의 구멍으로 카메라를 고정한다.

애플리케이션 설명 : UI 디자인

64 ict dollying (3)

① 애플리케이션 시작 화면이다.
② 메뉴화면으로 블루투스 연결과 모드선택(직선 촬영, 원형 촬영, 혼합 촬영)이 가능하다.
③ 직선 촬영 모드 > 이동거리와 이동시간을 입력할 수 있고 기능(순방향, 역방향, 왕복)을 설정이 가능하다.

64 ict dollying (4)

④ 원형 촬영 모드 > 이동반경, 이동시간, 회전각도를 입력 할 수 있고 기능(순방향, 역방향, 왕복)을 설정 가능, 이동반경은 회전 반지름을, 회전각도는 원형으로 회전하는 각도를 의미한다.
⑤ 혼합 촬영 모드 > 직선촬영모드와 원형 촬영 모드를 합친 모드로 직선운동1-원형운동-직선운동2 구조로 구성, 직선운동 1,2구간의 이동거리와 이동시간과 원형운동의 이동반경, 이동시간, 회전 각도를 입력 할 수 있다. 또한 기능(순방향, 역방향, 왕복)을 설정이 가능하다.
⑥ 각 모드에서 실행을 눌렀을 때 넘어가는 화면. 기기 작동 시간이 종료되는 시간을 나타내며 입력 값은 수정이 가능하다.

64 ict dollying (5)

③,④,⑤번 상단의 전동 달리 그림은 설정 값에 따라 움직이며 사용자가 기기 실행 전 움직임을 알 수 있도록 도와준다.
⑥번 상단의 숫자는 기기가 움직이는데 걸리는 시간을 알려주며 시간이 지나면서 감소한다.

3.2 전체 시스템 구성

64 ict dollying (6)

<> 전송의 시작과 끝을 나타내는 구분자
① 촬영 모드(직선 촬영, 원형 촬영, 혼합 촬영)를 결정하는 변수
② 직선 촬영 모드 시 이동거리 변수, 혼합 촬영 모드 시 직선운동 1구간의 이동거리 변수
③ 직선 촬영 모드 시 이동시간 변수, 혼합 촬영 모드 시 직선운동 1구간의 이동시간 변수
④ 원형 촬영 모드 시 이동반경 변수, 혼합 촬영 모드 시 원형운동의 이동반경 변수
⑤ 원형 촬영 모드 시 이동시간 변수, 혼합 촬영 모드 시 원형운동의 이동시간 변수
⑥ 원형 촬영 모드 시 회전각도 변수, 혼합촬영모드 시 원형운동의 회전각도 변수
⑦ 혼합 촬영 모드 시 직선운동 2구간의 이동거리 변수
⑧ 혼합 촬영 모드 시 직선운동 2구간의 이동시간 변수
⑨ 기능(순방향, 역방향, 왕복)을 나타내는 변수

3.3 개발 환경(개발 언어, Tool, 사용 시스템 등)
전동 달리 코딩 : C,C++, Arduiono
애플리케이션 개발 : C#, Unity
전동 달리 모델링 : SOLIDWORKS
어플, 로고 디자인 : Adobe Photoshop,Adobe Illustrator

4. 단계별 제작 과정
·  0 단계: 아이디어 선정
·  1 단계: UI디자인 구성, 전동달리 구조 확정, 사용 부품 선정
·  2 단계: 전동달리 코딩 개발, 애플리케이션 개발, 전동달리 모델링 및 3D프린터 출력
·  3 단계: 3D프린터 파트 조립, 기기 시험 작동 후 코드 수정

1단계 : 어플 디자인 구성

64 ict dollying (3)

 

64 ict dollying (7)

사용부품 선정
· 아두이노 우노 x 1ea
· 아두이노 우노 쉴드 x 1ea
· 스텝모터, 모터 드라이버 x 2ea
· 서보모터 x 1ea
· 배터리 x 1ea
· 배터리 충전 모듈 x 1ea
· 바퀴 x 2ea

2단계 : 전동달리 모델링 및 3D프린터 출력

64 ict dollying (4)

전동달리 코드 개발

//헤더파일

//스테핑모터 정보. 모터 스펙에 맞게 설정
const int stepsPerRevolution = 2048; //28BYJ-48는 1회전당 2048스텝

//핀번호
//블루투스 설정
SoftwareSerial BTSerial(BT_RXD, BT_TXD); // change this to fit the number of steps per revolution

//data 읽기 시작, 종료 상태 변수
bool isStart = false; // 읽기 시작
bool isEnd = false; // 읽기 종료
String resultStr = “”; // 최종 Data를 저장할 문자열

//불루투스에서 받은 값을 나눠서 넣을 값.

//서브모터 설정
Servo servo; // Servo 클래스로 servo 객체 생성
int angle = 0; // Servo 모터의 각도 (0~180)
int stAngle = 82; //Servo 모터 직진용 각도, 82도가 직진, 사용하기 전에 기기마다 맞는 설정값을 입력해줘야 함
double ccAngle = 0; // 원형 운동시 서브모터 각도, 어플에서 넘어온 값으로 변경됨
int tnAngle = 0; // 혼합 운동시 서브모터 각도, 어플에서 넘어온 값으로 변경됨

//바퀴 데이터
int wheelRadius = 3; //바퀴 반지름
float wheelCircum = wheelRadius * 2 * 3.141592; // 바퀴 원주
//직선 운동시 필요 데이터를 계산하기 위한 변수
float stTurnNum = 0; //회전수
float stStepPerRevolution = 0; //step per revolution
float stSpeedNeed = 0; //회전속도(rpm)을 구하기 위해 필요한 변수
float stStepSpeed = 0; //회전속도(rpm)

//원형 운동시 필요 데이터를 계산하기 위한 변수
float ccTurnNum = 0; //회전수
float ccDis = 0; //회전 이동거리
float ccStepPerRevolution = 0; //step per revolution
float ccSpeedNeed = 0; //회전속도(rpm)을 구하기 위해 필요한 변수
float ccStepSpeed = 0; //회전속도(rpm)

//직선 운동3에 필요한 데이터를 계산하기 위한 변수
int stTurnNum3 = 0; //회전수
int stStepPerRevolution3 = 0; //step per revolution
int stSpeedNeed3 = 0; //회전속도(rpm)을 구하기 위해 필요한 변수
int stStepSpeed3 = 0; //회전속도(rpm)

//몸체 데이터
float bodylength = 10; // 몸체 세로 길이. 회전각을 구할 때에 필요

//,를 찾아내기 위한 변수

//회전에 필요한 데이터
int turnAngle = 0;
float turnData = 0;
void setup() {
//통신 설정
Serial.begin(9600); //컴퓨터와의 통신속도 설정
BTSerial.begin(9600); //블루투스와의 통신속도 설정

//Servo 모터 핀 설정
servo.attach(servoPin); //servoPin 데이터는 위에 표기
}

void loop() {

if (BTSerial.available()) {
while (1) {
char val = BTSerial.read(); //블루투스 데이터를 받아와 val변수에 삽입

//데이터 읽기 시작
if (val == ‘<’) {
Serial.println(“start”);
resultStr = “”; // 최종 Data 문자열 초기화
isStart = true;
isEnd = false;
continue; // while문으로 바로 이동
}
// 데이터 읽기 종료
else if (val == ‘>’) {
Serial.println(“end”);
isEnd = true;
break;
}
// 중간 데이터값을 최종 Data 문자열에 추가
else {
resultStr = String(resultStr + val);
}
}

//시작 부호와 종료 부호가 들어왔다면
if (isStart == true && isEnd == true) {
Serial.print(“전송된 데이터 : “);
Serial.println(resultStr);

//컴마 기호 파악
//문자열 나누기

//다음 불루투스 값을 받아들이기 위한 변수 초기화
isStart = false;
isEnd = false;

//직선 운동
if (sep == 2) {
//Serial.println(“직선 운동 모드로 설정되었습니다.”);

//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

//직선운동 스텝모터 작동에 필요한 값 계산
stTurnNum = (float)dis1 / wheelCircum; //회전수
stSpeedNeed = stTurnNum * 60; //계산과정 추후에 정리
stStepPerRevolution = (float)stTurnNum * stepsPerRevolution; //모터 한바퀴가 2048step이기 때문에 stepsPerRevolution을 곱함
stStepSpeed = (float)stSpeedNeed / tim1; //회전속도(rpm)

//직진모드
//후진모드
//왕복모드
else if (mod == 2) {
//Serial.println(“직선운동의 왕복모드가 시작되었습니다.”);
goForward(stStepSpeed, stStepPerRevolution);
goBackward(stStepSpeed, stStepPerRevolution);
}
}

//원형 운동
else if (sep == 3) {

//Serial.println(“원형 운동 모드로 설정되었습니다.”);

// 서보모터 회전각도 계산
// 계산과정은 나중에 따로 정리하겠습니다.
turnData = (float)rad2 / bodylength;
ccAngle = 180 – 2 * atan(turnData);

//서보모터 회전
servo.write(ccAngle); //서보모터 각도 설정
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

//스텝모터 관련 계산
ccDis = (float)0.01756 * ang2 * rad2; //회전 이동거리
ccTurnNum = (float)ccDis / wheelCircum; //회전수. 회전수는 이동거리 나누기 바퀴 원주
ccStepPerRevolution = (float)ccTurnNum * stepsPerRevolution; //step per revolution
ccSpeedNeed = ccTurnNum * 60; //회전속도(rpm)을 구하기 위해 필요한 변수
ccStepSpeed = (float)ccSpeedNeed / tim2; //회전속도(rpm)

//직진모드
//후진모드
//왕복모드
else if (mod == 2) {
//Serial.println(“원형운동의 왕복모드가 시작되었습니다.”);
goForward(stStepSpeed, stStepPerRevolution);
goBackward(stStepSpeed, stStepPerRevolution);
}
}

//회전운동 모드
else if (sep == 4) {

//직선운동1 스텝모터 작동에 필요한 값 계산
stTurnNum = (float)dis1 / wheelCircum; //회전수
stSpeedNeed = stTurnNum * 60; //계산과정 추후에 정리
stStepPerRevolution = (float)stTurnNum * stepsPerRevolution; //모터 한바퀴가 2048step이기 때문에 stepsPerRevolution을 곱함
stStepSpeed = (float)stSpeedNeed / tim1; //회전속도(rpm)

//스텝모터 회전 관련 계산
ccDis = (float)0.01756 * ang2 * rad2; //회전 이동거리
ccTurnNum = (float)ccDis / wheelCircum; //회전수. 회전수는 이동거리 나누기 바퀴 원주
ccStepPerRevolution = (float)ccTurnNum * stepsPerRevolution; //step per revolution
ccSpeedNeed = ccTurnNum * 60; /회전속도(rpm)을 구하기 위해 필요한 변수
ccStepSpeed = (float)ccSpeedNeed / tim2; //회전속도(rpm)

//직선운동3 스텝모터 작동에 필요한 값 계산
stTurnNum3 = (float)dis3 / wheelCircum; //회전수
stSpeedNeed3 = stTurnNum * 60; //계산과정 추후에 정리
stStepPerRevolution3 = (float)stTurnNum * stepsPerRevolution; //모터 한바퀴가 2048step이기 때문에 stepsPerRevolution을 곱함
stStepSpeed3 = (float)stSpeedNeed / tim3; //회전속도(rpm)

//직진모드
if (mod == 0) {
//Serial.println(“회전 운동 직진모드로 설정되었습니다.”);

//직진1
//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

//직선운동에서 스텝모터 움직임
goForward(stStepSpeed, stStepPerRevolution);

//회전
// 계산과정은 나중에 따로 정리하겠습니다.
turnData = (float)rad2 / bodylength;
ccAngle = 180 – 2 * atan(turnData);

//서보모터 회전
for (int i = 0; i < ccAngle; i++) {
turnAngle += 1;
servo.write(turnAngle); //서보모터 각도 설정
}

//스텝모터 관련 계산
ccDis = (float)0.01756 * ang2 * rad2; //회전 이동거리
ccTurnNum = (float)ccDis / wheelCircum; //회전수. 회전수는 이동거리 나누기 바퀴 원주
ccStepPerRevolution = (float)ccTurnNum * stepsPerRevolution; //step per revolution
ccSpeedNeed = ccTurnNum * 60; //전속도(rpm)을 구하기 위해 필요한 변수
ccStepSpeed = (float)ccSpeedNeed / tim2; //회전속도(rpm)
goForward(ccStepSpeed, ccStepPerRevolution);

// 직진3
//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

goForward(stStepSpeed, stStepPerRevolution);
}

else if (mod == 2) {
//Serial.println(“회전 운동 왕복모드 직진부로 설정되었습니다.”);

//직진1
//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

//직선운동에서 스텝모터 움직임
goForward(stStepSpeed, stStepPerRevolution);

//회전
// 계산과정은 나중에 따로 정리하겠습니다.
turnData = (float)rad2 / bodylength;
ccAngle = 180 – 2 * atan(turnData);

//서보모터 회전
for (int i = 0; i < ccAngle; i++) {
turnAngle += 1;
servo.write(turnAngle); //서보모터 각도 설정
}

//스텝모터 관련 계산
ccDis = (float)0.01756 * ang2 * rad2; //회전 이동거리
ccTurnNum = (float)ccDis / wheelCircum;  //회전수. 회전수는 이동거리 나누기 바퀴 원주
ccStepPerRevolution = (float)ccTurnNum * stepsPerRevolution; //step per revolution
ccSpeedNeed = ccTurnNum * 60;  //회전속도(rpm)을 구하기 위해 필요한 변수
ccStepSpeed = (float)ccSpeedNeed / tim2;  //회전속도(rpm)

goForward(ccStepSpeed, ccStepPerRevolution);

// 직진3
//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500);  //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

goForward(stStepSpeed, stStepPerRevolution);

//Serial.println(“회전 운동 왕복모드 후진부로 설정되었습니다.”);
//직진1
//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

//직선운동에서 스텝모터 움직임
goBackward(stStepSpeed, stStepPerRevolution);

//회전
// 계산과정은 나중에 따로 정리하겠습니다.
turnData = (float)rad2 / bodylength;
ccAngle = 180 – 2 * atan(turnData);

//서보모터 회전
for (int i = ccAngle; i > 0; i–) {
turnAngle -= 1;
}
servo.write(turnAngle); //서보모터 각도 설정

//스텝모터 관련 계산
ccDis = (float)0.01756 * ang2 * rad2; //회전 이동거리
ccTurnNum = (float)ccDis / wheelCircum; //회전수. 회전수는 이동거리 나누기 바퀴 원주
ccStepPerRevolution = (float)ccTurnNum * stepsPerRevolution; //step per revolution
ccSpeedNeed = ccTurnNum * 60; //회전속도(rpm)을 구하기 위해 필요한 변수
ccStepSpeed = (float)ccSpeedNeed / tim2; //회전속도(rpm)

goBackward(stStepSpeed, stStepPerRevolution);

// 직진3
//직선운동에서 서브모터 각도 수정
servo.write(stAngle); //변수 값으로 고정했습니다. 장치 개발 후 수정이 필요합니다.
delay(500); //서브모터가 돌고 바로 스텝모터가 도는 것을 방지하기 위해 잠깐의 텀을 둡니다.

goBackward(stStepSpeed, stStepPerRevolution);
}

}
//변수초기화 혹시 몰라서 넣어봅니다.
turnAngle = 0;
}
}
void goForward(float a, int b) {
rightStepper.setSpeed(a);
leftStepper.setSpeed(a);
for (int i = 0; i < b; i++) {
rightStepper.step(1);
leftStepper.step(-1);
}
}

void goBackward(float c, int d) {
rightStepper.setSpeed(c);
leftStepper.setSpeed(c);
for (int i = 0; i < d; i++) {
rightStepper.step(-1);
leftStepper.step(1);
}
}

어플리케이션 개발

① BT_connect -
블루투스를 이용하여 개발 어플과 Dollying(기기)을 연동

using TechTweaking.Bluetooth; // BT 제어 모듈
public class BT_connect : MonoBehaviour
{
private BluetoothDevice device;

BT연결 설정
private void Awake()
{
BluetoothAdapter.enableBluetooth(); //Force Enabling Bluetooth
device = new BluetoothDevice();
device.Name = “BT1″; // 내 블루투스 이름
}
public void connect()
{
device.connect();
}

public void disconnect()
{
device.close();
}
}
② 어플 페이지 설정

void Start()
{
ContextChanger(“1Page1″); // 앱 실행시 로고 출력

// 2초 후 2Page2 내용 출력
Invoke(“ShowFirstContext”, 2f);
}
public void ShowFirstContext()
{
ContextChanger(“2Page2″);
}
//콘텐츠 활성화 및 비활성화 처리
/// <param name=”conName”>콘텐츠 활성화 시킬 게임오브젝트 이름</param>
public void ContextChanger(string conName)
{
for (int i = 0; i < contextArr.Length; i++)
{
if (contextArr[i].name == conName)
{
if (i != 5) prevContextName = conName;

contextArr[i].SetActive(true);

if (i < 5) menu = i;
switch (i)
{
case 2:
mode = dirType1;
break;
case 3:
mode = dirType2;
break;
case 4:
mode = dirType3;
break;
default:
break;
}
}
else
{
contextArr[i].SetActive(false);
}
}
}
// 직전 설정 화면으로 이동하는 함수
public void BackToModify()
{
ContextChanger(prevContextName);
}
③ 블루투스로 데이터 전송하기
public void SendDataToBt()
{
if (device != null)
{
string distance1;
string time1;
string distance2;
string time2;
string angle2;
//혼합이동을 위해 나누어 처리
if (menu == 4)
{
distance1 = inputField[7].text; //어플을 통해 사용자로 부터 입력받은 데이터를 변수값에 넣어줌
time1 = inputField[8].text;
distance2 = inputField[9].text;
time2 = inputField[10].text;
angle2 = inputField[11].text;
}
else
{
distance1 = inputField[0].text;
time1 = inputField[1].text;
distance2 = inputField[2].text;
time2 = inputField[3].text;
angle2 = inputField[4].text;
}

string distance3 = inputField[5].text;
string time3 = inputField[6].text;
string menu1 = menu.ToString();
string mode1 = mode.ToString();

//아두이노가 값을 읽어처리하는 형식과 동일하게 구성시켜 데이터를 보내줌
string resultStr = “<” + menu1 + “,” + distance1 + “,” + time1 + “,” + distance2 + “,” + time2 + “,” + angle2 + “,” + distance3 + “,” + time3 + “,” + mode1 + “>”;
device.send(System.Text.Encoding.ASCII.GetBytes(resultStr));
Debug.Log(resultStr);
//t.GetComponent<Text>().text = resultStr;

// 타이머 설정(마지막 페이지(잔여시간 보여주기 기능)를 위해)
timer = 0;
switch (menu)
{
case 2:
timer = int.Parse(time1);
if (mode == 2)
{
timer *= 2;
}
break;
case 3:
timer = int.Parse(time2);
if (mode == 2)
{
timer *= 2;
}
break;
case 4:
timer = int.Parse(time1) + int.Parse(time2) + int.Parse(time3);
if (mode == 2)
{
timer *= 2;
}
break;
default:
break;
}

maxTimer = timer;
timerGuage.fillAmount = 1f;
// 타이머 UI 실행 및 타이머 감소
StartCoroutine(TimerCoroutine());
}

3단계 : 3D프린터 파트 조립

64 ict dollying (5)

기기 시험 작동 후 코드 수정

64 ict dollying (6)

5. 기타
5.1 회로도

64 ict dollying (8)

5.2 플레이스토어 등록

64 ict dollying (9)

5.3 특허 출원

64 ict dollying (10)

 

5.4 계산 과정
스텝 모터가 움직이는 데 필요한 값 계산
계산을 시작하기 전에 알아야 하는 값

1. 스텝모터가 1회전이 몇 개의 스텝으로 이루어져 있는지 여부

2. 바퀴 반지름.
· 왼쪽 모터의 1회전에 필요한 스텝은 8이다.
· 디바이스마트에 나와있는 스텝모터 (SZH-EK060) 사양

64 ict dollying (11)
Step angle이 5.425。이고 감속비는 1/64이므로 1스텝 0.084765625。당 회전한다. 360÷0.084765625 ≒4247이지만 모터드라이버의 full step모드에서는 1/2한 근사치인 2048을 이용한다.

애플리케이션에서 전송받는 값
1. 기기의 이동거리, 2. 기기 이동에 걸리는 시간

구해야 하는 값
1. 스텝모터의 회전속도는 rpm단위이기 때문에 위의 값들을 활용하여 rpm값을 구해야 한다.
2. 해당 거리만큼 이동하는 데 필요한 스텝 수를 알아야 한다.

회전에 필요한 스텝 수 구하기
1. 바퀴의 원주를 알아야 하므로 2πr(r은 반지름)을 통해서 원주를 알아낸다.
2. 이동 거리를 원주로 나누어 바퀴의 회전수를 구한다.
3. 회전수에 스텝 모터 한바퀴 스텝을 곱하여(이번 프로젝트에 사용한 스텝모터의 1회전에 필요한 스텝은 2048) 이동에 필요한 스텝을 알 수 있다.

회전속도 구하기
1.  64 ict dollying (12)을 이용한다.

2. 회전 반지름에 따른 회전 각도 구하기

64 ict dollying (13)
r= 회전 반지름
L= 기기 길이
α=  64 ict dollying (14)

빨간 삼각형과 주황 삼각형은 합동이므로 θ=180-2α이다.

Leave A Comment

*