<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>iru</title>
    <link>https://haniru.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 2 Jun 2026 21:26:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>haniru</managingEditor>
    <item>
      <title>Dobot Magician + 터틀봇 제어</title>
      <link>https://haniru.tistory.com/255</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 DobotLab을 사이트에서 받아서 사용했지만 여러가지 기능을 붙이려다보니 한계가 있었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(프로그램 다운로드: &lt;span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.dobot-robots.com/service/download-center&quot;&gt;https://www.dobot-robots.com/service/download-center&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image (1).png&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baBm4g/dJMcaaStjdE/fjd3PC6HPwbj44fX7zv6V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baBm4g/dJMcaaStjdE/fjd3PC6HPwbj44fX7zv6V1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baBm4g/dJMcaaStjdE/fjd3PC6HPwbj44fX7zv6V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaBm4g%2FdJMcaaStjdE%2Ffjd3PC6HPwbj44fX7zv6V1%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;910&quot; height=&quot;175&quot; data-filename=&quot;image (1).png&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byKqEi/dJMcaaStjdF/KLT32hJWGNWur8WXR0Pexk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byKqEi/dJMcaaStjdF/KLT32hJWGNWur8WXR0Pexk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byKqEi/dJMcaaStjdF/KLT32hJWGNWur8WXR0Pexk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyKqEi%2FdJMcaaStjdF%2FKLT32hJWGNWur8WXR0Pexk%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;916&quot; height=&quot;342&quot; data-filename=&quot;image.png&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image (2).png&quot; data-origin-width=&quot;1765&quot; data-origin-height=&quot;970&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tsDok/dJMcad2EOAU/nWVHLba8Q77H7R1i1Iojd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tsDok/dJMcad2EOAU/nWVHLba8Q77H7R1i1Iojd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tsDok/dJMcad2EOAU/nWVHLba8Q77H7R1i1Iojd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtsDok%2FdJMcad2EOAU%2FnWVHLba8Q77H7R1i1Iojd0%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;1765&quot; height=&quot;970&quot; data-filename=&quot;image (2).png&quot; data-origin-width=&quot;1765&quot; data-origin-height=&quot;970&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;737&quot; data-origin-height=&quot;828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GJmDt/dJMcacJwDRK/0JC28xMXvhwJrm4zE6K340/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GJmDt/dJMcacJwDRK/0JC28xMXvhwJrm4zE6K340/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GJmDt/dJMcacJwDRK/0JC28xMXvhwJrm4zE6K340/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGJmDt%2FdJMcacJwDRK%2F0JC28xMXvhwJrm4zE6K340%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;737&quot; height=&quot;828&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;828&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;그래서 DOBOT DLL을 사용해서 기능을 구현했다&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;사용한 DOBOT DLL 파일:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/SERLatBTH/StarterGuide-Dobot-Magician-with-Python/tree/master&quot;&gt;https://github.com/SERLatBTH/StarterGuide-Dobot-Magician-with-Python/tree/master&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776050887974&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;GitHub - SERLatBTH/StarterGuide-Dobot-Magician-with-Python: Dobot Magician with pure Python - Starter Guide&quot; data-og-description=&quot;Dobot Magician with pure Python - Starter Guide . Contribute to SERLatBTH/StarterGuide-Dobot-Magician-with-Python development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/SERLatBTH/StarterGuide-Dobot-Magician-with-Python/tree/master&quot; data-og-url=&quot;https://github.com/SERLatBTH/StarterGuide-Dobot-Magician-with-Python&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Ixl2E/dJMb81fTSEW/bYnGxxKyXYkaFYknFagi40/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/heCC1/dJMb81fTSEX/RVer5IeBrrWHp9la3lKxNk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/SERLatBTH/StarterGuide-Dobot-Magician-with-Python/tree/master&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/SERLatBTH/StarterGuide-Dobot-Magician-with-Python/tree/master&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Ixl2E/dJMb81fTSEW/bYnGxxKyXYkaFYknFagi40/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/heCC1/dJMb81fTSEX/RVer5IeBrrWHp9la3lKxNk/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;GitHub - SERLatBTH/StarterGuide-Dobot-Magician-with-Python: Dobot Magician with pure Python - Starter Guide&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Dobot Magician with pure Python - Starter Guide . Contribute to SERLatBTH/StarterGuide-Dobot-Magician-with-Python 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;파이썬은 32bit 버전을 사용해야 함:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;32 bit &amp;rarr; &lt;b&gt;Note that Python 3.10.11&amp;nbsp;cannot&amp;nbsp;be used on Windows 7 or earlier.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.python.org/ftp/python/3.10.11/python-3.10.11.exe&quot;&gt;https://www.python.org/ftp/python/3.10.11/python-3.10.11.exe&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;일단 도봇 매지션에 있는 석션으로 간단한 Pick And Place 부터 해봤다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtu.be/cBSbV4C7d6U&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/cBSbV4C7d6U&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=cBSbV4C7d6U&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bHz1AC/dJMb86O21Mq/Hj9xCKiPjZpsuryEkTVI71/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/8Sokv/dJMb84p9USW/a1WsvTsfOV1IM7WjkDKgAK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/kim6f/dJMb84XZZCh/mBifQMl2MbQYZKOYV07ZVK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;DOBOT 매지션&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/cBSbV4C7d6U&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&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;그리고 터틀봇과의 소켓 통신으로 터틀봇이 일정 초간 다 움직이면 DOBOT에게 소켓으로 알림을 보내고 -&amp;gt; DOBOT이 다 움직이면 터틀봇에게 또 소켓으로 알림을 주는 동작이다&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://youtu.be/Ut5felQxtw8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/Ut5felQxtw8&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=Ut5felQxtw8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/nY3Ji/dJMb8QenrkK/M0BiR3PC3I9RkUPsxuQvIk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bGJ60t/dJMb9b3TjsZ/1OFkK4TXIcAYGoN1FYY5FK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ic5Ph/dJMb9b3TjsY/uVCBpeYZQuAkKkFS6fwMB0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;DOBOT 매지션+터틀봇 실패&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Ut5felQxtw8&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&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;a href=&quot;https://youtu.be/Ut5felQxtw8&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://youtu.be/Ut5felQxtw8&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=Ut5felQxtw8&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/nY3Ji/dJMb8QenrkK/M0BiR3PC3I9RkUPsxuQvIk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/bGJ60t/dJMb9b3TjsZ/1OFkK4TXIcAYGoN1FYY5FK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/ic5Ph/dJMb9b3TjsY/uVCBpeYZQuAkKkFS6fwMB0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;DOBOT 매지션+터틀봇 실패&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/Ut5felQxtw8&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOBOT 이라는게 교육용으로 나와서 그런지 팔을 움직이면 좌표값을 따올 수 있어서 좋았다&lt;/p&gt;
&lt;pre id=&quot;code_1776051417221&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import DobotDllType as dType
import time

# 1. 연결 설정
api = dType.load()
state = dType.ConnectDobot(api, &quot;&quot;, 115200)[0]

if state == dType.DobotConnect.DobotConnect_NoError:
    saved_points = []
    print(&quot;  티칭 모드를 시작합니다.&quot;)
    print(&quot;[방법] 1. Unlock 버튼을 누르고 팔을 이동&quot;)
    print(&quot;       2. 기록하고 싶은 지점에서 'Enter' 키 입력&quot;)
    print(&quot;       3. 종료하려면 'q' 입력 후 Enter&quot;)
    print(&quot;-&quot; * 50)

    try:
        while True:
            # 현재 위치 실시간 출력
            pose = dType.GetPose(api)
            x, y, z = pose[0], pose[1], pose[2]
            print(f&quot;\r  현재 위치 -&amp;gt; X: {x:7.2f}, Y: {y:7.2f}, Z: {z:7.2f} | 저장된 지점: {len(saved_points)}개&quot;, end=&quot;&quot;)

            # 사용자 입력 확인 (Enter를 치면 기록, q를 치면 종료)
            # input()은 루프를 잠시 멈추기 때문에 정확한 지점 확보에 더 좋습니다.
            cmd = input(&quot;\n[명령] Enter(기록) / q(종료): &quot;).lower()

            if cmd == '':
                # 현재 좌표 저장
                saved_points.append([round(x, 2), round(y, 2), round(z, 2)])
                print(f&quot;✅ 지점 저장 완료: {saved_points[-1]}&quot;)
            elif cmd == 'q':
                break

    except KeyboardInterrupt:
        pass

    # 종료 후 결과 출력
    print(&quot;\n&quot; + &quot;=&quot; * 50)
    print(&quot;  기록된 좌표 리스트 (복사해서 main.py에 붙여넣으세요)&quot;)
    print(&quot;=&quot; * 50)
    for i, pt in enumerate(saved_points):
        print(f&quot;지점 {i + 1}: {pt}&quot;)
    print(&quot;=&quot; * 50)

    dType.DisconnectDobot(api)
else:
    print(&quot;❌ 도봇 연결 실패!&quot;)&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;DOBOT -&amp;nbsp;&lt;a href=&quot;https://github.com/iru-han/dobot_ws.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/iru-han/dobot_ws.git&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776051632666&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;GitHub - iru-han/dobot_ws&quot; data-og-description=&quot;Contribute to iru-han/dobot_ws development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/iru-han/dobot_ws.git&quot; data-og-url=&quot;https://github.com/iru-han/dobot_ws&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/04PDg/dJMb9effdYY/3qxAPkmw5xppN2Z5F9XRT1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/oeiIx/dJMb9c9y8rp/fKugeumHTEFnLeJMeptne0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/dobot_ws.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/iru-han/dobot_ws.git&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/04PDg/dJMb9effdYY/3qxAPkmw5xppN2Z5F9XRT1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/oeiIx/dJMb9c9y8rp/fKugeumHTEFnLeJMeptne0/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;GitHub - iru-han/dobot_ws&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to iru-han/dobot_ws 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;터틀봇(Remote PC랑 라즈베리파이 둘다 사용 가능) -&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1776051776426&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist
import socket
import time

# [설정] 노트북 정보
LAPTOP_IP = '192.168.0.33' 
PORT = 9999

class TurtlebotMissionNode(Node):
    def __init__(self):
        super().__init__('turtlebot_mission_node')
        # 네임스페이스 반영된 토픽 이름 (/r3/cmd_vel)
        self.publisher = self.create_publisher(Twist, '/cmd_vel', 10)
        time.sleep(1.0) # 퍼블리셔 안정화 대기
        self.run_mission()

    def move_turtlebot(self, speed, duration, label):
        &quot;&quot;&quot;지정된 속도로 지정된 시간만큼 이동하는 함수&quot;&quot;&quot;
        print(f&quot;&amp;gt;&amp;gt; {label}: 속도 {speed}로 {duration}초간 이동 시작&quot;)
        msg = Twist()
        msg.linear.x = speed
        
        start_time = time.time()
        while rclpy.ok() and (time.time() - start_time &amp;lt; duration):
            self.publisher.publish(msg)
            time.sleep(0.1) # 10Hz 주기로 발행
            
        # 정지 명령
        self.publisher.publish(Twist())
        print(f&quot;&amp;gt;&amp;gt; {label}: 정지 완료.&quot;)

    def run_mission(self):
        # 1. 도봇 앞으로 이동 (몸통 2개 거리만큼 0.01 속도로)
        # 약 27.6초 동안 이동 (0.01m/s * 27.6s = 0.276m)
        self.move_turtlebot(speed=0.01, duration=27.6, label=&quot;도봇으로 접근 중&quot;)

        # 2. 소켓 통신 (신호 보내기)
        print(&quot;&amp;gt;&amp;gt; Arrived at Dobot. Sending signal to Laptop...&quot;)
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(60) # 도봇 작업 시간을 고려하여 타임아웃 넉넉히 설정
            s.connect((LAPTOP_IP, PORT))
            
            # 도착 신호 전송
            s.send(&quot;ARRIVED&quot;.encode())
            print(&quot;&amp;gt;&amp;gt; Waiting for Dobot to load object...&quot;)
            
            # 도봇으로부터 작업 완료(OK) 신호를 대기
            response = s.recv(1024).decode()
            
            if response == &quot;OK&quot;:
                print(&quot;&amp;gt;&amp;gt; [SIGNAL RECEIVED] Dobot task finished!&quot;)
                
                # 3. 추가 이동 (몸통 반개 거리만큼 0.01 속도로)
                # 약 6.9초 동안 이동 (0.01m/s * 6.9s = 0.069m)
                self.move_turtlebot(speed=0.01, duration=6.9, label=&quot;추가 목적지로 이동 중&quot;)
                print(&quot;&amp;gt;&amp;gt; [MISSION COMPLETE] Arrived at final destination.&quot;)
            
            s.close()
        except Exception as e:
            print(f&quot;&amp;gt;&amp;gt; [ERROR] Connection or Task failed: {e}&quot;)

def main():
    rclpy.init()
    node = TurtlebotMissionNode()
    # 미션 완료 후 노드 종료
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()&lt;/code&gt;&lt;/pre&gt;</description>
      <category>로봇팔</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/255</guid>
      <comments>https://haniru.tistory.com/255#entry255comment</comments>
      <pubDate>Mon, 13 Apr 2026 12:43:07 +0900</pubDate>
    </item>
    <item>
      <title>터틀봇 펌웨어를 수정해서 센서 데이터값 가져오기</title>
      <link>https://haniru.tistory.com/254</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이에 센서를 연결하면 파이썬 코드로 센서값을 가져올 수 있지만, openCR에 연결하면 펌웨어 코드 변경 후 turtlebot_node 코드도 수정해야한다&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://github.com/iru-han/turtlebot3_ros2.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/iru-han/turtlebot3_ros2.git&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 펌웨어코드를 수정해서 PC와 아두이노를 연결해 arduino ide로 올려야한다&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;turtlebot3_node 코드:&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/turtlebot3.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/iru-han/turtlebot3.git&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776040904553&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;GitHub - iru-han/turtlebot3&quot; data-og-description=&quot;Contribute to iru-han/turtlebot3 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/iru-han/turtlebot3.git&quot; data-og-url=&quot;https://github.com/iru-han/turtlebot3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/S5wPn/dJMb8WeARMX/UyIKmOTfDvCxKrC7uSxQvK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/j6JMP/dJMb9cBJljN/N3OrCo4E3FKvqhGRN2k7xK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/turtlebot3.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/iru-han/turtlebot3.git&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/S5wPn/dJMb8WeARMX/UyIKmOTfDvCxKrC7uSxQvK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/j6JMP/dJMb9cBJljN/N3OrCo4E3FKvqhGRN2k7xK/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;GitHub - iru-han/turtlebot3&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to iru-han/turtlebot3 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;Remote PC에 turtlebot3_ws/src 경로에 turtlebot3 를 git pull 받고 colcon build 해줘야한다&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;turtlebot3_msgs 코드:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/turtlebot3_msgs.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/iru-han/turtlebot3_msgs.git&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776040960637&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;GitHub - iru-han/turtlebot3_msgs&quot; data-og-description=&quot;Contribute to iru-han/turtlebot3_msgs development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/iru-han/turtlebot3_msgs.git&quot; data-og-url=&quot;https://github.com/iru-han/turtlebot3_msgs&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cj6QX5/dJMb8XR6UJx/KdU4nbuXfbkFos5ek7Thm0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/tnT1A/dJMb8YXMLH3/DuQjtHGPYt6cJbUGPQsw61/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/turtlebot3_msgs.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/iru-han/turtlebot3_msgs.git&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cj6QX5/dJMb8XR6UJx/KdU4nbuXfbkFos5ek7Thm0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/tnT1A/dJMb8YXMLH3/DuQjtHGPYt6cJbUGPQsw61/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;GitHub - iru-han/turtlebot3_msgs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to iru-han/turtlebot3_msgs 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;&lt;br /&gt;마찬가지로 Remote PC에 turtlebot3_ws/src 경로에 turtlebot3_msgs 를 git pull 받고 colcon build 해줘야한다&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;센서 모니터링 코드:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 거치면 sensor_state에서 센서값을 읽어올 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/sensor_monitor_ws.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/iru-han/sensor_monitor_ws.git&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1776041139031&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;GitHub - iru-han/sensor_monitor_ws&quot; data-og-description=&quot;Contribute to iru-han/sensor_monitor_ws development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/iru-han/sensor_monitor_ws.git&quot; data-og-url=&quot;https://github.com/iru-han/sensor_monitor_ws&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ukc5i/dJMb8WeARQQ/O8CB84RYWuhi5kmhmcX4bK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/VTX8U/dJMb8T90Je9/NOit79oXmucW9qcvRXwBG0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/iru-han/sensor_monitor_ws.git&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/iru-han/sensor_monitor_ws.git&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ukc5i/dJMb8WeARQQ/O8CB84RYWuhi5kmhmcX4bK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/VTX8U/dJMb8T90Je9/NOit79oXmucW9qcvRXwBG0/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;GitHub - iru-han/sensor_monitor_ws&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to iru-han/sensor_monitor_ws 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;</description>
      <category>터틀봇</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/254</guid>
      <comments>https://haniru.tistory.com/254#entry254comment</comments>
      <pubDate>Mon, 13 Apr 2026 09:47:22 +0900</pubDate>
    </item>
    <item>
      <title>인천인력개발원 - 실무로 배우는 ROS 2 AI 로봇 과정 수강 후기</title>
      <link>https://haniru.tistory.com/253</link>
      <description>&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;평소 로봇공학과 AI에 관심이 많았지만, 독학으로 접한 ROS 2의 진입장벽을 넘기는 쉽지 않았습니다. 이론을 넘어 실제 터틀봇 3&amp;nbsp;기기를 직접 분해&amp;middot;조립해보고, 센서 데이터를 직접 핸들링하며 자율주행 알고리즘을 구현해보고 싶어 이번 과정을 신청했습니다.&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;5&quot; data-ke-size=&quot;size23&quot;&gt;과정을 신청한 이유&lt;/h3&gt;
&lt;p data-path-to-node=&quot;6&quot; data-ke-size=&quot;size16&quot;&gt;평소 로봇공학과 AI에 관심은 많았지만, 독학으로는 ROS 2의 높은 진입장벽을 넘기가 쉽지 않았습니다. 이론뿐만 아니라 실제 터틀봇 3 기기를 직접 제어해보고, 자율주행 알고리즘을 다뤄보고 싶어 이번 과정을 신청하게 되었습니다.&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;7&quot; data-ke-size=&quot;size23&quot;&gt;수강 후 배우거나 달라진 점&lt;/h3&gt;
&lt;p data-path-to-node=&quot;8&quot; data-ke-size=&quot;size16&quot;&gt;가장 큰 변화는 로봇의 언어를 이해하게 되었다는 점입니다. Nav2 스택을 다루면서 로봇이 지도를 생성하고(SLAM), 실시간으로 장애물을 회피하며 최적의 경로를 계산하는 메커니즘을 깊이 있게 배웠습니다. 가상 환경뿐만 아니라 실제 하드웨어를 연결해 보며 실무 감각을 익히고 있습니다.&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;10&quot; data-ke-size=&quot;size23&quot;&gt;프로젝트&amp;middot;실습을 통해 얻은 성과&lt;/h3&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;최근에는 터틀봇 3를 이용해 특정 좌표로 정밀하게 이동시키는 실습을 진행했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-path-to-node=&quot;12&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RViz2를 활용한 실시간 모니터링 및 위치 추정 최적화&lt;/li&gt;
&lt;li&gt;YAML 설정 파일 커스터마이징을 통한 장애물 회피 반경(Inflation Radius) 조절&lt;/li&gt;
&lt;li&gt;좌표 데이터를 직접 터미널로 전송하여 목적지에 정확히 도달시키는 정밀 주행 성공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;단순히 로봇을 움직이는 것을 넘어, 환경에 맞춰 파라미터를 튜닝하고 최적의 주행 효율을 찾아내는 과정을 통해 로봇 소프트웨어 엔지니어로서의 자신감을 얻었습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;13&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-path-to-node=&quot;15&quot; data-ke-size=&quot;size23&quot;&gt;실습 현장 및 결과물&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4080&quot; data-origin-height=&quot;3060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7yHWa/dJMcafe9orE/iXe1r2CTbTxe2KEvmkKwrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7yHWa/dJMcafe9orE/iXe1r2CTbTxe2KEvmkKwrk/img.png&quot; data-alt=&quot;센서를 달고 주행 준비중인 터틀봇&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7yHWa/dJMcafe9orE/iXe1r2CTbTxe2KEvmkKwrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7yHWa%2FdJMcafe9orE%2FiXe1r2CTbTxe2KEvmkKwrk%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;4080&quot; height=&quot;3060&quot; data-origin-width=&quot;4080&quot; data-origin-height=&quot;3060&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-path-to-node=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>KDT</category>
      <category>인천AI로봇</category>
      <category>인천국비교육</category>
      <category>인천인력개발원</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/253</guid>
      <comments>https://haniru.tistory.com/253#entry253comment</comments>
      <pubDate>Thu, 9 Apr 2026 01:49:28 +0900</pubDate>
    </item>
    <item>
      <title>온습도 센서(D11) openCR 에러</title>
      <link>https://haniru.tistory.com/252</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;온습도 센서를 openCR에서 라즈베리로 보내주면 계속 에러가 났다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnpXrS/dJMcagZl9Pb/g3OtbbrR7gNvaGKm8MuWG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnpXrS/dJMcagZl9Pb/g3OtbbrR7gNvaGKm8MuWG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnpXrS/dJMcagZl9Pb/g3OtbbrR7gNvaGKm8MuWG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnpXrS%2FdJMcagZl9Pb%2Fg3OtbbrR7gNvaGKm8MuWG0%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;795&quot; height=&quot;492&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;492&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;IDLE을 쓰면 해결된다 했는데, There is no status packet! 에러가 늦게 뜰 뿐 여전히 에러가 남&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K51Bx/dJMcaf7dz6r/JffvDicHvirGYQSBIi1FI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K51Bx/dJMcaf7dz6r/JffvDicHvirGYQSBIi1FI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K51Bx/dJMcaf7dz6r/JffvDicHvirGYQSBIi1FI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK51Bx%2FdJMcaf7dz6r%2FJffvDicHvirGYQSBIi1FI0%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;782&quot; height=&quot;527&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;527&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-path-to-node=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;비차단(Non-blocking) 방식의 핵심은 **&quot;데이터가 올 때까지 CPU가 delay()하며 기다리지 않고, 다른 일을 하다가 데이터가 준비되면 낚아채는 것&quot;**입니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;1&quot; data-ke-size=&quot;size16&quot;&gt;사용자님의 환경(OpenCR + DHT11)에 맞춰서 &lt;b data-index-in-node=&quot;30&quot; data-path-to-node=&quot;1&quot;&gt;DHT_NonBlocking&lt;/b&gt; 라이브러리를 사용하는 방식과 이를 &lt;b data-index-in-node=&quot;65&quot; data-path-to-node=&quot;1&quot;&gt;상태 머신&lt;/b&gt;으로 관리하는 통합 코드를 짜드릴게요.&lt;/p&gt;
&lt;hr data-path-to-node=&quot;2&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;3&quot; data-ke-size=&quot;size23&quot;&gt;1. 사전 준비 (라이브러리 설치)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;4&quot; data-ke-size=&quot;size16&quot;&gt;아두이노 IDE의 **라이브러리 관리자(Ctrl+Shift+I)**에서 &lt;b data-index-in-node=&quot;40&quot; data-path-to-node=&quot;4&quot;&gt;DHT_NonBlocking&lt;/b&gt; (작성자: Ole Wolf)을 검색해서 설치하세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3Qd4K/dJMcaarkFNg/EKt6LvV5ZVPD6eqxTZqFK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3Qd4K/dJMcaarkFNg/EKt6LvV5ZVPD6eqxTZqFK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3Qd4K/dJMcaarkFNg/EKt6LvV5ZVPD6eqxTZqFK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3Qd4K%2FdJMcaarkFNg%2FEKt6LvV5ZVPD6eqxTZqFK0%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; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-path-to-node=&quot;5&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;6&quot; data-ke-size=&quot;size23&quot;&gt;2. Turtlebot3Sensor.h (헤더 파일 수정)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;7&quot; data-ke-size=&quot;size16&quot;&gt;기존 DHT 포인터를 새로운 라이브러리 클래스로 교체해야 합니다.&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjh8P-OhtyTAxUAAAAAHQAAAAAQpQM&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;&lt;span&gt;C++&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;// turtlebot3_sensor.h 내부
#include &amp;lt;dht_nonblocking.h&amp;gt; // 라이브러리 변경

class Turtlebot3Sensor {
private:
  DHT_NonBlocking *p_dht; // 클래스명 변경
  int dht_pin_;

public:
  void initDHT(void);
  bool readDHT(float &amp;amp;temp, float &amp;amp;humi); // 이제 한 번에 온습도를 읽는 방식으로 변경
};
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-path-to-node=&quot;9&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;10&quot; data-ke-size=&quot;size23&quot;&gt;3. Turtlebot3Sensor.cpp (함수 구현 수정)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;11&quot; data-ke-size=&quot;size16&quot;&gt;readDHT 함수는 데이터가 준비되었을 때만 true를 반환하도록 설계합니다.&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjh8P-OhtyTAxUAAAAAHQAAAAAQpgM&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;&lt;span&gt;C++&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// turtlebot3_sensor.cpp

void Turtlebot3Sensor::initDHT(void) {
  dht_pin_ = 4; 
  p_dht = new DHT_NonBlocking(dht_pin_, DHT_TYPE_11); // DHT11 지정
}

// 비차단 방식으로 온습도를 읽는 함수
bool Turtlebot3Sensor::readDHT(float &amp;amp;temp, float &amp;amp;humi) {
  // measure 함수는 내부적으로 타이머를 체크하여 
  // 데이터 읽기가 완료된 순간에만 true를 리턴합니다. (내부 delay 없음)
  if (p_dht-&amp;gt;measure(&amp;amp;temp, &amp;amp;humi)) {
    return true; 
  }
  return false;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-path-to-node=&quot;13&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;14&quot; data-ke-size=&quot;size23&quot;&gt;4. turtlebot3.cpp (상태 머신 적용)&lt;/h3&gt;
&lt;p data-path-to-node=&quot;15&quot; data-ke-size=&quot;size16&quot;&gt;가장 중요한 부분입니다. update_analog_sensors에서 &lt;b data-index-in-node=&quot;38&quot; data-path-to-node=&quot;15&quot;&gt;&quot;데이터가 준비됐을 때만&quot;&lt;/b&gt; 제어표(Control Table)를 갱신합니다.&lt;/p&gt;
&lt;div data-ved=&quot;0CAAQhtANahgKEwjh8P-OhtyTAxUAAAAAHQAAAAAQpwM&quot; data-hveid=&quot;0&quot;&gt;
&lt;div&gt;&lt;span&gt;C++&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;void update_analog_sensors(uint32_t interval_ms)
{
  static uint32_t pre_time = 0;
  
  // [Part 1] 빠른 센서 (가스, 불꽃 등 - 30ms 주기)
  if(millis() - pre_time &amp;gt;= interval_ms){
    pre_time = millis();
    // (기존 가스, 불꽃 센서 로직 유지)
    control_items.flame_digital_status = (analogRead(A2) &amp;lt;= 300) ? 1 : 0;
    control_items.gas_digital_status = (digitalRead(12) == LOW) ? 1 : 0;
  }

  // [Part 2] 비차단 온습도 업데이트 (상태 머신)
  float temp, humi;
  // readDHT는 내부 타이머에 따라 약 2~4초마다 한 번씩만 true를 반환합니다.
  // 그 외의 시간에는 0.001초도 멈추지 않고 바로 false를 뱉고 지나갑니다.
  if (sensors.readDHT(temp, humi)) {
    // 데이터가 준비된 찰나에만 값을 업데이트합니다.
    control_items.dht_temp = (int32_t)(temp * 100.0f);
    control_items.dht_humi = (int32_t)(humi * 100.0f);

    // 디버깅용 로그 (필요할 때만 확인)
    // DEBUG_PRINT(&quot;[DHT Success] T: &quot;); DEBUG_PRINT(temp);
    // DEBUG_PRINT(&quot; H: &quot;); DEBUG_PRINTLN(humi);
  }
  
  // 이 함수가 종료되면 즉시 dxl_slave.processPacket()이 실행될 수 있으므로
  // 다이나믹셀 통신이 끊기지 않습니다.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-path-to-node=&quot;17&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-path-to-node=&quot;18&quot; data-ke-size=&quot;size23&quot;&gt;  이 코드의 작동 원리 (왜 안 멈추나?)&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-path-to-node=&quot;19&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,0,0&quot;&gt;기존 방식:&lt;/b&gt; readTemperature() 호출 &amp;rarr; 데이터 올 때까지 CPU가 멍하니 기다림(Blocking) &amp;rarr; 라즈베리파이가 부르는데 대답 못 함 &amp;rarr; &lt;b data-index-in-node=&quot;87&quot; data-path-to-node=&quot;19,0,0&quot;&gt;에러 발생&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;19,1,0&quot;&gt;비차단 방식:&lt;/b&gt; readDHT() 호출 &amp;rarr; &quot;아직 시간 안 됐네?&quot; 또는 &quot;읽는 중이야&quot; 하고 &lt;b data-index-in-node=&quot;52&quot; data-path-to-node=&quot;19,1,0&quot;&gt;바로 리턴&lt;/b&gt; &amp;rarr; 메인 루프 돌면서 &lt;b data-index-in-node=&quot;70&quot; data-path-to-node=&quot;19,1,0&quot;&gt;dxl_slave.processPacket() 실행&lt;/b&gt; &amp;rarr; 라즈베리파이와 사이좋게 대화 &amp;rarr; &lt;b data-index-in-node=&quot;119&quot; data-path-to-node=&quot;19,1,0&quot;&gt;통신 유지&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-path-to-node=&quot;20&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 수정하면 온습도 센서 때문에 전체 시스템이 기절하는 현상을 완벽하게 막을 수 있습니다.&lt;/p&gt;
&lt;p data-path-to-node=&quot;21&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b data-index-in-node=&quot;0&quot; data-path-to-node=&quot;21&quot;&gt;지금 바로 DHT_NonBlocking 라이브러리를 설치하고 코드를 적용해 보시겠어요?&lt;/b&gt; 설치 중에 막히는 부분이 있으면 바로 말씀해 주세요!&lt;/p&gt;</description>
      <category>아두이노</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/252</guid>
      <comments>https://haniru.tistory.com/252#entry252comment</comments>
      <pubDate>Thu, 9 Apr 2026 01:45:32 +0900</pubDate>
    </item>
    <item>
      <title>3d 프린터 - 공차 안맞음</title>
      <link>https://haniru.tistory.com/251</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;거진 한달에 걸쳐 뽑은 출력물들이 서보 혼 공차가 안맞아서 다시 뽑아야한다고 함&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4080&quot; data-origin-height=&quot;3060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KJFnX/dJMcaibOqq5/F2PAoMGLXkGkbLeyRrKZmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KJFnX/dJMcaibOqq5/F2PAoMGLXkGkbLeyRrKZmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KJFnX/dJMcaibOqq5/F2PAoMGLXkGkbLeyRrKZmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKJFnX%2FdJMcaibOqq5%2FF2PAoMGLXkGkbLeyRrKZmK%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;4080&quot; height=&quot;3060&quot; data-origin-width=&quot;4080&quot; data-origin-height=&quot;3060&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;3060&quot; data-origin-height=&quot;4080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz5oR4/dJMcafF8235/kCPUsOpAw3rBNXMuksW4K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz5oR4/dJMcafF8235/kCPUsOpAw3rBNXMuksW4K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz5oR4/dJMcafF8235/kCPUsOpAw3rBNXMuksW4K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz5oR4%2FdJMcafF8235%2FkCPUsOpAw3rBNXMuksW4K1%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;3060&quot; height=&quot;4080&quot; data-origin-width=&quot;3060&quot; data-origin-height=&quot;4080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;(이방법은 나사 부분까지 커질 수 있어 아래 수정) Horizontal Expansion - -0.2mm로 해보고 출력하려고 한다&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDzB26/dJMcaf7bM8U/wpakcc7a6MLsv0kt8VNYjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDzB26/dJMcaf7bM8U/wpakcc7a6MLsv0kt8VNYjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDzB26/dJMcaf7bM8U/wpakcc7a6MLsv0kt8VNYjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDzB26%2FdJMcaf7bM8U%2Fwpakcc7a6MLsv0kt8VNYjk%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;1260&quot; height=&quot;679&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;서포트도 너무 떼기 힘들어서 설정 변경&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7qYEg/dJMcaiJAhig/uUfwzoYvMkdgh1hFcnSRTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7qYEg/dJMcaiJAhig/uUfwzoYvMkdgh1hFcnSRTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7qYEg/dJMcaiJAhig/uUfwzoYvMkdgh1hFcnSRTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7qYEg%2FdJMcaiJAhig%2FuUfwzoYvMkdgh1hFcnSRTk%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;491&quot; height=&quot;475&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;475&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;482&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nJLUR/dJMcajhqdNX/bIJOdb5iaRso30FcJQOlFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nJLUR/dJMcajhqdNX/bIJOdb5iaRso30FcJQOlFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nJLUR/dJMcajhqdNX/bIJOdb5iaRso30FcJQOlFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnJLUR%2FdJMcajhqdNX%2FbIJOdb5iaRso30FcJQOlFK%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;482&quot; height=&quot;468&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;벽 라인도 6으로 변경&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1266&quot; data-origin-height=&quot;742&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cURWI0/dJMcabRfZDW/0hb1OKvVlYPjem2sgh1ZZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cURWI0/dJMcabRfZDW/0hb1OKvVlYPjem2sgh1ZZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cURWI0/dJMcabRfZDW/0hb1OKvVlYPjem2sgh1ZZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcURWI0%2FdJMcabRfZDW%2F0hb1OKvVlYPjem2sgh1ZZk%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;1266&quot; height=&quot;742&quot; data-origin-width=&quot;1266&quot; data-origin-height=&quot;742&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;484&quot; data-origin-height=&quot;477&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obEM8/dJMcafe6BQa/exNCk94d6CtKfeKwySX9Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obEM8/dJMcafe6BQa/exNCk94d6CtKfeKwySX9Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obEM8/dJMcafe6BQa/exNCk94d6CtKfeKwySX9Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobEM8%2FdJMcafe6BQa%2FexNCk94d6CtKfeKwySX9Kk%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;484&quot; height=&quot;477&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;477&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;그리고 빨리 뽑아야 하므로 layer height 도 0.1 에서 0.2로 변경&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba0F5V/dJMcagSAupj/AqaTe6xyRV0PKfJJnxQSZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba0F5V/dJMcagSAupj/AqaTe6xyRV0PKfJJnxQSZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba0F5V/dJMcagSAupj/AqaTe6xyRV0PKfJJnxQSZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba0F5V%2FdJMcagSAupj%2FAqaTe6xyRV0PKfJJnxQSZ1%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;484&quot; height=&quot;478&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCYxMQ/dJMcabcDLPx/hR10dhLLGfwafqGYMMFZG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCYxMQ/dJMcabcDLPx/hR10dhLLGfwafqGYMMFZG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCYxMQ/dJMcabcDLPx/hR10dhLLGfwafqGYMMFZG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCYxMQ%2FdJMcabcDLPx%2FhR10dhLLGfwafqGYMMFZG0%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;469&quot; height=&quot;391&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;391&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;960&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wWQjY/dJMcagZkqVA/ZW9F4THXDm6dLksPlPcjJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wWQjY/dJMcagZkqVA/ZW9F4THXDm6dLksPlPcjJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wWQjY/dJMcagZkqVA/ZW9F4THXDm6dLksPlPcjJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwWQjY%2FdJMcagZkqVA%2FZW9F4THXDm6dLksPlPcjJ0%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;960&quot; height=&quot;418&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;&lt;li&gt;&lt;b&gt;상자 만들기:&lt;/b&gt; 왼쪽 메뉴 아래 **'Support Blocker'**를 누르고 모델의 서보혼 구멍을 클릭합니다. 작은 상자가 생깁니다.&lt;/li&gt;&lt;li&gt;&lt;b&gt;위치 잡기:&lt;/b&gt; 상자를 클릭하고 **'Move'**와 &lt;b&gt;'Scale'&lt;/b&gt; 도구로 &lt;b&gt;서보혼 구멍 영역만&lt;/b&gt; 쏙 덮게 만드세요. (나사 구멍은 피해서!)&lt;/li&gt;&lt;li&gt;&lt;b&gt;개별 설정:&lt;/b&gt; 왼쪽 메뉴 세 번째 &lt;b&gt;'Per Model Settings'&lt;/b&gt; 아이콘 클릭 -&amp;gt; &lt;b&gt;'Modify settings for overlaps'&lt;/b&gt; 선택.&lt;/li&gt;&lt;li&gt;&lt;b&gt;명령어 추가:&lt;/b&gt; &lt;b&gt;'Select Settings'&lt;/b&gt; 누르고 Horizontal Expansion 검색해서 체크.&lt;/li&gt;&lt;li&gt;&lt;b&gt;값 입력:&lt;/b&gt; 새로 생긴 칸에 &lt;b&gt;-0.2&lt;/b&gt; 입력.&lt;/li&gt;&lt;li&gt;&lt;b&gt;확인:&lt;/b&gt; 슬라이싱 후 &lt;b&gt;'Preview'&lt;/b&gt; 탭에서 그 상자가 있는 부분만 구멍이 넓어졌는지 확인하세요.&lt;/li&gt;&lt;/ol&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;-&amp;gt; 결론: 이방법 해봐도 차이가 없어서 그냥 전체적으로 Horizontal Expansion 설정해줌&lt;/p&gt;</description>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/251</guid>
      <comments>https://haniru.tistory.com/251#entry251comment</comments>
      <pubDate>Sun, 5 Apr 2026 20:53:19 +0900</pubDate>
    </item>
    <item>
      <title>아두이노 - 도트 매트릭스</title>
      <link>https://haniru.tistory.com/250</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;하트 그리기&lt;/p&gt;
&lt;pre id=&quot;code_1774785433632&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;

// R1~R4가 빠져있어서 추가했습니다.
enum { R5=1, R7, C2, C3, R8, C5, R6, R3, R1, C4, C6, R4, C1, R2, C7, C8 };

const unsigned int pins[1+16] = {
  -1, 10, 11, 12, 13, 14, 15, 16, 17, 2, 3, 4, 5, 6, 7, 8, 9
};

const unsigned int R[1+8] = { -1, R1, R2, R3, R4, R5, R6, R7, R8 };
const unsigned int C[1+8] = { -1, C1, C2, C3, C4, C5, C6, C7, C8 }; // C5 중복 및 오타 수정

const unsigned int heart[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 1, 1, 0, 0, 1, 1, 0},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 0, 1, 1, 1, 1, 1, 1, 0},
  {-1, 0, 0, 1, 1, 1, 1, 0, 0},
  {-1, 0, 0, 0, 1, 1, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0}
}; // 세미콜론 추가

void dot_matrix_init() {
  for (int n=1; n&amp;lt;=8; n++) {
    pinMode(pins[R[n]], OUTPUT);
    pinMode(pins[C[n]], OUTPUT);
  }
  for (int n=1; n&amp;lt;=8; n++) {
    digitalWrite(pins[R[n]], HIGH);
    digitalWrite(pins[C[n]], HIGH);
  }
}

void dot_matrix_draw(const unsigned int image[1+8][1+8]) {
  static int n = 1;
  
  // 이전 라인 끄기
  digitalWrite(pins[R[n]], HIGH); 

  n++;
  if (n &amp;gt; 8) n = 1;

  // 열 제어 (Common Cathode/Anode에 따라 HIGH/LOW가 달라질 수 있음)
  for (int m=1; m&amp;lt;=8; m++) {
    if (image[n][m] == 1) {
      digitalWrite(pins[C[m]], LOW); // 선택된 열을 LOW로 (일반적 matrix 기준)
    } else {
      digitalWrite(pins[C[m]], HIGH);
    }
  }

  // 현재 행 켜기
  digitalWrite(pins[R[n]], HIGH); 
  // ※ 실제 매트릭스 구동 방식에 따라 HIGH/LOW 논리는 하드웨어에 맞춰 조정해야 합니다.
}

void draw() {
  dot_matrix_draw(heart);
}

NDelayFunc nDelayDraw(1, draw); // 언더바(_)를 공백으로 수정

void setup() {
  dot_matrix_init();
}

void loop() {
  nDelayDraw.run();
}&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;함수 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DotMatrix.h&lt;/p&gt;
&lt;pre id=&quot;code_1774786025448&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#ifndef NDelayFunc_h_
#define NDelayFunc_h_

enum { R5=1, R7, C2, C3, R8, C5, R6, R3, R1, C4, C6, R4, C1, R2, C7, C8 };

class _DotMatrix {
    static const unsigned int pins[1+16];
    static const unsigned int R[1+8];
    static const unsigned int C[1+8];

    public:
        static void init();
        static void draw(const unsigned int image[1+8][1+8]);
};

extern _DotMatrix DotMatrix;

#endif&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;DotMatrix.cpp&lt;/p&gt;
&lt;pre id=&quot;code_1774786010560&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;Arduino.h&quot;
#include &quot;DotMatrix.h&quot;

const unsigned int _DotMatrix::pins[1+16] = {
    -1, 10, 11, 12, 13, 14, 15, 16, 17, 2, 3, 4, 5, 6, 7, 8, 9
};

const unsigned int _DotMatrix::R[1+8] = { -1, R1, R2, R3, R4, R5, R6, R7, R8 };
const unsigned int _DotMatrix::C[1+8] = { -1, C1, C2, C3, C4, C5, C6, C7, C8 };

void _DotMatrix::init() {
    for (int n=1; n&amp;lt;=8; n++) {
        pinMode(pins[R[n]], OUTPUT);
        pinMode(pins[C[n]], OUTPUT);
    }

    for (int n=1; n&amp;lt;=8; n++) {
        digitalWrite(pins[R[n]], HIGH);
        digitalWrite(pins[C[n]], HIGH);
    }
}

void _DotMatrix::draw(const unsigned int image[1+8][1+8]) {
    static int n = 1;
    n++;
    if (n&amp;gt;8) n = 1;

    if (n&amp;gt;1) digitalWrite(pins[R[n-1]], HIGH);
    if (n==1) digitalWrite(pins[R[8]], HIGH);

    for (int m=1; m&amp;lt;=8; m++) {
        if (image[n][m] == 1) {
            digitalWrite(pins[C[m]], HIGH);
        } else {
            digitalWrite(pins[C[m]], LOW);
        }
    }

    for (int m=1; m&amp;lt;=8; m++) {
        if (image[n][m] == 1) {
            digitalWrite(pins[R[n]], LOW);
            break;
        }
    }
}

_DotMatrix DotMatrix;&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;함수 활용해 하트 그리기&lt;/p&gt;
&lt;pre id=&quot;code_1774786121383&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;
#include &quot;DotMatrix.h&quot;

const unsigned int heart[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 1, 1, 0, 0, 1, 1, 0},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 0, 1, 1, 1, 1, 1, 1, 0},
  {-1, 0, 0, 1, 1, 1, 1, 0, 0},
  {-1, 0, 0, 0, 1, 1, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0}
}; // 세미콜론 추가

void draw() {
  DotMatrix.draw(heart);
}

NDelayFunc nDelayDraw(1, draw);

void setup() {
  DotMatrix.init();
}

void loop() {
  nDelayDraw.run();
}&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;pre id=&quot;code_1774786416244&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;
#include &quot;DotMatrix.h&quot;

const unsigned int heart[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 1, 1, 0, 0, 1, 1, 0},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 0, 1, 1, 1, 1, 1, 1, 0},
  {-1, 0, 0, 1, 1, 1, 1, 0, 0},
  {-1, 0, 0, 0, 1, 1, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0}
}; // 세미콜론 추가

const unsigned int small_heart[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 1, 0, 0, 1, 0, 0},
  {-1, 0, 1, 1, 1, 1, 1, 0, 0},
  {-1, 0, 0, 1, 1, 1, 1, 0, 0},
  {-1, 0, 0, 0, 1, 1, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0}
}; // 세미콜론 추가

int heart_state = 0;
void choose() {
  heart_state++;
  if (heart_state &amp;gt; 1) heart_state = 0;
}

NDelayFunc nDelayChoose(500, choose);
void draw() {
  if (heart_state == 0) DotMatrix.draw(heart);
  else if (heart_state == 1) DotMatrix.draw(heart_small);
}

NDelayFunc nDelayDraw(1, draw);

void setup() {
  DotMatrix.init();
}

void loop() {
  nDelayChoose.run();
  nDelayDraw.run();
}&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;pre id=&quot;code_1774789047946&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;
#include &quot;DotMatrix.h&quot;

unsigned int game_display[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 1, 1, 1, 1, 1, 1, 1, 1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 1, 1, 1, 0, 0, 0},
};

unsigned int game_lose[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 1, 1, 0, 0, 1, 1, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 1, 1, 1, 1, 0, 0},
  {-1, 0, 1, 0, 0, 0, 0, 1, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
};


unsigned int game_win[1+8][1+8] = {
  {-1, -1, -1, -1, -1, -1, -1, -1},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 1, 0, 0, 1, 0, 0},
  {-1, 0, 0, 1, 0, 0, 1, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 1, 0, 0, 0, 0, 1, 0},
  {-1, 0, 0, 1, 1, 1, 1, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
  {-1, 0, 0, 0, 0, 0, 0, 0, 0},
};

enum {PLAY=0, LOSE, WIN};
int game_state = PLAY;

int ball_x = 4;
int ball_x_dir = 1;
int ball_y = 7;
int ball_y_dir = 1;

int how_many_bricks = 24;

void ball_move() {

  if (game_state != PLAY) return;

  game_display[ball_y][ball_x] = 0;
  ball_x += ball_x_dir;
  if (ball_x &amp;gt;= 8) {
    ball_x = 8;
    ball_x_dir = ball_x_dir;
  }

  if (ball_x &amp;lt;= 1) {
    ball_x = 1;
    ball_x_dir = -ball_x_dir;
  }

  ball_y += ball_y_dir;
  if(ball_y&amp;gt;=8) {
    if (game_display[ball_y][ball_x] == 1) {
      ball_y-=2*ball_y_dir;
      ball_y_dir=-ball_y_dir;
    } else {
      game_state = LOSE;
      return;
    }
  }

  if (ball_y &amp;lt;= 1) {
    ball_y = 1;
    ball_y_dir = -ball_y_dir;
  }

  if (game_display[ball_y+ball_y_dir][ball_x]==1) {
    if (ball_y != 7) {
      game_display[ball_y+ball_y_dir][ball_x] = 0;
      how_many_bricks--;
      if (how_many_bricks == 0) game_state = WIN;
    }
    ball_y_dir = -ball_y_dir;
  } else if (game_display[ball_y+ball_y_dir][ball_x+ball_x_dir] == 1) {
    if (ball_y != 7) {
      game_display[ball_y+ball_y_dir][ball_x+ball_x_dir] = 0;
      how_many_bricks--;
      if(how_many_bricks == 0) game_state = WIN;
    }
    ball_y_dir=-ball_y_dir;
    ball_x_dir=-ball_x_dir;
  }

  game_display[ball_y][ball_x] = 1;
}

NDelayFunc nDelayGame(500, ball_move);

void draw() {
  if(game_state == PLAY) DotMatrix.draw(game_display);
  if(game_state == LOSE) DotMatrix.draw(game_lose);
  if(game_state == WIN) DotMatrix.draw(game_win);
}

NDelayFunc nDelayDraw(1, draw);

int bar_x = 4;
const int bar_y = 8;

void bar_move() {
  if (game_state != PLAY) return;

  int analogValue = analogRead(A5);

  static int prevAnalogValue = 0;

  int new_bar_x = bar_x;

  if (analogValue &amp;gt; prevAnalogValue + 1024/8) {
    prevAnalogValue = analogValue;
    new_bar_x++;
    if (new_bar_x &amp;gt;= 7) new_bar_x = 7;
    Serial.println(new_bar_x);
  } else if (analogValue &amp;lt; prevAnalogValue-1024/8) {
    prevAnalogValue = analogValue;
    new_bar_x--;
    if(new_bar_x&amp;lt;=2) new_bar_x = 2;
    Serial.println(new_bar_x);
  }

  if (new_bar_x != bar_x) {
    game_display[bar_y][bar_x] = 0;
    game_display[bar_y][bar_x-1] = 0;
    game_display[bar_y][bar_x+1] = 0;

    bar_x = new_bar_x;

    game_display[bar_y][bar_x] = 1;
    game_display[bar_y][bar_x-1] = 1;
    game_display[bar_y][bar_x+1] = 1;
  }
}

void setup() {
  DotMatrix.init();
  Serial.begin(115200);
}

void loop() {
  bar_move();
  nDelayGame.run();
  nDelayDraw.run();
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>아두이노</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/250</guid>
      <comments>https://haniru.tistory.com/250#entry250comment</comments>
      <pubDate>Sun, 29 Mar 2026 21:57:29 +0900</pubDate>
    </item>
    <item>
      <title>아두이노 millis</title>
      <link>https://haniru.tistory.com/249</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;millis 함수로 현재 시간 확인하기&lt;/p&gt;
&lt;pre id=&quot;code_1774758037587&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;void setup() {
  Serial.begin(115200);
}

void loop() {
  unsigned long t_now = millis();
  Serial.println(t_now);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PAl54/dJMcaipe58M/5FO8Etwq7YvZ1aHwLiRwkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PAl54/dJMcaipe58M/5FO8Etwq7YvZ1aHwLiRwkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PAl54/dJMcaipe58M/5FO8Etwq7YvZ1aHwLiRwkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPAl54%2FdJMcaipe58M%2F5FO8Etwq7YvZ1aHwLiRwkK%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;379&quot; height=&quot;302&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;302&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;millis&amp;nbsp; 함수로&amp;nbsp; delay&amp;nbsp; 대체하기&lt;/p&gt;
&lt;pre id=&quot;code_1774758135362&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned long t_prev = 0;
const unsigned long t_delay = 1000;

void setup() {
  Serial.begin(115200);
}

void loop() {
  unsigned long t_now = millis();
  if (t_now - t_prev &amp;gt;= t_delay) {
    t_prev = t_now;

    Serial.println(t_now);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rj2Gp/dJMcaaEK4tu/GS2OezbwfsMfXFOCAH5FS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rj2Gp/dJMcaaEK4tu/GS2OezbwfsMfXFOCAH5FS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rj2Gp/dJMcaaEK4tu/GS2OezbwfsMfXFOCAH5FS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRj2Gp%2FdJMcaaEK4tu%2FGS2OezbwfsMfXFOCAH5FS1%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;320&quot; height=&quot;230&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;230&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초에 한번 t1, 0.5초에 한번 t2 문자열 출력&lt;/p&gt;
&lt;pre id=&quot;code_1774758376573&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unsigned long t1_prev = 0;
const unsigned long t1_delay = 1000;

unsigned long t2_prev = 0;
const unsigned long t2_delay = 500;

void setup() {
  Serial.begin(115200);
}

void loop() {
  unsigned long t1_now = millis();
  if (t1_now - t1_prev &amp;gt;= t1_delay) {
    t1_prev = t1_now;

    Serial.println(&quot;t1&quot;);
  }

  unsigned long t2_now = millis();
  if (t2_now - t2_prev &amp;gt;= t2_delay) {
    t2_prev = t2_now;
    Serial.println(&quot;\tt2&quot;);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;169&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m4s8Z/dJMcaaEK4vd/wPThU37CQrLUJUVwrd7cTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m4s8Z/dJMcaaEK4vd/wPThU37CQrLUJUVwrd7cTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m4s8Z/dJMcaaEK4vd/wPThU37CQrLUJUVwrd7cTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm4s8Z%2FdJMcaaEK4vd%2FwPThU37CQrLUJUVwrd7cTK%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;169&quot; height=&quot;165&quot; data-origin-width=&quot;169&quot; data-origin-height=&quot;165&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;LED 점멸 반복해보기 - 0.5초 간격&lt;/p&gt;
&lt;pre id=&quot;code_1774758594963&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const int LED = 13;

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  for (int on_off=0; on_off&amp;lt;=1; on_off++) {
    digitalWrite(LED, on_off);
    delay(500);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774758912522&quot; class=&quot;arduino&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;const int LED = 13;
int on_off = 0;

unsigned long t_prev = 0;
const unsigned long t_delay = 500;

void setup() {
  pinMode(LED, OUTPUT);
}

void loop() {
  unsigned long t_now = millis();
  
  if (t_now - t_prev &amp;gt;= t_delay) {
    t_prev = t_now;
    on_off++;
    if (on_off&amp;gt;1) on_off=0;
    digitalWrite(LED, on_off);
  }
}&lt;/code&gt;&lt;/pre&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/bw7MH8/dJMcagrpnze/XfqzPqLghk8DAijkYBTa7k/KakaoTalk_20260329_133054233.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260329_133054233.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.54MB&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;millis 함수로 LED 밝기 조절해보기 - 1초간 256단계로 LED 의 밝기가 증가&lt;/p&gt;
&lt;pre id=&quot;code_1774759380577&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const int LED = 10;
int t_high = 0;

unsigned long t_prev = 0;
const unsigned long t_delay = 4;

void setup() {

}

void loop() {
  unsigned long t_now = millis();
  if (t_now - t_prev &amp;gt;= t_delay) {
    t_prev = t_now;
    t_high++;

    if (t_high &amp;gt; 255) t_high = 0;
    analogWrite(LED, t_high);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774767499450&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class NDelayFunc {
  unsigned long t_prev;
  const unsigned long t_delay;
  void (* func)();

public:
  NDelayFunc(
    const unsigned long t_delay,
    void (* func)())
    : t_prev(0), t_delay(t_delay), func(func) {}

  void run() {
    unsigned long t_now = millis();
    if (t_now - t_prev &amp;gt;= t_delay) {
      t_prev = t_now;

      func();
    }
  }
};

const int LED = 10;
unsigned int t_high = 0;

void fading() {
  t_high++;
  if(t_high &amp;gt; 255) t_high = 0;
  analogWrite(LED, t_high);
}

NDelayFunc nDelayFading(4, fading);

void setup() {

}

void loop() {
  nDelayFading.run();
}&lt;/code&gt;&lt;/pre&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/cjbWU3/dJMcafMQdj1/tGmDXymaR1sICobeepfL51/KakaoTalk_20260329_134209664.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260329_134209664.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.47MB&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;mills 함수로 다중작업 하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;13번은 0.5초 주기로, 10번은 1초 주기로 깜빡깜빡 한다&lt;/p&gt;
&lt;pre id=&quot;code_1774767036122&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const int t1_LED = 13;
unsigned int on_off = 0;

const int t2_LED = 10;
unsigned int t_high = 0;

unsigned long t1_prev = 0;
const unsigned long t1_delay = 500;

unsigned long t2_prev = 0;
const unsigned long t2_delay = 4;

void setup() {
  pinMode(t1_LED, OUTPUT);
}

void loop() {
  unsigned long t1_now = millis();
  if (t1_now - t1_prev &amp;gt;= t1_delay) {
    t1_prev = t1_now;
    on_off++;
    if (on_off &amp;gt; 1) on_off = 0;
    digitalWrite(t1_LED, on_off);
  }

  unsigned long t2_now = millis();
  if (t2_now - t2_prev &amp;gt;= t2_delay) {
    t2_prev = t2_now;

    t_high++;

    if (t_high &amp;gt; 255) t_high = 0;
    analogWrite(t2_LED, t_high);
  }
}&lt;/code&gt;&lt;/pre&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/mnKtk/dJMcaiCKq11/lbcckJ0SjHtivSnaUbKiwK/KakaoTalk_20260329_155030074.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260329_155030074.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.85MB&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NDelayFunc 사용자 정의 라이브러리 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(C:\Users\유저명\OneDrive\문서\Arduino\libraries)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xMWZs/dJMcaa5OpOm/KY75wFmFuTTjsO4b7k55YK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xMWZs/dJMcaa5OpOm/KY75wFmFuTTjsO4b7k55YK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xMWZs/dJMcaa5OpOm/KY75wFmFuTTjsO4b7k55YK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxMWZs%2FdJMcaa5OpOm%2FKY75wFmFuTTjsO4b7k55YK%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;722&quot; height=&quot;166&quot; data-origin-width=&quot;722&quot; data-origin-height=&quot;166&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;687&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5PRhP/dJMcadBnMz0/g4XQ0jDJ2lSyhHmvrFch60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5PRhP/dJMcadBnMz0/g4XQ0jDJ2lSyhHmvrFch60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5PRhP/dJMcadBnMz0/g4XQ0jDJ2lSyhHmvrFch60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5PRhP%2FdJMcadBnMz0%2Fg4XQ0jDJ2lSyhHmvrFch60%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;687&quot; height=&quot;143&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;143&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;NDelayFunc.cpp&lt;/p&gt;
&lt;pre id=&quot;code_1774774900695&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;Arduino.h&quot;
#include &quot;NDelayFunc.h&quot;

NDelayFunc::NDelayFunc(
    const unsigned long t_delay,
    void (* func)())
    : t_prev(0), t_delay(t_delay), func(func) {}

void NDelayFunc::run() {
    unsigned long t_now = millis();
    if (t_now - t_prev &amp;gt;= t_delay) {
        t_prev = t_now;

        func();
    }
}&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;NDelayFunc.h&lt;/p&gt;
&lt;pre id=&quot;code_1774775034639&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#ifndef NDelayFunc_h_
#define NDelayFunc_h_

class NDelayFunc {
    unsigned long t_prev;
    const unsigned long t_delay;
    void (* func)();

    public:
    NDelayFunc(
        const unsigned long t_delay,
        void (* func)());

    void run();
};

#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;945&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMpsJc/dJMcacvOi9U/zl5pQjCrh9T8vR0C4bMr8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMpsJc/dJMcacvOi9U/zl5pQjCrh9T8vR0C4bMr8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMpsJc/dJMcacvOi9U/zl5pQjCrh9T8vR0C4bMr8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMpsJc%2FdJMcacvOi9U%2Fzl5pQjCrh9T8vR0C4bMr8k%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;517&quot; height=&quot;945&quot; data-origin-width=&quot;517&quot; data-origin-height=&quot;945&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;NDelayFunc&amp;nbsp; 사용자 정의 라이브러리 사용하기1&lt;/p&gt;
&lt;pre id=&quot;code_1774775571053&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;

const int LED = 10;
unsigned int t_high = 0;

void fading() {
  t_high++;
  if(t_high&amp;gt;255) t_high=0;
  analogWrite(LED, t_high);
}

NDelayFunc nDelayFading(4, fading);

void setup() {

}

void loop() {
  nDelayFading.run();
}&lt;/code&gt;&lt;/pre&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/cV1ADK/dJMcac3AZf4/y3BvD8YBgNVnohFXywXDe1/?attach=1&amp;amp;knm=tfile.mp4&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;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;다운로드&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;NDelayFunc&amp;nbsp; 사용자 정의 라이브러리 사용하기2&lt;/p&gt;
&lt;pre id=&quot;code_1774777243776&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;

const int t1_LED = 13;
unsigned int on_off = 0;

const int t2_LED = 10;
unsigned int t_high = 0;

unsigned long t1_prev = 0;
const unsigned long t1_delay = 500;

unsigned long t2_prev = 0;
const unsigned long t2_delay = 4;

void setup() {
  pinMode(t1_LED, OUTPUT);
}

void loop() {
  unsigned long t1_now = millis();
  if (t1_now - t1_prev &amp;gt;= t1_delay) {
    t1_prev = t1_now;

    on_off++;
    if (on_off&amp;gt;1) on_off = 0;
    digitalWrite(t1_LED, on_off);
  }

  unsigned long t2_now = millis();

  if (t2_now - t2_prev &amp;gt;= t2_delay) {
    t2_prev = t2_now;

    t_high++;
    if (t_high&amp;gt;255) t_high = 0;
    analogWrite(t2_LED, t_high);
  }
}&lt;/code&gt;&lt;/pre&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/rNkVU/dJMcadOV3Jw/NLuun5p7sSkvzYIb0O8Fo0/?attach=1&amp;amp;knm=tfile.mp4&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;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;다운로드&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;13번 핀에 연결된 LED를 0.5초 간격으로, 10번 핀에 연결된 LED를 1초 간격으로 껐다 켜기&lt;/p&gt;
&lt;pre id=&quot;code_1774777572121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;NDelayFunc.h&quot;

const int blink_LED = 13;
unsigned int on_off = 0;

const int fading_LED = 10;
unsigned int t_high = 0;

void blink() {
  on_off++;
  if (on_off &amp;gt; 1) on_off = 0;
  digitalWrite(blink_LED, on_off);
}

void fading() {
  t_high++;
  if (t_high&amp;gt;255) t_high = 0;
  analogWrite(fading_LED, t_high);
}

NDelayFunc nDelayBlink(500, blink);
NDelayFunc nDelayFading(4, fading);

void setup() {
  pinMode(blink_LED, OUTPUT);
}

void loop() {
  nDelayBlink.run();
  nDelayFading.run();
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>아두이노</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/249</guid>
      <comments>https://haniru.tistory.com/249#entry249comment</comments>
      <pubDate>Sun, 29 Mar 2026 20:02:54 +0900</pubDate>
    </item>
    <item>
      <title>아두이노 - 7세그먼트</title>
      <link>https://haniru.tistory.com/248</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;세그먼트 활용하기&lt;/p&gt;
&lt;pre id=&quot;code_1774529787177&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led_a = 2;
const unsigned int led_b = 3;
const unsigned int led_c = 4;
const unsigned int led_d = 5;
const unsigned int led_e = 6;
const unsigned int led_f = 7;
const unsigned int led_g = 8;

void setup() {
  pinMode(led_a, OUTPUT);
  pinMode(led_b, OUTPUT);
  pinMode(led_c, OUTPUT);
  pinMode(led_d, OUTPUT);
  pinMode(led_e, OUTPUT);
  pinMode(led_f, OUTPUT);
  pinMode(led_g, OUTPUT);

  digitalWrite(led_a, HIGH);
  digitalWrite(led_b, HIGH);
  digitalWrite(led_c, HIGH);
  digitalWrite(led_d, HIGH);
  digitalWrite(led_e, HIGH);
  digitalWrite(led_f, HIGH);
  digitalWrite(led_g, HIGH);
}

void loop() {

}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774530996596&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };

void setup() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }

  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], HIGH);
  }
}

void loop() {

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qnILA/dJMcahw4PVA/iLYN3KXZpQUWZqEgtH1ojK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qnILA/dJMcahw4PVA/iLYN3KXZpQUWZqEgtH1ojK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qnILA/dJMcahw4PVA/iLYN3KXZpQUWZqEgtH1ojK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqnILA%2FdJMcahw4PVA%2FiLYN3KXZpQUWZqEgtH1ojK%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;3000&quot; height=&quot;2250&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;2250&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;LED 켜고 끄기 반복&lt;/p&gt;
&lt;pre id=&quot;code_1774531108180&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };

void setup() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void loop() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], HIGH);
  }
  delay(500);

  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
  delay(500);

}&lt;/code&gt;&lt;/pre&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/UPvx8/dJMcafMOnQM/krVGkQnkKIn2RtF7HoZL81/KakaoTalk_20260326_221911418.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260326_221911418.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.50MB&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;LED 차례대로 켜고 꺼보기 -&amp;gt; 주파수: 0.286Hz, 0.5초 간격으로 켜지고 꺼짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;delay를 50으로 설정하면 초당 2.86회 / 2.86Hz, delay를 5로하면 초당 28.6회 28.6Hz, delay를 1로하면 초당 143회&lt;/p&gt;
&lt;pre id=&quot;code_1774531342924&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };

void setup() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void loop() {
  for (int x=0; x&amp;lt;7; x++) {
    for (int x=0; x&amp;lt;7; x++) {
      digitalWrite(led[x], LOW);
    }
    digitalWrite(led[x], HIGH);
    delay(500);
  }
}&lt;/code&gt;&lt;/pre&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/bkT72o/dJMcaako9Oa/mO82WKNYGaLow7o1JynXzK/KakaoTalk_20260326_222145607.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260326_222145607.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.71MB&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;함수로 만들기&lt;/p&gt;
&lt;pre id=&quot;code_1774532831910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void setup() {
  display_init();
}

void loop() {
  for (int x=0; x&amp;lt;7; x++) {
    display_clear();
    digitalWrite(led[x], HIGH);
    delay(1);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774533551957&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num_0[7] = { 1, 1, 1, 1, 1, 1, 0 };

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_0() {
  for(int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], num_0[x]==1?HIGH:LOW);
  }
}

void setup() {
  display_init();
  display_clear();
  display_0();
}

void loop() {
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRhiOn/dJMcadOT9F3/BSXHgMDY8Zd6HsBFrIJhp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRhiOn/dJMcadOT9F3/BSXHgMDY8Zd6HsBFrIJhp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRhiOn/dJMcadOT9F3/BSXHgMDY8Zd6HsBFrIJhp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRhiOn%2FdJMcadOT9F3%2FBSXHgMDY8Zd6HsBFrIJhp0%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;1428&quot; height=&quot;1071&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&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;0, 1숫자 표시하기&lt;/p&gt;
&lt;pre id=&quot;code_1774534315136&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num_0[7] = { 1, 1, 1, 1, 1, 1, 0 };
const unsigned int num_1[7] = { 0, 1, 1, 0, 0, 0, 0 };

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_0() {
  for(int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], num_0[x]==1?HIGH:LOW);
  }
}

void display_1() {
  for(int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], num_1[x]==1?HIGH:LOW);
  }
}

void setup() {
  display_init();
}

void loop() {
  display_clear();
  display_0();
  delay(500);

  display_clear();
  display_1();
  delay(500);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774534505144&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num[2][7] = {
  { 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0 }
};

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_0() {
  for(int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], num[0][x]==1?HIGH:LOW);
  }
}

void display_1() {
  for(int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], num[1][x]==1?HIGH:LOW);
  }
}

void setup() {
  display_init();
}

void loop() {
  display_clear();
  display_0();
  delay(500);

  display_clear();
  display_1();
  delay(500);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774534669095&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num[2][7] = {
  { 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0 }
};

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_number(int n) {
  if (0&amp;lt;=n&amp;amp;&amp;amp;n&amp;lt;=1) {
    for(int x=0; x&amp;lt;7; x++) {
      digitalWrite(led[x], num[n][x]==1?HIGH:LOW);
    }
  }
}

void setup() {
  display_init();
}

void loop() {
  display_clear();
  display_number(0);
  delay(500);

  display_clear();
  display_number(1);
  delay(500);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1774534769458&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num[2][7] = {
  { 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0 }
};

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_number(int n) {
  if (0&amp;lt;=n&amp;amp;&amp;amp;n&amp;lt;=1) {
    for(int x=0; x&amp;lt;7; x++) {
      digitalWrite(led[x], num[n][x]==1?HIGH:LOW);
    }
  }
}

void setup() {
  display_init();
}

void loop() {
  for (int n=0; n&amp;lt;=1; n++) {
    display_clear();
    display_number(n);
    delay(500);
  }
}&lt;/code&gt;&lt;/pre&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/DwmKs/dJMcafeYZog/KANDd0Ekya5k8fMKiYRnG0/KakaoTalk_20260326_231304612.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260326_231304612.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.25MB&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자표시 함수 일반화 하기&lt;/p&gt;
&lt;pre id=&quot;code_1774535062469&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num[10][7] = {
  { 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0 },
  { 1, 1, 0, 1, 1, 0, 1 },
  { 1, 1, 1, 1, 0, 0, 1 },
  { 0, 1, 1, 0, 0, 1, 1 },
  { 1, 0, 1, 1, 0, 1, 1 },
  { 1, 0, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 0, 0, 1, 0 },
  { 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 0, 1, 1 },
};

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_number(int n) {
  if (0&amp;lt;=n&amp;amp;&amp;amp;n&amp;lt;=9) {
    for(int x=0; x&amp;lt;7; x++) {
      digitalWrite(led[x], num[n][x]==1?HIGH:LOW);
    }
  }
}

void setup() {
  display_init();
}

void loop() {
  for (int n=0; n&amp;lt;=9; n++) {
    display_clear();
    display_number(n);
    delay(500);
  }
}&lt;/code&gt;&lt;/pre&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/b5gusn/dJMcagdROIx/bad3F202GRW7OKSovwONA0/KakaoTalk_20260326_232353008.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260326_232353008.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.85MB&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;시리얼 입력으로 숫자 표시하기&lt;/p&gt;
&lt;pre id=&quot;code_1774535817996&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const unsigned int led[7] = { 2, 3, 4, 5, 6, 7, 8 };
const unsigned int num[10][7] = {
  { 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0 },
  { 1, 1, 0, 1, 1, 0, 1 },
  { 1, 1, 1, 1, 0, 0, 1 },
  { 0, 1, 1, 0, 0, 1, 1 },
  { 1, 0, 1, 1, 0, 1, 1 },
  { 1, 0, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 0, 0, 1, 0 },
  { 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 0, 1, 1 },
};

void display_init() {
  for (int x=0; x&amp;lt;7; x++) {
    pinMode(led[x], OUTPUT);
  }
}

void display_clear() {
  for (int x=0; x&amp;lt;7; x++) {
    digitalWrite(led[x], LOW);
  }
}

void display_number(int n) {
  if (0&amp;lt;=n&amp;amp;&amp;amp;n&amp;lt;=9) {
    for(int x=0; x&amp;lt;7; x++) {
      digitalWrite(led[x], num[n][x]==1?HIGH:LOW);
    }
  }
}

void setup() {
  Serial.begin(115200);
  display_init();
}

void loop() {
  if (Serial.available()) {
    char userInput = Serial.read();
    if ('0' &amp;lt;= userInput &amp;amp;&amp;amp; userInput &amp;lt;= '9') {
      int num = userInput - '0';
      display_clear();
      display_number(num);
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwvLgS/dJMcaflIy3c/egvRMRLN08EB2HnI8nvQIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwvLgS/dJMcaflIy3c/egvRMRLN08EB2HnI8nvQIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwvLgS/dJMcaflIy3c/egvRMRLN08EB2HnI8nvQIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwvLgS%2FdJMcaflIy3c%2FegvRMRLN08EB2HnI8nvQIK%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;245&quot; height=&quot;165&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>아두이노</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/248</guid>
      <comments>https://haniru.tistory.com/248#entry248comment</comments>
      <pubDate>Thu, 26 Mar 2026 23:51:56 +0900</pubDate>
    </item>
    <item>
      <title>아두이노 - 서보모터, 초음파</title>
      <link>https://haniru.tistory.com/247</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;서보모터 각도 조절해보기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int SERVO = 10;
const int SERVO_PERIOD = 20000; // 20ms (50Hz)

// 10비트(1024) 기준으로 0.7ms~2.3ms 계산 (실수 연산 사용)
const int SERVO_MINDUTY = (1024.0 / 20.0) * 0.7; 
const int SERVO_MAXDUTY = (1024.0 / 20.0) * 2.3;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize(SERVO_PERIOD); // 초기화 시 주기를 설정하는 것이 좋습니다.
&amp;nbsp;&amp;nbsp;Timer1.pwm(SERVO, SERVO_MINDUTY);
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;delay(1000);
}

void loop() {
&amp;nbsp;&amp;nbsp;// loop 안에 넣어야 계속해서 반복 동작합니다.
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(SERVO, SERVO_MINDUTY);
&amp;nbsp;&amp;nbsp;delay(1000);
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(SERVO, SERVO_MAXDUTY);
&amp;nbsp;&amp;nbsp;delay(1000);
}&lt;/code&gt;&lt;/pre&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/bSenZY/dJMcaivSSoq/2wqpGpC4LURSGbBNCFUTQ1/KakaoTalk_20260323_210233184.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_210233184.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.24MB&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;br /&gt;서보모터 0~180도 조절해보기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int SERVO = 10;
const int SERVO_PERIOD = 20000; // 20ms (50Hz)

// 10비트(1024) 기준으로 0.7ms~2.3ms 계산 (실수 연산 사용)
const int SERVO_MINDUTY = (1024.0 / 20.0) * 0.7; 
const int SERVO_MAXDUTY = (1024.0 / 20.0) * 2.3;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize(SERVO_PERIOD); // 초기화 시 주기를 설정하는 것이 좋습니다.
&amp;nbsp;&amp;nbsp;Timer1.pwm(SERVO, SERVO_MINDUTY);
&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;delay(1000);

&amp;nbsp;&amp;nbsp;for (int angle=SERVO_MINDUTY; angle&amp;lt;=SERVO_MAXDUTY; angle++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(SERVO, angle);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(30);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;Timer1.disablePwm(SERVO);
}

void loop() {
}&lt;/code&gt;&lt;/pre&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/dXOLXv/dJMcadux1bz/HhkXQPMrP5YEThJfJelNA1/KakaoTalk_20260323_210827547.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_210827547.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.74MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;attachInterrupt(digitalPinToInterrupt(pin), ISR, mode): 버튼을 누르는 순간 또는 떼는 순간을 감지할 수 있다&lt;br /&gt;할당된 핀이 0에서 1로, 또는 1에서 0으로 바뀌는 순간을 감지하고 원하는 동작을 수행하고자 할 때 사용&lt;br /&gt;&amp;nbsp;&lt;br /&gt;pin: 핀번호, 아두이노 우노의 경우 2, 3&lt;br /&gt;ISR: 인터럽트가 발생하면 하드웨어적으로 호출되는 인터럽트 처리 함수&lt;br /&gt;mode: 인터럽트 발생 조건, LOW, CHANGE, RISING, FALLING 중 하나&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;const int ledPin = 13;
const int buttonPin = 2;

int led_state = LOW;
bool led_state_changed = false;

void buttonPressed() {
&amp;nbsp;&amp;nbsp;led_state = (led_state == LOW) ? HIGH : LOW;
&amp;nbsp;&amp;nbsp;led_state_changed = true;
}

void setup() {
&amp;nbsp;&amp;nbsp;pinMode(ledPin, OUTPUT);
&amp;nbsp;&amp;nbsp;pinMode(buttonPin, INPUT);
&amp;nbsp;&amp;nbsp;attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPressed, RISING);
}

void loop() {
&amp;nbsp;&amp;nbsp;if (led_state_changed) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;led_state_changed = false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digitalWrite(ledPin, led_state);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&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/bmmeqy/dJMcaaq7Zb4/2cmKZgMMkhAK9tUkyxV411/KakaoTalk_20260323_213825705.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_213825705.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.81MB&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;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;Servo.h&amp;gt;
 const int SERVO = 10;
 Servo servo;
 const int buttonPin = 2;

 int servo_state = 30;
 bool servo_state_changed = false;

 void buttonPressed() {
&amp;nbsp;&amp;nbsp;servo_state = (servo_state == 30) ? 150 : 30;
&amp;nbsp;&amp;nbsp;servo_state_changed = true;
 }

 void setup() {
&amp;nbsp;&amp;nbsp;pinMode(buttonPin, INPUT);
&amp;nbsp;&amp;nbsp;attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPressed, RISING);
&amp;nbsp;&amp;nbsp;servo.attach(SERVO);
&amp;nbsp;&amp;nbsp;servo.write(0);
&amp;nbsp;&amp;nbsp;delay(1000);
 }

 void loop() {
&amp;nbsp;&amp;nbsp;if(servo_state_changed) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;servo_state_changed = false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;servo.write(servo_state);
&amp;nbsp;&amp;nbsp;}
 }&lt;/code&gt;&lt;/pre&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/K6kFH/dJMb99TgWaT/KR0U1fkze7MD2kg7sq8vvK/KakaoTalk_20260323_215927936.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_215927936.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.00MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;attachPCINT(digitalPinToPCINT(pin), ISR, mode): 특정한 핀에 특정한 조건에 맞는 핀 신호 변화 인터럽트가 발생할 경우 수행할 함수를 등록하는 함수&lt;br /&gt;digitalPinToPCINT(pin): 핀번호, 아두이노 우노의 경우 2, 3을 제외한 나머지 핀&lt;br /&gt;ISR: 인터럽트가 발생하면 하드웨어적으로 호출되는 인터럽트 처리 함수&lt;br /&gt;mode: 인터럽트 발생 조건, CHANGE, RISING, FALLING 중 하나&lt;br /&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;544&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5yzmm/dJMcafzdaVi/ciMRh6kzTod9yqlcIDLeRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5yzmm/dJMcafzdaVi/ciMRh6kzTod9yqlcIDLeRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5yzmm/dJMcafzdaVi/ciMRh6kzTod9yqlcIDLeRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5yzmm%2FdJMcafzdaVi%2FciMRh6kzTod9yqlcIDLeRk%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;544&quot; height=&quot;439&quot; data-origin-width=&quot;544&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;204&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y3sJa/dJMb99TgWo0/R7CKVKIsHg2elVZNC9uVGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y3sJa/dJMb99TgWo0/R7CKVKIsHg2elVZNC9uVGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y3sJa/dJMb99TgWo0/R7CKVKIsHg2elVZNC9uVGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy3sJa%2FdJMb99TgWo0%2FR7CKVKIsHg2elVZNC9uVGk%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;204&quot; height=&quot;672&quot; data-origin-width=&quot;204&quot; data-origin-height=&quot;672&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;버튼 인터럽트로 LED 켜기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &quot;PinChangeInterrupt.h&quot;

const int ledPin = 13;
const int buttonPin = 4;

int led_state = LOW;
bool led_state_changed = false;

void buttonPressed() {
&amp;nbsp;&amp;nbsp;led_state = (led_state == LOW) ? HIGH : LOW;
&amp;nbsp;&amp;nbsp;led_state_changed = true;
}

void setup() {
&amp;nbsp;&amp;nbsp;pinMode(ledPin, OUTPUT);
&amp;nbsp;&amp;nbsp;pinMode(buttonPin, INPUT);
&amp;nbsp;&amp;nbsp;attachPCINT(digitalPinToPCINT(buttonPin), buttonPressed, RISING);
}

void loop() {
&amp;nbsp;&amp;nbsp;if(led_state_changed) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;led_state_changed = false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digitalWrite(ledPin, led_state);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&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/ypJ46/dJMcaaxTMuU/5SLSWS4THTd6PN3rT5XdjK/KakaoTalk_20260323_221530687.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_221530687.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.66MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;초음파 센서로 거리 측정해보기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;const int trig_pin = 11;
const int echo_pin = 12;

void setup() {
&amp;nbsp;&amp;nbsp;pinMode(trig_pin, OUTPUT);
&amp;nbsp;&amp;nbsp;pinMode(echo_pin, INPUT);

&amp;nbsp;&amp;nbsp;Serial.begin(115200);
}

void loop() {
&amp;nbsp;&amp;nbsp;digitalWrite(trig_pin, LOW);
&amp;nbsp;&amp;nbsp;delayMicroseconds(2);
&amp;nbsp;&amp;nbsp;digitalWrite(trig_pin, HIGH);
&amp;nbsp;&amp;nbsp;delayMicroseconds(10);
&amp;nbsp;&amp;nbsp;digitalWrite(trig_pin, LOW);

&amp;nbsp;&amp;nbsp;long duration = pulseIn(echo_pin, HIGH);
&amp;nbsp;&amp;nbsp;long distance = (duration/2) / 29.1;

&amp;nbsp;&amp;nbsp;Serial.print(distance);
&amp;nbsp;&amp;nbsp;Serial.println(&quot;cm&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;pulseIn 함수 수행 시간 살펴보기&lt;/p&gt;
&lt;pre id=&quot;code_1774278824194&quot; class=&quot;arduino&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;const int trig_pin = 11;
const int echo_pin = 12;

void setup() {
  pinMode(trig_pin, OUTPUT);
  pinMode(echo_pin, INPUT);

  Serial.begin(115200);
}

void loop() {
  digitalWrite(trig_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig_pin, LOW);

  unsigned long t_begin = millis();

  long duration = pulseIn(echo_pin, HIGH);
  unsigned long t_end = millis();
  Serial.print(t_end - t_begin);
  Serial.println(&quot;ms&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;핀 신호변화 인터럽트 사용하기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;PinChangeInterrupt.h&amp;gt;

const int trig_pin = 11;
const int echo_pin = 12;

unsigned long echo_duration = 0;
void echoIsr(void) {
&amp;nbsp;&amp;nbsp;static unsigned long echo_begin = 0;
&amp;nbsp;&amp;nbsp;static unsigned long echo_end = 0;
&amp;nbsp;&amp;nbsp;unsigned int echo_pin_state = digitalRead(echo_pin);
&amp;nbsp;&amp;nbsp;if(echo_pin_state == HIGH) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo_begin = micros();
&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo_end = micros();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo_duration = echo_end - echo_begin;
&amp;nbsp;&amp;nbsp;}
}

void setup() {
&amp;nbsp;&amp;nbsp;pinMode(trig_pin, OUTPUT);
&amp;nbsp;&amp;nbsp;pinMode(echo_pin, INPUT);

&amp;nbsp;&amp;nbsp;attachPCINT(digitalPinToPCINT(echo_pin), echoIsr, CHANGE);

&amp;nbsp;&amp;nbsp;Serial.begin(115200);
}

void loop() {
&amp;nbsp;&amp;nbsp;if (echo_duration == 0) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digitalWrite(trig_pin, LOW);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delayMicroseconds(2);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digitalWrite(trig_pin, HIGH);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delayMicroseconds(10);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;digitalWrite(trig_pin, LOW);
&amp;nbsp;&amp;nbsp;} else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned long distance = echo_duration / 58;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Serial.print(distance);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Serial.println(&quot;cm&quot;);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo_duration = 0;
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lQPmZ/dJMb99Z4SOr/sM8XF7CQ3XZEKvK0k6b581/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lQPmZ/dJMb99Z4SOr/sM8XF7CQ3XZEKvK0k6b581/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lQPmZ/dJMb99Z4SOr/sM8XF7CQ3XZEKvK0k6b581/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlQPmZ%2FdJMb99Z4SOr%2FsM8XF7CQ3XZEKvK0k6b581%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;1428&quot; height=&quot;1071&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&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;</description>
      <category>아두이노</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/247</guid>
      <comments>https://haniru.tistory.com/247#entry247comment</comments>
      <pubDate>Mon, 23 Mar 2026 22:47:41 +0900</pubDate>
    </item>
    <item>
      <title>아두이노 - Timer (빛, 부저)</title>
      <link>https://haniru.tistory.com/246</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Timer1.initialize(): Timer1을 초기화하는 함수&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Timer1.pwm(pin, duty): 특정한 핀에 사각 파형을 생성하도록 함&lt;br /&gt;pin: 사각 파형을 내보낼 핀 번호, 9, 10번 핀 중 하나&lt;br /&gt;duty: 사각 파형의 HIGH 구간의 개수, 0~1023 사이 값&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Timer.setPeriod(period): 마이크로초 단위로 주기를 설정&lt;br /&gt;period: 마이크로 초 단위 주기, 1~8388480 사이 값, 주파수로는 0.12~1MHz&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Timer.setPwmDuty(pin, duty): 주어진 핀에 사각 파형의 duty를 설정하는 함수&lt;br /&gt;pin: 사각 파형의 HIGH 구간 값을 변경할 핀&lt;br /&gt;duty:&amp;nbsp; 변경할 사각 파형의 HIGH 구간 값, 1~1023 사이 값&lt;br /&gt;&amp;nbsp;&lt;br /&gt;timerone 설치: 스케치 - 라이브러리 포함하기 - 라이브러리 관리&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rr1vJ/dJMb99MtiIv/0JBdd4VQKigBLvkc3kxmck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rr1vJ/dJMb99MtiIv/0JBdd4VQKigBLvkc3kxmck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rr1vJ/dJMb99MtiIv/0JBdd4VQKigBLvkc3kxmck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frr1vJ%2FdJMb99MtiIv%2F0JBdd4VQKigBLvkc3kxmck%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;254&quot; height=&quot;371&quot; data-origin-width=&quot;254&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;잘 설치되어있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;890&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXZIX9/dJMcadH5yCk/ji5vDtYbWUgWGRyN4IrbF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXZIX9/dJMcadH5yCk/ji5vDtYbWUgWGRyN4IrbF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXZIX9/dJMcadH5yCk/ji5vDtYbWUgWGRyN4IrbF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXZIX9%2FdJMcadH5yCk%2Fji5vDtYbWUgWGRyN4IrbF0%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;544&quot; height=&quot;890&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;890&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;LED 켜고 끄기 반복하기 - 1Hz 의 주파수로 LED 점멸 확인 (1초 주기로 LED가 점멸하는 것을 확인)&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000);
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, 511);
}

void loop() {
&amp;nbsp;&amp;nbsp;
}&lt;/code&gt;&lt;/pre&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/wWTN1/dJMcaiWV0ir/el01tbF3iWasjZslXcm9k0/KakaoTalk_20260323_001003432.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_001003432.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.68MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;LED 켜고 끄기 간격 줄여보기 - 10Hz의 주파수로 점멸 (초당 10번 점멸)&lt;/p&gt;
&lt;pre id=&quot;code_1774192426409&quot; class=&quot;reasonml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
  Timer1.initialize();
  Timer1.pwm(LED, 0);

  Timer1.setPeriod(1000000/10);
  Timer1.setPwmDuty(LED, 511);
}

void loop() {

}&lt;/code&gt;&lt;/pre&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/EV0Ud/dJMcagLDVG1/O4QGTuATzvtSQKkUsxIefK/KakaoTalk_20260323_001137355.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_001137355.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.32MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;LED 켜고 끄기 간격 줄여보기 - 100Hz의 주파수로 점멸 (불빛이 계속 켜져있는 것 처럼 보임)&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/100);
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, 511);
}

void loop() {

}&lt;/code&gt;&lt;/pre&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/cv5Ilj/dJMcajnYoua/qnwCtdQMo03eBRDKMktwU0/KakaoTalk_20260323_001525341.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_001525341.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.30MB&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;br /&gt;주파수 늘리기 - 초당 1000번 점멸&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/1000);
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, 511);
}

void loop() {

}&lt;/code&gt;&lt;/pre&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/bRLnHG/dJMcah4QpUb/sz7xRwWuXKqSyJktRZBHW0/KakaoTalk_20260323_001650988.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_001650988.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.30MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;LED 어둡게 하기 - 10% 만큼 점등, 90% 만큼 소등&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/1000);
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, 100);
}

void loop() {

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RkgOe/dJMcacbn4u3/UJKdj6M0C8tWkv6P813hIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RkgOe/dJMcacbn4u3/UJKdj6M0C8tWkv6P813hIk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RkgOe/dJMcacbn4u3/UJKdj6M0C8tWkv6P813hIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRkgOe%2FdJMcacbn4u3%2FUJKdj6M0C8tWkv6P813hIk%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;1428&quot; height=&quot;1071&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;LED 밝게 하기 - 90% 만큼 점등, 10% 만큼 소등&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/1000);
&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, 900);
}

void loop() {

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WeAIh/dJMcadaeIi8/ED5CaSpxkT7c4WVjurboCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WeAIh/dJMcadaeIi8/ED5CaSpxkT7c4WVjurboCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WeAIh/dJMcadaeIi8/ED5CaSpxkT7c4WVjurboCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWeAIh%2FdJMcadaeIi8%2FED5CaSpxkT7c4WVjurboCk%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;1428&quot; height=&quot;1071&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1071&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;LED 밝기를 11단계로 조절해보기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000);
}

void loop() {
&amp;nbsp;&amp;nbsp;for (int t_high=0; t_high&amp;lt;=10; t_high++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, t_high*100);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(100);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&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/tI7Wj/dJMcaiimAAN/QDqJ3XKX2jhLAMzsnBFB3k/KakaoTalk_20260323_002217347.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_002217347.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.54MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;밝기를 1024 단계로 조절&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int LED = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(LED, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000);
}

void loop() {
&amp;nbsp;&amp;nbsp;for (int t_high=0; t_high&amp;lt;=1023; t_high++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(LED, t_high);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(1);
&amp;nbsp;&amp;nbsp;}
}&lt;/code&gt;&lt;/pre&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/bJtY9I/dJMcabXQ6Lq/kNTKSIjlFDTsVCQq3JvdF1/KakaoTalk_20260323_002530069.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_002530069.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.45MB&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;br /&gt;&amp;nbsp;&lt;br /&gt;피에조 부저 제어&lt;br /&gt;&amp;nbsp;&lt;br /&gt;수동 부저 소리내보기 - 도라는 음이 나옴&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int BUZZER = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(BUZZER, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(BUZZER, 512);

&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/262);

&amp;nbsp;&amp;nbsp;delay(3000);

&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(BUZZER, 0);
}

void loop() {
&amp;nbsp;&amp;nbsp;
}&lt;/code&gt;&lt;/pre&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/biVmxj/dJMcaflEvtz/UJEZkok28xtuN42vYEIBX1/KakaoTalk_20260323_003205058.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_003205058.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.74MB&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;br /&gt;도, 레 3회 반복&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int BUZZER = 10;

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(BUZZER, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(BUZZER, 100);

&amp;nbsp;&amp;nbsp;for (int cnt=0; cnt&amp;lt;=2; cnt++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/262);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(1000);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/294);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(1000);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(BUZZER, 0);
}

void loop() {

}&lt;/code&gt;&lt;/pre&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/T881i/dJMcabXQ6X8/cM4k5GNqlw1jkKZs38WsZ0/KakaoTalk_20260323_003931243.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_003931243.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.45MB&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;br /&gt;도레미파솔라시도&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#include &amp;lt;TimerOne.h&amp;gt;

const int BUZZER = 10;

const int melody[] = {
&amp;nbsp;&amp;nbsp;262, 294, 330, 349, 393, 440, 494, 523,
};

void setup() {
&amp;nbsp;&amp;nbsp;Timer1.initialize();
&amp;nbsp;&amp;nbsp;Timer1.pwm(BUZZER, 0);

&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(BUZZER, 100);

&amp;nbsp;&amp;nbsp;for (int note=0; note&amp;lt;8; note++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Timer1.setPeriod(1000000/melody[note]);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(500);
&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;Timer1.setPwmDuty(BUZZER, 0);
}

void loop() {

}&lt;/code&gt;&lt;/pre&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/CMnSv/dJMcabQ4zjr/03qvpEnAAx4yAFwMIcLE41/KakaoTalk_20260323_004215778.mp4?attach=1&amp;amp;knm=tfile.mp4&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;KakaoTalk_20260323_004215778.mp4&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;1.41MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>아두이노</category>
      <author>haniru</author>
      <guid isPermaLink="true">https://haniru.tistory.com/246</guid>
      <comments>https://haniru.tistory.com/246#entry246comment</comments>
      <pubDate>Mon, 23 Mar 2026 00:43:11 +0900</pubDate>
    </item>
  </channel>
</rss>