[Arduino/아두이노] 아두이노 보드 연결하여 기본 세팅 및 포트 설정하기

 

안녕하세요~

저번 포스팅인 [아두이노/Arduino] 아두이노 IDE(통합 개발 환경, Integrated Development Environment) 다운받고 설치하고 실행하기에 이어 두번째 시간! 아두이노 개발환경을 받았으니, 아두이노 보드를 연결하고 포트를 설정하여 기본 프로젝트를 구동시켜보겠습니다!

정말 쉬우니 그냥 팔로팔로미!

 

1. 아두이노 보드 설명

자, 이제 단순히 소프트웨어 뿐만 아니라 아두이노 라고 하는 하드웨어 보드가 추가되는데요, 그만큼 어떻게보자면 컴퓨터 환경인 온라인과 하드웨어인 오프라인을 넘나들며 설명을 해야 합니다!

일단 포트설정과 기본 세팅에 앞서 어떤 아두이노 보드를 사용하는지가 조금 중요해 집니다!

저는 지금 '아두이노 메가 2560'과 '아두이노 우노' 그리고 '아두이노 나노' 세가지 보드를 쓰고있습니다!

일부러 판매 사이트로 링크를 걸어놨는데요, 인터넷에서 specification을 찾는 것보다 판매 사이트에서 설명되어있는 부분이 더 자세하기에 링크를 걸었습니다.

 

기본적인 차이점은 가장 큰것이 크기인데요, 나노가 가장 작고 그다음이 우노 그리고 메가2560이 제일 큽니다!

당연히 포트 수도 메가2560이 가장 많구요, 마이크로 프로세서(마이크로 컨트롤러 혹은 ARM 혹은 AVR: 넷 다 비슷한 용어입니다.)의 강력함도 메가2560이 가장 크죠.

그러면 크다고 마냥 좋은건가 하면 아니죠. RC카라던가 라인 트레이서 같이 움직이는 것 안에 내장하여 쓰려면 나노처럼 작고 가벼운 것이 좋겠죠!

 

그리고 여기서 가장 큰 부분이 공식 아두이노 보드가 아닌 중국에서 아두이노 호환보드로 제작한 ch340 칩이 약간 문제가 되는데요, 일단은 기본 세팅과 포트설정 후 기본 프로젝트를 구동해 보는 과정에서 에러사항을 한번 살펴보겠습니다!

 

저는 일단 여기서 가장 사람들이 입문으로 많이 쓰는 아두이노 우노로 설정을 진행하도록 하겠습니다!

 

먼저 아두이노 보드컴퓨터연결해주세요!(아두이노 보드와 동봉된 USB 선으로 아두이노에는 USB type A(육각형으로 집처럼 생긴 모양)를 컴퓨터에는 USB type B(우리가 아는 usb 모양)를 연결해주시면 됩니다. 이렇게 생긴 선일겁니다)

 

2. 보드 선택하기

자, 처음으로 아두이노 IDE를 키셨다면 바로 아래와 같은 화면이 나올 것 입니다.

그리고 여기서 오른쪽 아래 표시된 것과 같이 'No board selected'라고 표시됩니다. 즉, 아두이노 보드가 선택되지 않았다는 것인데요.

여기서 저희는 메뉴에 'Tools'>'Board'>'Arduino AVR Boards'를 차례대로 선택하면

이와같이 엄청나게 많은 아두이노 보드들이 보이게 됩니다. 저는 'Uno' 였으니까 위에서 두번째 'Arduino Uno'를 선택해줄 거구요, 나노나 메가도 메뉴에 보이는 Arduino Nano, Arduino Mega를 각각 선택해주시면 되겠습니다. 그외에도 여러 보드를 선택할 수 있으니, 결국 내가 지금 가지고 있는 보드가 무엇인지 확인하는게 가장 중요하겠죠!?

자, 이렇게 선택하면 아까 보았던 상태표시줄 우측이 선택한 보드명으로 바뀌는 것을 볼 수 있습니다!

특히 이 보드를 잘 못 설정하게 되면 각 AVR마다 명령어 체계가 약간은 다른데 그것을 보정할 수 없어 컴파일이 안되거나, 실행이 되지 않습니다! 혹시 컴파일이 안되거나 보드로 실행이 안되는 경우는 한번 이 보드 설정을 제대로 하셨나 확인해보시는 것도 한가지 방법입니다!

자, 여기서 잘 살펴보면 'not connected'라고도 나와있는 걸 볼 수 있습니다.

이는 물리적으로 현재 아두이노 우노 보드와 컴퓨터가 연결되어 있음에도 볼 수 있는데요, 그 이유는 포트 설정이 되지 않아, 아두이노 IDE가 아두이노 보드가 현재 컴퓨터에 연결되었음을 알지 못하는 것입니다.

 

3. 포트 선택하기!

눈치채신 분들도 있겠지만, 포트는 'Tools'의 'Board' 아래 있습니다. 근데 혹시나 'Port'가 안보이시는 분들은 IDE를 끄고, 아두이노 보드를 먼저 컴퓨터에 연결하신 다음 아두이노 IDE를 다시 실행시켜 주시고 2번 보드 설정부터 다시 해주시면 됩니다!

자, 이렇게 포트를 누르면 자동으로 아두이노 보드가 연결된 포트(COM5)를 보여줍니다. 여기서 포트 명(COM5)는 크게 의미는 없습니다. 보통 대부분의 사람들은 COM3로 뜨지만, 포트가 다른데 연결되어있거나 하면 포트명은 달라질 수 있습니다. 그러나 중요한건 여기서 괄호 안에 본인이 사용하는 아두이노 보드명이 일치하는지만 잘 확인하시고, 일치한다면 그 포트로 사용해주시면 됩니다!

자 이렇게 포트까지 설정해주면, 아두이노 보드와 연결이 되게되고, 오른쪽 아래가 'Arduino Uno on COM5'라고 바뀌게 됩니다.

 

자, 이제 보드와 IDE가 연결되었습니다. 아주 기본적인 프로젝트를 할 수 있게 되었네요!

좀 더 하고 싶지만, 일단 포스팅 길이가 너무 길어질 것 같아 다음으로 넘겨야겠네요!

다음시간에는 아주 기본적인 프로젝트를 하나 만들고 컴파일해서 아두이노 보드로 보내고, 보드에서 작동하는지 확인하며, 그 과정에서 일어날 수 있는 아주 기본적이지만 당혹스러운(그리고 자주 나타나는) 문제들을 짚어보겠습니다!

 

다음에 보아요~

 

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

[아두이노/Arduino] 아두이노 IDE(통합 개발 환경, Integrated Development Environment) 다운받고 설치하고 실행하기

 

안녕하세요! 한동안 아두이노를 가지고 개발을 하다가 아주 잠~시 개발을 멈추고 다른일을 하다 다시 아두이노를 시작해보려고 합니다!

이전에는 너무나도 당연하게 아두이노 통합 개발 환경이 깔려있었고, 당연하게 모든 설정이 다 되어있었다면, 이제 다시 시작하는 마당에 컴퓨터도 너무나도 깔~끔하게 설치가 제거되어있고, 설정도 없으니 이제 제가 다시 다 깔고 설치해야합니다.

그런 의미에서 다시 시작하는 제 과정을 블로그에 공유합니다. 혹~시나 이 글을 보시는 여러분들께 작지만 큰 도움이 되었으면 좋겠습니다!

자, 팔로팔로미!

 

1. 설치파일 다운 받기

자, 그럼 일단 먼저 설치 파일 부터 다운을 받아야겠죠?

 

1) 다운로드 사이트 접속!

다운로드 사이트에 접속하는 방법에는 크게 두가지가 있습니다. 하나는 여기에서 제공해드리는 링크로 바로 접속하시는 방법과, 두번째로는 검색사이트를 이용하는 방법이죠. 여기서 검색사이트는 '네이X'가 공식사이트 링크를 최상단에 올려주지 않기에 '구글'을 추천드립니다.

1> 링크이용

2> 검색엔진이용

 

1> 링크이용!

이 페이지에 들어오셨다면! 가장 간단한건 제가 바로 링크를 달아드리는거겠죠!

과거 인터넷 혼란기?에는 진짜 검색창에 뭐 '다운로드'만 치면 진짜 불법사이트들이 난립을 해서, 잘못 받다가 컴 날려먹기 일수였는데요.. 요새는 사이트 정립도 잘 되어있고, 검색 사이트도 자체적으로 업데이트가 많이 되어 그런일은 별로 없는 것 같습니다.. 그래서 과거에는 무슨 소개글에 꼭 공식 홈페이지를 링크로 달아놨는데.. 요새는 필요가 없어보이지만, 그래도 저는 한번 달아보겠습니다.

https://www.arduino.cc/en/software

 

Software

Open-source electronic prototyping platform enabling users to create interactive electronic objects.

www.arduino.cc

네! 여기로 접속해주시고 2)번으로 이동해주세요!!

 

2> 검색엔진 이용

자, 먼저 구글을 이용해 볼까요?

1> 'Google' 검색창에 '아두이노 다운로드'검색

2> 검색 후 제일 처음에 뜨는 링크인 'Software | Arduino'를 선택(여기서 주소가 www.arduino.cc(공식사이트)인지 확인해보는 것도 팁!)

여기서도 2)번으로 이동해주세요!

네이버에서는 어떨까요?

아쉽게도 네이버에서는 공식홈페이지로 연결이 되지 않고, 다른 사이트가 최상단에 뜹니다.. 그러니 가급적 구글을 이용해주시는게 좋습니다. 물론 네이버에서도 스크롤을 내리면 하단에 공식홈페이지 링크가 존재하긴합니다.

자, 2)번으로 이동하도록 하죠! 공식홈페이지에서의 다운로드 입니다!

 

2) 홈페이지에서 다운로드!

1> 페이지가 영어라고 당황하지 말고! 오른쪽의 DOWNLOAD OPTIONS에서 Windows버전의 제일 윗 링크를 클릭해줍니다!

 

여담!(무시하셔도 됩니다!)

더보기

여담으로 Arduino IDE 2.0.1이라는 것은 현재 아두이노 IDE의 버전입니다. 혹시라도 과거의 버전이 필요하신 분들은 스크롤을 내리면 Legacy IDE (1.8.X)와 Previous Releases가 있는  것을 확인하실 수 있고, 이쪽 링크를 통해서 다운로드 받으시면 됩니다.

또한 다운로드 옵션에서 OS에 따른 윈도우, 리눅스, 맥OS를 빼고도 윈도우 안에서도 파일이 여러개로 나뉜 것을 볼 수 있는데, 윈도우에서 첫번째 링크와 두번째 MSI 링크는 둘다 설치파일을 다운로드 하며, ZIP file은 설치파일 없이 다운로드합니다. 혹시 윈도우에 아두이노가 설치되는 것이 싫다하시면 ZIP파일로 받으셔서 'Arduino IDE.exe'파일만 실행해주시면 됩니다. 그럼 설치과정 없이 바로 실행이 됩니다. 여기서 가끔 처음 실행시 무한 로딩(2.0.1버전 기준 아두이노 로고 무한 두근거림)이 걸리는 경우가 있는데 꺼주시면 잠시 후 windows defender에서 네트워크 차단 허용 메시지가 뜹니다. 이걸 허용 해주시고 다시 실행하시면 제대로 실행됩니다.

 

2> 기부창이 뜹니다. 저희가 돈이 많다면 아두이노에 기부를 해줄테지만.. 일단은 JUDT DOWNLOAD를 눌러 그냥 다운로드를 진행해줍니다! 다운로드 파일 선택창이 뜨고(이 곳을 잘 기억해주세요!) 저장 버튼을 누르면 바로 다운로드가 시작됩니다!

 

2. 설치하기!

다운로드 받은 파일(arduino-ide_2.0.1_Windows_64bit.exe)을 더블클릭하여 실행하면 먼저 '사용권 계약'이 뜰겁니다. 여기서 '동의함' 누르시고 설치옵션 중 '사용자 선택'하는 부분에서 '전용'으로 선택하고 넘기세요!

설치 위치는 그냥 보통 자동으로 설정하는 값을 그대로 두고 설치합니다! 임의로 바꾸시면 나중에 다른 추가 프로그램 설치시 문제가 될 수도 있으니, 정말 부득이하게 꼭 바꿔야 하는 경우를 제외하고는 그냥 바로 '설치'를 눌러줍니다!

까만건 제 윈도우 아이디..
중간에 빈공간은 제 윈도우 아이디..

설치가 시작됩니다!

한 5분여 좀 넘게 기다리다 보면 설치 완료 창이 뜹니다.

바로 실행까지 해볼까요? 'Arduino IDE 실행하기'에 체크표시 된 상태로 마침을 눌러줍니다!

여기서 가끔 처음 실행시 무한 로딩(2.0.1버전 기준 아두이노 로고 무한 두근거림)이 걸리는 경우가 있는데 꺼주시면 잠시 후 windows defender에서 네트워크 차단 허용 메시지가 뜹니다. 이걸 허용 해주시고 다시 실행하시면 제대로 실행됩니다.

 

3. 실행 후!

아두이노 창이 열리고 갑자기 윈도우에서 '띠로링'하면서 알림창이 여러개 뜹니다! 이때는 당황하지 말고 전부 '허용' 혹은 '설치'를 눌러주시면 되는데

가장 처음 뜨는 알림창이 dpinst-amd64.exe을 허용할건지 여부입니다.

이것은 아두이노가 설치파일로 설치되었을 때 포트와 드라이버를 설정하고 설치하는 과정에서 Driver Package Installer가 작동하게 허용할거냐는 부분이니 당연히 '허용'을 눌러주시면 됩니다.

그 다음엔 순서대로 'Adafruit Industries LLC 포트(COM & LPT)', 'Arduino USB Driver', 'Genuino USB Driver'를 설치할건지 물어보는 창이 나오는데, 세개 다 설치를 눌러주시면 됩니다.

그러면 마지막으로 dpinst-amd64.exe 허용창이 한번 더 뜨는데, 허용 눌러주시면 아두이노 설치가 전부 끝납니다!

 

4. 재실행!

설치 후 실행한 화면을 끄거나 해서 아두이노 IDE를 다시 실행하고 싶으신 경우 바탕화면에 자동으로 'Arduino IDE' 바로가기가 생성되었으니 이것을 클릭하여 실행해주시면 됩니다.

 

네, 여기까지 아두이노 IDE(통합 개발 환경) 설치를 진행해 보았습니다! 이 다음에는 아두이노 기본 세팅과 포트설정, 그리고 Library 추가에 대해서 진행해보도록하겠습니다!

 

그럼 다음포스팅까지 안녕~~

직선 두개로 원을 삼등분하기

 

원을 삼등분하는 방법은 정말 여러가지가 있다.

일본에서는 챌린지까지 열릴정도라고하니 열기가 대단함을 알 수 있다.

그 중에는 실용적인 것도 있지만, 오로지 수학적 아름다움만을 위해 있는 것들도 있고... 하지만, 이번에 소개하려는 방식은 그 챌린지에 없지만, 실용적으로 쓸 수 있는 직선 두개로 원을 삼등분 하는 방식이다.

물론 수치가 완전히 딱 떨어지게는 나오지 않기 때문에 실전에서 사용하려면 어느정도 비슷한 근사치로 봐야하지만, 그래도 빠르게 직선만으로 3등분을 내기에는 적합하지 않나 싶다.

 

그래서 우리의 목표는

색칠한 세 면의 넓이가 모두 같으면 삼등분!

위와같이 원을 세로로 한번, 가로로 한번 잘라 면적이 동일하게 나오게 하는 것이다. 면적이 동일하면 3등분!

그렇지만, 따져보면 왼쪽의 두 부분은 위아래 대칭으로 한쪽 넓이만 계산하면 자동으로 반대편 넓이가 나오므로, 여기서 가장 중요한 포인트는 첫번째 세로로 자를 때 주황부분과 초록부분이 넓이가 같아지는지가 제일중요하게 된다.

그러면 어느 x점에서 잘라야 하는지가 중요해지고, 이것만 계산할 수 있으면 원을 직선 두개로 삼등분 할 수 있게 된다.

어느 x 지점에서 잘라야 원을 3등분 할 수 있을까?

자, 그러면 두 넓이가 같다는 식을 세워보자

음영처리된 부분의 넓이가 키포인트 입니다

음영처리된 부분의 넓이를 구하는게 키포인트인데, 일단 간단하게 음영처리된 부분의 넓이를 $ a $라고 하고 넓이구하는 식을 만들어 봅시다. 원은 단위원으로 반지름은 1입니다.

(노란부분) $ \frac{\pi}{4} + a = 2(\frac{\pi}{4} - a) $ (초록부분)

근데 식을 써보니 식이 a에 대해서 정리될 것 같습니다.

$ \frac{\pi}{4} + a = 2(\frac{\pi}{4} - a) $

$ 3a = \frac{\pi}{4} $

$ a = \frac{\pi}{12} $

즉, 전체 넓이를 구하는 식에서 음영처리된 넓이가 $ \frac{\pi}{12} $면 된다는 식으로 식이 더 간단해 졌군요.

그럼 이제 우리는 음영처리된 넓이만 구하면 되겠습니다.

 

1) 각도와 삼각함수로 구하기

이전 포스팅(링크)에서 구했던 방식인데, 여기서 x값으로 다시 나타내지 않고, 각도값 그대로 사용하여 푸는 방식입니다.

theta 놓는 방향에 주의하세요

원과 각도가 주어졌고, 위와 같은 모양의 넓이면, 호의 넓이+삼각형 넓이 해서 구할수 있으며, 이 식은

$ \frac{1}{2} \theta $ (호의 넓이) + $ \frac{1}{2} sin\theta \cdot cos\theta $ (삼각형의 넓이) [r=1 생략]

그러면 우리가 구하고자 했던 $ \frac{\pi}{12} $로 방정식을 놓으면

$ \frac{1}{2} \theta + \frac{1}{2} sin\theta \cdot cos\theta = \frac{\pi}{12} $

정리하면

$ \theta + sin\theta \cdot cos\theta = \frac{\pi}{6} $

가 됩니다. 전에도 말씀드렸다시피 삼각함수의 일반각 계산은 사람이 할 수 없으므로 울프람 알파(https://www.wolframalpha.com/)를 돌려줍니다.

[위 식을 그대로 긁어서 붙이면 울프람에서 인식을 못합니다. θ + sin θ ⋅ cos θ = π/6 이거를 붙여 넣어주세요]

그러면 결과가

$ \theta = 0.268133... $

으로 나옵니다.

그러나 이거는 각도 값일 뿐, 우리가 원하는 것은 x좌표이므로, 위의 그림에서 놓은 $ \theta $ 방향을 보면, $ sin \theta $가 x좌표임을 알 수 있습니다.

다시 $ sin \theta $에 0.268133값을 넣어서 울프람 알파를 돌리면

$ sin 0.268133 = 0.264932... = x $

이와 같은 값을 얻고, 이는 바로 x좌표입니다.

 

2) 부정적분으로 구하기

이전 포스팅(링크)에서 주야장천 구했던 식을 가지고 푸는 방법입니다.

물론 계산은 울프람 알파가 해줄겁니다.

먼저 방정식을 세웁니다.

$ \frac{1}{2} \cdot x \cdot \sqrt{1-x^{2}} + \frac{1}{2} \cdot arcsin \, x = \frac{\pi}{12} $

정리하여

$ x \cdot \sqrt{1-x^{2}} + arcsin \, x = \frac{\pi}{6} $

으로 만들고 울프람을 돌리겠습니다. 마찬가지로 위 식을 그대로 붙이면 울프람에서 인식 못하니 x ⋅ √ (1 − x^2) + arcsin x = π/6로 붙여넣어 주세요.

그러면 이번에는 한번에 x 값을 알려줍니다. 결과는 1)번과 같습니다.

 

결론

위의 계산으로 단위원의 원점에서 약 0.265만큼 떨어진 위치에서 세로로 한번, 나머지 부분에 가로로 한번 잘라주면 3등분이 된다는 사실을 알았네요!

좀 더 실용적으로 말해보자면 어떤 크기의 원이든, 원점에서 약 1/4 지점보다 조금 더 나가서 T자로 자르면 3분할이 된다고 볼 수 있겠습니다!

#Arduino #3D printer #아두이노 #3D프린터 # 3D프린터개발산업기사

 

로터리인코더(로타리엔코더) 쉽게 이해하기

 

0. 서론

로터리 인코더는 CLK와 DT라는 두개의 포인트를 가지고 회전을 검출하는 장치입니다.

사실상 원리는 간단하고 이를 아두이노에 활용하기에도 쉽지만 의외로 이 인코더의 작동원리를 이해하기 힘들어 아두이노 코드에 접목하기가 쉽지 않은 것이 현실입니다.

이에 오늘은 로터리인코더(로타리엔코더)의 회전방향 검출에 대해 알아보도록 하겠습니다.

 

1. 로터리 인코더 작동원리

로터리 인코더는 CLK와 DT라는 두개의 포인트로 회전을 검출합니다.

발광부-수광부로 이해해도 좋고, 금속 원판에 포인트가 붙었다 떨어졌다로 이해해도 좋습니다.

어찌되었든 이 두 지점이 거리를 두고 위치하고 있기 때문에 원판이 돌아갈 때 시간차이가 나게 되고, 이 시간차이를 가지고 이 원판이 시계방향으로 회전하는지, 반시계방향으로 회전하는지를 알아낼 수 있습니다.

출처: www.ElectroPeak.com



그림의 이해를 쉽게 하기 위해 원형철판에 두 지점이 닿아있다고 보겠습니다. 이 상황에선 두 포인트 전부 전기가 통하는 상태입니다.(수치로는 1 혹은 HIGH라고 볼 수 있습니다.)
또한 CLK(그림의 Output A)는 DT(Output B)보다 왼쪽에 위치하며, 이미지상으로는 위쪽에 위치합니다.

일단 시계방향으로 돌아갈때를 보죠.
이 상황에서 시계방향으로 돌면 CLK가 먼저 원판에서 떨어집니다. 그리고 그 다음 DT가 떨어지고, 그 다음 다시 CLK가 원판에 붙고, 다시 DT가 붙습니다.
1주기를 살펴보면

CLK DT
1 1
0 1
0 0
1 0
1 1

이렇게 되는 것을 볼 수 있습니다.
또한 최소 분해능은 1/4주기로 볼 수 있습니다. 1/4주기마다 회전을 검출할 수 있기 때문이죠.


그럼 반시계방향으로 돌아가는 상황을 보도록 합시다.
원판이 반시계방향으로 돌면 DT가 먼저 원판에서 떨어집니다. 다음 CLK가 떨어지고, 다음 DT가 다시 붙고, 다음 CLK가 붙겠죠.
1주기를 살펴보면

CLK DT
1 1
1 0
0 0
0 1
1 1

이렇게 되는 것을 볼 수 있습니다.

이를 펄스그림으로 보게되면 아래와 같습니다.

출처: https://protosupplies.com/

 

2. 소자의 이해(HW-040)

저희가 쓸 소자는 HW040이라는 소자입니다. 이 소자의 특징은 로터리 인코더가 한번 딸깍하고 돌아갈때 위에서 말한 1주기 중 1/2주기씩 움직인다는 것입니다. 이를 이미지로 설명하면 원판에 둘다 붙어있다가 한번 딸깍에 둘다 떨어지고, 다음 딸깍에 둘다 붙는다는 말이 되죠. 참고로 첫 시작값은 보통 CLK, DT 모두 1값으로 시작하는게 보통이나 상황에 따라 달라질 수 있기에 소스코드에서 한번 처음 읽어주도록 합시다.

 

3. 코드에의 적용

이렇게 1주기에 CLK와 DT값이 4가지로 변화하기 때문에 이 모든 값에 대응해서 코딩을 해야할 것 같지만(물론 이런 경우가 제일 완벽하겠죠), 자세히 들여다보면 어떤 규칙이 있습니다. 바로 CLK값이 변화할때 시계방향이면 DT와 읽는 값이 정 반대이고(CLK가 왼쪽이므로 원판에서 먼저떨어집니다), 반시계방향이면 CLK값이 변화할때 DT값이랑 같다는 것이죠.(CLK가 왼쪽인데, CLK에서 변화가 감지될 때는 이미 DT값이 변한 이후입니다.)

특히 저희가 쓸 소자는 1번 딸깍에 1/2주기씩 진행하기 때문에 모든 상황에 대해서 코딩하는 것이 낭비라고 볼 수도 있기도 하고, 한번 딸깍에 코딩으로 반응이 와야하기 때문에 모든 주기에 대해서 코딩하기 보단 변화를 가지고 코딩하는게 좋습니다.(1주기 코딩을 하게되면 두번 딸깍해야 반응이 오겠죠)

여기서의 포인트는 딱 두가지입니다.

1) CLK값이 변화할때
2) 그 순간 DT와 CLK값의 차이(정방향 변화: 두 값이 차이, 역방향 변화: 두값이 동일)

 

 그럼 코드를 작성해보겠습니다. 이전과 같이 LED는 각 2, 3, 4번 핀에 대응시키고 로터리 인코더의 CLK, DT는 각 8, 9번 핀에 대응시키겠습니다.(SW는 그냥 스위치처럼 사용하기에 편리하므로 이번 포스팅에서는 제외하겠습니다.) 목표는 로터리 인코더가 오른쪽으로 돌면 빨간불, 왼쪽으로 돌면 파란불이 들어오게 하는 것입니다.

#define LED_R 2 
#define LED_G 3 
#define LED_B 4 
#define CLK 8 
#define DT 9 

bool pre_clk = 0; 

void setup() { 
  pinMode(LED_R, OUTPUT); 
  pinMode(LED_G, OUTPUT); 
  pinMode(LED_B, OUTPUT); 
  pinMode(CLK, INPUT); 
  pinMode(DT, INPUT); 
  pre_clk = digitalRead(CLK); 
} 

void loop() { 
  bool cur_clk = digitalRead(CLK); 
  if(pre_clk != cur_clk){ 
    if(digitalRead(DT) != cur_clk){ 
      digitalWrite(LED_R, HIGH); 
      digitalWrite(LED_G, LOW); 
      digitalWrite(LED_B, LOW); 
    } 
    else{ 
      digitalWrite(LED_R, LOW); 
      digitalWrite(LED_G, LOW); 
      digitalWrite(LED_B, HIGH); 
    } 
  } 
  pre_clk = cur_clk; 
}

#Arduino #3D printer #아두이노 #3D프린터 # 3D프린터개발산업기사

 

millis() 함수와 delay() 함수의 차이

 

0. 서론(매우 빠른 작동속도를 가진 아두이노)

아두이노는 사실 1ms(1/1000초, 밀리세컨드, millisecond)보다 더 빨리 작동하고 있습니다. 물론 내부의 코드 길이나 상황에 따라 또한 어떤 구문을 실행하냐에 따라 걸리는 속도가 달라지기는하겠습니다만 이론적으로 대략 1/16000초의 속도로 한 명령어를 처리(16MHz)합니다.(이쪽으로 더 나가면 플립플롭(Flip-Flop), 래치(Latch), 클록스피드(Clock speed)와 같은 디지털 논리 회로의 영역으로 들어갑니다)

그래서 루프문 안에 시간을 지연시켜주지 않고 켰다 껐다하는 신호만 준다면 아주 단순한 LED를 깜빡이는 프로그램도 LED가 꺼졌다 켜졌다 하는게 눈으로 안보이고 LED가 계속 켜져있는 것처럼 보일겁니다. 약 0.001초마다 스위치를 계속 켰다껐다 하는거니까요.

 

1. 가장 쉽게 쓸 수 있는 delay함수

그래서 가장 쉽게 사용할 수 있는 명령 지연 함수가 delay함수입니다. 이 함수 안에 ms(밀리세컨드)단위의 시간을 입력하면 그 시간만큼 쉽게말해 프로세서는 "정지"하죠.

프로세서가 "정지"하기에 다음 명령 실행까지 시간적으로 지연이 되기는 합니다만, 그 "정지"해 있는 동안엔 프로세서가 아무 일도 못한다는 단점이 있습니다. 말그대로 일시정지하는거죠. 그 시간엔 그 어떤 다른 일도 하지 못합니다.

이런건 단순히 LED를 껐다 키거나 하는 단일 소자로 단일 명령을 시키는데는 전혀 걸림돌이 되지 않지만, 만약 "동시에" 일을 시켜야 하면 난감한 상황이 올겁니다.

 

가령 (delay가 적용된 깜빡이가 있는) 차를 타고가면서 왼쪽 깜빡이를 켰는데,

1) 라이트가 켜진 순간 차가 멈춰버립니다.(불 켜고 딜레이 0.5초=모든 걸 정지 0.5초)
2) 당황하여 깜빡이를 꺼보지만 라이트가 꺼지기 전까진 깜빡이가 꺼지지 않습니다.(깜빡이 스위치를 껐지만 불 꺼지고 딜레이 0.5초 가 지나기 전까지 프로세서는 어떤 입력도 못받아들임)
3) 그리고 깜빡이가 꺼지면서 차가 다시 움직이기 시작합니다.

난감하죠? 100% 교통사고 각입니다.

 

2. delay의 대안 millis함수

그래서 이를 해결하기위해 여러 방법들을 강구하게되고, 그 중에 하나가 millis함수를 이용하는 겁니다.
(여담으로 이를 "병렬처리"라 하고(순차처리=직렬처리, 동시처리=병렬처리), 이를 구현하기 위해서 CPU시스템적인 부분 뿐만 아니라(여기는 진짜로 각 클록 주파수 사이사이에 명령어들을 배치해서 "병렬처리인 척"하는 부분이긴 합니다만..) 각 언어마다 많은 방법들을 만들어냅니다. 싱크로, 메서드 등이 그것들인데 그건 여기서는 제쳐두죠)

아두이노 프로세서는 프로그램이 작동된 후 자동으로 ms단위로 프로그램이 실행되는 시간을 저장하고 있습니다.
따라서 어떤 A라는 순간의 millis값과 B라는 순간의 millis값을 비교하면 시간이 얼마나 흘렀는지 알 수 있게 되죠.(B ms - A ms = 걸린 시간 ms)
[이 부분은 매우 중요한게, millis뿐만 아니라 어떤 프로그램 언어를 사용하든 시간 차이(time delta)는 매우 중요한 개념이 됩니다.]

거기에 millis함수는 delay함수와 다르게 프로세서를 일정기간 멈추는 명령이 아닙니다. 말그대로 시간만 체크하는 명령어죠.(시계 한번 흘깃 보는 명령어입니다.) 이는 엄청난 강점이 됩니다.

 

가령 "10분 있다 엄마가 와서 책상에 앉아있나 확인할거야"라는 명령이 있었다고 보면,

delay: 10분동안 아무것도 안하고 내내 책상에 앉아서 멍때리기
millis: 10분동안 틈틈이 시간보면서, 그 안에서 책도보고 컴퓨터도하다가 10분째 착석

결과는 같지만 10분 활용이 다르죠. millis는 엄마의 명령시간 안에서 이런저런 일들을 "같이(병렬)" 처리했으니까요

 

따라서 millis를 사용하게 되면 경과시간을 알아내어서 시간에 따른 지연 조작을 할 수 있으면서도 내부 명령은 아두이노 속도대로 처리가 되는 병렬처리가 가능해집니다.(프로세서 자체가 멈춰서 시간을 지연하는거나, 사용자가 시계로 체크해서 일정 시간 후를 체크하는 것의 차이?)

 

3. delay함수와 millis함수의 활용

아두이노 자체 적인 개발 외에도 "3D프린터개발산업기사"의 실기부분에도 이 내용이 활용됩니다.

시험 항목을 보죠.

5) HEATING BED 설정
라) 설정온도인 30'C에 도달하면 LED는 R->G->B 순으로 500ms 간격으로 점등 되도록하며, 모터는 시계방향으로 계속적으로 동작 되도록 합니다.

이 부분인데요, 문제를 잘 보시면 LED가 500ms라는 시간을 가지고 점등이 되는 "와중에" 모터는 계속 돌아가야합니다. 병렬로 작동이 되어야 한다는 것이죠. 그럼 여기서는 millis함수를 써야겠죠.

 

반대로 굳이 millis함수를 쓸 필요가 없는 항목도 있습니다.

6) EMERGENCY 설정
나) ~ 근접센서에 물체 또는 손을 이용하여 접촉할 경우 ~ 회전 중인 모터가 정지되고, 부저를 1초 간격으로 5회 울린 후 ~

[회전 중인 모터 정지 -> 부저"" 1초 간격으로 5회 작동 -> ~~]의 순차적인 처리이기때문에 여기서는 굳이 millis안쓰고 delay로 써도 상관이 없습니다.

 

4. 실제 코드 작성

그러면 실제로 응용은 어떻게 해야할까요?

다른 부분은 다 제쳐두고, HEATING BED 설정의 라)항목만 실행하는 프로그램을 작성해보죠(온도가 30도에 도달하여 조건들을 실행하는 부분만 작성했습니다.)

#define LED_R 2  
#define LED_G 3  
#define LED_B 4

unsigned long start_time = 0;

void setup() {  
  pinMode(LED_R, OUTPUT);
  pinMode(LED_G, OUTPUT);
  pinMode(LED_B, OUTPUT);
}

void loop() {  
  start_time = millis(); // 이벤트 시작시간을 저장  
  unsigned long time_delta = millis() - start_time; // 시간차이(time_delta) 설정(현재시간-이벤트시작시간)  
  while(time_delta < 1500*3){ // 시작시간 기준(time_delta가 0부터 증가할 것이므로) (1500ms * 3번)의 시간동안 작동  
    if(time_delta%1500 < 500){ // 시간차이(이벤트 시작부터 진행된 시간)를 1500으로 나눠서 나머지가 500보다 작으면 
      digitalWrite(LED_R, HIGH); // 빨간불 켜기  
      digitalWrite(LED_G, LOW);  
      digitalWrite(LED_B, LOW);  
    }  
    else if(time_delta%1500 < 1000){ // 근데 나머지가 500 이상이고(위의 if가 거짓이기 때문에 else if로 왔으므로) 1000보다 작으면  
      digitalWrite(LED_R, LOW); // 빨간불 끄기  
      digitalWrite(LED_G, HIGH); // 초록불 켜기  
      digitalWrite(LED_B, LOW);  
    }  
    else{ // 그 외의 경우(위에 조건들이 모두 거짓일 때 else로 오므로 나머지가 1000이상인 경우)  
      digitalWrite(LED_R, LOW);  
      digitalWrite(LED_G, LOW); // 초록불 끄기  
      digitalWrite(LED_B, HIGH); // 파란불 켜기  
    }  
    // 모터 작동 코드 작성: delay가 없으므로 매 순간마다 모터가 작동  
    time_delta = millis() - start_time; // 코드 단위를 실행한 후 time_delta 재설정(이벤트 시작부터 진행된 시간 갱신)
  }  
  // 모든 불 끄기  
  digitalWrite(LED_R, LOW);  
  digitalWrite(LED_G, LOW);  
  digitalWrite(LED_B, LOW);  
  delay(2000); // 마무리 확인용 delay(세 번이 제대로 작동됐는지)  
}

이와 같은 코드가 작성될 것입니다.

 

5. 여담

참고로 millis함수는 프로그램 시작 후 50여일 이후의 시간도 ms단위로 기록할정도로(물론 50일경 오버플로나서 다시 0으로 돌아간다지만..) 큰 메모리 용량을 필요로 하기 때문에 unsigned long(4바이트)형태의 자료형을 가집니다.

사실 컴퓨터로 코딩할때는 큰 고려사항이 아닙니다만, 아주 제한된 메모리양과 처리속도를 가진 마이크로프로세서에 코딩할때는 전체적인 메모리와 처리속도를 모두 고려해야하는, 어떻게보면 컴퓨터로 프로그래밍하는 것보다 더 복잡한 과정을 거치게 됩니다.(자료형을 무엇을 쓸지, 프로그램 최적화는 어떻게 해야할지, 변수를 전역으로 두고 쓸지 지역으로 두고 쓸지 등..) 아두이노 기본 프로젝트 같은경우에야 문제가 안되겠지만 프로젝트가 커지면 문제죠. 따라서 프로젝트가 크지 않으면 그냥 unsigned long그대로 써주시되, 어차피 실행시간이 길지 않을 거고 다른 작업들로 메모리가 부족한 상황이다 싶으시면 int(2바이트) 자료형으로 써주시면 됩니다.

원넓이의 부정적분 구하기 - 2) 부정적분으로 구해보기

intetral root(1-x^2) dx

 

굉장히 오랜만에 다시 써보는 포스팅이네요.

저번 시간에 원 내부의 사다리꼴과 같은 도형의 넓이를 구하는 방법을 가장 기본적인 공식(부채꼴 공식+삼각형 공식)을 가지고 구해보았습니다.

원 내부의 하얀부분은 "활꼴의 절반"이라고 쉽게 설명이 가능한데, 그 반대편에 대한 용어는 따로 존재하지 않네요..

이번 시간에는 이것을 부정적분으로 x값을 가지고 바로 구하는 방법을 알아볼까 합니다.

저번에 각도 $\theta$를 부채꼴 부분으로 잡았는데, 이번에도 한번 이렇게 잡아서 수식을 전개해보려고 합니다.

부채꼴 부분이 $\theta$입니다.

일단 이렇게 특수한 상황에 가기 전에, 일반적으로 원의 넓이를 적분으로 어떻게 구하는지 다시 한번 살펴보도록하겠습니다.

 

자, 일단 원의 방정식은 $x^{2}+y^{2}=r^{2}$입니다. 저희는 $r$이 1인 단위원을 사용하기 때문에 식은 더욱 간단하게 $x^{2}+y^{2}=1$이 되겠네요.

이를 좀 더 보기 편하게 y에 대한 값으로 나타내면(x의 값에 따라 y값을 결정하는 방식) $y=\pm \sqrt{1-x^{2}}$으로 정리할 수 있습니다.

이 때 부호에 따라 양의 부호는 y축을 기준으로 0보다 위에 그려지는 반원을, 음의 부호는 아래쪽에 그려지는 반원을 의미합니다.

현재 저희는 위에 그려지는 반원 중에서도 1사분면 위의 사반원에 대해 구하려고 하고 있으므로, 이에 대한 적분 수식은 $\int \sqrt{1-x^2} \, dx$라고 볼 수 있습니다.

 

여기서 루트가 들어간 적분은 그냥 풀기에 너무 힘들기 때문에 x를 치환시켜 줄 것입니다.

예전에 고등학교 때 적분을 공부하면서 도대체 왜 치환하는지 의문을 가졌었는데, 실상은 치환해서 더 쉬운 형태로 만들어서 적분을 쉽게 만들기 위해서 하는 작업입니다 치환적분은!

 

루트를 없애줄 수 있으면서 적분 형태를 간단하게 해줄 수 있는 것이 무엇이 있나 한번 살펴보다보니, 언뜻 지나가는 공식이 있습니다.

$ sin^{2} \theta + cos^{2} \theta = 1 $이라는 공식이지요.(이 공식은 그냥 암기할 게 아니라, 너무 당연한 것을 표현한 것입니다. 아까 단위원의 방정식은 $x^{2}+y^{2}=1$이라고 했습니다. 이것은 원 위에서 무조건 성립하는 값입니다. 여기서 매개변수 표현법을 사용하면 $y=sin \theta, x=cos \theta$라고 했습니다. 즉, 단위원의 방정식에 매개변수 표현법을 사용하여 표현 방법만 x, y 변수가 아닌 $\theta$변수 로 바꿔준 것이 됩니다.)

이항해보면

$cos^{2} \theta =1-sin^{2} \theta$

제곱을 제거하면

$cos \theta = \sqrt{1-sin^{2} \theta}$

어디선가 많이 본 보양이지요?

즉, $x$를 $sin \theta$로 치환하면 자연스럽게 루트가 들어간 식이 정리되면서 적분이 가능한 형태로 바뀔 것 같습니다!

일단, $x$를 치환하면 $dx$도 같이 치환해 줘야 하므로 미분을 때려 봅시다.

$x=sin \theta$

$dx=cos \theta d\theta$

그럼 이렇게 준비된 x를 가지고 치환적분을 해보겠습니다.

$ \int \sqrt{1-x^{2}} dx $

$ \int \sqrt{1-sin^{2} \theta} cos \theta d\theta]_{x=sin \theta, dx=cos \theta d\theta} $

$ \int cos \theta \cdot cos \theta d\theta $

$ \int cos^{2} \theta \, d\theta $

여기서 다시 난관에 봉착합니다. $ cos^{2} \theta $를 적분하려면 많은 애로사항이 꽃핍니다.

일단 제곱을 떨어내야하는데, 어떻게 떨어내야할지 생각해봤더니... 배각공식을 역이용해서 떨어보겠습니다.

$ cos 2\theta \, = \, cos^{2} \theta - sin^{2} \theta $

참고로 배각공식은 삼각함수의 덧셈공식에서 온겁니다

$ cos (\alpha+\beta) = cos \alpha \cdot cos \beta - sin \alpha \cdot sin \beta $

자, 일단 $ cos^{2} \theta $를 $ cos 2\theta $로 바꿀 수 있는 실마리를 잡았는데, 뒤에 $ sin^{2} \theta $는 어떻게 없앨 수 있을까요?

여기서 삼각함수 무적의 공식 $ sin^{2} \theta + cos^{2} \theta = 1 $이 등장합니다.

$ sin^{2} \theta = 1 - cos^{2} \theta $로 만들고, 원 식에 대입하면

$ cos 2\theta = cos^{2} \theta - (1 - cos^{2} \theta) $

$ cos 2\theta = 2cos^{2} \theta - 1 $

우리는 $ cos^{2} \theta $를 바꿔야 하니 $ cos^{2} \theta $로 정리해보죠

$ cos^{2} \theta = \frac{cos 2\theta +1}{2} $

그럼 바로 대입하면

$ \int cos^{2} \theta \, d\theta $

$ \int \frac{cos 2\theta +1}{2} \, d\theta $

$ \frac{1}{2} (\int (cos 2\theta + 1) \, d\theta) $

$ \frac{1}{2} (\frac{1}{2}sin 2\theta + \theta) $ +C 생략

자, 드디어 적분을 완료해서 적분기호가 사라졌습니다.

그러나 $ sin 2\theta $는 뭔가 보기에 깔끔하지 않죠.. 똑같이 삼각함수 배각공식을 이용하여 단일 $ \theta $항으로 만들어줍시다.

$ sin 2\theta = 2 \cdot sin \theta \cdot cos\theta $

물론 이 배각공식도 덧셈공식에서 왔습니다.

$ sin (\alpha+\beta) = sin \alpha \cdot cos \beta + cos \alpha \cdot sin \beta $

따라서 원 식에 배각공식을 이용하여 풀어주면

$ \frac{1}{2} (\frac{1}{2}(2 \cdot sin \theta \cdot cos\theta) + \theta) $

$ \frac{1}{2} (sin \theta \cdot cos\theta + \theta) $

$ \frac{1}{2}sin \theta \cdot cos\theta + \frac{1}{2}\theta $

여기서

$ x = sin \theta $

$ \theta = arcsin x $

$ y = \sqrt{1-x^{2}} = cos \theta $

이므로, $ \theta $에 대한 식이 아닌, 원 x에 대한 식으로 바꿔주면

$ \frac{1}{2} \cdot x \cdot \sqrt{1-x^{2}} + \frac{1}{2} \cdot arcsin \, x $

이 나오고, 이는 이 전 포스팅의 결과 식과 완전히 같은 모양이 됩니다.

 

원넓이의 부정적분 구하기원넓이의 부정적분 구하기 - 1) 일반공식으로 구해보기

 

원넓이를 처음 배우는 것은 초등학교 때, $\pi$를 3.14 근사값으로 배우면서 공식 암기와 함께 시작한다.

이후 중학교 과정에서 수의 확장과 함께 무리수로 $\pi$를 배워 무리수가 들어간 공식으로 배우고, 고등학교에 이르러서는 적분을 통해 원의 넓이를 새삼스레 다시 구해본다.

결국 우리의 수학 교과과정은 원에 대해서 배우는 것이다 라고 말해도 과언이 아닐 정도이다.

 

여기서 고등학교에서 정적분으로 원의 넓이를 구할 때 기계적으로 치환, 공식대입, 정적분을 통해서 '아 그냥 그렇게 되는구나'라고 알고 넘어가는 사람들이 대다수 일 터.

이번에 뭔가 궁금증이 생겨서 다시 풀어보니, 예전엔 그냥 단순히 치환하고 공식을 대입해서 풀었던 여기에는 참 많은 이유들이 있다는 것을 알게되었다.

 

그리하여 부정적분을 통해서 왜 이렇게 치환하고 그것으로 어떻게 넓이를 구하는지 알아보고자 한다.

요런식으로 x가 0부터 0.5일때 원의 넓이를 구하는 방법을 알아보려고 한다.

 

물론 원은 사분원 넓이의 네배이니까 적분으로 원넓이 공식을 유도할 때 처럼, 반지름이 1인 단위원을 기준으로 하여 사분원의 넓이를 구하는 식으로 진행한다.

 

1] 일반식으로 원 넓이 구하기

부정적분으로 넘어가기 전에, 우리가 아는 일반 공식으로 $x$축에 대한 원의 넓이를 구할 수 있다.

딱 위의 그림에서와 같이 한번에 구하려면 왠지 적분을 써야 할 것 같지만,

호와 삼각형으로 나눠서 구한다면?

위 그림과 같이 부채꼴과 삼각형으로 나눠서 구한다면 쉽게 원의 부분 넓이를 구할 수 있다.

부채꼴의 넓이는 호도법으로 전체 각도($2\pi$(360도))에 대한 원 넓이 $\pi r^2$을 전체 각도에 대한 부분각도의 비 만큼 곱해주면( $\frac{\theta}{2\pi}$ ) 부채꼴의 넓이($\frac{\theta}{2\pi}*\pi r^2 = \frac{1}{2} r^2\theta$)가 나온다.

물론 여기서는 r(반지름)을 1로 놨으니 r 변수는 사라질 것이다.

부채꼴의 각도를 기준으로 놨으니, 이제 삼각형도 계산할 수 있다. 삼각형의 넓이는 가로*세로/2이다.

xy좌표축의 x와 y의 값을 $\theta$로 표현하면 단위원의 매개변수 표현법에 의거 $y=sin\theta, x=cos\theta$로 표현할 수 있다. 다만 여기서는 부채꼴의 각도를 기준으로 표현을 했으니 우리가 쓰는 좌표축의 $y$값이 $cos\theta$가 될것이며 $x$값은 $sin\theta$가 될 것이다. 뭔가 두 길이가 달라진 것 같지만, 사실상 직사각형에서의 삼각형이니 두개는 대칭이다.(엄밀히 매개변수 표현법으로 $y=sin\theta, x=cos\theta$이니, 위의 예에서 $y=sin(90-\theta), x=cos(90-\theta)$가 되고 각각, $y=sin(90-\theta)=cos\theta$, $x=cos(90-\theta)=sin\theta$의 관계가 성립한다.)

$ \theta $를 부채꼴의 각도로 놓았다.

수식으로 표현하면 $\frac{1}{2}sin\theta cos\theta$가 삼각형의 넓이가 될 것이다.

 

그리하여 두 식을 더한 $\frac{1}{2} \theta + \frac{1}{2}sin\theta cos\theta$ 값이 저 사다리꼴과 같은 도형의 부분 넓이가 된다는 것을 알았다.

 

여기까지 우리는 각도를 알면 그 각도에 해당하는 원의 사다리꼴과 같은 도형의 부분넓이를 구할 수 있게 되었으나, 반드시 각도를 알아야 한다는 단점이 있다.

 

여기서 x축 값 만으로 이 넓이를 구하려면, arcsin값만 알면 된다. 위의 그래프에서 x값과 같은 값을 나타내는 것은 $\theta$ 각도를 가지고 구한 $sin$값과 같다는 것을 알 수 있다. 그렇다면, 반대로 x값을 sin함수의 역함수인 arcsin에 넣어주면, 그 값에 해당하는 각도가 구해질 것이고, 그 각도값으로 부채꼴의 넓이 공식에 적용하면 부채꼴의 넓이를 알 수 있으므로 arcsin만 써주면 해결이다.

그렇다면 삼각형 부분은 어떻게 해결할 것인가?

사실 이 삼각형 부분은 x축 값이 밑변, 원의 방정식에서 x값을 대입한 값이 y값이다. 즉, y값은 $y = \sqrt{1-x^2}$이다.

이렇게 되면, 우리는 일반식으로 원에서의 사다리꼴과 같은 형태의 넓이를 x값에 따라 얻을 수 있는 일반식을 만들 수 있다.

 

$\frac{1}{2} arcsin\, x + \frac{1}{2}\cdot x \cdot \sqrt{1-x^2}$

 

다음 포스팅에서는 이를 부정적분으로 구해보는 시간을 가져볼 예정이다.

 

 

단순 선형 회귀에서 상관계수와 결정계수와의 관계(The relationship between a correlation coefficient and a coefficient of determination)

 

1) $ r(x, y) $

 $ r(x, y) = \frac{\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i-\bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 

2) $ r(\hat{y}, y) $

 $ r(\hat{y}, y) = \frac{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})(y_i-\hat{y}_i+\hat{y}_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i y_i-\bar{y} \hat{y}_i-\bar{y} y_i+\bar{y}^2)}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}[(y_i - \hat{y}_i)(\hat{y}_i-\bar{y})+(\hat{y}_i - \bar{y})^2]}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $
 $ \qquad \quad meanwhile, $
 $ \qquad \quad SST = SSR+SSE $ 
 $ \qquad \quad \sum_{i=1}^{n}(y_i - \bar{y})^2 = \sum_{i=1}^{n}((y_i - \hat{y}_i) + (\hat{y}_i - \bar{y}))^2 $ 
 $ \qquad \quad \qquad \qquad \qquad = \sum_{i=1}^{n}[e_i + (\hat{y}_i-\bar{y})]^2, e_i = (y_i-\hat{y}_i) $  
 $ \qquad \quad \qquad \qquad \qquad = \sum_{i=1}^{n}e_{i}^{2}+2\sum_{i=1}^{n}e_i(\hat{y}_i-\bar{y})+\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2 $  
 $ \qquad \quad \qquad \qquad \qquad \therefore \sum_{i=1}^{n}e_i(\hat{y}_i-\bar{y}) = 0 $ 
 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\bar{y})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \sqrt{\frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 

3) $ r(x, y) = r(\hat{y}, y) $

 $ \hat{y}_i = \beta_0 + \beta_1 x_i $

 $ x_i = \frac{\hat{y}_i - \beta_0}{\beta_1} $

 $ \bar x = \frac{1}{n}\sum_{i=1}^{n}\frac{\hat{y}_i - \beta_0}{\beta_1} $

 $ \quad = \frac{1}{n \beta_1}(\sum_{i=1}^{n}\hat{y}_i - n\beta_0) $

 $ \quad = \frac{1}{n \beta_1}\sum_{i=1}^{n}\hat{y}_i - \frac{\beta_0}{\beta_1} $

 $ r(x, y) = \frac{\sum_{i=1}^{n}(x_i-\bar{x})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i-\bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\frac{\hat{y}_i - \beta_0}{\beta_1}-\frac{1}{n \beta_1}\sum_{i=1}^{n}\hat{y}_i + \frac{\beta_0}{\beta_1})(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\frac{\hat{y}_i - \beta_0}{\beta_1}-\frac{1}{n \beta_1}\sum_{i=1}^{n}\hat{y}_i + \frac{\beta_0}{\beta_1})^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\frac{1}{\beta_1}\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}\frac{1}{\beta_1^2}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\frac{1}{\beta_1}\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)(y_i-\bar{y})}{\frac{1}{\beta_1}\sqrt{\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i - \beta_0-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i + \beta_0)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i-\frac{1}{n}\sum_{i=1}^{n}\hat{y}_i)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $
$ \qquad \quad y_i = \hat y_i + e_i $
$ \qquad \quad \sum_{i=0}^n y_i = \sum_{i=0}^n \hat y_i + \sum_{i=0}^n e_i $
$ \qquad \quad \sum_{i=0}^n y_i = \sum_{i=0}^n \hat y_i \; \because $ sum of errors = 0

 $ \qquad \quad = \frac{\sum_{i=1}^{n}(\hat{y}_i-\bar y)(y_i-\bar{y})}{\sqrt{\sum_{i=1}^{n}(\hat{y}_i - \bar y)^2}\sqrt{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 $ \qquad \quad = r(\hat y, y) = \sqrt{\frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sum_{i=1}^{n}(y_i-\bar{y})^2}} $

 

 $ \therefore r(x, y)^2 = r(\hat y, y)^2 = \frac{\sum_{i=1}^{n}(\hat{y}_i - \bar{y})^2}{\sum_{i=1}^{n}(y_i-\bar{y})^2} = \frac {SSR}{SST} = R^2 $ (only in simple regression)

피보나치 수열의 일반항과 비율의 극한(황금비)

 

피보나치 수열하면 모르는 사람이 없을 정도로 아주 간단한 규칙을 가진 수열이다.

바로 앞의 두 숫자를 더하면 다음 숫자가 나오는 수열이다.

여기서 앞의 두 숫자는 1, 1 이다.

 

그러면 바로 아래와 같은 수열이 나오게 된다.

 

1 1 2 3 5 8 13 ...

 

물론 이 수열의 극한은 무한대로 발산할 것이 분명하지만, 이 수열의 두 항의 '비율'의 극한은 수렴할까? 수렴한다면 어디로 수렴할까? 한번 확인해보자.

 

여기서 수열의 극한을 확인하려면 항상 일반항이 있어야 한다. 그러나 피보나치 수열은 '앞의 두 수를 더하면 다음 숫자가 된다'는 점화식만 있는 형태이다. 그러면 이 점화식을 통해서 일단 피보나치 수열의 일반항을 구해보도록 하자.

 

피보나치 수열의 일반항 구하기

1. 피보나치 수열의 점화식을 써보자.

  피보나치 수열은 이 전의 두 항을 더하면 다음 항이 되는 수열이다.

  $ a_{n+2} = a_{n+1} + a_{n} $

  이러한 형태 점화식만 있는 상태로 등차, 등비, 멱급수 등등등 그 어떤 수열의 형태도 아니다.

2. 일반식으로 확장

  이 수열의 상태만으로는 우리가 뭔가 찝쩍거릴 건덕지가 없으니까, 일반적인 일반식으로 확장한 뒤 근과 계수와의 관계(Vieta's formulas, 두 근을 $ \alpha, \; \beta $로 놓으면 $ px^2+qx+r=0 $의 방정식에서 $ \alpha + \beta = - \frac{q}{p}, \alpha \beta = \frac{r}{p} $의 관계가 생긴다는 공식)를 활용하여 근을 활용한 일반식으로 변화시켜 볼 것이다. 참고로 수열에서 항수는 차수가 다른 방정식과 동일하게 볼 수 있다.(더 자세한 내용은 >>점화식에서의 특성방정식(characteristic equation)<<에서 확인할 수 있다.)

  $ a_{n+2} = a_{n+1} + a_{n} \Rightarrow x^2 = x + 1 \Leftrightarrow x^2 -x -1 = 0 $와 같이 쓴뒤, $ px^2+qx+r=0 $의 일반식으로 변환시켜주면, $ p = 1, q = -1, r = -1 $이 되고, 근과 계수와의 관계에서 $ \alpha+\beta=-\frac{q}{p}=1, \; \alpha \beta = \frac{r}{p} = -1 $이다.

  이는 다시 쓰면, $ p $가 기본적으로 1이기 때문에 $ \alpha+\beta = -q, \; \alpha \beta = r $이라고 놓을 수 있다.

  그래서 일반식을 다시 근과 계수와의 관계를 이용하여 계수가 아닌 근의 형태로 표현해주면

  $ x^2-(\alpha+\beta)x+\alpha \beta = 0 $

  이를 다시 수열의 항을 통해서 표현해주면

  $ a_{n+2} = (\alpha+\beta)a_{n+1} - \alpha \beta a_n $과 같은 근을 활용한 일반식으로 확장이 되었다.

  이때, $ a_1 = 1, \; a_2 = 1, \; \alpha + \beta = 1, \; \alpha \beta = -1 $이다.

 

3. 반복되는 형태를 만들어서 계산가능하게 만들자

  과거 >>https://omnil.tistory.com/172<<포스팅에서 감마함수를 팩토리얼로 변환하는 과정과 같이 등식의 좌변과 우변이 반복되는 형태를 만들어주게 되면 계산이 되지 않을 것 같은 등식도 계산이 된다. 특히 최종단계를 우리가 직접 계산해서 값을 알 수 있다면 더더욱이 말이다. 참고로 감마함수는 n=1일때 값이 1이며, 우리는 뭔가 이런단계를 거치면 1항이 1, 2항이 1이라는 것을 통해서 값을 구할 수 있을 것이다.

  $ a_{n+2} = (\alpha+\beta)a_{n+1} - \alpha \beta a_n $

  $ a_{n+2} = \alpha a_{n+1} + \beta a_{n+1} - \alpha \beta a_n $

  $ a_{n+2}-\alpha a_{n+1} = \beta a_{n+1} - \alpha \beta a_n $

  $ a_{n+2}-\alpha a_{n+1} = \beta (a_{n+1} - \alpha a_n) $

  이렇게 변환하면 등식의 좌변과 우변의 공동되는 부분의 한 항 차이가 $ \beta $배라는 것을 알 수 있다. 바로 이것으로 우리가 아는 $ a_2 $와 $ a_1 $를 가지고 계산할 수 있는 형태로 반복계산이 가능하다.

  $ a_{n+2}-\alpha a_{n+1} = \beta (a_{n+1} - \alpha a_n) $

  $ a_{n+1}-\alpha a_{n} = \beta (a_{n} - \alpha a_{n-1}) $

  $ \Rightarrow a_{n+2}-\alpha a_{n+1} = \beta^2 (a_{n} - \alpha a_{n-1}) $

  이런식으로 $ \beta $배씩 곱해주면 우항을 a2와 a1항으로 계산할 수 있는 형태로 만들어줄 수 있다.

  이 때, $ \beta $가 몇개 생기는지는 항 수를 보고 생각하면 된다.

  우변의 맨 오른쪽항이 a2항에서 a1항으로 떨어지게 되면, $ \beta $는 한개가 생길 것이다. 즉, an항에서 a1항으로 떨어지면 (n-1)개의 $ \beta $가 생성될 것이다.

  $ a_{n+2}-\alpha a_{n+1} = \beta \cdot \beta^{n-1} \cdot (a_{2} - \alpha a_1) $

  $ a_{n+2}-\alpha a_{n+1} = \beta \cdot \beta^{n-1} \cdot (1 - \alpha \cdot 1) \leftarrow \because a_2=1,\; a_1=1 $

  $ a_{n+2}-\alpha a_{n+1} = \beta \cdot \beta^{n-1} \cdot \beta \leftarrow \because \alpha + \beta = 1 $

  $ a_{n+2}-\alpha a_{n+1} = \beta^{n+1} $

  즉  $ a_{n+2}-\alpha a_{n+1} $는 $ \beta $를 $ n+1 $번 곱한 것이니 항수 만큼 $ \beta $를 곱해주는 횟수가 된다는 것을 알 수 있다. 그렇다면 우리가 알고싶은 $ a_n $을 기준으로 하는 식으로 바꿔주면

  $ a_{n}-\alpha a_{n-1} = \beta^{n-1} \cdots (1)$

  이 되고, 이는 $ \alpha $ 변수와 $ \beta $ 변수를 바꾸어도 변수위치만 바뀐 동일한 식이 나온다.

  $ a_{n}-\beta a_{n-1} = \alpha^{n-1} \cdots (2)$

4. 연립하여 $ a_n $에 대한 일반항으로 풀어준다.

  변수 두개에 식이 두개가 나왔으니 연립방정식으로 풀 수 있다.

  (2)식에 $ \frac{\alpha}{\beta} $배를 해준 뒤 (1)-(2)식을 해줘서 $ a_{n-1} $항을 소거하여 $ a_n $의 일반항을 얻을 수 있다.

  $ a_{n}-\alpha a_{n-1} = \beta^{n-1} \cdots (1)$

  $ \frac{\alpha}{\beta}a_{n}-\alpha a_{n-1} = \frac{\alpha^{n}}{\beta} \cdots (2)$

  $ (1)-(2) $

  $ a_{n}-\frac{\alpha}{\beta}a_n = \beta^{n-1}-\frac{\alpha^n}{\beta} $

  $ \beta a_{n}-\alpha a_n = \beta^{n}-\alpha^n $

  $ (\beta -\alpha) a_n = \beta^{n}-\alpha^n $

  $ \therefore a_n = \frac{\beta^{n}-\alpha^n}{\beta -\alpha} $

  일반항 겟!!

  이제 일반항에 값만 대입해주면 진짜 n에 몇번째 항인지만 대입해주면 거기에 해당하는 값이 나오는 일반항이 된다.

5. $ \alpha $와 $ \beta $의 값 구하여 일반항에 대입하기

  여기서 $ \alpha $와 $ \beta $는 사실 $ x^2 -x -1 = 0 $의 두 근과 같기 때문에 근의 공식을 통하여 바로 값을 구할 수 있다.

  $ ax^2+bx+c = 0 $에서 두 근은 $ \frac{-b\pm \sqrt{b^2-4ac}}{2a} $식으로 구할 수 있다.
  $ \frac{1\pm \sqrt{5}}{2}, \; a=1, \: b=-1, \: c=-1 $

  $ \beta = \frac{1 + \sqrt{5}}{2}, \; \alpha = \frac{1 - \sqrt{5}}{2} $

  $ a_n = \frac{\left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n}{\frac{1+\sqrt{5}}{2}-\frac{1-\sqrt{5}}{2}} $

  $ \therefore a_n = \frac{1}{\sqrt{5}}\left(\left(\frac{1+\sqrt{5}}{2}\right)^n-\left(\frac{1-\sqrt{5}}{2}\right)^n\right) $

  이렇게 피보나치 수열의 일반항을 구했다!!

  근데, 유리수의 합으로 나타나는 피보나치 수열에서 일반항에 무리수가 들어가는 것이 신기하지 않은가!

 

피보나치 수열의 비율의 극한

이렇게 일반항을 구했으면 비율의 극한도 쉽게 구할 수 있다.

여기서는 더 큰수를 더 작은수로, 즉 $ \frac{a_{n+1}}{a_n} $의 비를 구할 것이다.

이번엔 비율을 구할 것이기 때문에, 숫자까지 들어간 일반항 보다는 문자로 표현된 더 한눈에 보기 간편한 일반항을 사용하여 극한을 구해볼 것이다.

1. 비율 식 구하기

  $ a_{n+1} = \frac{\beta^{n+1}-\alpha^{n+1}}{\beta -\alpha} $

  $ a_{n} = \frac{\beta^{n}-\alpha^{n}}{\beta -\alpha} $

  $ \frac{a_{n+1}}{a_n} = \frac{\frac{\beta^{n+1}-\alpha^{n+1}}{\beta -\alpha}}{\frac{\beta^{n}-\alpha^{n}}{\beta -\alpha}} $

  $ \frac{a_{n+1}}{a_n} = \frac{\beta^{n+1}-\alpha^{n+1}}{\beta^{n}-\alpha^{n}} $

  $ \frac{a_{n+1}}{a_n} = \frac{\beta-\alpha \left(\frac{\alpha}{\beta}\right)^n}{1-\left(\frac{\alpha}{\beta}\right)^{n}} $

2. 극한 씌워주기

  $ \lim_{n \to \infty} \frac{a_{n+1}}{a_n} = \lim_{n \to \infty} \frac{\beta-\alpha \left(\frac{\alpha}{\beta}\right)^n}{1-\left(\frac{\alpha}{\beta}\right)^{n}} $

  여기서 $ \beta = \frac{1 + \sqrt{5}}{2}, \; \alpha = \frac{1 - \sqrt{5}}{2} $이고, $ \beta $가 $ \alpha $보다 크기 때문에 $ \left(\frac{\alpha}{\beta}\right)^n $항은 $ n $이 무한대로 갈 때 값이 0으로 수렴한다.

  참고로 실제 값을 대입해서 계산해본 $ \left(\frac{\alpha}{\beta}\right) $ 값은 $ \frac{\sqrt{5}-3}{2} $이며, 그 값은 약 -0.382이다. 즉, 이 값을 무한대로 제곱할 경우 양과 음을 반복 진동하며 수렴한다.

  즉, 극한을 취한 뒤의 값은

  $ \lim_{n \to \infty} \frac{a_{n+1}}{a_n} = \frac{\beta-\alpha 0}{1-0} $

  $ \lim_{n \to \infty} \frac{a_{n+1}}{a_n} = \beta $

  $ \therefore \beta $

  이며, 이 $ \beta $값은  $ \frac{1 + \sqrt{5}}{2} $이므로, 피보나치 수열의 비율의 극한 값은 $ \frac{1 + \sqrt{5}}{2} $이 된다.

 

  그러면 이 값은 과연 무엇일까

 

황금비

  인생을 살면서 '황금비'라는 단어를 한번은 들어본다.

  황금비는 1: 1.618로써 근사하면 5:8정도의 비율을 나타내는 것을 황금비라고 한다.

  이것은 우리가 어떤 비율을 봤을 때 가장 아름답다고 생각하는 비율이라고 하는데, 이 1.618이라는 값은

  $ \frac{1 + \sqrt{5}}{2} $을 계산하면 나오는 값이다.

  즉, 피보나치 수열의 비율을 극한으로 가져가면 황금비를 가진다는 사실!

0에서 1사이의 x^x(x의 x승) 적분 값 계산(integral from 0 to 1 x to the power x dx)

1. Gamma function(감마함수)를 통하여 gamma(n+1)=n! 증명

  https://omnil.tistory.com/172에 증명 되어 있음

2. $ e^x $의 매클로린 급수(Maclaurin series)를 구하기

  매클로린 급수의 일반항

    $ p(x) = \sum_{n=0}^{\infty} \frac{f^{(n)}(0)}{n!}x^n $

  $ e^x $는 모든 미분 차수에 대하여 그대로 $ e^x $이며, $ x=0 $일 때 항상 1값을 갖는다.

  따라서, $ e^x $를 매클로린 급수로 전개하면

    $ e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} $

3. $ x^x $를 변환하기

  $ \int_0^1 x^x dx $

  $ = \int_0^1 e^{x\, ln\, x} dx \leftarrow \because x $ 는 $ e^{ln\, x} $와 같으므로, $ x^x = e^{x\, ln\, x} $

  $ = \int_0^1 \sum_{n=0}^{\infty} \frac{(x\, ln\, x)^n}{n!} dx \leftarrow \because e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} $ 이므로

  $ = \sum_{n=0}^{\infty} \frac{1}{n!} \int_{0}^{1} (x\, ln\, x)^n dx $

4. $ -ln\, x $를 $ t $로 치환하기

  $ -ln\, x = t $

  $ ln\, x = -t $

  $ x = e^{-t} $

  $ dx = -e^{-t}dt $

  $ x = 1 \rightarrow t = 0 $

  $ x = 0 \rightarrow t = \infty $

  $ \sum_{n=0}^{\infty} \frac{1}{n!} \int_{0}^{1} (x\, ln\, x)^n dx $

  $ = \sum_{n=0}^{\infty} \frac{1}{n!} \int_{\infty}^{0} e^{-nt}(-t)^n(-e^{-t}) dt $

  $ = \sum_{n=0}^{\infty} \frac{1}{n!} \int_{0}^{\infty} e^{-nt}(-t)^n(e^{-t}) dt $

  $ = \sum_{n=0}^{\infty} \frac{1}{n!} \int_{0}^{\infty} e^{-t(n+1)}(-t)^n dt $

  $ = \sum_{n=0}^{\infty} \frac{(-1)^n}{n!} \int_{0}^{\infty} e^{-t(n+1)}t^n dt $

5. $ t(n+1) $을 $ p $로 다시 치환해주기

  $ t(n+1) = p $

  $ t = \frac{p}{n+1} $

  $ dt = \frac{1}{n+1} dp $

  $ \sum_{n=0}^{\infty} \frac{(-1)^n}{n!} \int_{0}^{\infty} e^{-t(n+1)}t^n dt $

  $ = \sum_{n=0}^{\infty} \frac{(-1)^n}{n!} \int_{0}^{\infty} e^{-p} \frac{p^n}{(n+1)^n} \frac{1}{n+1} dp $

  $ = \sum_{n=0}^{\infty} \frac{(-1)^n}{n!} \int_{0}^{\infty} e^{-p} \frac{p^n}{(n+1)^{(n+1)}} dp $

  $ = \sum_{n=0}^{\infty} \frac{(-1)^n}{n!} \frac{1}{(n+1)^{(n+1)}} \int_{0}^{\infty} e^{-p} p^n dp $

  $ = \sum_{n=0}^{\infty} \frac{(-1)^n}{n!} \frac{1}{(n+1)^{(n+1)}} n! \leftarrow \because \int_{0}^{\infty}e^{-x}x^{n} dx = n! $

  $ = \sum_{n=0}^{\infty} \frac{(-1)^n}{(n+1)^{(n+1)}} \leftarrow \because n!$ 약분

  $ = 1 - \frac{1}{2^2} + \frac{1}{3^3} - ... $

6. 결과

  $ \simeq 0.783431$

+ Recent posts