<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>유리상자 속 이야기</title>
    <link>https://crystalcube.tistory.com/</link>
    <description>언제나 재미난것을 찾아서</description>
    <language>ko</language>
    <pubDate>Wed, 8 Apr 2026 11:09:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>unD3R</managingEditor>
    <image>
      <title>유리상자 속 이야기</title>
      <url>https://t1.daumcdn.net/cfile/tistory/13149C0B4C0C75C488</url>
      <link>https://crystalcube.tistory.com</link>
    </image>
    <item>
      <title>[Atmega328] 부트로더 및 스케치 업로드</title>
      <link>https://crystalcube.tistory.com/224</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이번 포스팅에서는 Atmega 328(P) 칩에 아두이노 부트로더와 스케치를 업로드 하는 방법에 대해서 이야기 하려고 한다. 인터넷에 있는 수 많은 포스팅과는 엄연히 차이가 있는데, Arduino UNO 가 필요 없다라는 것이다. 정말 순수하게 Atmega 328 칩만(?) 사용하는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;299&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSfQDS/btsK7H8NV0G/MCl4rjesvz1k5g9L27cb70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSfQDS/btsK7H8NV0G/MCl4rjesvz1k5g9L27cb70/img.png&quot; data-alt=&quot;이게 말이야 방구야?&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSfQDS/btsK7H8NV0G/MCl4rjesvz1k5g9L27cb70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSfQDS%2FbtsK7H8NV0G%2FMCl4rjesvz1k5g9L27cb70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;299&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;299&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이게 말이야 방구야?&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 기존 MicroController 를 제거할거면,, 뭣하러 복잡하게 회로 연결을 하나..? -_-a 그냥 해당 슬롯에 삽입하고 말지..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: #000000;&quot;&gt;부트로더 업로드&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노의 부트로더는 AT 의 수 많은 칩들과 마찬가지로 ISP 프로토콜을 이용한다. 매우 쉽다. 간단하다. Attiny MicroController 에 부트로더 올릴때와 동일하다. 그래서 부트로더를 업로드 하는 방법에 대해서는 간결히 설명하고, 스케치를 올리는 방법에 대해서는 다소 자세히 다루겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;준비물&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Atmega 328 은 Attiny 와 비교했을때, 약간의 준비물이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Crystal 16Mhz 1개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 22pF 세라믹 커패시터 2개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Arduino 아무거나~ (ISP 프로그래머로 사용 예정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반드시 세라믹 커패시터일 필요는 없는데, 22pF 와 같이 매우 작은 용량의 경우 대부분 세라믹이더라...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크리스탈이 꼭 필요한가? 라는 의문을 갖는다면 그러하다. 왜냐면,, 기본적으로 구매한 Atmega328 시리즈 대부분 초기에 External Clock 으로 세팅되어 있다. 그래서 외부 클럭(crystal)이 반드시 필요하다. 이것 없이 어떻게든 해 보려고 했는데 안되더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시라도 crystal 없이 시도했고, 성공한 케이스가 있다면 공유해 주면 감사하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;Arduino as ISP&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;굳이 이것까지 설명해야 하는가 싶지만, 그래도 순서상 설명해 본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;1109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXHgRr/btsK7fkpIjR/mb7JnsNrVJKMHE8TJABep0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXHgRr/btsK7fkpIjR/mb7JnsNrVJKMHE8TJABep0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXHgRr/btsK7fkpIjR/mb7JnsNrVJKMHE8TJABep0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXHgRr%2FbtsK7fkpIjR%2Fmb7JnsNrVJKMHE8TJABep0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;1109&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;1109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;해당 샘플을 불러온 후, 연결된 임의의 Arduino 에 스케치를 올린다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;끗.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;&lt;br /&gt;배선방법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;별것 없다. 인터넷에 나오는 수 많은 그림과 같이 하면 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다시 말하지만, Arduino UNO 가 아니어도 된다. 필자의 경우에는 Arduino Nano 로 진행하였다. AtMega256 이든 Leonardo 든 뭐든 무관하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPNJ07/btsK7CNfasB/hNUHBkvcHaokspwnauQuSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPNJ07/btsK7CNfasB/hNUHBkvcHaokspwnauQuSK/img.png&quot; data-alt=&quot;참고로 1번핀에 PullUp 저항이 달려 있는데, 굳이 필요 없다. (내부 PullUp 으로 동작하는것으로 예상)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPNJ07/btsK7CNfasB/hNUHBkvcHaokspwnauQuSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPNJ07%2FbtsK7CNfasB%2FhNUHBkvcHaokspwnauQuSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;829&quot; height=&quot;593&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;참고로 1번핀에 PullUp 저항이 달려 있는데, 굳이 필요 없다. (내부 PullUp 으로 동작하는것으로 예상)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;부트로더 올리기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아두이노 IDE 에 아래 URL 을 추가하여, Boards Manager 를 추가한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VJXhA/btsK8sXlvkY/pnD9Yao6M3NC7WEjusFjJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VJXhA/btsK8sXlvkY/pnD9Yao6M3NC7WEjusFjJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VJXhA/btsK8sXlvkY/pnD9Yao6M3NC7WEjusFjJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVJXhA%2FbtsK8sXlvkY%2FpnD9Yao6M3NC7WEjusFjJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1185&quot; height=&quot;786&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;786&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후에 Boards Manager 에서 MiniCore 를 검색하여 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4JWD0/btsK6sqZZb4/kzkckUEXLVoOMwKzxQmjtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4JWD0/btsK6sqZZb4/kzkckUEXLVoOMwKzxQmjtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4JWD0/btsK6sqZZb4/kzkckUEXLVoOMwKzxQmjtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4JWD0%2FbtsK6sqZZb4%2FkzkckUEXLVoOMwKzxQmjtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;485&quot; height=&quot;598&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;준비가 끝났다. 이제 아래와 같이 설정하고, Burn Bootloader 를 클릭하면 정상적으로 BootLoader 가 Atmega328 에 올라간다. 필자의 경우 Atmega328P 라서 아래와 같이 설정하였다. 그리고 Clock 은 External 16 MHz 로 설정하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cixNgW/btsK7bvw4H6/dpdZSHMHhp0C1TQu3Q0C80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cixNgW/btsK7bvw4H6/dpdZSHMHhp0C1TQu3Q0C80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cixNgW/btsK7bvw4H6/dpdZSHMHhp0C1TQu3Q0C80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcixNgW%2FbtsK7bvw4H6%2FdpdZSHMHhp0C1TQu3Q0C80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;625&quot; height=&quot;740&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;740&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지는 큰 문제없이 잘 된다. 쉽다. 인터넷에 수 많은 자료가 있으니까ㅡ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1297&quot; data-origin-height=&quot;1002&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TBDXK/btsK6T2YsvY/lJxI27GxNJEI0fejx04KXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TBDXK/btsK6T2YsvY/lJxI27GxNJEI0fejx04KXK/img.png&quot; data-alt=&quot;매번 연결하기 귀찮으니, 이렇게 해 두면 편하다. 배선은 믿지 말자(잘못 연결해서 기판 뒤에 땜빵했음)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TBDXK/btsK6T2YsvY/lJxI27GxNJEI0fejx04KXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTBDXK%2FbtsK6T2YsvY%2FlJxI27GxNJEI0fejx04KXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1297&quot; height=&quot;1002&quot; data-origin-width=&quot;1297&quot; data-origin-height=&quot;1002&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;매번 연결하기 귀찮으니, 이렇게 해 두면 편하다. 배선은 믿지 말자(잘못 연결해서 기판 뒤에 땜빵했음)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: #000000;&quot;&gt;스케치 업로드&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자, 이제 Atmega328 에 아두이노 부트로더를 올렸다. 스케치는 어떻게 올려야 할까? 앞서 이야기한대로 인터넷에 나온 자료는 온통 보유하고 있는 Arduino UNO 에 MicroController 를 제거한 후, Atmega328 과 연결하든 꼽든 하라고 한다. &lt;b&gt;아니;;; 찌..발..&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;나는 Arduino UNO 가 없다니까???&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;준비물&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 부트로더를 올릴때와 마찬가지로 아래 것들이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Crystal 16Mhz 1개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 22pF 세라믹 커패시터 2개&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Arduino 아무거나~ (필자의 경우 Nano 를 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;배선방법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에 ESP8266 의 펌웨어 업그레이드때와 비슷하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://crystalcube.co.kr/215&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://crystalcube.co.kr/215&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;요컨데 보유한 Arduino 보드를 UART to TTL 로 사용할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdnQdh/btsK77eON4x/wPOGDzdwK1VjkjhZJ3iZ60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdnQdh/btsK77eON4x/wPOGDzdwK1VjkjhZJ3iZ60/img.png&quot; data-alt=&quot;Atmega328&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdnQdh/btsK77eON4x/wPOGDzdwK1VjkjhZJ3iZ60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdnQdh%2FbtsK77eON4x%2FwPOGDzdwK1VjkjhZJ3iZ60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;885&quot; height=&quot;602&quot; data-origin-width=&quot;885&quot; data-origin-height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Atmega328&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;647&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nT3v2/btsK7JyPd5Y/hOi3HSgxlhSK9jThnOHSkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nT3v2/btsK7JyPd5Y/hOi3HSgxlhSK9jThnOHSkK/img.png&quot; data-alt=&quot;Arduino Nano&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nT3v2/btsK7JyPd5Y/hOi3HSgxlhSK9jThnOHSkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnT3v2%2FbtsK7JyPd5Y%2FhOi3HSgxlhSK9jThnOHSkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;647&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;647&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Arduino Nano&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Arduino Nano 의 +5V 를 Atmega328 의 VCC 와 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Arduino Nano 의 GND 를 Atmega328 의 GND 와 연결한다. (위 사진상 우측의 GND)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Arduino Nano 의 RESET(좌측)을 Arduino Nano GND(좌측)에 연결하여, &lt;span style=&quot;color: #ee2323;&quot;&gt;항상 RESET 상태를 유지하도록 한다.&lt;/span&gt; UART to TTL 로 사용하기 위한 목적.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Arduino Nano 의 RX 를 Atmega328 의 RX 와 맞물린다. &lt;span style=&quot;color: #ee2323;&quot;&gt;(RX-TX 연결이 아닌 RX-RX 임에 주의)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Arduino Nano 의 TX 를 Atmega328 의 TX 와 맞물린다. &lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;(TX-RX 연결이 아닌 TX-TX 임에 주의) &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;6. 부트로더를 올릴때와 마찬가지로 Atmega328 에 Crystal 과 커패시터를 연결한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;스케치 업로드&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 아래처럼 설정하고, Blink Example 스케치를 올려보자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;1150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHTvBa/btsK7fEKvH4/QSQMcfbo6ggxVhaKXY7t0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHTvBa/btsK7fEKvH4/QSQMcfbo6ggxVhaKXY7t0K/img.png&quot; data-alt=&quot;응~ 당연히 안돼~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHTvBa/btsK7fEKvH4/QSQMcfbo6ggxVhaKXY7t0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHTvBa%2FbtsK7fEKvH4%2FQSQMcfbo6ggxVhaKXY7t0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1171&quot; height=&quot;1150&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;1150&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;응~ 당연히 안돼~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의할점은 Programmer 을 더 이상 Arduino as ISP 로 하면 안된다. 알다시피 지금 연결한 Arduino Nano (꼭 Nano 일 필요는 없음)는 더 이상 ISP 로 동작하는게 아니다. UART to TTL 로서 동작하는 것이다. 그냥 Bypass 를 위해 연결된 장치일 뿐이다. 그러므로 AVRISP mkll 로 선택한다.&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하고 스케치를 올리면, 당연히 안된다. 헤헤..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 Retry 를 10번 수행 후, 실패할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한게 있는데, 바로 Reset 이다. 스케치를 올리기 위해서는 해당 Micro Controller 를 RESET 해 주어야 한다.&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;span style=&quot;color: #ee2323;&quot;&gt;Atmega328 의 RESET(1번핀)을 적절한 타이밍에 GND 와 연결/제거해 주어야 한다&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;.&lt;/span&gt;&lt;/b&gt; 필자의 생각에는 Arduino Nano 의 어떤 핀과 적절히 연결해 주면 될것 같은데, 아직 찾지 못했다. 혹시 알고 있다면 공유해 주길 바란다. 아무튼 나는 그래서 수동으로.... 적절한 타이밍에... 직접 RESET 과 GND 를 연결해주었다가 땐다. -_-&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 타이밍을 잡는게 다소 어려운데, 여러번 하다보면 감이 잡힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대략적으로라도 타이밍에 대한 설명을 하자면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 IDE 에서 Ctrl+ U 를 누르고 나면, 컴파일 후에 업로드가 진행된다. 이때 로그를 보면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KneWN/btsK8v0QDYb/LllH72r7i9dKlvlFv9Khsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KneWN/btsK8v0QDYb/LllH72r7i9dKlvlFv9Khsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KneWN/btsK8v0QDYb/LllH72r7i9dKlvlFv9Khsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKneWN%2FbtsK8v0QDYb%2FLllH72r7i9dKlvlFv9Khsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1420&quot; height=&quot;792&quot; data-origin-width=&quot;1420&quot; data-origin-height=&quot;792&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색으로 박스친 'Compiling core...' 출력 후, 잠시 뒤에 아래 녹색 영역이 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;타이밍은 다음과 같다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Atmega328 의 RESET(1번핀)와 GND(22번핀)을 점퍼로 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Alt + U 를 누른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Compiling core...이 출력되는것을 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 다음 녹색 영역이 출력되는 순간, 1의 점퍼를 제거한다. (정확히는 Compiling 이 끝나고 Uploading 프로세스 진행 직전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타이밍에 대한 좀 더 정확한 정보는 아래 유튜브 영상을 참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtu.be/cvyq-qohljg?si=TkTl60iH7jV_CldZ&amp;amp;t=170&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/cvyq-qohljg?si=TkTl60iH7jV_CldZ&amp;amp;t=170&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;1083&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ChrLs/btsK7HOwybw/6Gkt0yp05SjSUXqfyCvgh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ChrLs/btsK7HOwybw/6Gkt0yp05SjSUXqfyCvgh0/img.png&quot; data-alt=&quot;짧은 파란색 점퍼와 같이 RESET 과 GND 에 연결해 두었다가, 서술한 타이밍에 제거한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ChrLs/btsK7HOwybw/6Gkt0yp05SjSUXqfyCvgh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FChrLs%2FbtsK7HOwybw%2F6Gkt0yp05SjSUXqfyCvgh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1518&quot; height=&quot;1083&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;1083&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;짧은 파란색 점퍼와 같이 RESET 과 GND 에 연결해 두었다가, 서술한 타이밍에 제거한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 아래와 같이 문제없이 스케치가 Atmega328 에 올라간다. 배선에 문제가 없다면 분명히 된다. 포기하지 말고 시도하자...ㅎ.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uCqXQ/btsK8unkAda/s4zXiGHljbBVo4L6TvEwP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uCqXQ/btsK8unkAda/s4zXiGHljbBVo4L6TvEwP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uCqXQ/btsK8unkAda/s4zXiGHljbBVo4L6TvEwP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuCqXQ%2FbtsK8unkAda%2Fs4zXiGHljbBVo4L6TvEwP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1753&quot; height=&quot;1453&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기판으로 만들면 이렇게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;927&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z2qcB/btsK8vgxRCw/HZTzf1CgA7bNKZdd68Ky81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z2qcB/btsK8vgxRCw/HZTzf1CgA7bNKZdd68Ky81/img.png&quot; data-alt=&quot;Sketch Programmer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z2qcB/btsK8vgxRCw/HZTzf1CgA7bNKZdd68Ky81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz2qcB%2FbtsK8vgxRCw%2FHZTzf1CgA7bNKZdd68Ky81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1270&quot; height=&quot;927&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;927&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Sketch Programmer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Atmega328 에 올릴 경우에는 아래 스위치를 통해 USB to TTL 로 전환하고, Ctrl+U 로 업로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Attiny 에 올릴 경우에는 아래 스위치를 통해 ISP 로 전환하고, Ctrl+Shift+U 로 업로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;동작 확인&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Atmega328 의 경우, 소스코드에 정의된 LED_BUILTIN 는 PB5 (19번핀)이다. LED 를 연결하면, 정상적으로 1초 주기로 깜빡이는 것을 확인 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1092&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCuVHH/btsK7bhZyl7/2arb1KWICKBwvL4GIn2kg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCuVHH/btsK7bhZyl7/2arb1KWICKBwvL4GIn2kg1/img.png&quot; data-alt=&quot;LED 가 1초 주기로 깜빡인다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCuVHH/btsK7bhZyl7/2arb1KWICKBwvL4GIn2kg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCuVHH%2FbtsK7bhZyl7%2F2arb1KWICKBwvL4GIn2kg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1830&quot; height=&quot;1092&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1092&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;LED 가 1초 주기로 깜빡인다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;마무리&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 타이밍을 맞춰서 RESET 연결하는 방법에 대해서는 좀 더 고민해 봐야겠다. 추후 알게되면 해당 포스트에 추가로 코멘트 하도록 하겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아무튼 이렇게해서 Atmega328 칩만 구매하여, 독립적인 회로를 구성할 수 있게 되었다. 정확하지 않지만 개당 2천원 내외로 구매했던것 같은데, Attiny85 랑 가격 차이가 별로 없어 보인다. 크기가 작아서 Attiny가 비싼걸까..? 핀 수는 Atmega328 이 훤씬 더 많은데...&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt;&quot;&gt;+추가내용&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Arduino Nano 의 경우 Atmega328 칩을 사용한다. 그리고 해당 포스팅에서는 다른 Atmega328 칩에 sketch 를 업로드 하는 방법에 대해 설명하고 있다. 그러다보니 단순히 Upload Sketch 를 수행하면, 다른 Atmega328 이 아닌 Arduino Nano 에 sketch 가 올라가는 문제가 발생했다. 그래서 Arduino Nano 를 USB to TTL 로 만들고, 적절한 타이밍이 RESET 을 점프 시켜서 sketch 를 올렸다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러나 부트로더를 올릴때와 동일한 회로 구성을 이용하여 스케치를 올리면, Atmega328 에 정상적으로 올라간다. 하지만, 치명적인 문제가 있는데 &lt;span style=&quot;color: #ee2323;&quot;&gt;연결된 Arduino Nano 에도 스케치가 동일하게 올라간다&lt;/span&gt;. 즉, Arduino as ISP 스케치가 삭제되고 두 Micro Controller 에 동일한 스케치가 덮어써진다.&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>ATMEGA328</category>
      <category>부트로더</category>
      <category>스케치</category>
      <category>아두이노</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/224</guid>
      <comments>https://crystalcube.tistory.com/224#entry224comment</comments>
      <pubDate>Thu, 5 Dec 2024 12:17:38 +0900</pubDate>
    </item>
    <item>
      <title>싸울아비 조이스틱, Windows 10 이상에서 동작하게 하기</title>
      <link>https://crystalcube.tistory.com/223</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;예전에 아주 오래전에 싸울아비 조이스틱을 샀었다. 10년은 족히 넘은 것으로 기억한다. 이후 결혼을 하고, 아이를 낳고 살다가 어느날 오후 아이들에게 추억의 오락실 게임을 시켜주려고 했다. 그러다 문득 그 녀석. '싸울아비 조이스틱' 이 생각났다. 거실 TV 에 작은 PC - 정확히는 라떼판다 - 를 꺼내어 연결해 둔게 있어서 여기 싸울아비 조이스틱만 연결하면 될 거라고 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFGxa4/btsKkjBL8JL/uKPSuh9FCjKzKSKNV52Kd1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFGxa4/btsKkjBL8JL/uKPSuh9FCjKzKSKNV52Kd1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFGxa4/btsKkjBL8JL/uKPSuh9FCjKzKSKNV52Kd1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFGxa4%2FbtsKkjBL8JL%2FuKPSuh9FCjKzKSKNV52Kd1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;2268&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;하.지.만.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;아무리 연결을 해 보아도, Plug And Prey 를 해 보아도 Prey 가 듣질 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;인터넷을 찾아보니 Windows 10 미만으로 하위호환 설정을 하라는 둥, 드라이버를 다시 설치하라는 둥.. 온갖 민간요법에 가까운 솔루션들이 넘쳐 났지만 그 어느하나 되는게 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이후 제대로 된 자료를 찾아보니, '싸울아비 온라인' 의 경우 USB 1.x 버전이며 요즘 나오는 메인보드들은 대부분 USB 2.0 이상부터 지원한다고 한다. USB 1.x 는 너무 오래된 스펙이라 지원 자체를 안 한다고...ㅠㅠ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 Windows 10 의 문제가 아니라, 하드웨어 자체의 호환성 문제라는 것. 즉,, 소프트웨어 적으로는 해결이 불가능하다는 이야기지.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: #000000;&quot;&gt;하드웨어 호환성 문제로 요즘 PC 에서는 사용이 불가&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다. 하드웨어 호환성 문제이니까, 이건 하드웨어로 쇼부를 봐야 한다는 그런 당연한 이야기다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떡하지? 어떡하긴 뭘 어떡해. 고치면 되지. 하드웨어적으로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;그까이꺼,, 대충.. 만들면 되는거 아녀?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각을 해 보자. 조이스틱이란 무엇인가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'버튼을 누른다.', '그 정보를 PC 로 보낸다.' 매우 단순하지 않은가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 재료들을 생각해 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼과 스틱이 필요하다. 준비 되었는가? ㅇㅋ. 싸울아비!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼의 상태를 PC 로 보내려면? 음.. 아두이노 쓰면 되지!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노를 PC 에서 HID (Human Interface Device) 로 인식하게 하려면? 아두...이노..?!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료를 찾아보니 아두이노 중에서 Atmega 32U4 칩셋을 쓰는 녀석이 가능하다고 한다. HID 회로가 내장 되어 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보니까 크기도 작아서 '싸울아비 온라인' 어딘가에 구겨 넣기도 적당하군.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cClr50/btsKmiVoNgw/XFjTqH779KkW2oPXAkyTVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cClr50/btsKmiVoNgw/XFjTqH779KkW2oPXAkyTVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cClr50/btsKmiVoNgw/XFjTqH779KkW2oPXAkyTVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcClr50%2FbtsKmiVoNgw%2FXFjTqH779KkW2oPXAkyTVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1065&quot; height=&quot;762&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노는 Micro 를 사용할 것이고, Pinout 을 보면 위와 같다. 사울아비 온라인의 경우 버튼 10개와 4방향 스틱으로 구성 되어 있으므로, 총 14개의 Pin 이 필요하다. Digital 2 ~ 10 번핀과 16번 핀으로 10개의 버튼을 커버할 것이다. 그리고 Analog 0 ~ 3 까지 4 개의 Pin 을 스틱을 위해 사용할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;내장(?)을 뜯어내자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;외과적인 수술을 먼저 수행하기로 했다. 왜? 쉬우니까 ㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lU1FQ/btsKkeU1uFi/MYbYc2niySEhNnw8uGLvZk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lU1FQ/btsKkeU1uFi/MYbYc2niySEhNnw8uGLvZk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lU1FQ/btsKkeU1uFi/MYbYc2niySEhNnw8uGLvZk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlU1FQ%2FbtsKkeU1uFi%2FMYbYc2niySEhNnw8uGLvZk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;2268&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;안에 있던 기판을 다 뜯어내었다. 잘...하고 있는거겠지?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;기판이 들어갈만한 위치를 찾다보니 후보지가 두 곳 정도 보였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3603&quot; data-origin-height=&quot;2133&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUKwof/btsKknYaiHw/n3Eb5rNf6oJOStkMxNRQn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUKwof/btsKknYaiHw/n3Eb5rNf6oJOStkMxNRQn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUKwof/btsKknYaiHw/n3Eb5rNf6oJOStkMxNRQn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUKwof%2FbtsKknYaiHw%2Fn3Eb5rNf6oJOStkMxNRQn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3603&quot; height=&quot;2133&quot; data-origin-width=&quot;3603&quot; data-origin-height=&quot;2133&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;A 후보지의 경우, B 에 비하여 공간이 협소하다. 즉, 매우 작게 만들어서 우겨 넣어야 한다. 반면, B 는 A 에 비하여 다소 넓은 공간 확보가 가능하다. 다만 지형에 이상한 불필요한 구조물이 있어서 철거를 추가적으로 해야 한다. 철거의 문제라기보다 본래의 기판에 물리적으로 손상을 가해야 한다는 점이 내키지 않았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;포스팅 마지막에 자세히 후술하겠지만, A 에 넣기 위해서 시도를 했었다. 그러기 위해 기판을 매우매우 작게 만들어야 했고, 모든 소자를 우겨 넣었다. 결국은 실패하여 B 에 위치 시키기로 하고 다시 만들었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;자, B 에 넣기로 하고 회로구성을 해 보자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;어떻게 회로를 구성할까?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나는 순수 소프트웨어쟁이다. 하드웨어는 어디까지나 취미일 뿐,, 본업은 소프트웨어 개발자. 앱/서버/웹 등등.. 하드웨어/전자랑은 거리가 멀다. 중등 교육을 받았다면 모두가 아는 F=MA, V=IR 과 키르히호프의 법칙 정도가 내가 아는 전부다 ㅎㅎㅎ.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;풀업회로로 구성하면, 아두이노 내부적으로 풀업저항이 있어서, 회로 구성이 매우매우 간단해 질 것으로 생각했다. 하지만,, 디바운싱 문제가 남아 있었다. 기계식 버튼을 생각해보자. 버튼이 눌리려면 회로가 접지 되어야 한다. 두 개의 구리판이 붙어있으면 눌린 것이고, 떨어지면 눌리지 않은 거겠지. 그런데 아날로그 세상에서는 생각처럼 이게 간단하지 않다. 어디까지 가까워 졌을때 붙은 것이고, 어디까지 멀어져야 떨어진 것이라고 할 수 있을까? 그리고 진동에 의해 순간적으로 버튼이 붙었다 떨어졌다를 반복하는 시점이 존재한다. 이를 채터링이라고 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;684&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZkqeX/btsKmjtfmTl/oicCO3ea3JbuV8mpx4zUwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZkqeX/btsKmjtfmTl/oicCO3ea3JbuV8mpx4zUwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZkqeX/btsKmjtfmTl/oicCO3ea3JbuV8mpx4zUwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZkqeX%2FbtsKmjtfmTl%2FoicCO3ea3JbuV8mpx4zUwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;985&quot; height=&quot;684&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;684&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저 바운싱을 제거하기 위해서 어떻게 해야 하는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;채터링, 바운싱, 디바운싱&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가장 손쉽게 해결 할 수 있는것은 버튼의 상태를 10~30 ms 정도 단위로 delay 를 주면서 읽는 것이다. 그러면 위의 현상을 어느정도 제거할 수 있다. 100%가 아닌 어느정도라고 표현한 이유가 있다. 만약 버튼을 누르는 속도가 30 ms 이하라면, 입력이 무시된다는 뜻이다. 즉,, 사람의 반응속도를 추정하고, 이보다 빠른 입력을 강제로 막는 방법으로 볼 수 있겠다. 재수가 없어서 바운싱이 30 ms 보다 길어진다면, 의도한대로 동작하지 않게 된다. 겁나,,찝찝하지 않은가?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;소프트웨어 개발자라면,, 상당히 내키지 않는 방법이라고 할 수 있겠다. ㅠㅠ&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 효과적인 방법은 무엇이 있을까? 바로 RC 필터 회로를 구성해서 넣는 것이다. RC 필터에는 RC 로우패스 필터와 RC 하이패스 필터가 있다. 하드웨어적으로 설명하자면 어느 주파수 대역의 노이즈를 없앨것인지, 통과시킬건지에 대한 차이라고 할 수 있겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;243&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UqLMZ/btsKk5iEYTL/3pX0wkp3hu64FcxcwDa1X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UqLMZ/btsKk5iEYTL/3pX0wkp3hu64FcxcwDa1X1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UqLMZ/btsKk5iEYTL/3pX0wkp3hu64FcxcwDa1X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUqLMZ%2FbtsKk5iEYTL%2F3pX0wkp3hu64FcxcwDa1X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;435&quot; height=&quot;243&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;243&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 커패스터와 저항은 어떤 값을 써야 하는가? 내가 제거해야 하는 주파수는 몇 Hz 인가? 계산 방법이 쉽지 않다. 나는 구글링을 통해서 적절한 값을 찾았고, 계산은 아래 사이트를 통해서 손쉽게 하였다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcSocz/btsKlFwGCu6/LuZeXJreaOadGagj1ib6ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcSocz/btsKlFwGCu6/LuZeXJreaOadGagj1ib6ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcSocz/btsKlFwGCu6/LuZeXJreaOadGagj1ib6ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcSocz%2FbtsKlFwGCu6%2FLuZeXJreaOadGagj1ib6ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;166&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;166&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계산기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.digikey.kr/ko/resources/conversion-calculators/conversion-calculator-low-pass-and-high-pass-filter&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.digikey.kr/ko/resources/conversion-calculators/conversion-calculator-low-pass-and-high-pass-filter&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 더하여, 하나를 추가해 주면 더욱 완벽해 진다. 그것은 바로 NOT 게이트(Invertor)를 붙이는 것이다. 1을 넣으면 0 이 나오고, 0을 넣으면 1 이 나오는 기본적인 게이트 소자이다. 이게 왜 도움이 되는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 소자인 74HC14 의 스펙을 보면 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;409&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MlSxV/btsKk1tJfhl/emc0JoqhAT3X0SKxMqj0yK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MlSxV/btsKk1tJfhl/emc0JoqhAT3X0SKxMqj0yK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MlSxV/btsKk1tJfhl/emc0JoqhAT3X0SKxMqj0yK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMlSxV%2FbtsKk1tJfhl%2Femc0JoqhAT3X0SKxMqj0yK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;883&quot; height=&quot;409&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;409&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1788&quot; data-origin-height=&quot;1333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdDVQS/btsKkXrl7CG/64ikMzE01kvUMkIM0CSwHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdDVQS/btsKkXrl7CG/64ikMzE01kvUMkIM0CSwHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdDVQS/btsKkXrl7CG/64ikMzE01kvUMkIM0CSwHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdDVQS%2FbtsKkXrl7CG%2F64ikMzE01kvUMkIM0CSwHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1788&quot; height=&quot;1333&quot; data-origin-width=&quot;1788&quot; data-origin-height=&quot;1333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.3 ~ 1.2 V 입력이면 LOW (0) 으로 인식하고, 1.5 v 이상이면 HIGH (1) 로 인식이 된다. 1.2 와 1.5 사잇값이면 변동이 없다라는 거겠지. 즉,, 디바운싱 효과를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;아두이노 프로그래밍을 해 보자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;소스 코드는 생각보다 단순하다. 소프트웨어 개발자라면,, 눈 감고 발가락으로 짜도 10분이 채 걸리지 않는다. 라고 허세를 부릴 만큼 단순하다. 풋ㅋ;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1730000996509&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;Joystick.h&amp;gt;

#define BTN_1 2
#define BTN_2 3
#define BTN_3 4
#define BTN_4 5
#define BTN_5 6
#define BTN_6 7
#define BTN_7 8
#define BTN_8 9
#define BTN_9 10
#define BTN_10 16

#define BTN_UP A3
#define BTN_RIGHT A2
#define BTN_DOWN A1
#define BTN_LEFT A0


// Global variables
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD,
  10, 0,                  // Button Count, Hat Switch Count
  true, true, false,     // X and Y, but no Z Axis
  false, false, false,   // No Rx, Ry, or Rz
  false, false,          // No rudder or throttle
  false, false, false);  // No accelerator, brake, or steering;

// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(BTN_1, INPUT);
  pinMode(BTN_2, INPUT);
  pinMode(BTN_3, INPUT);
  pinMode(BTN_4, INPUT);
  pinMode(BTN_5, INPUT);
  pinMode(BTN_6, INPUT);
  pinMode(BTN_7, INPUT);
  pinMode(BTN_8, INPUT);
  pinMode(BTN_9, INPUT);
  pinMode(BTN_10, INPUT);

  pinMode(BTN_UP, INPUT);
  pinMode(BTN_RIGHT, INPUT);
  pinMode(BTN_DOWN, INPUT);
  pinMode(BTN_LEFT, INPUT);

  Joystick.begin();
  Joystick.setXAxisRange(-1, 1);
  Joystick.setYAxisRange(-1, 1);
}


int prevUp = LOW;
int prevRight = LOW;
int prevDown = LOW;
int prevLeft = LOW;

int prevBtn1 = LOW;
int prevBtn2 = LOW;
int prevBtn3 = LOW;
int prevBtn4 = LOW;
int prevBtn5 = LOW;
int prevBtn6 = LOW;
int prevBtn7 = LOW;
int prevBtn8 = LOW;
int prevBtn9 = LOW;
int prevBtn10 = LOW;

// the loop function runs over and over again forever
void loop() {
  int up = digitalRead(BTN_UP);
  int right = digitalRead(BTN_RIGHT);
  int down = digitalRead(BTN_DOWN);
  int left = digitalRead(BTN_LEFT);

  int button1 = digitalRead(BTN_1);
  int button2 = digitalRead(BTN_2);
  int button3 = digitalRead(BTN_3);
  int button4 = digitalRead(BTN_4);
  int button5 = digitalRead(BTN_5);
  int button6 = digitalRead(BTN_6);
  int button7 = digitalRead(BTN_7);
  int button8 = digitalRead(BTN_8);
  int button9 = digitalRead(BTN_9);
  int button10 = digitalRead(BTN_10);

  if(up != prevUp || down != prevDown) {
    prevUp = up;
    prevDown = down;
    Joystick.setYAxis(up == HIGH ? -1 : (down == HIGH ? 1 : 0));
  }
  if(right != prevRight || left != prevLeft) {
    prevRight = right;
    prevLeft = left;
    Joystick.setXAxis(right == HIGH ? 1 : (left == HIGH ? -1 : 0));
  }
  

  if(button1 != prevBtn1) {
    prevBtn1 = button1;
    Joystick.setButton(0, button1);
  }
  if(button2 != prevBtn2) {
    prevBtn2 = button2;
    Joystick.setButton(1, button2);
  }
  if(button3 != prevBtn3) {
    prevBtn3 = button3;
    Joystick.setButton(2, button3);
  }
  if(button4 != prevBtn4) {
    prevBtn4 = button4;
    Joystick.setButton(3, button4);
  }
  if(button5 != prevBtn5) {
    prevBtn5 = button5;
    Joystick.setButton(4, button5);
  }
  if(button6 != prevBtn6) {
    prevBtn6 = button6;
    Joystick.setButton(5, button6);
  }
  if(button7 != prevBtn7) {
    prevBtn7 = button7;
    Joystick.setButton(6, button7);
  }
  if(button8 != prevBtn8) {
    prevBtn8 = button8;
    Joystick.setButton(7, button8);
  }
  if(button9 != prevBtn9) {
    prevBtn9 = button9;
    Joystick.setButton(8, button9);
  }
  if(button10 != prevBtn10) {
    prevBtn10 = button10;
    Joystick.setButton(9, button10);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;하드웨어? 난 초보자&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;소프트웨어 개발자가 겁대가리 없이 하드웨어를 바로 제작한다? X되는 지름길이라는것을 경험을 통해서 이미 익히 알고 이기 때문에, 예우를 갖춰 빵판에 먼저 회로 작업을 했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1207&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxjHBG/btsKlZaK3F2/hdzk49dzEdRKWbHz0xTa90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxjHBG/btsKlZaK3F2/hdzk49dzEdRKWbHz0xTa90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxjHBG/btsKlZaK3F2/hdzk49dzEdRKWbHz0xTa90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxjHBG%2FbtsKlZaK3F2%2Fhdzk49dzEdRKWbHz0xTa90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1207&quot; height=&quot;677&quot; data-origin-width=&quot;1207&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1199&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeUOro/btsKkuCY9XO/PtgK581lfxOwlV4BT5Otu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeUOro/btsKkuCY9XO/PtgK581lfxOwlV4BT5Otu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeUOro/btsKkuCY9XO/PtgK581lfxOwlV4BT5Otu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeUOro%2FbtsKkuCY9XO%2FPtgK581lfxOwlV4BT5Otu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1199&quot; height=&quot;679&quot; data-origin-width=&quot;1199&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아름답지 아니한가?! 팩토리오에서 공장을 짓듯이 한땀한땀 만들어 보았다. 굳이 14개의 모든 버튼을 만들 필요가 있을까? 있다. 왜냐고? 나는 전자회로/하드웨어에 있어서 브론즈는 커녕 아이언 등급이니까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노에 올리고 PC 와 연결해서 테스트 해 보니 잘 동작한다 ^O^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 가장 큰 것이 남았다. 위 빵판을 고스란히 싸울아비 온라인 내부에 넣을 수 없다는 것. 만능 기판에 작업을 해야 한다. 여기서 실수하면 진짜 X 된다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;한땀한땀 땜질&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 주요 소자를 위한 자리를 잡아 주었다. 바로 소자를 기판에 붙일 수도 있겠지만, 혹시라도 제거하고 다시 해야 하는 최악의 상황을 위해서 소켓을 붙여 주었다. 언제든지 제거할 수 있도록 :)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1507&quot; data-origin-height=&quot;973&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GYxMS/btsKkfszXQo/L9kbmjqMkSd5AnQpcrZh21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GYxMS/btsKkfszXQo/L9kbmjqMkSd5AnQpcrZh21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GYxMS/btsKkfszXQo/L9kbmjqMkSd5AnQpcrZh21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGYxMS%2FbtsKkfszXQo%2FL9kbmjqMkSd5AnQpcrZh21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1507&quot; height=&quot;973&quot; data-origin-width=&quot;1507&quot; data-origin-height=&quot;973&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;74HC14 는 총 다리를 14 개 가지고 있다. 근데,, 내가 가지고 있는 소켓은 15 핀 짜리네? 뭐..어쩔수 없지. 이거라도 써야지 ㅎ. 좌하단에 2 핀 짜리 JST XH 소켓은 GND 로 쓸 것이고, 그 다음 4 핀 짜리는 스틱의 4방향 핀. 나머지 5 핀 짜리 2개는 각각 1 ~ 5 번 버튼, 6 ~ 10 번 버튼을 위한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒷편 작업을 마쳤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1590&quot; data-origin-height=&quot;1025&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvqqyz/btsKlWZoDRL/5EFP9dCttvYbSPEjQcYIOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvqqyz/btsKlWZoDRL/5EFP9dCttvYbSPEjQcYIOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvqqyz/btsKlWZoDRL/5EFP9dCttvYbSPEjQcYIOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcvqqyz%2FbtsKlWZoDRL%2F5EFP9dCttvYbSPEjQcYIOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1590&quot; height=&quot;1025&quot; data-origin-width=&quot;1590&quot; data-origin-height=&quot;1025&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나름 최선의 회로 구성을 위해서 배치한 노력이 느껴지는가? 나는 이것도 꽤나 어려웠다. 최단 경로. 그리고 최적의 선 꼬임을 모두 고려해야 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1534&quot; data-origin-height=&quot;1021&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCJ8yw/btsKj2G1PqZ/Z4K2GUm1yKKGK753mzr7d1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCJ8yw/btsKj2G1PqZ/Z4K2GUm1yKKGK753mzr7d1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCJ8yw/btsKj2G1PqZ/Z4K2GUm1yKKGK753mzr7d1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCJ8yw%2FbtsKj2G1PqZ%2FZ4K2GUm1yKKGK753mzr7d1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1534&quot; height=&quot;1021&quot; data-origin-width=&quot;1534&quot; data-origin-height=&quot;1021&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후...여기까지가 74HC14 의 Output 핀과 아두이노 기판의 연결을 제외한 모든 연결을 마친 상태이다. 이제 가장 큰 놈이 남았다. 74HC14 에서 총 14개의 선을 아두이노 기판에 연결해야 한다. 문제는 자리가 너무 협소하다. 앞판에 이 모든것을 우겨 넣는것은 거의 불가능하다고 판단되어, 해당 연결은 뒷판에서 하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1533&quot; data-origin-height=&quot;1046&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kYEMK/btsKkhRvk0Q/9iCEyZqvsrhn7gYZU3KLpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kYEMK/btsKkhRvk0Q/9iCEyZqvsrhn7gYZU3KLpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kYEMK/btsKkhRvk0Q/9iCEyZqvsrhn7gYZU3KLpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkYEMK%2FbtsKkhRvk0Q%2F9iCEyZqvsrhn7gYZU3KLpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1533&quot; height=&quot;1046&quot; data-origin-width=&quot;1533&quot; data-origin-height=&quot;1046&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마음에 들지 않는다. 너무 지저분하다. 아마 IDC 에서 서버 UTP 케이블을 저렇게 연결해놨다면, 권고사직을 받았을 것 같다... ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 저렇게 연결하고, 각 소자와 아디우노를 끼워보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;1010&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bekj6Y/btsKknRmuew/iekfcnZUKbYoBaSjYvZ2J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bekj6Y/btsKknRmuew/iekfcnZUKbYoBaSjYvZ2J1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bekj6Y/btsKknRmuew/iekfcnZUKbYoBaSjYvZ2J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbekj6Y%2FbtsKknRmuew%2FiekfcnZUKbYoBaSjYvZ2J1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1370&quot; height=&quot;1010&quot; data-origin-width=&quot;1370&quot; data-origin-height=&quot;1010&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 납땜 작업을 위해서 끼워뒀던 PCV 서포터를 제거하고, 싸울아비 온라인에 우겨넣기 적당한 길이의 서포터로 교체. 이후 순간접착제를 이용하여 붙여보았다. 여담이지만, 다행히도 순간접착제로 잘 붙었다. 간혹 플라스틱 제질에 따라 순간접착제가 붙지 않는 거지같은 경우가 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1786&quot; data-origin-height=&quot;1022&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHMgsQ/btsKkjIzICo/jvou3E9UhbDcePjAUMeoZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHMgsQ/btsKkjIzICo/jvou3E9UhbDcePjAUMeoZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHMgsQ/btsKkjIzICo/jvou3E9UhbDcePjAUMeoZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHMgsQ%2FbtsKkjIzICo%2Fjvou3E9UhbDcePjAUMeoZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1786&quot; height=&quot;1022&quot; data-origin-width=&quot;1786&quot; data-origin-height=&quot;1022&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨.주.노.초.파.남.보 등등.. 나는 모든 성소수자를 지지합니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;두근두근, 잘 될까?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 모든 준비가 끝났다. PC 와 연결하고 잘 동작하는지 테스트 해 보았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/db67Te/btsKkqggo40/waG8pWeJMH0F3nbFm2oHd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/db67Te/btsKkqggo40/waG8pWeJMH0F3nbFm2oHd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/db67Te/btsKkqggo40/waG8pWeJMH0F3nbFm2oHd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdb67Te%2FbtsKkqggo40%2FwaG8pWeJMH0F3nbFm2oHd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;847&quot; height=&quot;439&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오호.. 내가 만든 스틱에 윈도우가 반응하기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H0sGo/btsKl3KQwhz/a5x8MyoOiuoHUrFyoAZAh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H0sGo/btsKl3KQwhz/a5x8MyoOiuoHUrFyoAZAh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H0sGo/btsKl3KQwhz/a5x8MyoOiuoHUrFyoAZAh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH0sGo%2FbtsKl3KQwhz%2Fa5x8MyoOiuoHUrFyoAZAh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;820&quot; height=&quot;415&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두근두근. 장치 목록을 살펴보자. CrystalCube Stick 이라고 잘 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjbaZ7/btsKlON4tV1/yfFicb5CRfJAkkvoNDZqzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjbaZ7/btsKlON4tV1/yfFicb5CRfJAkkvoNDZqzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjbaZ7/btsKlON4tV1/yfFicb5CRfJAkkvoNDZqzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjbaZ7%2FbtsKlON4tV1%2FyfFicb5CRfJAkkvoNDZqzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;286&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상세 화면에 들어가서 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nx2CX/btsKl6U8bjR/AE01KWBkB1reul0O4a60Q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nx2CX/btsKl6U8bjR/AE01KWBkB1reul0O4a60Q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nx2CX/btsKl6U8bjR/AE01KWBkB1reul0O4a60Q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNx2CX%2FbtsKl6U8bjR%2FAE01KWBkB1reul0O4a60Q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;609&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것저것 버튼을 눌러보니, 잘 인식이 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;852&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdGxBq/btsKlXcVK6Q/xwvXzpE36E3svCZ4OROKCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdGxBq/btsKlXcVK6Q/xwvXzpE36E3svCZ4OROKCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdGxBq/btsKlXcVK6Q/xwvXzpE36E3svCZ4OROKCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdGxBq%2FbtsKlXcVK6Q%2FxwvXzpE36E3svCZ4OROKCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;658&quot; height=&quot;852&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;852&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메마에 내가 좋아하던, 마하브레이커스를 설치하고 연결해서 테스트 해보면~!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;1067&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GzcCW/btsKkaZoerQ/ktbB35eHzwDnLhjEYY2xKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GzcCW/btsKkaZoerQ/ktbB35eHzwDnLhjEYY2xKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GzcCW/btsKkaZoerQ/ktbB35eHzwDnLhjEYY2xKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGzcCW%2FbtsKkaZoerQ%2FktbB35eHzwDnLhjEYY2xKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1558&quot; height=&quot;1067&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;1067&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 된다. 매우 잘 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게해서 죽어가던 싸울아비 온라인을 Windows 10 에서도 잘 동작하도록 문제 해결!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;Conclusion&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 스틱하나 새로 사는게 정신건강에 이롭다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인처럼 전자회로에 관심이 있고, 관련 이론을 공부하고 그것을 증명하기 위해서 만드는게 아니라면, 금전적으로나 물리적인 시간으로나 그냥 사는게 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 앞서 서술했듯이 처음에 더 작은 기판을 만들었었으나 실패하였다. 각 소자의 배치 문제와 납땜의 문제로 인하여 어디선가 오류가 발생하였다. 그런데 디버깅 또한 쉽지 않았다. 결국 다 버리고 조금더 큰 기판에 새로 작업했다라는 슬픈 이야기.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;675&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBFMal/btsKly5Me7f/eIUzZ0eKTRiATrCG41gQmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBFMal/btsKly5Me7f/eIUzZ0eKTRiATrCG41gQmK/img.png&quot; data-alt=&quot;망한 기판&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBFMal/btsKly5Me7f/eIUzZ0eKTRiATrCG41gQmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBFMal%2FbtsKly5Me7f%2FeIUzZ0eKTRiATrCG41gQmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1041&quot; height=&quot;675&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;675&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;망한 기판&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1177&quot; data-origin-height=&quot;837&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctYO3O/btsKlZBOXVM/PvSfKZXrcZEoT5szzofmIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctYO3O/btsKlZBOXVM/PvSfKZXrcZEoT5szzofmIK/img.png&quot; data-alt=&quot;지옥이 있다면 이런게 아닐까.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctYO3O/btsKlZBOXVM/PvSfKZXrcZEoT5szzofmIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctYO3O%2FbtsKlZBOXVM%2FPvSfKZXrcZEoT5szzofmIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1177&quot; height=&quot;837&quot; data-origin-width=&quot;1177&quot; data-origin-height=&quot;837&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;지옥이 있다면 이런게 아닐까.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;재미있는 점&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아두이노 보드를 사용했기 때문에, 소프트웨어 업데이트가 편리하다. 무슨 이야긴가면 USB 로 PC 와 연결하고 나면, 그 상태에서 언제든 소프트웨어(펌웨어) 업데이트가 가능하다. 그리고 Serial 로 디버깅도 가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를들어 10번 키를 누르면, 특정 버튼을 엄청난 속도로 클릭하는 메크로와 같은 이상한 기능들은 언제든 간편하게 추가할 수 있다라는 것이다 :)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음에 또 재미있는 작업이 생기면, 공유하도록 하겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>HID</category>
      <category>windows10</category>
      <category>마메</category>
      <category>싸울아비</category>
      <category>아두이노</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/223</guid>
      <comments>https://crystalcube.tistory.com/223#entry223comment</comments>
      <pubDate>Sun, 27 Oct 2024 13:12:35 +0900</pubDate>
    </item>
    <item>
      <title>아두이노의 소소한 함정들</title>
      <link>https://crystalcube.tistory.com/222</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;아두이노를 가지고 놀다보면, 여러가지 함정에 마주한다. 그리고 당연하게도 수 많은 시간을 빼앗긴다. 누군가 나와 같이 함정에 빠져 허우적 거리지 않길 바라며 적어본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: #000000;&quot;&gt;아두이노 보드 정리&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 보드 별 칩셋에 대한 정보를 숙지하지 않고 개발하다보면, 분명히 나중에 문제가 된다. 나는 여러가지 보드를 구매해서 사용 중이며, 그것들 위주로 기록한다. 뭐 이외의 보드들도 다 거기서 거기니까 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아두이노 보드명&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;MCU (마이크로 컨트롤러 유닛)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아두이노 메가 2560&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Atmega328 시리즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아두이노 나노&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Atmega328 시리즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아두이노 레오나르도 R3&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Atmega32u4 시리즈&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아두이노 마이크로 (Pro Micro)&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Atmega32u4 시리즈&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게보면 Atmega328 시리즈와 Atmega32u4 시리즈로 나뉜다. 시리즈라고 표현한 이유는 Atmega328P-AU, Atmega328P-PU 처럼 조금씩 다르기 때문이다. 하지만 기본적인 기능은 같으니 여기서는 무시하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Atmega32u4 의 특징이라고 한다면, 기본적으로 HID 를 지원한다. 아두이노로 가상 키보드나 마우스 등을 만들 생각이라면 ATmega32u4 칩을 사용하는 보드를 이용하는것이 정신건강에 이롭겠지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: #000000;&quot;&gt;수 많은 함정들&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이것저것 개발을 하면서 꼼꼼히 보지 않으면, 놓치기 쉬운 - 그리고 함정이 되는 - 것들을 몇가지 적어 보겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;Arduino Nano 의 Pinout&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;SCP(&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;Serial Peripheral Interface&lt;/span&gt;) 를 이용하여 ICSP 를 할 경우, 핀맵(Pinout)을 확인하는 경우가 허다하다. 그런데 아두이노 나노의 경우, 작은 함정이 있다. 검색을 해 보면 아래와 같이 대부분 나와 있다. 거의 모든 자료가 그렇다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1886&quot; data-origin-height=&quot;1528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkLYSl/btsKcNBJPen/HXtUmAVMzUKzOx68GrIRgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkLYSl/btsKcNBJPen/HXtUmAVMzUKzOx68GrIRgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkLYSl/btsKcNBJPen/HXtUmAVMzUKzOx68GrIRgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkLYSl%2FbtsKcNBJPen%2FHXtUmAVMzUKzOx68GrIRgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1886&quot; height=&quot;1528&quot; data-origin-width=&quot;1886&quot; data-origin-height=&quot;1528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 SCP 쪽을 유심히 보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;345&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/240C2/btsKbJGSmrW/txR2iKncZM1JvICZAUY20K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/240C2/btsKbJGSmrW/txR2iKncZM1JvICZAUY20K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/240C2/btsKbJGSmrW/txR2iKncZM1JvICZAUY20K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F240C2%2FbtsKbJGSmrW%2FtxR2iKncZM1JvICZAUY20K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;345&quot; data-origin-width=&quot;715&quot; data-origin-height=&quot;345&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색으로 박스 친 그림 그대로 해석하면 안된다. 이해가 가는가? 레이아웃 그대로 보면 안된다는 이야기다. 자세히보면 아두이노 나노의 경우 좌하단에 1 이라고 써 있는것을 알 수 있다. 응??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bucu3g/btsKdf5Atso/uSknp0831IL4IMEOd5wzak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bucu3g/btsKdf5Atso/uSknp0831IL4IMEOd5wzak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bucu3g/btsKdf5Atso/uSknp0831IL4IMEOd5wzak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbucu3g%2FbtsKdf5Atso%2FuSknp0831IL4IMEOd5wzak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;870&quot; height=&quot;724&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 1이 우상단으로 가도록 돌려 놓고 봐야 된다. -_-;; 조심하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;CSP 로 스케치 업로드 하기&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나는 Attiny45 와 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Attiny85 를 가지고 놀기 좋아한다. 왜냐면 나는 대부분 거창하게 바퀴가 달린 장난감이나 로봇을 만들지 않기에 때문이다. 소소하게 작은 단추 베터리 넣고, 오랫동안 저전력으로 사용하는 악세서리나 소품을 만든다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;아무튼 Attiny 를 사용할때 아두이노 보드를 ISP 로 만들고, 그것을 통해 Attiny 에 펌웨어도 올리고, 스케치도 업로드 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;어느날 새로 구매한 아두이노 나노에 펌웨어를 다시 올려야 할 일이 생겼다. 기존에 만들어둔 아두이노 나노(A라고 하자)를 ISP 프로그래머로 만든 후, 새로 산 아두이노 나노(B라고 하자)와 연결하였다. 그리고 펌웨어를 올렸다. 문제없이 잘 올라갔다. 이후에 스케치 파일을 B에 올리기 위해 업로드 하였으나, 연결에 계속해서 실패하였다. Attiny 에서는 잘 되던 시나리오인데 말이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;끝내 알아낸 원인은, Attiny 가 특이하게도(?) ICSP 를 통한 스케치 업로드를 지원하기 때문에 문제 없이 진행 되었던 것이다. 이게 기본적인 기능은 아니다. 그렇기 때문에 B에는 ICSP 를 통한 스케치 업로드가 불가능한 것이었다. 나의 익숙함이 함정이 되어 나를 곤경에 빠뜨린 셈이다. 주의하자. Attiny 처럼 칩셋에 스케치를 직접 올리는게 아닌 이상은 PC 와 연결해서 업로드 하도록 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>나노</category>
      <category>스케치</category>
      <category>아두이노</category>
      <category>핀맵</category>
      <category>핀아웃</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/222</guid>
      <comments>https://crystalcube.tistory.com/222#entry222comment</comments>
      <pubDate>Sat, 19 Oct 2024 03:22:57 +0900</pubDate>
    </item>
    <item>
      <title>타이머 LED 만들기</title>
      <link>https://crystalcube.tistory.com/221</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;나는 아이 둘을 키운다. 그 중 막내 아들은 아직 미취학 아동이라서인지 밤에 무서움이 많아, 늘 LED 등을 켜고 잔다. 그런데 당연하게도 잠이 들면 LED 를 끄지 않는다 -_-;;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;요즘 시간이 많이 남아서, 30분이 지나면 자동으로 꺼지도록 만들어 보았다. 그 과정에서 여러 삽질을 했고, 이를 기록하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt; color: #000000;&quot;&gt;어떤 것들로 만들어 볼까?&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 부피가 되도록 작았으면 하는 마음에 구매해 두었던 ATTINY 45 칩을 이용하자. 절대 ARDUINO NANO 나 MICRO 가 아까워서 그런게 아니야... 그리고 베터리가 문제인데, 아무래도 LED 등을 켜야 하므로 집에서 놀고 있던 26650 베터리를 2개 병렬로 이용할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 LED 는 이렇게 생긴 녀석이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;1124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMi4TB/btsJ7owNntw/wOHKOPYZePAF0Xzlk6nTWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMi4TB/btsJ7owNntw/wOHKOPYZePAF0Xzlk6nTWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMi4TB/btsJ7owNntw/wOHKOPYZePAF0Xzlk6nTWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMi4TB%2FbtsJ7owNntw%2FwOHKOPYZePAF0Xzlk6nTWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;510&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;1124&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;물론 별도로 구매한건 아니고 ㅎ, 문화센터라든지 어디가서 무언가를 만들어 오면서 집에 쌓여있던 것들이다. 보통 길이가 1 미터 정도 되는것 같던데, 3개를 모두 연결하였다. 대략 3 미터?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 외에는 4.2v 의 리튬이온 충전모듈과 저항. 그리고 불의 밝기 조절을 위한 트랜지스터가 필요하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;어떤 동작을 할 것인가?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하다. 버튼은 총 3개면 된다. 끄고 켤 수 있는 전원버튼 하나. 그리고 밝기 조절을 위한 버튼 두개. 근데 그냥 만들면 되는데,, 우리같은 공돌이들은 또 욕심이 있지 않은가? 초저전력으로 구성할 것이다. 사용하지 않을때는 저전력 모드로 진입하여 베터리 사용량을 최저로 해야한다. 자료를 좀 찾아보니 대기전력이 0.25mA 정도밖에 되지 않는다더라. 대략 0.001 와트?!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전원버튼이 해야 하는 역할은 다음과 같다. 전원이 꺼져 있는 상태라면, 버튼이 눌렸을때 전원을 켠다. 그리고 TIMER 를 돌리고 30분 뒤에 자동으로 꺼진다. 켜져 있는 상태라면, 버튼이 눌렸을때 전원을 끈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정도 로직이면, 눈 감고 발로도 만들지 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;아니, 왜 안되는데?!!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;상당한 삽질을 했다. 일단 setup() 함수에서 대기모드에 들어간다. 그리고 전원버튼이 눌리면 interrupt 를 발생하고, sleep mode 에서 빠져나오는 코드를 짠다. 그리고 30분이 지나거나, 다시 전원 버튼이 누르면 sleep mode 로 들어간다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 간단한 로직이 제대로 동작하지 않고 개판이다. ATTINY 45 라는 요 녀석은 핀이 너무 없다. SoftwareSerial 로 print 를 찍어가며 디버깅을 해 보려고 해도 핀이 부족하여 불가능하다. 겁나 답답하네.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1079&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exju9m/btsJ8m58NLq/gBKWvy5a1Rn7ZHaot71Yk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exju9m/btsJ8m58NLq/gBKWvy5a1Rn7ZHaot71Yk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exju9m/btsJ8m58NLq/gBKWvy5a1Rn7ZHaot71Yk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fexju9m%2FbtsJ8m58NLq%2FgBKWvy5a1Rn7ZHaot71Yk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1079&quot; height=&quot;271&quot; data-origin-width=&quot;1079&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우선 ATTINY 45 에서 PB2 를 전원 스위치로 쓸 것이므로, 절전모드에서 빠져나가는 INTERRUPT 설정을 다음과 같이 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1729092478122&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  cli();
  GIMSK = 0b00100000;
  PCMSK = 0b00000100;
  sei();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;PCMSK 의 0번째 비튼은 PB0 을 의미한다. PB2 는 세 번째 비트가 되는 셈이지. 그리고 interrupt 가 발생했을때, 아래 함수가 호출된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729092561361&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ISR(PCINT0_vect)
{
  // do something
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무나 화가난다. 의도한대로 동작하지 않는다. 바쁠수록 돌아가라고 했나?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대기모드와 INTERRUPT 가 어떻게 돌아가는지 확인하기 위해서, 빈 프로젝트를 하나 만들고 해당 코드만 넣었다. 그리고 Serial 로 찍어 보았다. 나는 충격에 빠졌다. 내가 알고 있던것과 동작이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;내가 잘못 알고 있던것들과 실제 동작&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째로는 대기 모드로 진입하고, 빠져나가는 로직이 전혀 다르다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729092750850&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  // 대기모드 진입
  sleep_enable();  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();

  // woke up
  start(); // 내가 만든 함수&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sleep_cpu() 를 호출하는 순간 대기모드로 빠진다. 80x86 아키텍쳐로 설명하자면, EIP 레지스터가 해당 주소에서 멈춰 있다고 생각하면 쉽다. 그리고 INTERRUPT 가 발생하면, 대기모드가 풀린다. 그 어떤 INTERRUPT 든 발동되면 대기모드가 풀린다. 나의 경우&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;PCMSK 에서 PB2 만 INTERRUPT 로 정의하였다. 그러면 어떻게 되는가?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;코드는 sleep_cpu() 아래 코드부터 시작한다. 마치 '얼음 땡' 과 같다. 그러면 아래 함수는 어떻게 되는가?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1729092963778&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ISR(PCINT0_vect) {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 대기모드와 전혀 관계없다. 그냥 INTERRUPT 가 발생하였으니 호출된다. 난 이 부분의 동작을 오해하고 있었고, 그로 인해서 원하는대로 돌아가지 않았던것...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면, sleep_cpu() 를 호출함과 동시에 freeze 된다. 이후 어떤 인터럽트라도 발생하면, 프리징이 풀린다. 더불어 당연히 INTERRUPT 가 발생하였으니 ISR CALLBACK 이 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 고려해서 모든 코드를 다 뜯어 고치자..ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;또 다른 함정...&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;잘 돌아 가는것 같은데, 시간이 되어서 LED 가 꺼지고나면 다시 켜지지가 않는다. INTERRUPT 를 발생해도 대기모드에서 빠져나오지를 못한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;삽질한 결과 알아낸 사실은 INTERRUPT 함수의 CONTEXT 에서 대기모드로 들어가면 안된다. 영원히 죽어 버린다. 정확히 분석한것은 아니지만, 현상에 대해서 쉽게 설명하면 다음과 같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;loop() 함수를 호출하는 thread 와 INTERRUPT 함수를 호출하는 thread 는 별개다. 별개의 context 이다. sleep_mode() 를 호출하면, 해당 context 가 freeze 된다. 그러므로 INTERRUPT 함수 내에서 sleep_mode() 를 호출하면, 영원히 멈춘다. 그러면 어떻게 해야 하는가? sleep_mode() 를 loop() 함수의 context 에서 실행해야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;요컨데, 특정 버튼을 눌러서 INTERRUPT 를 발생시키고 sleep_mode() 에 진입하게 하려면, 임의의 FLAG 를 하나 만들고 INTERRUPT 핸들러에서는 이 FLAG 값만 수정한다. 이후 loop() 함수에서 FLAG 를 읽고 직접 sleep_mode() 를 호출하게 해야 한다. 그래야 이후 버튼을 다시 눌렀을때 깨어날 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1049&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Idou3/btsJ8JGs3xk/P8vi1DVhdlMWXETyVtApbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Idou3/btsJ8JGs3xk/P8vi1DVhdlMWXETyVtApbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Idou3/btsJ8JGs3xk/P8vi1DVhdlMWXETyVtApbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIdou3%2FbtsJ8JGs3xk%2FP8vi1DVhdlMWXETyVtApbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1876&quot; height=&quot;1049&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1049&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;왜 시간이 이상하지?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드를 다 뜯어 고치고 나니, 동작을 잘 한다. 전체 소스코드는 아래에서 확인이 가능하다. 다만 nano 에서 테스트 한 흔적에 주의.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/und3rs/arduino/blob/main/NightLight2/NightLight2.ino&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/und3rs/arduino/blob/main/NightLight2/NightLight2.ino&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1729093845192&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;arduino/NightLight2/NightLight2.ino at main &amp;middot; und3rs/arduino&quot; data-og-description=&quot;Contribute to und3rs/arduino development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/und3rs/arduino/blob/main/NightLight2/NightLight2.ino&quot; data-og-url=&quot;https://github.com/und3rs/arduino/blob/main/NightLight2/NightLight2.ino&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kMNwB/hyXhVHjhH3/1AdhZNGldOPLL60S8eAk00/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bZ5hob/hyXhSDQYT9/Eq3ogE3vDqZfzRq2pC3MS1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/und3rs/arduino/blob/main/NightLight2/NightLight2.ino&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/und3rs/arduino/blob/main/NightLight2/NightLight2.ino&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kMNwB/hyXhVHjhH3/1AdhZNGldOPLL60S8eAk00/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bZ5hob/hyXhSDQYT9/Eq3ogE3vDqZfzRq2pC3MS1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;arduino/NightLight2/NightLight2.ino at main &amp;middot; und3rs/arduino&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to und3rs/arduino development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 분명 10초 뒤에 꺼지도록 하였는데, 5초에 꺼진다. 왜 절반???&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는.. 내가 사용하는 ATTINY 가 부트로더를 올릴 당시에 Clock 을 16 Mhz 로 했었나보다. 그것도 모르고 코드를 올릴때 Clock 을 8 Mhz 로 올렸다. Clock 이 16 Mhz 라는것은 16 백만번 진동해야 1초라는 것이고, 8 Mhz 라는 것은 8 백만번 진동해야 1초라는 것이다. 그러니 이 사단이 난 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;드디어 완성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이젠 정말 모든 동작이 잘 된다. 오늘도 별것 아니라고 생각한것을 하면서 많은 것을 깨달았다. :)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1763&quot; data-origin-height=&quot;1053&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1qZuJ/btsJ7ocsVa6/BkIGkPEdwQfg9G76pm1hvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1qZuJ/btsJ7ocsVa6/BkIGkPEdwQfg9G76pm1hvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1qZuJ/btsJ7ocsVa6/BkIGkPEdwQfg9G76pm1hvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1qZuJ%2FbtsJ7ocsVa6%2FBkIGkPEdwQfg9G76pm1hvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1763&quot; height=&quot;1053&quot; data-origin-width=&quot;1763&quot; data-origin-height=&quot;1053&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㅅㅂ... 아크릴로 케이스 만드는게 전체 시간의 50%는 사용한것 같다. 1T 짜리인데도 가공이 너무 힘들다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐 좋은 방법 없을까......&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>attiny45</category>
      <category>attiny85</category>
      <category>INTERRUPT</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/221</guid>
      <comments>https://crystalcube.tistory.com/221#entry221comment</comments>
      <pubDate>Thu, 17 Oct 2024 00:59:12 +0900</pubDate>
    </item>
    <item>
      <title>하드웨어 프로그래밍의 기초</title>
      <link>https://crystalcube.tistory.com/220</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노를&amp;nbsp;이용하여,&amp;nbsp;디스플레이나&amp;nbsp;WIFI,&amp;nbsp;Bluetooth&amp;nbsp;등&amp;nbsp;각종&amp;nbsp;모듈을&amp;nbsp;이용하다보면&amp;nbsp;수&amp;nbsp;많은&amp;nbsp;통신관련&amp;nbsp;약어들이&amp;nbsp;나온다.&amp;nbsp;하나하나&amp;nbsp;꼼꼼히&amp;nbsp;찾아보면&amp;nbsp;좋겠지만&amp;nbsp;우리는&amp;nbsp;늘&amp;nbsp;시간이&amp;nbsp;부족하지&amp;nbsp;않은가?&amp;nbsp;그러다보니&amp;nbsp;대부분&amp;nbsp;감각적으로&amp;nbsp;육감적으로&amp;nbsp;그러려니&amp;nbsp;하고&amp;nbsp;추측성&amp;nbsp;개발을&amp;nbsp;하게&amp;nbsp;된다. &lt;br /&gt;&lt;br /&gt;이번에&amp;nbsp;본인이&amp;nbsp;여유를&amp;nbsp;가지고&amp;nbsp;하나씩&amp;nbsp;찾아본&amp;nbsp;것들을&amp;nbsp;정리해&amp;nbsp;본다.&amp;nbsp;아마&amp;nbsp;전자관련&amp;nbsp;학과나&amp;nbsp;관련&amp;nbsp;업무를&amp;nbsp;하고&amp;nbsp;있는&amp;nbsp;사람이라면&amp;nbsp;너무나&amp;nbsp;당연하게&amp;nbsp;알고&amp;nbsp;있을&amp;nbsp;것&amp;nbsp;들이다.&amp;nbsp;그러므로&amp;nbsp;이번&amp;nbsp;글을&amp;nbsp;나와&amp;nbsp;마찬가지로&amp;nbsp;비전공자를&amp;nbsp;위한&amp;nbsp;것으로&amp;nbsp;보기&amp;nbsp;바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-size: 24px;&quot;&gt;ISP 와 ICSP. 그리고 SCP&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노에 펌웨어를 업로드 할때, ISP 나 ICSP 라는 용어가 나온다. 그리고 아두이노 보드를 보면 ICSP 라고 써 있는 곳이 있다. 그 영역의 핀을 보면 MOSI, MISO, SS 등이 존재한다. 그동안 대충 통신 프로토콜인가? 하고 넘어갔었다. 이번에 정리를 하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;ISP 와 ICSP&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ISP 는 In-System Programming 의 약자이고, ICSP 는 In-Circuit Serial Programming 의 약자이다. 둘다 MCU 에 프로그래밍을 한다는 행위에 대한 이야기다. 좀 더 엄밀히 나눠 보자면 ICSP 는 시리얼 통신 방식으로 프로그램을 올리는 것이고, ISP 는 MCU 에 프로그램을 올리는 모든 행위를 의미한다. 그렇기에 ISP 가 좀 더 넓은 개념이라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 말하지만 ISP 와 ICSP 는 '행위/행동' 을 지칭하는 것이지 프로토콜이 아니다. 그렇다면 보통 어떤 프로토콜을 이용하여 이 '행위'를 할까? 이때 사용되는 프로토콜이 바로 SPI 이다. 이외에 JTAG 등이 존재한다. 아두이노에서는 모두 SPI 를 이용하는것으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;SPI&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;SPI 는 Serial Peripheral Interface 의 약자로서 해석하자면, '직렬 주변기기 인터페이스' 정도라고 할 수 있다.&lt;span&gt; SPI 통신은 프로토콜이며 다음의 4가지로 구성되어 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MOSI: Master Out, Slave In 의 약어로서, 마스터 장치에서 슬레이브 장치로 보내는 데이터 LINE&lt;/li&gt;
&lt;li&gt;MISO: Master In, Slave Out 의 약어로서, 슬레이브 장치에서 마스터 장치로 보내는 데이터 LINE&lt;/li&gt;
&lt;li&gt;SCLK: Serial Clock 의 약어로서, 클럭 신오를 위한 LINE&lt;/li&gt;
&lt;li&gt;SS: Slave Select 의 약어로서, 각 슬레이브 장치를 선택하는 LINE&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약하자면 ISP 는 MCU 에 프로그램을 올리는 행위를 말하며, 그 중에서 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ICSP&lt;span&gt; &lt;/span&gt;&lt;/span&gt;는 시리얼 통신 방식을 이용한 ISP 이다. SPI 는 4개의 LINE 을 이용하는 통신 프로토콜이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 우리가 펌웨어를 올리기 위해서 이용할때 사용하는 예제 코드인 'Arduino as ISP' 의 의미를 정확히 알 수 있게 되었다. 굳이 번역하자면, ' 아두이노를 MCU 프로그래머로' 정도가 되지 않을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;UART 와 TTL&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노에 펌웨어를 업로드 할때 함께 나오는 용어가 바로 UART TTL 이라는 것이다. 나는 처음에 UART 가 USB 와 관련된 것으로 생각했다. 그럼 TTL 은 뭐지?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;UART 가 뭔데?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UART 는 Universal Asynchronous Receiver/Transmitter 의 약어로서, 통신 프로토콜을 의미한다. 즉 우리가 흔히 생각하는 RX 와 TX로 단순하게 데이터를 주고 받는 그 Serial 통신이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;그럼 TTL 은?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TTL 은 UART 통신의 전압에 대한 표준 중 하나이다. 즉 RX 와 TX 로 데이터를 주고받고 하는데, 전압을 몇 volt 로 할 것이냐에 대한 이야기다. 흔히 0 과 1 이 있다고 할때 전압 0v 는 0을 의미하고, 5v 는 1을 의미한다고 어림잡아 알고 있을 것이다. 이게 바로 TTL 에서 정의한 표준이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 또 다른게 있나? 물론 있다. 바로 RS-232, RS-422, RS-485 등이다. RS-232 는 0v ~ 5v 가 아닌 -12V ~ 12V 를 이용하며, RS-485 는 차동 신호를 이용한다. 왜 서로 다른 전압을 이용할까? 그것은 바로 더 먼 거리에서 통신이 가능토록 하기 위해서다. 전압이 낮으면 아무래도 먼 거리(긴 선) 통신을 하기에 불리하다. 손실이 있으니까ㅡ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약하자면 UART 는 RX, TX 를 이용한 통신이며, TTL 은 UART 통신의 전압 표준 중 하나이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;USB to UART TTL&quot; 이라는 모듈은 PC 의 USB 통신 프로토콜을 UART 통신 프로토콜로 변환해 주는 모듈인 셈이다. 물론 전압은 0v ~ 5v 를 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 16pt; color: #000000;&quot;&gt;I2C&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;OLED Display 같은 장치를 이용하면 I2C 를 이용해 봤을 것이다. 혹은 아두이노 보드에 SCL 혹은 SDA 라고 써 있는것을 보았을 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;I2C 는 IIC 를 의미하며, Inter-Integrated Circuit 의 약어이다. '직접 회로 간 통신' 정도로 해석이 가능하다. 즉, 시리얼 통신 프로토콜이며, 다음으로 구성되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SCL: Serial Clock 를 뜻하며, 클럭 신호를 위한 LINE&lt;/li&gt;
&lt;li&gt;SDA: Serial Data 를 뜻하며, 데이터 전송을 위한 LINE&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔 I2C 통신 프로토콜의 SCL 와 SPI 통신 프로토콜의 SCLK 가 헷갈린다. 둘다 각각의 프로토콜에서 Clock 신호를 위한 LINE 을 의미하기 때문이다. 헷갈리지 않기 위해서는 다음과 같이 생각하면 편하다. I2C 는 각 LINE 의 약어가 모두 세 글자. SPI 의 LINE 약어는 모두 네 글자이다. 그러므로 SCLK 는 네 글자이므로 SPI 통신에 쓰이며, SCL 은 세 글자이므로 I2C 에 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>I2C</category>
      <category>ICSP</category>
      <category>iSP</category>
      <category>miso</category>
      <category>MOSI</category>
      <category>SCL</category>
      <category>SDA</category>
      <category>UART</category>
      <category>아두이노</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/220</guid>
      <comments>https://crystalcube.tistory.com/220#entry220comment</comments>
      <pubDate>Thu, 17 Oct 2024 00:00:56 +0900</pubDate>
    </item>
    <item>
      <title>[ESP8266-01] 아두이노 프로그래밍</title>
      <link>https://crystalcube.tistory.com/216</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노에서 ESP8266 과 Serial 통신을 하는 이야기가 아니다. ESP8266-01 은 MCU 가 포함되어 있으므로, 아두이노와의 연결 없이 독립적인 개발/실행이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;ESP8266-01 을 이용한 프로그래밍&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에 자료를 보면 대부분 아두이노와 ESP8266 모듈을 RX-TX, TX-RX 로 연결 한 뒤 AT 커맨드를 SoftwareSerial 로 날려서 이용을 하는 글들이 많다. 그러나 WIFI 를 이용한 스위치 ON/OFF 같은 간단한 IoT 를 개발할때는 아두이노가 굳이 필요하지 않다. 3.3V 수은전지 + ESP8266 + 릴레이 스위치 세 개면 충분하다. 그 밖에 만들려는 작품이 복잡한 HttpServer 가 필요한 상황이라면 ESP8266 을 주축으로 개발을 해 나가는게 편할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 이 글에서는 ESP8266 에 직접 스케치를 올리는 개발에 대해 이야기 한다. 이렇게 하면 AT 커맨드 따위는 더 이상 쓸 수 없게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과부터 이야기하자면, 내가 개발한 스케치를 올리고나서 Serial 모니터로 찍어보면 이렇게 앞 부분(부트로더)은 살아 있는것을 확인 할 수 있다. 그러므로 부트로더를 올릴 필요 없이 바로 스케치부터 올리면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1647881207926&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3460, room 16 
tail 4
chksum 0xcc
load 0x3fff20b8, len 40, room 4 
tail 4
chksum 0xc9
csum 0xc9
v0004a0d0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;아두이노와 ESP8266 를 어떻게 결선해야 하는데?&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분에 대해서 제대로 다루는 곳이 없다. 아두이노 개발자들에게는 당연한 것이라 그런지, 자료가 잘 없어서 찾는데 조금 애를 먹었다. 나는 ATTiny85 에 부트로더를 올려서 개발하던 경험이 있는지라, ESP8266 도 뭔가 복잡한 연결을 해야 한다고 생각했다. 아두이노 부트로더는 어떻게 올리지? 이것부터가 문제였다. ATTiny 는 부트로더/스케치를 업로드 하기 위해서 ISP 통신(MOSI/MISO)을 한다. 그러기 위해서 AndroidISP 스케치를 아두이노에 먼저 올려야 했다. 그리고나서 프로그래머를 아두이노로 설정한 뒤 나머지 작업을 해야했다. 이런 나로서는 ESP8266 도 비슷한 과정을 거쳐야 한다고 생각했다. 그러나 이런 나의 생각은 잘못 된 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 PC 와 아두이노는 Serial 통신을 한다(UART). 그리고 ESP8266 도 펌웨어든 스케치든 통신을 위해서 Serial 을 이용한다. 무슨 이야긴가면, 아두이노를 USB to Serial TTL 처럼 bypass 가능한 모드로 실행 시키고, 아두이노 IDE 에서 그냥 스케치를 올리면 된다. 그러면 ESP8266 에 알아서 스케치가 올라가고 원하는 동작을 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CSIwz/btrwLhioyi6/Ixei90KkXb2KKtTA2irkH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CSIwz/btrwLhioyi6/Ixei90KkXb2KKtTA2irkH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CSIwz/btrwLhioyi6/Ixei90KkXb2KKtTA2irkH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCSIwz%2FbtrwLhioyi6%2FIxei90KkXb2KKtTA2irkH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;870&quot; height=&quot;472&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노 우노 기준으로는 위 그림처럼 하면 된다. 아두이노 메가라면 앞선 글에서 펌웨어를 올릴때와 같은 배선을 하면 된다.(&lt;a href=&quot;https://crystalcube.co.kr/215&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://crystalcube.co.kr/215&lt;/a&gt;) 메가라면 RESET 과 GND 를 연결해야 한다. 해당 포스팅을 참고하시라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;LED 를 점멸하는 간단한 스케치를 올려보자&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복잡할게 없으므로 순서대로 방법을 나열하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ESP8266 보드를 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보드매니저에 ESP8266 URL 을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://arduino.esp8266.com/stable/package_esp8266com_index.json&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://arduino.esp8266.com/stable/package_esp8266com_index.json&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UML9r/btrwJvuUCH7/EkMmHXEagH9OqdB1qvnjj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UML9r/btrwJvuUCH7/EkMmHXEagH9OqdB1qvnjj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UML9r/btrwJvuUCH7/EkMmHXEagH9OqdB1qvnjj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUML9r%2FbtrwJvuUCH7%2FEkMmHXEagH9OqdB1qvnjj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;802&quot; height=&quot;488&quot; data-origin-width=&quot;802&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 뒤 '보드 매니저'에 들어가서 esp8266 으로 검색되는 것을 설치한다. 글을 쓰고있는 현재기준 3.0.2 가 최신버전.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;443&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zVm7z/btrwJVz6v0s/2NbsiXevdpsRtiX4K4nGB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zVm7z/btrwJVz6v0s/2NbsiXevdpsRtiX4K4nGB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zVm7z/btrwJVz6v0s/2NbsiXevdpsRtiX4K4nGB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzVm7z%2FbtrwJVz6v0s%2F2NbsiXevdpsRtiX4K4nGB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;443&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;443&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 보드에서 'Generic ESP8266 Module' 을 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;763&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzxPCx/btrwIivP3Qx/Yf7sq7ryS8a44gdNiX7gUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzxPCx/btrwIivP3Qx/Yf7sq7ryS8a44gdNiX7gUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzxPCx/btrwIivP3Qx/Yf7sq7ryS8a44gdNiX7gUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzxPCx%2FbtrwIivP3Qx%2FYf7sq7ryS8a44gdNiX7gUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;864&quot; height=&quot;763&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;763&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선택하고나면, 아래 상당히 많은 각종 설정값들이 있다. 내 느낌에는 연결된 ESP8266 의 값을 알아서 읽어온 뒤 현재값으로 자동으로 선택되는 것 같다. 왜냐면 내가 지금 연결한 ESP8266 은 약간 불량품으로 Flash Mode 가 QIO 가 아닌 DOUT 으로 되어있는데, DOUT 으로 잘 선택되어 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이제 예제에서 Blink 를 선택해서 업로드하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;651&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kwBEV/btrwA0V6nWz/CW9qpKv49lDKkSOKtMkoN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kwBEV/btrwA0V6nWz/CW9qpKv49lDKkSOKtMkoN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kwBEV/btrwA0V6nWz/CW9qpKv49lDKkSOKtMkoN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkwBEV%2FbtrwA0V6nWz%2FCW9qpKv49lDKkSOKtMkoN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;697&quot; height=&quot;651&quot; data-origin-width=&quot;697&quot; data-origin-height=&quot;651&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하게도 업로드 하는 시점에 ESP8266 의 RESET 을 GND 와 잠시 연결했다 떼어주어야 한다. 앞서 결선도라면 RESET 버튼을 한번 눌러주면 된다. 그러고나면 문제없이 스케치가 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 Blink 소스코드에서 LED_BUILTIN 은 당연히 본인이 원하는 핀으로 바꿔주어야 한다. 나는 GPIO 2 번을 사용할 것이므로 2 로 변경해주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldSyv/btrwJ8Mwgfb/cXBVD2iB7D8cfEY8ncxlaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldSyv/btrwJ8Mwgfb/cXBVD2iB7D8cfEY8ncxlaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldSyv/btrwJ8Mwgfb/cXBVD2iB7D8cfEY8ncxlaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FldSyv%2FbtrwJ8Mwgfb%2FcXBVD2iB7D8cfEY8ncxlaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;713&quot; height=&quot;333&quot; data-origin-width=&quot;713&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업로드가 완료된 후 ESP8266 의 FLASH 연결을 끊어주고, Reset 을 한번 해 준다. 그리고 GPIO 2 에 LED 를 연결 하면 Blink 되는 결과를 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 ATTiny 시리즈에 부트로더를 올려서 작업하는 것을 먼저 경험했던터라 너무 어렵게 생각했던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모쪼록 이제 본격적으로 ESP8266 을 가지고 놀아봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>ESP01</category>
      <category>ESP8266</category>
      <category>아두이노</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/216</guid>
      <comments>https://crystalcube.tistory.com/216#entry216comment</comments>
      <pubDate>Tue, 22 Mar 2022 01:14:39 +0900</pubDate>
    </item>
    <item>
      <title>[ESP8266-01] 최신 Firmware 업그레이드</title>
      <link>https://crystalcube.tistory.com/215</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border: 1px solid #eeeeee; padding: 10px; background-color: #eeeeee;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;ESP8266-01 최신 펌웨어 업그레이드 (a.k.a 거지같은 것)&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WiFi 통신을 위해서 모듈을 하나 구매했다. 그건 바로 가장 저렴한 ESP 모듈 중에서 01 이라고도 불리는 ESP8266 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 그런지도 모르겠지만, 다들 펌웨어 업그레이드를 하길래 나도 한번 해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실,, 해야만 하는 줄 알았다 -_-;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분 아두이노 우노를 가지고 개발을 많이 하는데, 이 경우 Serial Port 가 1개 밖에 없기 때문에, ESP8266 과의 통신을 위해서는 SoftwareSerial 을 사용해야 했다. 그런데 SoftwareSerial 의 경우 115200 Baud Rate 를 지원하지 않는다. 그렇기 때문에 ESP8266 의 Baud Rate 를 57600 정도로 낮춰야 한다. 그럼 어떻게 낮춰야 하는가? &lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;&quot;&lt;/span&gt;AT&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;+&lt;/span&gt;UART_DEF&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;=&lt;/span&gt;57600&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;,8,1,0,0&quot; 이렇게 AT 커맨드로 낮출 수 있다. 그런데 이게 옛날 펌웨어에서는 지원되지 않는 커맨드이다. 만약 구매한 ESP8266 이 해당 커맨드를 지원하는 펌웨어가 설치되어 있다면, 아두이노를 이용해서 ESP8266 에 시리얼 연결 후, 해당 커맨드로 Baud Rate 를 낮추면 된다. 그러면 펌웨어 업그레이드 없이 SoftwareSerial 로도 통신이 가능하다. 안타깝게도 해당 커맨드를 지원하지 않는 펌웨어가 설치되어 있다면, 이 글에서처럼 펌웨어 업그레이드를 해 주어야 하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156;&quot;&gt;만약 ESP8266 을 가지고 아두이노와 통신할게 아니라, 자체적으로 아두이노 부트로더를 올려서 독립적인 ESP8266의 MCU 프로그래밍을 할 것이라면, 이 모든 것은 필요가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 해당 글은 &lt;span style=&quot;color: #ee2323;&quot;&gt;아두이노 메가 2560 기준&lt;/span&gt;이라는 점을 주의하기 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;하드웨어쟁이들은 상종하지 말아야지&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 내가 가장 크게 느낀것은 하드웨어쟁이들은 상종하지 말아야 겠다는 것이다. 소프트웨어도 불친절하고(90년대에도 이것보다 나았겠다!), UX 도 UI 도 너무나 불편했다. 제대로 된 자료도 없고 - 심지어 같은 내용인데 블로그마다 말이 다름 - 왜 그런지 설명 따위도 사치인 동네 같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 불평불만은 여기까지만 하고, 본론으로 들어 보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;삽질의 시작. 저항 그거 달아야해?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 ESP8266-01 모듈 세 개를 구매했다. 개당 천 몇백원 정도 준 것으로 기억한다. 아무튼 비싸도 2천원 내외.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;313&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l0Pdk/btrwqNhG7rS/8mUKkZuvmBc5twKJuCsmPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l0Pdk/btrwqNhG7rS/8mUKkZuvmBc5twKJuCsmPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l0Pdk/btrwqNhG7rS/8mUKkZuvmBc5twKJuCsmPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl0Pdk%2FbtrwqNhG7rS%2F8mUKkZuvmBc5twKJuCsmPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;301&quot; height=&quot;313&quot; data-origin-width=&quot;301&quot; data-origin-height=&quot;313&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 연결하는것부터 삽질의 시작이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에 자료를 찾아보았으나, 말이 다 다르고 방식이 다 다르다. -_-;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누구는 저항을 달아야 한다고 하고, 어떤 곳에서는 저항을 따로 달지 않았다. 무슨 이야긴가면 아두이노는 5V 전압을 사용하는데 ESP8266 의 경우에는 3.3V 를 사용하므로, RX 단자에 저항을 이용하여 전압을 낮춰야 한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과부터 이야기 하자면, 전혀 필요가 없다. 아니 있으면 안된다. 이것 때문에 삽질을 엄청 했다. 아무리 AT 커맨드를 날려도 수신되는게 없더라..... 나중에 저항을 전부 제거했더니 그때부터 RX 단자로 데이터가 수신되기 시작했다. -_-;; 난 참고로 1K옴과 2K옴을 이용하여 전압을 3.3V 로 만들었었다. 아무래도 전류량이 너무 낮아져서 수신되지 않는 것 같다. 아무튼 저항을 제거해도 이상이 없었다. 조금 작은 저항을 이용했으면 어떻게 되었을지는 궁금하긴 하나 귀찮다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mycTe/btrwnPHxu62/iQsFmGnSoKPAQkLC6aDRa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mycTe/btrwnPHxu62/iQsFmGnSoKPAQkLC6aDRa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mycTe/btrwnPHxu62/iQsFmGnSoKPAQkLC6aDRa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmycTe%2FbtrwnPHxu62%2FiQsFmGnSoKPAQkLC6aDRa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;477&quot; height=&quot;346&quot; data-origin-width=&quot;477&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 달지 않은 사람도 많고,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eHU15t/btrwmqHG159/gyqfHGHweEM6zkK0rL6gbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eHU15t/btrwmqHG159/gyqfHGHweEM6zkK0rL6gbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eHU15t/btrwmqHG159/gyqfHGHweEM6zkK0rL6gbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeHU15t%2FbtrwmqHG159%2FgyqfHGHweEM6zkK0rL6gbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;293&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 단 사람도 많단 말이다 -_-;;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 생각에는 SoftwareSerial 을 이용할 경우 5V 라서 저항을 달아야 하는 것 같고, 그 Hardware Serial 인 경우에는 달지 않아야 하나? 싶기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론은 &lt;span style=&quot;color: #ee2323;&quot;&gt;저항은 달지 않는편이 낫다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;그래서 Serial 통신을 위한 결선도는 어떻게 되는거야?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에 자료가 온통 아두이노 우노 기준이어서 삽질을 많이 했다. 참고로 난 우노가 없기 때문에 내가 한 방법이 우노에서도 동작하는건지, 아니면 메가에서만 그런지 잘 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 펌웨어를 업그레이드 하기 위해서는 다음과 같은 연결이 이루어 져야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. PC 와 아두이노가 연결 되어 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 아두이노는 USB 를 통해서 Serial 통신이 가능하도록, 컨버터(USB to TTL Serial) 같은 역할만 해야 한다. 즉, 아두이노에 의존하는건 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 아두이노의 Serial 단자를 ESP8266 과 연결해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. PC 는 현재 COM 포트에 연결된것이 아두이노가 아닌 ESP8266 으로 인식하고 통신할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 개념을 잘 생각하고 진행해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아두이노가 USB to TTL Serial 단자처럼 동작하게 하려면~~ 아두이노의 Reset 단자를 GND 와 연결시켜야 한다. 그렇지 않으면 아두이노는 업로드 되어 있는 스케치를 실행하기 때문이다. 그래서 그냥 단자만 살려두고, 아무짓도 못 하도록 Reset 을 GND 에 물려둔다. 그 이후에 전원을 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PC 와 ESP8266 이 직접 연결되어야 하므로, &lt;span style=&quot;color: #ee2323;&quot;&gt;아두이노의 RX 단자는 ESP8266 의 RX 단자에, 아두이노의 TX 단자는 ESP8266 의 TX 단자&lt;/span&gt;에 물려야 한다. 일반적으로 두 개의 디바이스가 통신하려면 RX 와 TX, TX 와 RX 처럼 반대로 물려야 하는데, 지금 하려는건 그게 아니다. 아두이노와 ESP8266 이 통신하게 하려는 것이 아니라, PC 와 ESP8266 이 통신하게 하려는 것이다. 그러므로 그냥 전선을 연결해서 연장한것처럼 생각하면 된다. RX 는 RX로, TX 는 TX 로, 저항 따위 없이.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/efHlg3/btrwoowbQ2v/rHkaL23Uool9tKrCBbBXg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/efHlg3/btrwoowbQ2v/rHkaL23Uool9tKrCBbBXg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/efHlg3/btrwoowbQ2v/rHkaL23Uool9tKrCBbBXg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FefHlg3%2FbtrwoowbQ2v%2FrHkaL23Uool9tKrCBbBXg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1067&quot; height=&quot;577&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;472&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfZLxu/btrwmY591KL/ckIy8zkskDBJIqs0dUCDE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfZLxu/btrwmY591KL/ckIy8zkskDBJIqs0dUCDE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfZLxu/btrwmY591KL/ckIy8zkskDBJIqs0dUCDE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfZLxu%2FbtrwmY591KL%2FckIy8zkskDBJIqs0dUCDE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;472&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;472&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가진게 없어서,, 있는 점프선으로 대강 연결했다. 다시 말하지만 저항 따윈 없다. 있으면 안되더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 결선도를 한번 넣어주면 좋은데, 그리기가 귀찮은 관계로 테이블로 대체하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;228&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgl6iY/btrwrGQbXGT/XPLb87lwVCx2pPb0NmgLg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgl6iY/btrwrGQbXGT/XPLb87lwVCx2pPb0NmgLg0/img.png&quot; data-alt=&quot;하드웨어쟁이들은 결선도는 핀이 왼쪽에 가도록 그려놓고는, Pin map 은 우측으로 뒤집어진걸 그려놓더라 -_-;; 난 동일하게 방향 맞춤!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgl6iY/btrwrGQbXGT/XPLb87lwVCx2pPb0NmgLg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcgl6iY%2FbtrwrGQbXGT%2FXPLb87lwVCx2pPb0NmgLg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;228&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;228&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하드웨어쟁이들은 결선도는 핀이 왼쪽에 가도록 그려놓고는, Pin map 은 우측으로 뒤집어진걸 그려놓더라 -_-;; 난 동일하게 방향 맞춤!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 180px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;&lt;b&gt;ESP8266-01&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;&lt;b&gt;아두이노 Mega 2560&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&lt;b&gt;비고&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Reset 을 GND 와 연결&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;아두이노가 터미널(젠더) 역할을 하도록 &lt;span style=&quot;color: #ee2323;&quot;&gt;항상 연결유지&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;TX (GPIO1)&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;TX0&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;CH_PD/EN&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;3.3V&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;RST&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;리셋이 필요할때만 GND 랑 연결/해제 할 예정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;3.3V&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;3.3V&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;GND&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;GND&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;FLASH (GPIO0)&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&lt;b&gt;펌웨어를 올릴때만 GND 와 연결상태 유지&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 15.3101%; height: 20px;&quot;&gt;RX (GPIO3)&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 20px;&quot;&gt;RX0&lt;/td&gt;
&lt;td style=&quot;width: 34.8062%; height: 20px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RST 는 다른 모듈들처럼 리셋이 필요한 시점에 GND 에 잠깐 연결했다가 떼면 된다. 그리고 FLASH (GPIO0) 은 펌웨어를 ESP8266 에 올릴때 (다운로드 라는 용어가 본래 맞음)만 연결된 상태를 유지한다. 잘 올라갔는지 나중에 COM 포트로 연결해서 AT 커맨드를 날릴때는 제거되어 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;그래서 어떤게 최신인데?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분도 참으로 삽질한 포인트 중 하나이다. 인터넷에 ESP8266 펌웨어 올리는 글을 찾아보면, 무지성으로 나온게 너무 많다. 2021년에 올라온 글에서 2016년에 만들어진 펌웨어를 올리고 있고, 또 어떤 글에서는 Flash Updater 를 쓰는데 어디서는 FLASH DOWNLOAD TOOL 을 쓴다. 누구는 2.0을 쓰고 누구는 3.0을 쓴다. 메뉴얼도 제 각각이다. -_-;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 온라인에 떠도는 모든 툴을 다 써봤다고 감히 이야기 해 정도이다. 결론만 말하겠다. 과정을 일일이 설명하기에는 너무 많은 삽질들을 해 왔기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br5CBa/btrwonD7IyY/Xt00jAfhXvQ70eXUOJWMKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br5CBa/btrwonD7IyY/Xt00jAfhXvQ70eXUOJWMKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br5CBa/btrwonD7IyY/Xt00jAfhXvQ70eXUOJWMKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr5CBa%2FbtrwonD7IyY%2FXt00jAfhXvQ70eXUOJWMKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;642&quot; height=&quot;352&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 생긴 프로그램이 있다. 아마 다른 글들을 봤다면 한번씩 마주쳤을 툴이다. 결론부터 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 필요한 시점은 딱 한가지다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ESP8266 이 맛탱이가 가서 공장 초기화를 해야 할때.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그때 어떤것을 받아야 하는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.ai-thinker.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://www.ai-thinker.com&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647700194665&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Ai-Thinker Co., Ltd&quot; data-og-description=&quot;B&amp;amp;T provides customers with N92 series modules with wide coverage, multiple connections, high speed, low cost, low power consumption, excellent architecture, etc., which can be widely used in various IoT occasions, suitable for smart cities, smart meters ,&quot; data-og-host=&quot;www.ai-thinker.com&quot; data-og-source-url=&quot;http://www.ai-thinker.com/&quot; data-og-url=&quot;http://www.ai-thinker.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.ai-thinker.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.ai-thinker.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Ai-Thinker Co., Ltd&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;B&amp;amp;T provides customers with N92 series modules with wide coverage, multiple connections, high speed, low cost, low power consumption, excellent architecture, etc., which can be widely used in various IoT occasions, suitable for smart cities, smart meters ,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ai-thinker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사이트에서 받으면 되는데.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'상단 Document' &amp;gt; '본문 중간쯤 WiFi Module Series' &amp;gt; '본문 ESP8266 series' &amp;gt; '본문 하단 Various AT firmware'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 아래 보면 다음과 같이 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공장 초기 AT 펌웨어!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beHYF0/btrwpuCYOHc/KY9lnZh4XNikOeROW1qHzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beHYF0/btrwpuCYOHc/KY9lnZh4XNikOeROW1qHzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beHYF0/btrwpuCYOHc/KY9lnZh4XNikOeROW1qHzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeHYF0%2FbtrwpuCYOHc%2FKY9lnZh4XNikOeROW1qHzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1043&quot; height=&quot;293&quot; data-origin-width=&quot;1043&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일일이 찾아가기 귀찮다면 아래 링크를 클릭하면 된다. 홈페이지가 리뉴얼되면 주소가 종종 바뀌는 경우가 있으므로 위에서 굳이 설명한것 뿐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.ai-thinker.com/en/%E5%9B%BA%E4%BB%B6%E6%B1%87%E6%80%BB&quot;&gt;https://docs.ai-thinker.com/en/%E5%9B%BA%E4%BB%B6%E6%B1%87%E6%80%BB&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647700200591&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Various AT firmware summary |
        安信可科技&quot; data-og-description=&quot;&quot; data-og-host=&quot;docs.ai-thinker.com&quot; data-og-source-url=&quot;https://docs.ai-thinker.com/en/%E5%9B%BA%E4%BB%B6%E6%B1%87%E6%80%BB&quot; data-og-url=&quot;https://docs.ai-thinker.com/en/%E5%9B%BA%E4%BB%B6%E6%B1%87%E6%80%BB&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.ai-thinker.com/en/%E5%9B%BA%E4%BB%B6%E6%B1%87%E6%80%BB&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.ai-thinker.com/en/%E5%9B%BA%E4%BB%B6%E6%B1%87%E6%80%BB&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Various AT firmware summary | 安信可科技&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.ai-thinker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 위 파일을 다운로드 해서 압축을 풀고나면(아니 하드웨어 쟁이들은 언제적 rar 을 쓰고 있는거야 -_-;;;),,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ai-Thinker_ESP8266_DOUT_8Mbit_v1.5.4.1-a_20171130 &amp;gt; Ai-Thinker_ESP8266_DOUT_8Mbit_v1.5.4.1-a_20171130.bin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파일이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것을 위에 'ESP8266 Flash Downloader' 에 넣어 준 뒤, COM1 대신 본인 아두이노가 연결된 포트를 써 주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 다음에 ESP8266 의 'FLASH (GPIO0)' 핀을 아두이노 GND 와 연결한다. 마지막으로 ESP8266 의 RST 단자를 GND 와 잠깐 연결했다가 뗀다. 그리고나서 Download 버튼을 누르면 해당 bin 파일이 ESP8266 의 Flash 칩에 복사가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 잠깐!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;펌웨어는 어디에 저장되는가? 바로 FLASH 메모리에 저장된다. 그렇다면 FLASH 메모리는 어디에 있는가? ESP8266 에 보면 다리가 총 8개 달린 칩이 하나 있다. 그것이 FLASH 메모리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 요 녀석의 용량은 얼마인가? 1MB 이다. 즉 8Mbit 로 환산된다. 그게 왜 중요한가? 그것은 바로 펌웨어가 이곳에 저장될 것이므로 우리가 올릴 수 있는 &lt;span style=&quot;color: #ee2323;&quot;&gt;펌웨어의 용량은 1MB 보다 작아야 한다는 이야기&lt;/span&gt;다. 즉 1024KB 이하만 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에 뒤지다보면 ESP8266 의 32Mbit (즉 4MB) 짜리 펌웨어들이 있는데, 이것은 ESP8266-01 에는 올릴수가 없는 것이다. 그러니 이 부분에서 삽질하지 않도록 하자. ESP8266-IDF-AT_V2.2.0.0.zip 이런 파일도 굴러다니는데(공식 사이트에 있음), 이것도 용량이 2MB 이므로 당연히 ESP01 에는 올릴수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일의 업로드가 다 끝났다면 이제 FLASH 핀을 GND 에서 제거한다. 그리고 아두이노(혹은 다른)의 시리얼 모니터를 연다. &lt;span style=&quot;color: #ee2323;&quot;&gt;보드레이트는 74880&lt;/span&gt; 이고, 줄바꿈은 'Both NL &amp;amp; CR' 로 해야한다. 소프트웨어 개발자라면 알겠지만, 개행문자를 New line 과 Carriage&amp;nbsp;return 모두 넣겠다는 뜻이다. '\n\r' 를 의미.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2MFkN/btrwoopsYKs/wo6ghjkRgypAhppRSUMDX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2MFkN/btrwoopsYKs/wo6ghjkRgypAhppRSUMDX1/img.png&quot; data-alt=&quot;주의하라 115200 이 아니라 74880 이다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2MFkN/btrwoopsYKs/wo6ghjkRgypAhppRSUMDX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2MFkN%2FbtrwoopsYKs%2Fwo6ghjkRgypAhppRSUMDX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;384&quot; height=&quot;35&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주의하라 115200 이 아니라 74880 이다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 인터넷을 좀 본 사람들은 의문을 가질 것이다. 왜 115200 이나 9600 도 아닌 74880 인가?!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그것은 ESP8266-01 의 기본 보드레이트가 74880 이기 때문이다. 이렇게 하지 않고 115200 이나 9600 으로 설정하면, 처음 ESP8266-01 이 구동될때 나오는 메세지를 볼 수가 없다. 깨진 문자가 출력되어 내용을 볼 수 없다. 그러므로 의심하지 말고 74880 으로 세팅하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 ESP8266-01 의 RST 단자를 GND 와 연결한 뒤 1초정도 있다가 제거를 한다. 그러면 시리얼 모니터에 ESP8266 의 부팅 메세지가 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647701287976&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 1856, room 16 
tail 0
chksum 0x63
load 0x3ffe8000, len 776, room 8 
tail 0
chksum 0x02
load 0x3ffe8310, len 552, room 8 
tail 0
chksum 0x79
csum 0x79

2nd boot version : 1.5
  SPI Speed      : 40MHz
  SPI Mode       : DOUT
  SPI Flash Size &amp;amp; Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000

rf cal sector: 249
rf[112] : 00
rf[113] : 00
rf[114] : 01

SDK ver: 1.5.4.1(39cb9a32) compiled @ Jul  1 2016 20:04:35
phy ver: 972, pp ver: 10.1

)?NO&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 보드레이트를 115200 으로 변경 한 후, AT+GMR 이라고 커맨드를 날려보면 아래처럼 추가 정보를 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1647703811180&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;AT version:1.2.0.0(Jul  1 2016 20:04:45)
SDK version:1.5.4.1(39cb9a32)
v1.0.0
Mar 11 2018 18:27:31
OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2nd boot version 과 SDK 의 정보를 보라. 공장초기화의 맛이 어떠냐?!! 무려 6년전의 파일이다. ㅎㅎ.....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 SPI Mode 를 보면 DOUT 으로 되어 있다. 이건 나중에 설명하도록 하겠다. 간략히 설명하자면 우리가 받은 초기화 bin 파일이 DOUT 이다.(파일명 참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 맨 아랫줄에 깨진듯한 문자는 Ready 라는 문자열이다. 이것을 확인하고 싶다면, 보드레이트를 115200 으로 바꾸고나서, ESP8266 의 Reset 단자를 GND 와 잠깐 연결했다가 떼어 보아라. 위 화면과는 다르게 앞 부분이 전부 깨진 문자로 나오고, 맨 아랫줄만 Ready 라고 제대로 보일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 이건 공장초기화 방법이고.. 이제 본래 목적대로 최신 펌웨어를 업그레이드 해 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;그래서 최신버전은 어떻게 올리는데?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신버전 관련해서 삽질을 많이 했다. 온통 어디서 주워온 파일들만 존재하고, 그래서 도대체 그 파일이 어디서 생산되는지 정보가 없다. 하드웨어쟁이들은 아직도 90년대초 HD 5.25인치 플로피 디스크로 파일을 주고 받던 - 출처도 모르는 - 시절에 머물러 있는 것 같다. 그 누구하나 제대로 된 정보를 제공하는 곳이 없다. -_-&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 인터넷에서 펌웨어를 구하다보면 아래 사이트 이야기가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.espressif.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.espressif.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647701698694&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Wi-Fi &amp;amp; Bluetooth MCUs and AIoT Solutions I Espressif Systems&quot; data-og-description=&quot;Welcome to Espressif's Meeting Series at CES 2019 Jan 8 - 11, 2019 CES attendees are invited to book one-to-one meetings with Espressif's representatives at CES 2019, so they can have a more structured and productive business discussion. To book a meeting,&quot; data-og-host=&quot;www.espressif.com&quot; data-og-source-url=&quot;https://www.espressif.com/&quot; data-og-url=&quot;https://www.espressif.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pQty1/hyNLKtoRbR/rkV665EDxvUb3cETzvkNfk/img.png?width=2880&amp;amp;height=1000&amp;amp;face=0_0_2880_1000,https://scrap.kakaocdn.net/dn/PYjot/hyNLP9jzGU/aPzoffm4Kt6NmYdaYhJC51/img.jpg?width=2850&amp;amp;height=1000&amp;amp;face=0_0_2850_1000,https://scrap.kakaocdn.net/dn/b7CEYN/hyNJ5MH9XL/m0gwYRqEKrYtQ5I6vlIYY0/img.jpg?width=2850&amp;amp;height=1000&amp;amp;face=0_0_2850_1000&quot;&gt;&lt;a href=&quot;https://www.espressif.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.espressif.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pQty1/hyNLKtoRbR/rkV665EDxvUb3cETzvkNfk/img.png?width=2880&amp;amp;height=1000&amp;amp;face=0_0_2880_1000,https://scrap.kakaocdn.net/dn/PYjot/hyNLP9jzGU/aPzoffm4Kt6NmYdaYhJC51/img.jpg?width=2850&amp;amp;height=1000&amp;amp;face=0_0_2850_1000,https://scrap.kakaocdn.net/dn/b7CEYN/hyNJ5MH9XL/m0gwYRqEKrYtQ5I6vlIYY0/img.jpg?width=2850&amp;amp;height=1000&amp;amp;face=0_0_2850_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Wi-Fi &amp;amp; Bluetooth MCUs and AIoT Solutions I Espressif Systems&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Welcome to Espressif's Meeting Series at CES 2019 Jan 8 - 11, 2019 CES attendees are invited to book one-to-one meetings with Espressif's representatives at CES 2019, so they can have a more structured and productive business discussion. To book a meeting,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.espressif.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 펌웨어를 찾아서 가 보면,, 아래처럼 절망적인 글이 보인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkgEZb/btrwnO20Mbb/fdG8BPIAPzH51FE1gH9tk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkgEZb/btrwnO20Mbb/fdG8BPIAPzH51FE1gH9tk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkgEZb/btrwnO20Mbb/fdG8BPIAPzH51FE1gH9tk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkgEZb%2FbtrwnO20Mbb%2FfdG8BPIAPzH51FE1gH9tk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;948&quot; height=&quot;354&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ESP8266 NonOS AT Bin 이 Deprecated 되었다. -_-a&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;날짜가 무려 2021.12.28 이다. 그리고 내용을 읽어보면 ESP8266 IDF AT Bin 을 사용하란다. 바로 밑에 있다. 이녀석의 Release Date 를 보면 2020.07.29 이다. 앵?? 왜 더 과거지???&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모쪼록 이것을 눌러서 들어가보면, 링크의 링크의 링크... 결국 Github 에 도착한다. ㅅㅂ... 어쨋든 그렇게해서 파일을 얻은것을 보면..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chIra4/btrwl9zrVC4/jho5fpp34ZYJRGicgwgi41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chIra4/btrwl9zrVC4/jho5fpp34ZYJRGicgwgi41/img.png&quot; data-alt=&quot;어쩌라고....&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chIra4/btrwl9zrVC4/jho5fpp34ZYJRGicgwgi41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchIra4%2Fbtrwl9zrVC4%2Fjho5fpp34ZYJRGicgwgi41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;277&quot; data-origin-width=&quot;608&quot; data-origin-height=&quot;277&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;어쩌라고....&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도대체 어떤 파일을 올려야 하는건지 알 수가 없다. 일단 확실한것은 앞서 이야기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;했듯이 1024KB 를 초과하는것은 ESP8266-01 용 펌웨어가 아니다. 그러니 시도조차 하지 마시라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 여기서 몇가지 bin 파일을 가지고 실험을 했으나 모두 실패하였다. 혹시라도 위 파일을 가지고 성공한 사람이 있다면 코멘트를 달아주면 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 그래서 여기저기 찾다가 끝내 해당 펌웨어의 출처를 찾았다. Github 가 존재하고 있었다. 제조사인 espressif 의 Github 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/espressif/ESP8266_NONOS_SDK/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/espressif/ESP8266_NONOS_SDK/releases&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 보면 현재날짜 기준으로 최신 파일인 1.7.5 (v3.5.0) 이 존재한다. 2021년 10월 18일 버전이다. 다운로드 받아서 열어봤더니, 빌드된 파일이 포함되어 있다. 대략 압축을 풀면 이렇게 되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8QuKp/btrwpjOoDbx/hOsxe3nbV861FArm1osL40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8QuKp/btrwpjOoDbx/hOsxe3nbV861FArm1osL40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8QuKp/btrwpjOoDbx/hOsxe3nbV861FArm1osL40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8QuKp%2FbtrwpjOoDbx%2FhOsxe3nbV861FArm1osL40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;635&quot; height=&quot;260&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 이제 업로드하는 툴이 필요한데, 이것도 삽질을 많이 해봤다. 최신버전도 받아보고 여러가지 버전을 받아서 테스트 해 보았으나 내 경우에는 'FLASH_DOWNLOAD_TOOLS_v2.4_150924' 버전이 문제없이 정상동작 하였다. (웃긴건 실행하면 v2.3으로 나옴)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'flash_download_tool_3.9.2' 로도 해봤는데 안되더라 -_-;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/ESDSM/btrwnaSbOit/YsgknimYSqoLyjOqxU0EG1/FLASH_DOWNLOAD_TOOLS_v2.4_150924.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;FLASH_DOWNLOAD_TOOLS_v2.4_150924.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;7.44MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 별개로 공식적인 Tool 은 아래에서 다운로드 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.espressif.com/en/support/download/other-tools&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.espressif.com/en/support/download/other-tools&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1647875498499&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Tools | Espressif Systems&quot; data-og-description=&quot;Quickly get Espressif's RF performance test tool, test firmware, test guide and certification test guide for ESP32, ESP32-C3, ESP32-S2, and ESP8266 series of product.&quot; data-og-host=&quot;www.espressif.com&quot; data-og-source-url=&quot;https://www.espressif.com/en/support/download/other-tools&quot; data-og-url=&quot;https://www.espressif.com/en/support/download/other-tools&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b1c5HA/hyNMY6dqAA/cQDgwsaUSXQ7pOetaOAdEK/img.jpg?width=2851&amp;amp;height=571&amp;amp;face=0_0_2851_571&quot;&gt;&lt;a href=&quot;https://www.espressif.com/en/support/download/other-tools&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.espressif.com/en/support/download/other-tools&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b1c5HA/hyNMY6dqAA/cQDgwsaUSXQ7pOetaOAdEK/img.jpg?width=2851&amp;amp;height=571&amp;amp;face=0_0_2851_571');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Tools | Espressif Systems&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Quickly get Espressif's RF performance test tool, test firmware, test guide and certification test guide for ESP32, ESP32-C3, ESP32-S2, and ESP8266 series of product.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.espressif.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다운로드 받아서 실행하면 다음과 같이 창이 뜨는데, 여기서 이렇게 설정하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;633&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvVZ4N/btrwA5WtA7n/kKU0bOYk93GONlTwYvhd6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvVZ4N/btrwA5WtA7n/kKU0bOYk93GONlTwYvhd6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvVZ4N/btrwA5WtA7n/kKU0bOYk93GONlTwYvhd6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvVZ4N%2FbtrwA5WtA7n%2FkKU0bOYk93GONlTwYvhd6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;633&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;633&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색으로 쳐 놓은 박스는 주의할 부분이다. 첫번째로 좌측에 체크박스가 모두 체크되어 있어야 한다. 프로그램이 ㅂㅅ이라서 bin 파일명쪽의 녹색 하이라이트와 체크박스 싱크가 안 맞는 경우가 있다. 무조건 체크박스만 믿어라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 우측에 ADDR 이라고 플래시 메모리 어디에 써야 하는지 메모리 주소가 나와 있는데, 이건 다들 무지성으로 설명하더라 -_-;; 이건 bin 파일 설명을 보아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;bin &amp;gt; at 폴더에 보면, README.md&lt;/span&gt; 파일이 있다. 이것을 열어보자.&lt;/p&gt;
&lt;pre id=&quot;code_1647703039331&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Notice: 
AT firmware becomes larger since it supports more functions. So, we provide two firmwares here:

* 1024+1024: Normal AT, which is compiled from ESP8266_NONOS_SDK/examples/at, and uses mbedTLS lib.
* 512+512: Nano AT, which is compiled from ESP8266_NONOS_SDK/examples/at_nano, and uses SSL lib that supports less cipher suites.
It is suggested to use normal AT(1024+1024), if your flash size is 2MB or larger.

# BOOT MODE
## download

### Flash size 8Mbit: 512KB+512KB
    boot_v1.2+.bin              0x00000
    user1.1024.new.2.bin        0x01000
    esp_init_data_default.bin   0xfc000
    blank.bin                   0x7e000 &amp;amp; 0xfe000


### Flash size 16Mbit-C1: 1024KB+1024KB
    boot_v1.2+.bin              0x00000
    user1.2048.new.5.bin        0x01000
    esp_init_data_default.bin   0x1fc000
    blank.bin                   0xfe000 &amp;amp; 0x1fe000&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 이런식으로 쭉~ 뭐가 써있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 누차 이야기하지만 &lt;span style=&quot;color: #ee2323;&quot;&gt;8Mbit 플래시를 가지고 있는 ESP8266&lt;/span&gt; 이므로 첫번째 부분에 내용을 따라야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;boot_v1.2+.bin 이라고 되어 있는데 -_- 1.2 이상 버전이면 된다는 뜻이다. + 가 파일명이 아니라는거에 주의하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\bin\boot_v1.7.bin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\bin\at\512+512\user1.1024.new.2.bin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\bin\esp_init_data_default_v08.bin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\bin\blank.bin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;\bin\blank.bin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 4개의 파일을 우측에 나와있는 각 주소에 넣으면 된다. &lt;span style=&quot;color: #ee2323;&quot;&gt;blank.bin 은 잘 보면 주소가 두 개 나와있다&lt;/span&gt;. &amp;amp; 표시에 헷갈리지 말자(하드웨어쟁이들은 왜 &amp;amp; 를 함부로 쓰는가 -_-; 그냥 콤마 찍으면 안되나?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 '&lt;span style=&quot;color: #ee2323;&quot;&gt;DoNotChgBin&lt;/span&gt;' 이라는게 있는데, 이건 체크하면 안된다. 앞서 공장초기화처럼 단일 bin 파일을 업로드 할때는 체크를 해야하고, 지금처럼 여러개의 bin 파일을 올려서 합치는 경우에는 &lt;span style=&quot;color: #ee2323;&quot;&gt;체크하면 안된다&lt;/span&gt;. 절대로 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;SPI Mode 는 일단 QIO&lt;/span&gt; 로 하자. 자세한 설명은 나중에 하도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 COM 포트를 본인 환경에 맞게 설정하고 Baud Rate 는 115200 으로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 준비가 다 끝났다. ESP8266 의 FLASH 단자를 GND 에 연결하고, RST 단자는 GND 에 잠시 붙였다가 떼자. 그리고나서 START 버튼을 누르면, 쭉~~ 파일이 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8k75r/btrwnssmICZ/v91K4vlpXf9hSDMHzvfgO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8k75r/btrwnssmICZ/v91K4vlpXf9hSDMHzvfgO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8k75r/btrwnssmICZ/v91K4vlpXf9hSDMHzvfgO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8k75r%2FbtrwnssmICZ%2Fv91K4vlpXf9hSDMHzvfgO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;741&quot; height=&quot;512&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누가 하드웨어 쟁이 아니랄까봐 100% 찍히도록 못 만들고 99% 에서 끝난다. 소프트웨어쟁이들은 왜 저렇게 나오는지 알 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 FLASH 단자를 GND 에서 제거하고, 시리얼 모니터를 열자. 그리고나서 Baud rate 를 다시 74880 으로 변경한다. 이제 RST 단자를 GND 에 붙였다가 떼어서 출력되는 값을 확인하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647703861984&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x40100000, len 2592, room 16 
tail 0
chksum 0xf3
load 0x3ffe8000, len 764, room 8 
tail 4
chksum 0x92
load 0x3ffe82fc, len 676, room 4 
tail 0
chksum 0x22
csum 0x22

2nd boot version : 1.7(5d6f877)
SPI Speed : 40MHz
SPI Mode : QIO
SPI Flash Size &amp;amp; Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000

correct flash map
V2
Mo
Backup
 ⸮rf cal sector: 251
freq trace enable 0
rf[112] : 00
rf[113] : 00
rf[114] : 01

SDK ver: 3.0.5(b29dcd3) compiled @ Oct  9 2021 09:52:05
phy ver: 1156_0, pp ver: 10.2

)⸮NOAT+GMR
AT version:1.7.5.0(Oct  9 2021 09:26:04)
SDK version:3.0.5(b29dcd3)
compile time:Oct 15 2021 18:05:30
Bin version(Wroom 02):1.7.5
OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;싱싱한 버전이 올라갔다. :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것으로 완료!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;전 안되는데요???&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 부분에서 기대했던 로그가 아니라 다음과 같은 거지같은 화면을 마주하고 있는 사람도 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1647703983879&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x40100000, len 2592, room 16 
tail 0
chksum 0xef
load 0x88888888, len -2004318072, room 8 
flash read err, ets_unpack_flash_code
ets_main.c 
 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 2592, room 16 
tail 0
chksum 0xef
load 0x88888888, len -2004318072, room 8 

 ets Jan  8 2013,rst cause:2, boot mode:(3,2)

load 0x40100000, len 2592, room 16 
tail 0
chksum 0xef
load 0x88888888, len -2004318072, room 8&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절망적인 것이다. 나도 잘 한다. 당해봤으니까..............&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 이유는 앞서 언급했던 SPI 모드 때문이다. 본래 ESP8266-01 의 스팩상 달려있는 플래시 메모리는 QIO 모드가 지원되어야 하는 것 같다. 그런데 ㅅㅂ 아닌 모듈이 있더라. 난 구매한 세 개 중에서 한 개가 그랬다. 이게 Quad IO 인지 Dual IO 인지 등등 그런건데, 나도 정확하게는 모른다. 중요한건지도 사실 잘 모르겠다. 대충 속도랑 관련 있는것 같은데, 해결 방법은 안다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GP3Ka/btrwp1BxMC0/zFNK3uYiXcDCSUCfQotwc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GP3Ka/btrwp1BxMC0/zFNK3uYiXcDCSUCfQotwc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GP3Ka/btrwp1BxMC0/zFNK3uYiXcDCSUCfQotwc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGP3Ka%2Fbtrwp1BxMC0%2FzFNK3uYiXcDCSUCfQotwc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;634&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;634&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 구린,, &lt;span style=&quot;color: #ee2323;&quot;&gt;DOUT 으로 하고 펌웨어를 올린 후에 해 보면 된다.&lt;/span&gt; 그러면 아래처럼 출력을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬프지만 ISP 부분을 보면 DOUT 이라고 마빡에 찍혀있다 -_-;&lt;/p&gt;
&lt;pre id=&quot;code_1647704188146&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x40100000, len 2592, room 16 
tail 0
chksum 0xf3
load 0x3ffe8000, len 764, room 8 
tail 4
chksum 0x92
load 0x3ffe82fc, len 676, room 4 
tail 0
chksum 0x22
csum 0x22

2nd boot version : 1.7(5d6f877)
SPI Speed : 40MHz
SPI Mode : DOUT
SPI Flash Size &amp;amp; Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000

V2
Mo
Backup
 yrf cal sector: 251
freq trace enable 0
rf[112] : 00
rf[113] : 00
rf[114] : 01

SDK ver: 3.0.3(8427744) compiled @ Mar 19 2020 18:11:05
phy ver: 1156_0, pp ver: 10.2

)͈⸮
 ⸮⸮
AT+GMR
AT version:1.7.3.0(Mar 19 2020 18:15:04)
SDK version:3.0.3(8427744)
compile time:Apr 27 2020 10:06:00
Bin version(Wroom 02):3.0.3
OK&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 중국산 짝퉁인건지, 잘못 만들어진건지 사기당한건지 모르겠지만, 이 녀석은 죽어도 DOUT 밖에 안되더라. DIO, QOUT 등등 다 해봤다. DOUT 하나밖에 안되더라. 수없이 많이 해 봤으므로 여러분은 삽질하지 않길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것으로 펌웨어 업그레이드 하는 설명을 마치도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삽질을 그렇게 했음에도 아직 남는 궁금증이 있다. 왜 아두이노 우노의 경우에는 아두이노의 RESET 과 GND 를 연결한 상태로 유지하지 않는가? 안해도 동작하는걸까? 그리고 펌웨어를 꼭 업그레이드 해야만 AT 커맨드로 보드레이트를 9600 설정 가능한것처럼 하던데, 그냥 시리얼 모니터랑 ESP8266 이랑 연결한 상태에서 AT 커맨드로 보드레이트를 세팅하면 되는거 아닌가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;연결에 대한 요약&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 요약을 하자면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 아두이노의 RESET 과 GND 를 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 아두이노와 PC 를 USB 케이블로 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. ESP8266의 RESET 만 제외하고 나머지(FLASH 포함)을 모두 아두이노와 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 펌웨어를 올리기 직전에 ESP8266 의 RESET 을 GND 와 1초간 연결했다가 끊는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 펌웨어를 올린다.(공식적으로는 다운로드라는 표현을 씀)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 완료되면, FLASH 단자의 연결을 제거하고 RESET 을 GND 와 약 1초간 연결했다 끊어서 초기화 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: #353535;&quot;&gt;&lt;b&gt;기타 문제 상황&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr style=&quot;display: block; border: black 0 none; border-top: black 1px solid; height: 1px;&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음날 AT 커맨드로 작업을 하려고 했는데 다음과 같은 상황이 벌어졌다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Il4Nb/btrwqNpAUh5/rLMAgGE0kQ9Ks5QkQLk5K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Il4Nb/btrwqNpAUh5/rLMAgGE0kQ9Ks5QkQLk5K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Il4Nb/btrwqNpAUh5/rLMAgGE0kQ9Ks5QkQLk5K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIl4Nb%2FbtrwqNpAUh5%2FrLMAgGE0kQ9Ks5QkQLk5K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;678&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AT 라고 날렸는데, ERROR 이 찍혔다. 뭐지?????????????&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때는 반드시 하단의 new line 정책을 확인하자. '새 줄' 로 되어 있어서 그렇다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;693&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ljm9u/btrwonSBrml/7Ib381zkgpW0EMdZwSeSoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ljm9u/btrwonSBrml/7Ib381zkgpW0EMdZwSeSoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ljm9u/btrwonSBrml/7Ib381zkgpW0EMdZwSeSoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fljm9u%2FbtrwonSBrml%2F7Ib381zkgpW0EMdZwSeSoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;693&quot; height=&quot;677&quot; data-origin-width=&quot;693&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Both NL &amp;amp; CR' 로 변경하고 나니 잘 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 내가 삽질한 결과는 여기까지다. :) 많은 도움이 되었길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <category>ESP01</category>
      <category>ESP8266</category>
      <category>아두이노</category>
      <category>펌웨어</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/215</guid>
      <comments>https://crystalcube.tistory.com/215#entry215comment</comments>
      <pubDate>Sun, 20 Mar 2022 00:46:30 +0900</pubDate>
    </item>
    <item>
      <title>전압 측정기 만들기</title>
      <link>https://crystalcube.tistory.com/214</link>
      <description>&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;하드웨어를 제작은 휴식하는데 참 좋은 취미인 것 같습니다.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;내가 필요한 것을 직접 만들어 쓰면 기분도 좋고, 만드는 과정에서 인두 끝에서 퍼져 나오는 &lt;s&gt;납 연기를 마시다보면 세상에 그런 쾌락이 따로 없지요.&lt;/s&gt;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;아무튼 이번에 무엇을 만들어 볼까하다가 전압 측정기를 만들면 좋겠다는 생각을 했습니다. 지난번 유아용 전동 자동차를 개조한 것과 비슷한 맥락으로 이번에도 애들을 위해서 만드는 것 입니다. 아이들이 가지고 노는 장난감에는 건전지가 들어가는 것이 많습니다. 그러다보면 건전지의 전압을 측정해서 남은 수명을 가늠하는데요. 그때마다 멀티미터를 공구함에서 꺼내고 측정 후 다시 넣는 일은 여간 귀찮은게 아닙니다. 그리하여, 이번에 고놈을 하나 만들어서 상시 꺼내놓고 쓸 계획입니다.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;구상을 해 보자&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;우선 저는 하드웨어를 전공한 적도, 따로 배운적도 없습니다. 전공자라면 매우 간단하게 만들겠지만 저는 그게 아니므로 머리를 좀 써야 할 것 같습니다.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;어떻게 만들어야 하나?&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;일단 만들고 싶은건 3V 짜리 수은전지(단추형)으로 동작하며, 7-세그먼트 LED 로 전압을 표시하는 것 입니다. 그리고 최대한 작게 만들고 싶습니다. 전력소모도 적어서 오랫동안 베터리 교체 없이 쓰고 싶고요.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;필요한 것들을 나열해 보았습니다.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;ATTiny45 MCU, 7-Segment LED 2개 (Common Cathode), 저항들, 만능기판, LED 제어를 위한 Shift Register 2개. 전원 스위치, 기타 잡다한 것들&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;ATTiny 시리즈를 보면, 총 8개의 다리 중에 제가 사용 가능한건 5개 입니다. VCC, Ground, Reset 을 빼고나면 말이죠. 그럼 이 전압측정기를 5개의 다리를 가지고 만들어야 한다는건데, Shift Register 를 쓰면 가능할 것 같습니다. Shift Register 에 3개를 주고, 전압 측정을 위해 Analog Input 으로 1개를 쓰나면 그래도 1개가 남습니다 :)&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;회로도를 한번 그려봅시다.&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;font-size: 1.12em;&quot; data-ke-size=&quot;size16&quot;&gt;이제 PCB 에 만들기 전에, 제 생각대로 실제 동작하는지 브레드 보드에 회로구성을 해 봅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20200125_181221.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VvKbD/btqBFMEXzeB/GPyXqjImmgoosVGWy5Uk71/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VvKbD/btqBFMEXzeB/GPyXqjImmgoosVGWy5Uk71/img.jpg&quot; data-alt=&quot;망할..사진 회전이 안된다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VvKbD/btqBFMEXzeB/GPyXqjImmgoosVGWy5Uk71/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVvKbD%2FbtqBFMEXzeB%2FGPyXqjImmgoosVGWy5Uk71%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;2268&quot; data-filename=&quot;20200125_181221.jpg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;망할..사진 회전이 안된다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 동작은 잘 합니다. 그런데,, 7-Segment LED 를 주문을 잘못하는 바람에 Common Cathode 가 아니라 Common Anode 가 와버렸습니다 -_-;;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Hardware</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/214</guid>
      <comments>https://crystalcube.tistory.com/214#entry214comment</comments>
      <pubDate>Fri, 31 Jan 2020 19:56:05 +0900</pubDate>
    </item>
    <item>
      <title>정신건강에 좋은 파일 공유하기</title>
      <link>https://crystalcube.tistory.com/209</link>
      <description>&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;txc-textbox&quot; style=&quot;border: 1px solid rgb(238, 238, 238); padding: 10px; background-color: rgb(238, 238, 238);&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;정신건강에 좋은 파일 공유하기&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 개발을 하다보면, 자신의 앱에서 생산한 파일을 다른 앱으로 공유해야 하는 경우가 종종 발생합니다.&lt;/p&gt;&lt;p&gt;보통 촬영한 사진, 동영상 등이 되겠지요.&lt;/p&gt;&lt;p&gt;그러나 안드로이드의 개떡같은 '하위호환 따위 개나 줘버려' 정책에 의해서 이 단순한 기능을 버그없이 개발하는것은&amp;nbsp;상당히 어렵습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: rgb(53, 53, 53);&quot;&gt;&lt;b&gt;&lt;strike&gt;FileProvider 를 사용하자!&lt;/strike&gt; 는 훼이크다!&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(53, 53, 53);&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;hr style=&quot;display:block; border: black 0 none; border-top: black 1px solid; height: 1px&quot;&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;span style=&quot;color: rgb(53, 53, 53);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(53, 53, 53);&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;안드로이드 Build SDK 버전 24 이상부터(N버전) 파일 공유시에 FileProvider 를 통해서 content:// 형태의 uri 를 만들어 공유하도록 강제되었습니다.&lt;/p&gt;&lt;p&gt;이전버전에서야 file:///storage/emulator/0/... 과 같은 uri 를 사용해서 공유해도 잘 되었습니다. 하지만 N 이상부터는 Error 가 발생하면서 App 이 Crash 됩니다. (하..ㅅㅂ것들..)&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아무튼 그래서 FileProvider 라는 놈을 써서, file:// 대신 content:// 형태의 uri 를 손쉽게 뽑아낼 수 있습니다. 이것으로 공유를 하게되면 더 이상 에러가 발생하지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;사용법도 간단합니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;라고 말하지만, 그러면 우리의 하위호환성 개나줘버려 구글이 아니겠지요.&lt;/p&gt;&lt;p&gt;이렇게 FileProvider 를 통해서 content:// 를 뽑아내면, 일부 - 라고 부르지만 대부분 중국 앱들 - 에서는 정상적으로 파일 공유가 안됩니다.&lt;/p&gt;&lt;p&gt;FileProvider 를 안쓰면,, 앱이 뒤지고, 쓰면,, 앱에 정상적으로 파일 공유가 안되는 개떡같은 상황.&lt;/p&gt;&lt;p&gt;안드로이드 개발자라면 놀라지도 않을 상황.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;간략히 설명하자면, FileProvider 를 미디어 파일을 content:// 형태로 뽑아줍니다. 앱에서 설정한 형식에 맞추어서 말이죠.&lt;/p&gt;&lt;p&gt;예를들면,,&lt;/p&gt;&lt;p&gt;content://my-application/images/a.mp4 이런 형태가 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그러나~&lt;/p&gt;&lt;p&gt;앱에서 정상적으로 공유가 안됩니다.&lt;/p&gt;&lt;p&gt;App 의 Internal Storage 에 있는 파일들은 공유가 될지 모르겠지만, external storage 에 있는 파일들은 공유가 안됩니다.&lt;/p&gt;&lt;p&gt;그럼 어떻게 해야 하느냐??&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;OS 에서 기본적으로 동작되고 있는 MediaStore ( MediaScanner 친구)가 가지고 있는 uri 를 사용하면, 모든 앱에서 정상적으로 공유가 됩니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;각설하고, 이를 구현한 코드는 아래와 같습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre style=&quot;background-color:#2b2b2b;color:#a9b7c6;font-family:'굴림체';font-size:9.0pt;&quot;&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;package &lt;/span&gt;kr.co.crystalcube&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.annotation.&lt;span style=&quot;color:#bbb529;&quot;&gt;SuppressLint&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.content.ContentValues&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.content.Context&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.database.Cursor&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.net.Uri&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.os.Build&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.os.StrictMode&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.provider.MediaStore&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.support.annotation.&lt;span style=&quot;color:#bbb529;&quot;&gt;StringDef&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.text.TextUtils&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;android.util.Log&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.io.File&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.lang.annotation.&lt;span style=&quot;color:#bbb529;&quot;&gt;Retention&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.lang.annotation.RetentionPolicy&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import &lt;/span&gt;java.lang.reflect.Method&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;import static &lt;/span&gt;android.content.ContentValues.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;public class &lt;/span&gt;MediaUriManager {&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@StringDef&lt;/span&gt;({&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TEXT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;IMAGE&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;AUDIO&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VIDEO&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;File&lt;/span&gt;})&lt;br /&gt;    &lt;span style=&quot;color:#bbb529;&quot;&gt;@Retention&lt;/span&gt;(RetentionPolicy.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SOURCE&lt;/span&gt;)&lt;br /&gt;    @&lt;span style=&quot;color:#cc7832;&quot;&gt;interface &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType &lt;/span&gt;{&lt;br /&gt;        String &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TEXT &lt;/span&gt;= &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;text/plain&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;IMAGE &lt;/span&gt;= &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;image/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;AUDIO &lt;/span&gt;= &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;audio/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VIDEO &lt;/span&gt;= &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;video/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String &lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;File &lt;/span&gt;= &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;*/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;@ShareContentType &lt;/span&gt;String &lt;span style=&quot;color:#ffc66d;&quot;&gt;convertToContentType&lt;/span&gt;(String mediaType) {&lt;br /&gt;        String contentType = mediaType.toLowerCase().split(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;/&quot;&lt;/span&gt;)[&lt;span style=&quot;color:#6897bb;&quot;&gt;0&lt;/span&gt;]&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        switch &lt;/span&gt;(contentType) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;case &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;text&quot;&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TEXT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            case &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;image&quot;&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;IMAGE&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            case &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;audio&quot;&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;AUDIO&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            case &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;video&quot;&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VIDEO&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            case &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;*&quot;&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            default&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TEXT&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;public static &lt;/span&gt;Uri &lt;span style=&quot;color:#ffc66d;&quot;&gt;getFileUri &lt;/span&gt;(Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;String mediaType&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;File file){&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(context == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            Log.&lt;span style=&quot;font-style:italic;&quot;&gt;e&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;getFileUri current activity is null.&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            return null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(file == &lt;span style=&quot;color:#cc7832;&quot;&gt;null &lt;/span&gt;|| !file.exists()) {&lt;br /&gt;            Log.&lt;span style=&quot;font-style:italic;&quot;&gt;e&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;getFileUri file is null or not exists.&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            return null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        Uri uri = &lt;span style=&quot;color:#cc7832;&quot;&gt;null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        if &lt;/span&gt;(Build.VERSION.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SDK_INT &lt;/span&gt;&amp;lt; Build.VERSION_CODES.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;N&lt;/span&gt;) {&lt;br /&gt;            uri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;fromFile&lt;/span&gt;(file)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;else &lt;/span&gt;{&lt;br /&gt;            &lt;span style=&quot;color:#bbb529;&quot;&gt;@ShareContentType &lt;/span&gt;String shareContentType = &lt;span style=&quot;font-style:italic;&quot;&gt;convertToContentType&lt;/span&gt;(mediaType)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            if &lt;/span&gt;(TextUtils.&lt;span style=&quot;font-style:italic;&quot;&gt;isEmpty&lt;/span&gt;(shareContentType)) {&lt;br /&gt;                shareContentType = &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;*/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;switch &lt;/span&gt;(shareContentType) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;case &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;IMAGE &lt;/span&gt;:&lt;br /&gt;                    uri = &lt;span style=&quot;font-style:italic;&quot;&gt;getImageContentUri&lt;/span&gt;(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;file)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                case &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;VIDEO &lt;/span&gt;:&lt;br /&gt;                    uri = &lt;span style=&quot;font-style:italic;&quot;&gt;getVideoContentUri&lt;/span&gt;(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;file)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                case &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;AUDIO &lt;/span&gt;:&lt;br /&gt;                    uri = &lt;span style=&quot;font-style:italic;&quot;&gt;getAudioContentUri&lt;/span&gt;(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;file)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                case &lt;/span&gt;&lt;span style=&quot;color:#bbb529;&quot;&gt;ShareContentType&lt;/span&gt;.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;File &lt;/span&gt;:&lt;br /&gt;                    uri = &lt;span style=&quot;font-style:italic;&quot;&gt;getFileContentUri&lt;/span&gt;(context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;file)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                    break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                default&lt;/span&gt;: &lt;span style=&quot;color:#cc7832;&quot;&gt;break;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(uri == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            uri = &lt;span style=&quot;font-style:italic;&quot;&gt;forceGetFileUri&lt;/span&gt;(file)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;uri&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;Uri &lt;span style=&quot;color:#ffc66d;&quot;&gt;getFileContentUri&lt;/span&gt;(Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;File file) {&lt;br /&gt;        String volumeName = &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;external&quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String filePath = file.getAbsolutePath()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String[] projection = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;String[]{MediaStore.Files.FileColumns.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID&lt;/span&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;Uri uri = &lt;span style=&quot;color:#cc7832;&quot;&gt;null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;Cursor cursor = context.getContentResolver().query(MediaStore.Files.&lt;span style=&quot;font-style:italic;&quot;&gt;getContentUri&lt;/span&gt;(volumeName)&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;projection&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;MediaStore.Images.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA &lt;/span&gt;+ &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;=? &quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, new &lt;/span&gt;String[] { filePath }&lt;span style=&quot;color:#cc7832;&quot;&gt;, null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        if &lt;/span&gt;(cursor != &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(cursor.moveToFirst()) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;id = cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;uri = MediaStore.Files.&lt;span style=&quot;font-style:italic;&quot;&gt;getContentUri&lt;/span&gt;(volumeName&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;id)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;            cursor.close()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;uri&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;Uri &lt;span style=&quot;color:#ffc66d;&quot;&gt;getImageContentUri&lt;/span&gt;(Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;File imageFile) {&lt;br /&gt;        String filePath = imageFile.getAbsolutePath()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTERNAL_CONTENT_URI&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                new &lt;/span&gt;String[] { MediaStore.Images.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID &lt;/span&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;MediaStore.Images.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA &lt;/span&gt;+ &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;=? &quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                new &lt;/span&gt;String[] { filePath }&lt;span style=&quot;color:#cc7832;&quot;&gt;, null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;Uri uri = &lt;span style=&quot;color:#cc7832;&quot;&gt;null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        if &lt;/span&gt;(cursor != &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(cursor.moveToFirst()) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;Uri baseUri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;parse&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;content://media/external/images/media&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;uri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;withAppendedPath&lt;/span&gt;(baseUri&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;&quot; &lt;/span&gt;+ id)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;            cursor.close()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(uri == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            ContentValues values = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ContentValues()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;values.put(MediaStore.Images.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;filePath)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;uri = context.getContentResolver().insert(MediaStore.Images.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTERNAL_CONTENT_URI&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;values)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;uri&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;Uri &lt;span style=&quot;color:#ffc66d;&quot;&gt;getVideoContentUri&lt;/span&gt;(Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;File videoFile) {&lt;br /&gt;        Uri uri = &lt;span style=&quot;color:#cc7832;&quot;&gt;null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String filePath = videoFile.getAbsolutePath()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTERNAL_CONTENT_URI&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                new &lt;/span&gt;String[] { MediaStore.Video.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID &lt;/span&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;MediaStore.Video.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA &lt;/span&gt;+ &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;=? &quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                new &lt;/span&gt;String[] { filePath }&lt;span style=&quot;color:#cc7832;&quot;&gt;, null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        if &lt;/span&gt;(cursor != &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(cursor.moveToFirst()) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;Uri baseUri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;parse&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;content://media/external/video/media&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;uri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;withAppendedPath&lt;/span&gt;(baseUri&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;&quot; &lt;/span&gt;+ id)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;            cursor.close()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(uri == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            ContentValues values = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ContentValues()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;values.put(MediaStore.Video.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;filePath)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;uri = context.getContentResolver().insert(MediaStore.Video.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTERNAL_CONTENT_URI&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;values)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;uri&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;Uri &lt;span style=&quot;color:#ffc66d;&quot;&gt;getAudioContentUri&lt;/span&gt;(Context context&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;File audioFile) {&lt;br /&gt;        Uri uri = &lt;span style=&quot;color:#cc7832;&quot;&gt;null;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;String filePath = audioFile.getAbsolutePath()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTERNAL_CONTENT_URI&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                new &lt;/span&gt;String[] { MediaStore.Audio.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID &lt;/span&gt;}&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;MediaStore.Audio.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA &lt;/span&gt;+ &lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;=? &quot;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                new &lt;/span&gt;String[] { filePath }&lt;span style=&quot;color:#cc7832;&quot;&gt;, null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        if &lt;/span&gt;(cursor != &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(cursor.moveToFirst()) {&lt;br /&gt;                &lt;span style=&quot;color:#cc7832;&quot;&gt;int &lt;/span&gt;id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;_ID&lt;/span&gt;))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;Uri baseUri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;parse&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;content://media/external/audio/media&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;uri = Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;withAppendedPath&lt;/span&gt;(baseUri&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;&quot; &lt;/span&gt;+ id)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;            cursor.close()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(uri == &lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;) {&lt;br /&gt;            ContentValues values = &lt;span style=&quot;color:#cc7832;&quot;&gt;new &lt;/span&gt;ContentValues()&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;values.put(MediaStore.Audio.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;DATA&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;filePath)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;uri = context.getContentResolver().insert(MediaStore.Audio.Media.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;EXTERNAL_CONTENT_URI&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;values)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;        &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;uri&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color:#cc7832;&quot;&gt;private static &lt;/span&gt;Uri &lt;span style=&quot;color:#ffc66d;&quot;&gt;forceGetFileUri&lt;/span&gt;(File shareFile) {&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;if &lt;/span&gt;(Build.VERSION.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;SDK_INT &lt;/span&gt;&amp;gt;= Build.VERSION_CODES.&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;N&lt;/span&gt;) {&lt;br /&gt;            &lt;span style=&quot;color:#cc7832;&quot;&gt;try &lt;/span&gt;{&lt;br /&gt;                &lt;span style=&quot;color:#bbb529;&quot;&gt;@SuppressLint&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;PrivateApi&quot;&lt;/span&gt;)&lt;br /&gt;                Method rMethod = StrictMode.&lt;span style=&quot;color:#cc7832;&quot;&gt;class&lt;/span&gt;.getDeclaredMethod(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;disableDeathOnFileUriExposure&quot;&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;                &lt;/span&gt;rMethod.invoke(&lt;span style=&quot;color:#cc7832;&quot;&gt;null&lt;/span&gt;)&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;} &lt;span style=&quot;color:#cc7832;&quot;&gt;catch &lt;/span&gt;(Exception e) {&lt;br /&gt;                Log.&lt;span style=&quot;font-style:italic;&quot;&gt;e&lt;/span&gt;(&lt;span style=&quot;color:#9876aa;font-style:italic;&quot;&gt;TAG&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;, &lt;/span&gt;Log.&lt;span style=&quot;font-style:italic;&quot;&gt;getStackTraceString&lt;/span&gt;(e))&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;            &lt;/span&gt;}&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color:#cc7832;&quot;&gt;return &lt;/span&gt;Uri.&lt;span style=&quot;font-style:italic;&quot;&gt;parse&lt;/span&gt;(&lt;span style=&quot;color:#6a8759;&quot;&gt;&quot;file://&quot; &lt;/span&gt;+ shareFile.getAbsolutePath())&lt;span style=&quot;color:#cc7832;&quot;&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color:#cc7832;&quot;&gt;    &lt;/span&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;WeChat, QQ, Weibo 등에 공유할땐 위 코드를 사용하시는게 정신건강에 이롭습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;끗.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</description>
      <category>Android</category>
      <category>파일 공유</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/209</guid>
      <comments>https://crystalcube.tistory.com/209#entry209comment</comments>
      <pubDate>Fri, 4 Jan 2019 18:29:25 +0900</pubDate>
    </item>
    <item>
      <title>차량관리 시스템 - 스마트카즈</title>
      <link>https://crystalcube.tistory.com/207</link>
      <description>&lt;p&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class=&quot;txc-textbox&quot; style=&quot;border: 1px solid rgb(238, 238, 238); padding: 10px; background-color: rgb(238, 238, 238);&quot;&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;스마트한 차량관리 앱 - 스마트 카즈&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그 동안 시간 나는대로 틈틈히 만든 안드로이드 앱 입니다.&lt;/p&gt;&lt;p&gt;차량 관리를 위한 아주~ 스마트한 앱이에요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;color: rgb(53, 53, 53); font-size: 18.6667px;&quot;&gt;스마트카즈(Smart Caz) 소개&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;hr style=&quot;display:block; border: black 0 none; border-top: black 1px solid; height: 1px&quot;&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;예전 6~7년 전에 제가 차를 샀을때 이야기입니다.&lt;/p&gt;&lt;p&gt;첫 차인만큼 관리를 잘 해서 10년 20년 타 보겠다고 마음 먹었지요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그래서 차량관리를 위한 앱을 찾아보는데 마땅한게 없었습니다.&lt;/p&gt;&lt;p&gt;드라이버노트(?) 라는 앱이 유일해서 그것을 다운받아 사용했었죠.&lt;/p&gt;&lt;p&gt;그런데, 버그도 많고 사용한지 몇달 안되서 서비스가 없어졌습니다. OTL&lt;/p&gt;&lt;p&gt;그 뒤로 몇달동안 차량관리와 차계부 역할을 하는 앱이 나오지 않았습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;하여 직접 만들기로 마음먹고 최소한의 필요한 기능을 가지고 있는&amp;nbsp;앱을 만들어 갔지요.&lt;/p&gt;&lt;p&gt;그러다,, 막상 손이 많이가고 디자인도 안 이쁘고,, 해서 싹 갈아 엎었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그리고 약 3년 전부터 새 버전을 개발했는데,&lt;/p&gt;&lt;p&gt;제가 본업이 따로 있고, 가정도 있다보니 일을 한다는게 쉽지 않더라고요.&lt;/p&gt;&lt;p&gt;개발할 시간과 여유와 환경이 뒷받침 해 주지 않았습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;어쨌든 그렇게 꾸역꾸역 개발하여, 몇일 전에 드디어 안드로이드로 출시하였습니다.&lt;/p&gt;&lt;p&gt;본래 계획은 아이폰과 안드로이드 동시 출시였는데 말이죠. ㅠㅠ&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;참 스마트카즈의 영문은 Smart Caz 이며, Car 나 Cars 가 아닌 Caz 인 이유는 브랜딩을 위한 변형입니다 ^-^;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;color: rgb(53, 53, 53); font-size: 18.6667px;&quot;&gt;스마트카즈(Smart Caz) 기능&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;hr style=&quot;border-right: 0px none black; border-bottom: 0px none black; border-left: 0px none black; border-top-style: solid; border-top-color: black; border-image: initial; height: 1px;&quot;&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;웬만한 필수 기능은 거의 다 넣었습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot;&gt;&lt;li&gt;차량 소모품 관리&lt;/li&gt;&lt;li&gt;차량 지출 관리&lt;/li&gt;&lt;li&gt;누적 주행거리 자동입력 (사용자 입력 필요없음)&lt;/li&gt;&lt;li&gt;여러대 차량 관리 가능&lt;/li&gt;&lt;li&gt;주유시 자동 기입&lt;/li&gt;&lt;li&gt;커뮤니티 기능 제공&lt;/li&gt;&lt;li&gt;개인 / 단체 팝업쪽지 가능&lt;/li&gt;&lt;li&gt;차량에 대한 지식이 없어도 관리 가능한 UI&lt;/li&gt;&lt;li&gt;기타&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;제가 직접 필요에 의해서 만들기 시작했고, 실제로 사용하는 것이라 운전자로서 필요하다고 생각하는 기능을 최대한 편리하게 운전자 입장에서 만들려고 노력하였습니다.&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://caz.smartholic.com&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://caz.smartholic.com&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 750px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99B74E4B5BFCE50C25&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99B74E4B5BFCE50C25&quot; width=&quot;750&quot; height=&quot;578&quot; filename=&quot;123.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.smartholic.caz&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;https://play.google.com/store/apps/details?id=com.smartholic.caz&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 728px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9993B4425BFCE5522C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9993B4425BFCE5522C&quot; width=&quot;728&quot; height=&quot;651&quot; filename=&quot;1.jpg&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=&quot;color: rgb(53, 53, 53); font-size: 18.6667px;&quot;&gt;스마트카즈(Smart Caz) 여담&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;hr style=&quot;border-right: 0px none black; border-bottom: 0px none black; border-left: 0px none black; border-top-style: solid; border-top-color: black; border-image: initial; height: 1px;&quot;&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;혼자서 앱을 만든다는게 상당히 어려웠습니다.&lt;/p&gt;&lt;p&gt;개발이야 산전수전 다 겪고, 분야 안가리고 닥치는대로 해온터라,, 어려운건 아닌데.&lt;/p&gt;&lt;p&gt;진짜 &quot;자신과의 싸움&quot; 이 가장 어려웠습니다.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;퇴근하고나서 혹은 주말에 쉬고싶은데, 꾸역꾸역 개발한다는게 얼마나 힘들던지....&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;보여지는건 딸랑 앱 하나지만,,&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;- Server Hostring &amp;amp; Security Setting&lt;/p&gt;&lt;p&gt;- Redis, Mysql, Nginx 등 세팅&lt;/p&gt;&lt;p&gt;- Python Module, System Module 개발&lt;/p&gt;&lt;p&gt;- CMS 관리자 페이지 개발&lt;/p&gt;&lt;p&gt;- Service API 개발&lt;/p&gt;&lt;p&gt;- Landing Page 개발&lt;/p&gt;&lt;p&gt;- Android App 개발&lt;/p&gt;&lt;p&gt;- 각종 테스트 버그 픽스&lt;/p&gt;&lt;p&gt;- UI Component 개발&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;등등.. 일이 끝이 없더군요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;모쪼록 그렇게 완성된 앱.&lt;/p&gt;&lt;p&gt;지인 두세명한테만 소개해 주고, 지금 제 블로그에 처음으로 공개홍보 합니다 ^-^&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;아무런 홍보도 안하니까 앱이 플레이스토어에서 검색도 안되고 -_-a&lt;/p&gt;&lt;p&gt;다운로드도 없고, 쓸쓸하더라고요.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;그러니까...&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-size: 36pt;&quot;&gt;제발 좀 받아서 써 주세요~!&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;ㅋㅋ&lt;/p&gt;</description>
      <category>개발 프로그램/스마트카즈(Smart Caz)</category>
      <category>SmartCaz</category>
      <category>스마트카즈</category>
      <category>차계부</category>
      <category>차량관리</category>
      <author>unD3R</author>
      <guid isPermaLink="true">https://crystalcube.tistory.com/207</guid>
      <comments>https://crystalcube.tistory.com/207#entry207comment</comments>
      <pubDate>Tue, 27 Nov 2018 15:39:54 +0900</pubDate>
    </item>
  </channel>
</rss>