<div class="area-main" style="box-sizing: inherit; width: 640px; max-width: 640px; margin-top: 0px;">
   <div class="area-view" style="box-sizing: inherit;">
      <div class="article-view" style="box-sizing: inherit; margin-bottom: 12px;">
         <div class="tt_article_useless_p_margin contents_style" style="box-sizing: inherit;">
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">ESP32-CAM은 저가이지만 와이파이 와 카메라를 장착한 소형 모듈입니다.</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure class="imageblock alignCenter" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; display: table; position: relative; text-align: center;"><span data-url="https://blog.kakaocdn.net/dn/cfGVeM/btqFo5Crc4s/QKdKeQn1XyfkFaO3oxEulK/img.png" data-lightbox="lightbox" data-alt="" style="box-sizing: inherit; cursor: pointer;"><img src="https://blog.kakaocdn.net/dn/cfGVeM/btqFo5Crc4s/QKdKeQn1XyfkFaO3oxEulK/img.png" srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfGVeM%2FbtqFo5Crc4s%2FQKdKeQn1XyfkFaO3oxEulK%2Fimg.png" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; border-style: none; max-width: 100%; display: inline-block; width: 640px; margin: 0px; height: auto;" /></span></figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <h3 data-ke-size="size23" style="box-sizing: inherit; font-size: 20px; margin-bottom: 24px; font-weight: normal; color: rgba(0, 0, 0, 0.87); line-height: 1.4;">버튼 기능 구현</h3>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">D16 번 핀을 버튼과 연결하여 버튼 신호를 받습니다.</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure class="imageblock alignCenter" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; display: table; position: relative; text-align: center;"><span data-url="https://blog.kakaocdn.net/dn/Pvw6H/btqFpKSfklp/0AjBJ4TSbSgTSUk3dzqeV0/img.png" data-lightbox="lightbox" data-alt="" style="box-sizing: inherit; cursor: pointer;"><img src="https://blog.kakaocdn.net/dn/Pvw6H/btqFpKSfklp/0AjBJ4TSbSgTSUk3dzqeV0/img.png" srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPvw6H%2FbtqFpKSfklp%2F0AjBJ4TSbSgTSUk3dzqeV0%2Fimg.png" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; border-style: none; max-width: 100%; display: inline-block; width: 640px; margin: 0px; height: auto;" /></span></figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure data-ke-type="video" data-ke-style="alignCenter" data-video-host="kakaotv" data-video-url="https://tv.kakao.com/channel/2723244/cliplink/410534878" data-video-thumbnail="https://scrap.kakaocdn.net/dn/H9iij/hyGHkoay8L/7ZMYvs6ksFY86SRYlFmiU1/img.png?width=854&amp;height=429&amp;face=0_0_854_429,https://scrap.kakaocdn.net/dn/NleTp/hyGFLuabXj/rUxoknSaFK8wxlwpOptRf0/img.jpg?width=640&amp;height=360&amp;face=0_0_640_360" data-video-width="854" data-video-height="429" data-video-origin-width="854" data-video-origin-height="429" data-ke-mobilestyle="widthContent" data-video-play-service="daum_tistory" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; justify-content: center; align-items: center; position: relative; text-align: center; color: #bdbdbd; letter-spacing: -0.7px; font-size: 16px; line-height: 30px;"><iframe src="https://play-tv.kakao.com/embed/player/cliplink/410534878?service=daum_tistory" width="854" height="429" frameborder="0" allowfullscreen="true" style="box-sizing: inherit; max-width: 100%; margin: 0px;"></iframe>
               <figcaption style="box-sizing: inherit; font-size: 14px; word-break: break-word; padding-top: 10px; min-height: 20px; caption-side: bottom; color: #666666;"></figcaption>
               </figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">사진 촬영 &amp; FTP 업로드 함수를 프로그래밍합니다.</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure class="imageblock alignCenter" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; display: table; position: relative; text-align: center;"><span data-url="https://blog.kakaocdn.net/dn/qRbOz/btqFpAI20Yf/yMnvgOMFfhyG1L9Y4lglpk/img.png" data-lightbox="lightbox" data-alt="" style="box-sizing: inherit; cursor: pointer;"><img src="https://blog.kakaocdn.net/dn/qRbOz/btqFpAI20Yf/yMnvgOMFfhyG1L9Y4lglpk/img.png" srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqRbOz%2FbtqFpAI20Yf%2FyMnvgOMFfhyG1L9Y4lglpk%2Fimg.png" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; border-style: none; max-width: 100%; display: inline-block; width: 640px; margin: 0px; height: auto;" /></span></figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <h3 data-ke-size="size23" style="box-sizing: inherit; font-size: 20px; margin-bottom: 24px; font-weight: normal; color: rgba(0, 0, 0, 0.87); line-height: 1.4;">버튼을 눌러 사진 촬영후 FTP로 이미지 업로드</h3>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">버튼을 누르면 사진을 촬영하고 FTP 로 이미지를 업로드합니다.</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure data-ke-type="video" data-ke-style="alignCenter" data-video-host="kakaotv" data-video-url="https://tv.kakao.com/channel/2723244/cliplink/410536702" data-video-thumbnail="https://scrap.kakaocdn.net/dn/bwaCj0/hyGFQ3m9EC/3pc8IKWXpqhp3GRyBrD73k/img.png?width=672&amp;height=480&amp;face=0_0_672_480,https://scrap.kakaocdn.net/dn/cOgBJC/hyGFWJgrtp/Z8HHyL8jinrSRPagR7M4H1/img.jpg?width=640&amp;height=360&amp;face=0_0_640_360" data-video-width="672" data-video-height="480" data-video-origin-width="672" data-video-origin-height="480" data-ke-mobilestyle="widthContent" data-video-play-service="daum_tistory" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; justify-content: center; align-items: center; position: relative; text-align: center; color: #bdbdbd; letter-spacing: -0.7px; font-size: 16px; line-height: 30px;"><iframe src="https://play-tv.kakao.com/embed/player/cliplink/410536702?service=daum_tistory" width="672" height="480" frameborder="0" allowfullscreen="true" style="box-sizing: inherit; max-width: 100%; margin: 0px;"></iframe>
               <figcaption style="box-sizing: inherit; font-size: 14px; word-break: break-word; padding-top: 10px; min-height: 20px; caption-side: bottom; color: #666666;"></figcaption>
               </figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <h2 data-ke-size="size26" style="box-sizing: inherit; font-size: 24px; margin-bottom: 24px; font-weight: normal; color: rgba(0, 0, 0, 0.87); line-height: 1.38;">NTP 현재시간 얻어오기</h2>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;"><a href="https://www.arduinolibraries.info/libraries/ntp-client" style="box-sizing: inherit; display: inline-block; color: #3d62ce;" target="_blank">https://www.arduinolibraries.info/libraries/ntp-client</a></p>
            <figure id="og_1594090506803" contenteditable="false" data-ke-type="opengraph" data-og-type="website" data-og-title="NTPClient" data-og-description="An NTPClient to connect to a time server" data-og-host="www.arduinolibraries.info" data-og-source-url="https://www.arduinolibraries.info/libraries/ntp-client" data-og-url="https://www.arduinolibraries.info/libraries/ntp-client" data-og-image="" style="box-sizing: inherit; margin: 30px 0px; max-width: 100%; clear: both;"><a href="https://www.arduinolibraries.info/libraries/ntp-client" target="_blank" rel="noopener" data-source-url="https://www.arduinolibraries.info/libraries/ntp-client" style="box-sizing: border-box; display: block; color: #000000; position: relative; height: 200px; border: 1px solid rgb(217, 217, 217); text-decoration-line: none; z-index: 1;">
                  <div class="og-image" style="box-sizing: inherit; position: absolute; top: 0px; bottom: 0px; left: 0px; width: 200px; border-right: 1px solid rgb(217, 217, 217); background-size: cover; background-position: center center; background-image: url(&quot;&quot;);">&nbsp;</div>
                  <div class="og-text" style="box-sizing: border-box; position: absolute; inset: 0px 0px 0px 201px; padding: 33px 46px 0px 39px;">
                     <p class="og-title" style="box-sizing: inherit; font-size: 22px; line-height: 28px; max-width: 467px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; font-family: &quot;Noto Sans DemiLight&quot;, &quot;Noto Sans KR&quot;, sans-serif; padding-top: 0px !important; padding-bottom: 0px !important; margin-bottom: 10px !important;">NTPClient</p>
                     <p class="og-desc" style="box-sizing: inherit; font-size: 14px; line-height: normal; color: #909090; text-overflow: ellipsis; overflow: hidden; font-family: &quot;Noto Sans DemiLight&quot;, &quot;Noto Sans KR&quot;, sans-serif; font-stretch: normal; max-height: 42px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; display: -webkit-box; padding-top: 0px !important; padding-bottom: 0px !important;">An NTPClient to connect to a time server</p>
                     <p class="og-host" style="box-sizing: inherit; font-size: 14px; line-height: 26px; color: #909090; position: absolute; bottom: 24px; font-family: AvenirNext, sans-serif; padding-top: 0px !important; padding-bottom: 0px !important;">www.arduinolibraries.info</p>
                     </div>
                  </a></figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure class="imageblock alignCenter" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; display: table; position: relative; text-align: center;"><span data-url="https://blog.kakaocdn.net/dn/2A19u/btqFrotVcqy/Lcea5jPi8RwiFVnYsOFoPK/img.png" data-lightbox="lightbox" data-alt="" style="box-sizing: inherit; cursor: pointer;"><img src="https://blog.kakaocdn.net/dn/2A19u/btqFrotVcqy/Lcea5jPi8RwiFVnYsOFoPK/img.png" srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2A19u%2FbtqFrotVcqy%2FLcea5jPi8RwiFVnYsOFoPK%2Fimg.png" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; border-style: none; max-width: 100%; display: inline-block; width: 640px; margin: 0px; height: auto;" /></span></figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <h2 data-ke-size="size26" style="box-sizing: inherit; font-size: 24px; margin-bottom: 24px; font-weight: normal; color: rgba(0, 0, 0, 0.87); line-height: 1.38;">일정시간마다 사진 촬영후 업로드</h2>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">1분마다 FTP업로드하도록 프로그래밍 합니다.</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <figure class="imageblock alignCenter" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; display: table; position: relative; text-align: center;"><span data-url="https://blog.kakaocdn.net/dn/duKuTi/btqFqNucPKV/WVkECraeAoO0TxDYPiBnh0/img.png" data-lightbox="lightbox" data-alt="" style="box-sizing: inherit; cursor: pointer;"><img src="https://blog.kakaocdn.net/dn/duKuTi/btqFqNucPKV/WVkECraeAoO0TxDYPiBnh0/img.png" srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FduKuTi%2FbtqFqNucPKV%2FWVkECraeAoO0TxDYPiBnh0%2Fimg.png" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; border-style: none; max-width: 100%; display: inline-block; width: 640px; margin: 0px; height: auto;" /></span></figure>
            <figure class="imageblock alignCenter" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; margin: 0px auto 20px; max-width: 100%; clear: both; display: table; position: relative; text-align: center;"><span data-url="https://blog.kakaocdn.net/dn/mFznW/btqFroOhGas/C58wv6aFx1EjDnd3qYGM3k/img.png" data-lightbox="lightbox" data-alt="" style="box-sizing: inherit; cursor: pointer;"><img src="https://blog.kakaocdn.net/dn/mFznW/btqFroOhGas/C58wv6aFx1EjDnd3qYGM3k/img.png" srcset="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmFznW%2FbtqFroOhGas%2FC58wv6aFx1EjDnd3qYGM3k%2Fimg.png" data-origin-width="0" data-origin-height="0" data-ke-mobilestyle="widthContent" style="box-sizing: inherit; border-style: none; max-width: 100%; display: inline-block; width: 640px; margin: 0px; height: auto;" /></span></figure>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">&nbsp;</p>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;">esp32_CameraWebServer.ino</p>
            <pre id="code_1594091186175" class="java" data-ke-language="java" data-ke-type="codeblock" style="box-sizing: inherit; overflow: auto; font-family: monospace, monospace; font-size: 16px; padding: 20px; background: rgba(0, 0, 0, 0.05); color: rgba(34, 85, 51, 0.87); white-space: pre-wrap;">
               <code class="hljs" style="box-sizing: inherit; font-family: monospace, monospace; font-size: 1em; display: block; overflow-x: auto; padding: 0.5em; color: #333333; background: rgb(248, 248, 248);">#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"esp_camera.h"</span>
#include &lt;WiFi.h&gt;
#include &lt;WiFiClient.h&gt; 
#include &lt;ESP32_FTPClient.h&gt;
#include &lt;NTPClient.h&gt;
#include &lt;WiFiUdp.h&gt;
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"time.h"</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Define NTP Client to get time</span>
WiFiUDP ntpUDP;
<span class="hljs-function" style="box-sizing: inherit;">NTPClient <span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">timeClient</span><span class="hljs-params" style="box-sizing: inherit;">(ntpUDP)</span></span>;
<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Variables to save date and time</span>
String formattedDate;
String dayStamp;
String timeStamp;
<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// WARNING!!! Make sure that you have either selected ESP32 Wrover Module,</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//            or another board which has PSRAM enabled</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Select camera model</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// #define CAMERA_MODEL_WROVER_KIT</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//#define CAMERA_MODEL_ESP_EYE</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//#define CAMERA_MODEL_M5STACK_PSRAM</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//#define CAMERA_MODEL_M5STACK_WIDE</span>
#define CAMERA_MODEL_AI_THINKER
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"camera_pins.h"</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span>* ssid = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"ZEROWIN"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span>* password = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"zzzzzzzz"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> ftp_server[] = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"192.168.0.3"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> ftp_user[]   = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"admin"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> ftp_pass[]   = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"admin"</span>;
<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// you can pass a FTP timeout and debbug mode on the last 2 arguments</span><span class="hljs-function" style="box-sizing: inherit;">ESP32_FTPClient <span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">ftp</span><span class="hljs-params" style="box-sizing: inherit;">(ftp_server,ftp_user,ftp_pass, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">5000</span>, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">2</span>)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">startCameraServer</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">setup</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>{
  Serial.begin(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">115200</span>);
  Serial.setDebugOutput(<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">true</span>);
  Serial.println();
  pinMode(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">16</span>, INPUT);
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">20000000</span>;
  config.pixel_format = PIXFORMAT_JPEG;
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//init with high specs to pre-allocate larger buffers</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">10</span>;
    config.fb_count = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">2</span>;
  } <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">else</span> {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">12</span>;
    config.fb_count = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>;
  }
#<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">defined</span><span class="hljs-params" style="box-sizing: inherit;">(CAMERA_MODEL_ESP_EYE)</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">pinMode</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">13</span>, INPUT_PULLUP)</span></span>;
  pinMode(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">14</span>, INPUT_PULLUP);
#endif
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// camera init</span>
  esp_err_t err = esp_camera_init(&amp;config);
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (err != ESP_OK) {
    Serial.printf(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Camera init failed with error 0x%x"</span>, err);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span>;
  }
  sensor_t * s = esp_camera_sensor_get();
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//initial sensors are flipped vertically and colors are a bit saturated</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (s-&gt;id.PID == OV3660_PID) {
    s-&gt;set_vflip(s, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>);<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//flip it back</span>
    s-&gt;set_brightness(s, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>);<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//up the blightness just a bit</span>
    s-&gt;set_saturation(s, -<span class="hljs-number" style="box-sizing: inherit; color: #008080;">2</span>);<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//lower the saturation</span>
  }
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//drop down frame size for higher initial frame rate</span>
  s-&gt;set_framesize(s, FRAMESIZE_QVGA);
#<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">defined</span><span class="hljs-params" style="box-sizing: inherit;">(CAMERA_MODEL_M5STACK_WIDE)</span>
  s-&gt;<span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">set_vflip</span><span class="hljs-params" style="box-sizing: inherit;">(s, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>)</span></span>;
  s-&gt;set_hmirror(s, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>);
#endif
  WiFi.begin(ssid, password);
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">while</span> (WiFi.status() != WL_CONNECTED) {
    delay(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">500</span>);
    Serial.print(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"."</span>);
  }
  Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">""</span>);
  Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"WiFi connected"</span>);
  startCameraServer();
  Serial.print(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Camera Ready! Use 'http://"</span>);
  Serial.print(WiFi.localIP());
  Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"' to connect"</span>);
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Initialize a NTPClient to get time</span>
  timeClient.begin();
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Set offset time in seconds to adjust for your timezone, for example:</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// GMT +1 = 3600</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// GMT +8 = 28800</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// GMT -1 = -3600</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// GMT 0 = 0</span>
  timeClient.setTimeOffset(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">32400</span>); 
  {
      <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">while</span>(!timeClient.update()) {
        timeClient.forceUpdate();
      }
      <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// The formattedDate comes with the following format:</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// 2018-05-28T16:00:13Z</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// We need to extract date and time</span>
      formattedDate = timeClient.getFormattedDate();
      Serial.println(formattedDate);
      <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Extract date</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> splitT = formattedDate.indexOf(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"T"</span>);
      dayStamp = formattedDate.substring(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>, splitT);
      Serial.print(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"DATE: "</span>);
      Serial.println(dayStamp);
      <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Extract time</span>
      timeStamp = formattedDate.substring(splitT+<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>, formattedDate.length()-<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>);
      Serial.print(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"HOUR: "</span>);
      Serial.println(timeStamp);
  }
<span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">/*
    struct tm tm;
    tm.tm_year = 2018 - 1900;
    tm.tm_mon = 10;
    tm.tm_mday = 15;
    tm.tm_hour = 14;
    tm.tm_min = 10;
    tm.tm_sec = 10;
    time_t t = mktime(&amp;tm); */</span>
    time_t t = timeClient.getEpochTime();
    <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// printf("Setting time: %s", asctime(&amp;tm));</span>
    struct timeval now = { .tv_sec = t };
    settimeofday(&amp;now, NULL);
    timeClient.end();
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">FTP_uploadImage</span><span class="hljs-params" style="box-sizing: inherit;">(int64_t t, unsigned <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> * pdata, unsigned <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> size)</span></span>{
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> filename[<span class="hljs-number" style="box-sizing: inherit; color: #008080;">32</span>] = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">""</span>;
  Serial.print(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"FTP_uploadImage="</span>);
  Serial.println(size);
  ftp.OpenConnection();
  struct tm timeinfo;
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(!getLocalTime(&amp;timeinfo)){
    Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Failed to obtain time"</span>);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> -<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>;
  }
  sprintf(filename, <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"CAPTURE_%04d%02d%02d_%02d%02d%02d.jpg"</span>,
    timeinfo.tm_year + <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1900</span>,
    timeinfo.tm_mon+<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>,
    timeinfo.tm_mday,
    timeinfo.tm_hour,
    timeinfo.tm_min,
    timeinfo.tm_sec
    );
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//ftp.InitFile("Type A");</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//ftp.ChangeWorkDir("/");</span>
  ftp.InitFile(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Type I"</span>);
  ftp.NewFile(filename); <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// "capture.jpg");</span>
  ftp.WriteData( pdata, size );
  ftp.CloseFile();
  ftp.CloseConnection();
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span><span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">printLocalTime</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>{
  struct tm timeinfo;
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(!getLocalTime(&amp;timeinfo)){
    Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Failed to obtain time"</span>);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span>;
  }
  Serial.println(&amp;timeinfo, <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"%A, %B %d %Y %H:%M:%S"</span>);
}
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> timeout = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
<span class="hljs-function" style="box-sizing: inherit;">extern <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">capture_ftpupload</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span>)</span></span>;
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">loop</span><span class="hljs-params" style="box-sizing: inherit;">()</span></span>{
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// put your main code here, to run repeatedly:</span>
  timeout += <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>;
  delay(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">100</span>);
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> value = digitalRead(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">16</span>);
  <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Serial.println(value);</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(value == <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>) {
    capture_ftpupload();
  }
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(timeout % <span class="hljs-number" style="box-sizing: inherit; color: #008080;">100</span> == <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>) { <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// display time per 10 sec</span>
      printLocalTime();
  }
  <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(timeout % (<span class="hljs-number" style="box-sizing: inherit; color: #008080;">60</span> * <span class="hljs-number" style="box-sizing: inherit; color: #008080;">10</span>) == <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>) { <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// capture &amp; upload per 1 min</span>
    capture_ftpupload();
  }
}
</code>
               </pre>
            <p style="box-sizing: inherit; margin-bottom: 28px; font-size: 16px; line-height: 26px; color: #555555; padding-top: 0px !important; padding-bottom: 0px !important;"><a href="http://app_httpd.cpp/" target="_blank" rel="noopener" style="box-sizing: inherit; display: inline-block; color: #3d62ce;">app_httpd.cpp</a></p>
            <pre id="code_1594093565710" class="java" data-ke-language="java" data-ke-type="codeblock" style="box-sizing: inherit; overflow: auto; font-family: monospace, monospace; font-size: 16px; padding: 20px; background: rgba(0, 0, 0, 0.05); color: rgba(34, 85, 51, 0.87); white-space: pre-wrap;">
               <code class="hljs" style="box-sizing: inherit; font-family: monospace, monospace; font-size: 1em; display: block; overflow-x: auto; padding: 0.5em; color: #333333; background: rgb(248, 248, 248);"><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Licensed under the Apache License, Version 2.0 (the "License");</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// you may not use this file except in compliance with the License.</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// You may obtain a copy of the License at</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//     http://www.apache.org/licenses/LICENSE-2.0</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// Unless required by applicable law or agreed to in writing, software</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// distributed under the License is distributed on an "AS IS" BASIS,</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// See the License for the specific language governing permissions and</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// limitations under the License.</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"esp_http_server.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"esp_timer.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"esp_camera.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"img_converters.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"camera_index.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Arduino.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"fb_gfx.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"fd_forward.h"</span>
#include <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"fr_forward.h"</span>
#define ENROLL_CONFIRM_TIMES <span class="hljs-number" style="box-sizing: inherit; color: #008080;">5</span>
#define FACE_ID_SAVE_NUMBER <span class="hljs-number" style="box-sizing: inherit; color: #008080;">7</span>
#define FACE_COLOR_WHITE  <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0x00FFFFFF</span>
#define FACE_COLOR_BLACK  <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0x00000000</span>
#define FACE_COLOR_RED    <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0x000000FF</span>
#define FACE_COLOR_GREEN  <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0x0000FF00</span>
#define FACE_COLOR_BLUE   <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0x00FF0000</span>
#<span class="hljs-function" style="box-sizing: inherit;">define <span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">FACE_COLOR_YELLOW</span><span class="hljs-params" style="box-sizing: inherit;">(FACE_COLOR_RED | FACE_COLOR_GREEN)</span>
#define <span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">FACE_COLOR_CYAN</span><span class="hljs-params" style="box-sizing: inherit;">(FACE_COLOR_BLUE | FACE_COLOR_GREEN)</span>
#define <span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">FACE_COLOR_PURPLE</span><span class="hljs-params" style="box-sizing: inherit;">(FACE_COLOR_BLUE | FACE_COLOR_RED)</span>
typedef struct </span>{
        size_t size; <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//number of values used for filtering</span>
        size_t index; <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//current value index</span>
        size_t count; <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//value count</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> sum;
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> * values; <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//array to be filled with values</span>
} ra_filter_t;
typedef struct {
        httpd_req_t *req;
        size_t len;
} jpg_chunking_t;
#define PART_BOUNDARY <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"123456789000000000000987654321"</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span>* _STREAM_CONTENT_TYPE = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"multipart/x-mixed-replace;boundary="</span> PART_BOUNDARY;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span>* _STREAM_BOUNDARY = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"\r\n--"</span> PART_BOUNDARY <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"\r\n"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span>* _STREAM_PART = <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> ra_filter_t ra_filter;
httpd_handle_t stream_httpd = NULL;
httpd_handle_t camera_httpd = NULL;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> mtmn_config_t mtmn_config = {<span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>};
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> int8_t detection_enabled = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> int8_t recognition_enabled = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> int8_t is_enrolling = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> face_id_list id_list = {<span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>};
<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> ra_filter_t * ra_filter_init(ra_filter_t * filter, size_t sample_size){
    memset(filter, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>, sizeof(ra_filter_t));
    filter-&gt;values = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> *)malloc(sample_size * sizeof(<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>));
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(!filter-&gt;values){
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> NULL;
    }
    memset(filter-&gt;values, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>, sample_size * sizeof(<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>));
    filter-&gt;size = sample_size;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> filter;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">ra_filter_run</span><span class="hljs-params" style="box-sizing: inherit;">(ra_filter_t * filter, <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> value)</span></span>{
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(!filter-&gt;values){
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> value;
    }
    filter-&gt;sum -= filter-&gt;values[filter-&gt;index];
    filter-&gt;values[filter-&gt;index] = value;
    filter-&gt;sum += filter-&gt;values[filter-&gt;index];
    filter-&gt;index++;
    filter-&gt;index = filter-&gt;index % filter-&gt;size;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (filter-&gt;count &lt; filter-&gt;size) {
        filter-&gt;count++;
    }
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> filter-&gt;sum / filter-&gt;count;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">rgb_print</span><span class="hljs-params" style="box-sizing: inherit;">(dl_matrix3du_t *image_matrix, uint32_t color, <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> * str)</span></span>{
    fb_data_t fb;
    fb.width = image_matrix-&gt;w;
    fb.height = image_matrix-&gt;h;
    fb.data = image_matrix-&gt;item;
    fb.bytes_per_pixel = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">3</span>;
    fb.format = FB_BGR888;
    fb_gfx_print(&amp;fb, (fb.width - (strlen(str) * <span class="hljs-number" style="box-sizing: inherit; color: #008080;">14</span>)) / <span class="hljs-number" style="box-sizing: inherit; color: #008080;">2</span>, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">10</span>, color, str);
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">rgb_printf</span><span class="hljs-params" style="box-sizing: inherit;">(dl_matrix3du_t *image_matrix, uint32_t color, <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> *format, ...)</span></span>{
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> loc_buf[<span class="hljs-number" style="box-sizing: inherit; color: #008080;">64</span>];
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> * temp = loc_buf;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> len;
    va_list arg;
    va_list copy;
    va_start(arg, format);
    va_copy(copy, arg);
    len = vsnprintf(loc_buf, sizeof(loc_buf), format, arg);
    va_end(copy);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(len &gt;= sizeof(loc_buf)){
        temp = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span>*)malloc(len+<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>);
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(temp == NULL) {
            <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span><span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
        }
    }
    vsnprintf(temp, len+<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>, format, arg);
    va_end(arg);
    rgb_print(image_matrix, color, temp);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(len &gt; <span class="hljs-number" style="box-sizing: inherit; color: #008080;">64</span>){
        free(temp);
    }
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> len;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">draw_face_boxes</span><span class="hljs-params" style="box-sizing: inherit;">(dl_matrix3du_t *image_matrix, box_array_t *boxes, <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> face_id)</span></span>{
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> x, y, w, h, i;
    uint32_t color = FACE_COLOR_YELLOW;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(face_id &lt; <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>){
        color = FACE_COLOR_RED;
    } <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">else</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(face_id &gt; <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>){
        color = FACE_COLOR_GREEN;
    }
    fb_data_t fb;
    fb.width = image_matrix-&gt;w;
    fb.height = image_matrix-&gt;h;
    fb.data = image_matrix-&gt;item;
    fb.bytes_per_pixel = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">3</span>;
    fb.format = FB_BGR888;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">for</span> (i = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>; i &lt; boxes-&gt;len; i++){
        <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// rectangle box</span>
        x = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>)boxes-&gt;box[i].box_p[<span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>];
        y = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>)boxes-&gt;box[i].box_p[<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>];
        w = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>)boxes-&gt;box[i].box_p[<span class="hljs-number" style="box-sizing: inherit; color: #008080;">2</span>] - x + <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>;
        h = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>)boxes-&gt;box[i].box_p[<span class="hljs-number" style="box-sizing: inherit; color: #008080;">3</span>] - y + <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>;
        fb_gfx_drawFastHLine(&amp;fb, x, y, w, color);
        fb_gfx_drawFastHLine(&amp;fb, x, y+h-<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>, w, color);
        fb_gfx_drawFastVLine(&amp;fb, x, y, h, color);
        fb_gfx_drawFastVLine(&amp;fb, x+w-<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>, y, h, color);
#<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span><span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span><span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">// landmark</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> x0, y0, j;
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">for</span> (j = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>; j &lt; <span class="hljs-number" style="box-sizing: inherit; color: #008080;">10</span>; j+=<span class="hljs-number" style="box-sizing: inherit; color: #008080;">2</span>) {
            x0 = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>)boxes-&gt;landmark[i].landmark_p[j];
            y0 = (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span>)boxes-&gt;landmark[i].landmark_p[j+<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>];
            fb_gfx_fillRect(&amp;fb, x0, y0, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">3</span>, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">3</span>, color);
        }
#endif
    }
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">run_face_recognition</span><span class="hljs-params" style="box-sizing: inherit;">(dl_matrix3du_t *image_matrix, box_array_t *net_boxes)</span></span>{
    dl_matrix3du_t *aligned_face = NULL;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> matched_id = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
    aligned_face = dl_matrix3du_alloc(<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>, FACE_WIDTH, FACE_HEIGHT, <span class="hljs-number" style="box-sizing: inherit; color: #008080;">3</span>);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(!aligned_face){
        Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Could not allocate face recognition buffer"</span>);
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> matched_id;
    }
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (align_face(net_boxes, image_matrix, aligned_face) == ESP_OK){
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (is_enrolling == <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>){
            int8_t left_sample_face = enroll_face(&amp;id_list, aligned_face);
            <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(left_sample_face == (ENROLL_CONFIRM_TIMES - <span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>)){
                Serial.printf(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Enrolling Face ID: %d\n"</span>, id_list.tail);
            }
            Serial.printf(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Enrolling Face ID: %d sample %d\n"</span>, id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face);
            rgb_printf(image_matrix, FACE_COLOR_CYAN, <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"ID[%u] Sample[%u]"</span>, id_list.tail, ENROLL_CONFIRM_TIMES - left_sample_face);
            <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (left_sample_face == <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>){
                is_enrolling = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
                Serial.printf(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Enrolled Face ID: %d\n"</span>, id_list.tail);
            }
        } <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">else</span> {
            matched_id = recognize_face(&amp;id_list, aligned_face);
            <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span> (matched_id &gt;= <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>) {
                Serial.printf(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Match Face ID: %u\n"</span>, matched_id);
                rgb_printf(image_matrix, FACE_COLOR_GREEN, <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Hello Subject %u"</span>, matched_id);
            } <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">else</span> {
                Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"No Match Found"</span>);
                rgb_print(image_matrix, FACE_COLOR_RED, <span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Intruder Alert!"</span>);
                matched_id = -<span class="hljs-number" style="box-sizing: inherit; color: #008080;">1</span>;
            }
        }
    } <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">else</span> {
        Serial.println(<span class="hljs-string" style="box-sizing: inherit; color: #dd1144;">"Face Not Aligned"</span>);
        <span class="hljs-comment" style="box-sizing: inherit; color: #999988; font-style: italic;">//rgb_print(image_matrix, FACE_COLOR_YELLOW, "Human Detected");</span>
    }
    dl_matrix3du_free(aligned_face);
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> matched_id;
}
<span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">static</span> size_t <span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">jpg_encode_stream</span><span class="hljs-params" style="box-sizing: inherit;">(<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span> * arg, size_t index, <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">void</span>* data, size_t len)</span></span>{
    jpg_chunking_t *j = (jpg_chunking_t *)arg;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(!index){
        j-&gt;len = <span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
    }
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">if</span>(httpd_resp_send_chunk(j-&gt;req, (<span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">const</span><span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> *)data, len) != ESP_OK){
        <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span><span class="hljs-number" style="box-sizing: inherit; color: #008080;">0</span>;
    }
    j-&gt;len += len;
    <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">return</span> len;
}
<span class="hljs-function" style="box-sizing: inherit;">extern <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span><span class="hljs-title" style="box-sizing: inherit; color: #990000; font-weight: bold;">FTP_uploadImage</span><span class="hljs-params" style="box-sizing: inherit;">(int64_t t, unsigned <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">char</span> * pdata, unsigned <span class="hljs-keyword" style="box-sizing: inherit; font-weight: bold;">int</span> size)</span></span>;
<span class="hljs-function" style="box-sizing: inh