当前位置:网站首页>Design and implementation of esp32-cam wireless monitoring intelligent gateway

Design and implementation of esp32-cam wireless monitoring intelligent gateway

2022-06-23 10:59:00 daodanjishui

ESP32-CAM ArduinoIDE Development series article catalog


Chapter one :ESP32-CAM High cost performance WIFI Quick start tutorial of image transmission scheme
Second articles :ESP32-CAM The first wireless lighting program
Third articles :ESP32-CAM Design and implementation of intelligent gateway



Preface

    daodanjishui The core original technology of the Internet of things ESP32 Arduino IDE Development of embedded web server setup 、http Request sending, receiving and parsing 、 Single chip microcomputer IO Oral reading and writing operations and AJAX Technology integration constitutes :ESP32-CAM Realize embedded wireless monitoring intelligent gateway .


One 、ESP32-CAM What is the wireless monitoring intelligent gateway ?

     In the second part of the project :ESP32-CAM、ESP8266、WIFI、 bluetooth 、 Camera device realizes embedded server lighting , I demonstrated ESP32 Respond to wireless lighting requests as an Internet of things server , The way to submit forms with a browser lights up ESP32-cam Integrated on the module LED Flash lighting to achieve the functions that an embedded server can achieve , Readers who don't understand it can go to the second .
     In this third article , I will add more functions to the official program , That is to add functions on the basis of the second chapter , Program development is a step-by-step process .
The added functions are as follows :

(1) Embedded in the web page of the SCM server AJAX technology , By clicking the button cmd Submit the form request asynchronously to partially refresh the page , Don't worry about the whole page being refreshed , This function is necessary for developing web remote control ! It is also necessary to make a web remote control intelligent car . As shown by the arrow below :
 Insert picture description here

(2) After the server responds to a browser client button request, there will be an asynchronous refresh response , For example, once off After the operation of , The server will return a red “off ok” Go to the back of the feedback column , There will never be a web page Jump , This is a necessary function for human-computer interaction and environment parameter acquisition and display of intelligent gateway , There is also a function of querying instructions , Input check, Click send to query LED Operating state , This function makes a start to query the operation status of the single chip microcomputer . As shown in the figure below :
 Insert picture description here

(3) Add two web page Jump links to the homepage of the server ,“ Turn on the light quickly ” and “ Quick video ”, Clicking the first link will jump to another page and light up ESP32 The lamp of , Click the second link to see ESP32 Video captured by camera module . This is the jump technology and video streaming technology to realize the web page on the server home page , Making advertising gateway and intelligent surveillance camera must not miss the function . As shown in the figure below :
 Insert picture description here
The video image taken while turning on the lights is shown in the following figure :
 Insert picture description here

(4) Will server's IP The address is displayed on the browser of the client , It is believed that many buyers want to realize this function but fail to realize it ? Although I rely on serial port to print this code IP Enter the address into the browser to access the server's home page , But in the next project, I will add the functions of browser distribution and domain name resolution , Enter a fixed domain name to log in to the server's home page , Only then did I realize how important this function is . The technical points involved cannot be expressed in a few words !IP Will change as the network changes , Not a static web page . As shown in the figure below :
 Insert picture description here

watch daodanjishui The Youku video address is :https://v.youku.com/v_show/id_XNTE3ODY4MjYwMA==.html

Watch directly

Two 、 The development process

1. Modification based on official code

     There are two ways to submit the source code of this version get and post request , One is asynchronous submission ; One is to refresh the web page submission and get the server response directly , But refreshing the submission form will jump to the web page , A shortcut to submit forms is also presented , There is also a query light status check Function of instruction .
It took me two days to write this program , The difficulty is that the web page is converted to a string , Writing too large a web page will overflow the memory of the MCU , So I also deleted the comments on the web page , Just to reduce space .
Another way is to put html Webpage , course :
https://blog.csdn.net/qq_27114397/article/details/89643232

  1. First, through gzip take HTML The file is compressed to .gz file
  2. Use filetoarray Tools will .gz File to header file
  3. stay ESP32 The program sends out the array in the header file
    The code of the official code is just like this , But I think it's too much trouble , Just convert the URL to a string , So the size is limited , Used a string , I would also like to consider String Of html Converts a string to an array of characters , In this way, the incoming function can be sent out . Here is the code :
    int length=index_html.length();
    char buf[length];
    strcpy(buf, index_html.c_str());
    return httpd_resp_send(req, buf,sizeof(buf)/sizeof(buf[0]));
    Another problem is parsing the original web page , At that time, I always wanted to restore and compress the official source code into 16 Binary web page data source code , Later, it is reduced to garbled code , After that, you can directly run the official source code , Log in directly from the browser to the home page and press F12 Saved URL , Finally, I saw the source code of the web page , I didn't know how happy I was .
    After getting the source code, I found , send out get The requested code is not obvious , It looks like a script , It's a mess , Give up... Decisively , There is too much code . But it refers to the source code get Model and number of requested parameters , Finally, it is tested by the browser get Format of request , Successfully sent get request .
    send out get There was another problem after the request , There is no way for the server to give a response to the client , Because the source code does not do this , That means you let the server light up , But can we succeed , I don't know yet ! I'll look at the sending get When requesting a series of codes, I see :httpd_resp_set_type(req, “text/html”);
    httpd_resp_set_hdr(req, “Content-Encoding”, “gzip”); I can guess how the server responds to the client and returns the client information . This logic was finally smoothed out by me . Now I have written out the logic for checking the light on and off , But it's also simple , Query with fixed syntax pin4 The light on and off status will be known by the high and low level of the lamp , High level is on .
     Insert picture description here

At that time, there was a serious problem with asynchronously submitting requests , There is no way to respond , I don't know what the problem is , Are about to collapse and give up , And I only did the test of this request , But the browser used to open web files to test , The website is dead . Put it on the server to run , You can't send a request , I've been debugging for a long time , Later, it was reduced to changing various parameters at random , Even think that the parameters of the requested URL are wrong , Took a lot of detours . Later, I couldn't help but refer to the non asynchronous request submission method of other netizens , This way I was originally dismissive , Because the difficulty is too small , After joining the request submission method, you can , I found that this method was effective , Request the web page to the server to submit the request , Although it is submitted in the form of refresh , It is inconvenient to jump to the web page , At least the lights are on . Then I thought about , Since there is a possibility of success , Why not try again ? So I clicked on the browser again F12 Grab the source code of the server home page again , Then I saw the light , The browser's debug window displays function checkCmd(cmd) The definition of the function does not exist , I was in a panic , I know there is a play . Take a closer look. , When this function is defined , I wrote a note at the end , This js Comments written in the area , After converting to string, character array and then restoring the output to the browser, the flavor will change , So I decisively deleted all of the homepage js Comments in the area , It did , I'm so happy , Although the source code can't be sold for much , But it took two days to debug .
The upgrade and maintenance of the code in the later stage are natural , Because I understand the logic of the source code , Although many functions cannot find the definition of the source code , But you can guess the general function according to the entry parameters and the name of the function . Making wheels is not something I should do at my age , Making a project is the king . Besides java and c I have used a lot of socket functions in the language , This arduino It doesn't matter whether the socket function of the library function looks at the source code or not .

The official website code is as follows ( Example ):

<!DOCTYPE html>
<!-- saved from url=(0019)http://172.17.14.2/ -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>ESP32 OV2460</title>
        <style> body {
       font-family: Arial,Helvetica,sans-serif; background: #181818; color: #EFEFEF; font-size: 16px } h2 {
       font-size: 18px } section.main {
       display: flex } #menu,section.main {
       flex-direction: column } #menu {
       display: none; flex-wrap: nowrap; min-width: 340px; background: #363636; padding: 8px; border-radius: 4px; margin-top: -10px; margin-right: 10px; } #content {
       display: flex; flex-wrap: wrap; align-items: stretch } figure {
       padding: 0px; margin: 0; -webkit-margin-before: 0; margin-block-start: 0; -webkit-margin-after: 0; margin-block-end: 0; -webkit-margin-start: 0; margin-inline-start: 0; -webkit-margin-end: 0; margin-inline-end: 0 } figure img {
       display: block; width: 100%; height: auto; border-radius: 4px; margin-top: 8px; } @media (min-width: 800px) and (orientation:landscape) {
       #content {
       display:flex; flex-wrap: nowrap; align-items: stretch } figure img {
       display: block; max-width: 100%; max-height: calc(100vh - 40px); width: auto; height: auto } figure {
       padding: 0 0 0 0px; margin: 0; -webkit-margin-before: 0; margin-block-start: 0; -webkit-margin-after: 0; margin-block-end: 0; -webkit-margin-start: 0; margin-inline-start: 0; -webkit-margin-end: 0; margin-inline-end: 0 } } section#buttons {
       display: flex; flex-wrap: nowrap; justify-content: space-between } #nav-toggle {
       cursor: pointer; display: block } #nav-toggle-cb {
       outline: 0; opacity: 0; width: 0; height: 0 } #nav-toggle-cb:checked+#menu {
       display: flex } .input-group {
       display: flex; flex-wrap: nowrap; line-height: 22px; margin: 5px 0 } .input-group>label {
       display: inline-block; padding-right: 10px; min-width: 47% } .input-group input,.input-group select {
       flex-grow: 1 } .range-max,.range-min {
       display: inline-block; padding: 0 5px } button {
       display: block; margin: 5px; padding: 0 12px; border: 0; line-height: 28px; cursor: pointer; color: #fff; background: #ff3034; border-radius: 5px; font-size: 16px; outline: 0 } button:hover {
       background: #ff494d } button:active {
       background: #f21c21 } button.disabled {
       cursor: default; background: #a0a0a0 } input[type=range] {
       -webkit-appearance: none; width: 100%; height: 22px; background: #363636; cursor: pointer; margin: 0 } input[type=range]:focus {
       outline: 0 } input[type=range]::-webkit-slider-runnable-track {
       width: 100%; height: 2px; cursor: pointer; background: #EFEFEF; border-radius: 0; border: 0 solid #EFEFEF } input[type=range]::-webkit-slider-thumb {
       border: 1px solid rgba(0,0,30,0); height: 22px; width: 22px; border-radius: 50px; background: #ff3034; cursor: pointer; -webkit-appearance: none; margin-top: -11.5px } input[type=range]:focus::-webkit-slider-runnable-track {
       background: #EFEFEF } input[type=range]::-moz-range-track {
       width: 100%; height: 2px; cursor: pointer; background: #EFEFEF; border-radius: 0; border: 0 solid #EFEFEF } input[type=range]::-moz-range-thumb {
       border: 1px solid rgba(0,0,30,0); height: 22px; width: 22px; border-radius: 50px; background: #ff3034; cursor: pointer } input[type=range]::-ms-track {
       width: 100%; height: 2px; cursor: pointer; background: 0 0; border-color: transparent; color: transparent } input[type=range]::-ms-fill-lower {
       background: #EFEFEF; border: 0 solid #EFEFEF; border-radius: 0 } input[type=range]::-ms-fill-upper {
       background: #EFEFEF; border: 0 solid #EFEFEF; border-radius: 0 } input[type=range]::-ms-thumb {
       border: 1px solid rgba(0,0,30,0); height: 22px; width: 22px; border-radius: 50px; background: #ff3034; cursor: pointer; height: 2px } input[type=range]:focus::-ms-fill-lower {
       background: #EFEFEF } input[type=range]:focus::-ms-fill-upper {
       background: #363636 } .switch {
       display: block; position: relative; line-height: 22px; font-size: 16px; height: 22px } .switch input {
       outline: 0; opacity: 0; width: 0; height: 0 } .slider {
       width: 50px; height: 22px; border-radius: 22px; cursor: pointer; background-color: grey } .slider,.slider:before {
       display: inline-block; transition: .4s } .slider:before {
       position: relative; content: ""; border-radius: 50%; height: 16px; width: 16px; left: 4px; top: 3px; background-color: #fff } input:checked+.slider {
       background-color: #ff3034 } input:checked+.slider:before {
       -webkit-transform: translateX(26px); transform: translateX(26px) } select {
       border: 1px solid #363636; font-size: 14px; height: 22px; outline: 0; border-radius: 5px } .image-container {
       position: relative; min-width: 160px } .close {
       position: absolute; right: 5px; top: 5px; background: #ff3034; width: 16px; height: 16px; border-radius: 100px; color: #fff; text-align: center; line-height: 18px; cursor: pointer } .hidden {
       display: none } </style>
    </head>
    <body>
        <section class="main">
            <div id="logo">
                <label for="nav-toggle-cb" id="nav-toggle">*&nbsp;&nbsp;Toggle OV2640 settings</label>
            </div>
            <div id="content">
                <div id="sidebar">
                    <input type="checkbox" id="nav-toggle-cb" checked="checked">
                    <nav id="menu">
                        <div class="input-group" id="framesize-group">
                            <label for="framesize">Resolution</label>
                            <select id="framesize" class="default-action">
                                <option value="10">UXGA(1600x1200)</option>
                                <option value="9">SXGA(1280x1024)</option>
                                <option value="8">XGA(1024x768)</option>
                                <option value="7">SVGA(800x600)</option>
                                <option value="6">VGA(640x480)</option>
                                <option value="5" selected="selected">CIF(400x296)</option>
                                <option value="4">QVGA(320x240)</option>
                                <option value="3">HQVGA(240x176)</option>
                                <option value="0">QQVGA(160x120)</option>
                            </select>
                        </div>
                        <div class="input-group" id="quality-group">
                            <label for="quality">Quality</label>
                            <div class="range-min">10</div>
                            <input type="range" id="quality" min="10" max="63" value="10" class="default-action">
                            <div class="range-max">63</div>
                        </div>
                        <div class="input-group" id="brightness-group">
                            <label for="brightness">Brightness</label>
                            <div class="range-min">-2</div>
                            <input type="range" id="brightness" min="-2" max="2" value="0" class="default-action">
                            <div class="range-max">2</div>
                        </div>
                        <div class="input-group" id="contrast-group">
                            <label for="contrast">Contrast</label>
                            <div class="range-min">-2</div>
                            <input type="range" id="contrast" min="-2" max="2" value="0" class="default-action">
                            <div class="range-max">2</div>
                        </div>
                        <div class="input-group" id="saturation-group">
                            <label for="saturation">Saturation</label>
                            <div class="range-min">-2</div>
                            <input type="range" id="saturation" min="-2" max="2" value="0" class="default-action">
                            <div class="range-max">2</div>
                        </div>
                        <div class="input-group" id="special_effect-group">
                            <label for="special_effect">Special Effect</label>
                            <select id="special_effect" class="default-action">
                                <option value="0" selected="selected">No Effect</option>
                                <option value="1">Negative</option>
                                <option value="2">Grayscale</option>
                                <option value="3">Red Tint</option>
                                <option value="4">Green Tint</option>
                                <option value="5">Blue Tint</option>
                                <option value="6">Sepia</option>
                            </select>
                        </div>
                        <div class="input-group" id="awb-group">
                            <label for="awb">AWB</label>
                            <div class="switch">
                                <input id="awb" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="awb"></label>
                            </div>
                        </div>
                        <div class="input-group" id="awb_gain-group">
                            <label for="awb_gain">AWB Gain</label>
                            <div class="switch">
                                <input id="awb_gain" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="awb_gain"></label>
                            </div>
                        </div>
                        <div class="input-group" id="wb_mode-group">
                            <label for="wb_mode">WB Mode</label>
                            <select id="wb_mode" class="default-action">
                                <option value="0" selected="selected">Auto</option>
                                <option value="1">Sunny</option>
                                <option value="2">Cloudy</option>
                                <option value="3">Office</option>
                                <option value="4">Home</option>
                            </select>
                        </div>
                        <div class="input-group" id="aec-group">
                            <label for="aec">AEC SENSOR</label>
                            <div class="switch">
                                <input id="aec" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="aec"></label>
                            </div>
                        </div>
                        <div class="input-group" id="aec2-group">
                            <label for="aec2">AEC DSP</label>
                            <div class="switch">
                                <input id="aec2" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="aec2"></label>
                            </div>
                        </div>
                        <div class="input-group" id="ae_level-group">
                            <label for="ae_level">AE Level</label>
                            <div class="range-min">-2</div>
                            <input type="range" id="ae_level" min="-2" max="2" value="0" class="default-action">
                            <div class="range-max">2</div>
                        </div>
                        <div class="input-group" id="aec_value-group">
                            <label for="aec_value">Exposure</label>
                            <div class="range-min">0</div>
                            <input type="range" id="aec_value" min="0" max="1200" value="204" class="default-action">
                            <div class="range-max">1200</div>
                        </div>
                        <div class="input-group" id="agc-group">
                            <label for="agc">AGC</label>
                            <div class="switch">
                                <input id="agc" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="agc"></label>
                            </div>
                        </div>
                        <div class="input-group hidden" id="agc_gain-group">
                            <label for="agc_gain">Gain</label>
                            <div class="range-min">1x</div>
                            <input type="range" id="agc_gain" min="0" max="30" value="5" class="default-action">
                            <div class="range-max">31x</div>
                        </div>
                        <div class="input-group" id="gainceiling-group">
                            <label for="gainceiling">Gain Ceiling</label>
                            <div class="range-min">2x</div>
                            <input type="range" id="gainceiling" min="0" max="6" value="0" class="default-action">
                            <div class="range-max">128x</div>
                        </div>
                        <div class="input-group" id="bpc-group">
                            <label for="bpc">BPC</label>
                            <div class="switch">
                                <input id="bpc" type="checkbox" class="default-action">
                                <label class="slider" for="bpc"></label>
                            </div>
                        </div>
                        <div class="input-group" id="wpc-group">
                            <label for="wpc">WPC</label>
                            <div class="switch">
                                <input id="wpc" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="wpc"></label>
                            </div>
                        </div>
                        <div class="input-group" id="raw_gma-group">
                            <label for="raw_gma">Raw GMA</label>
                            <div class="switch">
                                <input id="raw_gma" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="raw_gma"></label>
                            </div>
                        </div>
                        <div class="input-group" id="lenc-group">
                            <label for="lenc">Lens Correction</label>
                            <div class="switch">
                                <input id="lenc" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="lenc"></label>
                            </div>
                        </div>
                        <div class="input-group" id="hmirror-group">
                            <label for="hmirror">H-Mirror</label>
                            <div class="switch">
                                <input id="hmirror" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="hmirror"></label>
                            </div>
                        </div>
                        <div class="input-group" id="vflip-group">
                            <label for="vflip">V-Flip</label>
                            <div class="switch">
                                <input id="vflip" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="vflip"></label>
                            </div>
                        </div>
                        <div class="input-group" id="dcw-group">
                            <label for="dcw">DCW (Downsize EN)</label>
                            <div class="switch">
                                <input id="dcw" type="checkbox" class="default-action" checked="checked">
                                <label class="slider" for="dcw"></label>
                            </div>
                        </div>
                        <div class="input-group" id="colorbar-group">
                            <label for="colorbar">Color Bar</label>
                            <div class="switch">
                                <input id="colorbar" type="checkbox" class="default-action">
                                <label class="slider" for="colorbar"></label>
                            </div>
                        </div>
                        <div class="input-group" id="face_detect-group">
                            <label for="face_detect">Face Detection</label>
                            <div class="switch">
                                <input id="face_detect" type="checkbox" class="default-action">
                                <label class="slider" for="face_detect"></label>
                            </div>
                        </div>
                        <div class="input-group" id="face_recognize-group">
                            <label for="face_recognize">Face Recognition</label>
                            <div class="switch">
                                <input id="face_recognize" type="checkbox" class="default-action">
                                <label class="slider" for="face_recognize"></label>
                            </div>
                        </div>
                        <section id="buttons">
                            <button id="get-still">Get Still</button>
                            <button id="toggle-stream">Start Stream</button>
                            <button id="face_enroll" class="disabled" disabled="disabled">Enroll Face</button>
                        </section>
                    </nav>
                </div>
                <figure>
                    <div id="stream-container" class="image-container hidden">
                        <div class="close" id="close-stream">×</div>
                        <img id="stream" src="http://172.17.14.2/">
                    </div>
                </figure>
            </div>
        </section>
        <script> document.addEventListener('DOMContentLoaded', function (event) {
       var baseHost = document.location.origin var streamUrl = baseHost + ':81' const hide = el => {
       el.classList.add('hidden') } const show = el => {
       el.classList.remove('hidden') } const disable = el => {
       el.classList.add('disabled') el.disabled = true } const enable = el => {
       el.classList.remove('disabled') el.disabled = false } const updateValue = (el, value, updateRemote) => {
       updateRemote = updateRemote == null ? true : updateRemote let initialValue if (el.type === 'checkbox') {
       initialValue = el.checked value = !!value el.checked = value } else {
       initialValue = el.value el.value = value } if (updateRemote && initialValue !== value) {
       updateConfig(el); } else if(!updateRemote){
       if(el.id === "aec"){
       value ? hide(exposure) : show(exposure) } else if(el.id === "agc"){
       if (value) {
       show(gainCeiling) hide(agcGain) } else {
       hide(gainCeiling) show(agcGain) } } else if(el.id === "awb_gain"){
       value ? show(wb) : hide(wb) } else if(el.id === "face_recognize"){
       value ? enable(enrollButton) : disable(enrollButton) } } } function updateConfig (el) {
       let value switch (el.type) {
       case 'checkbox': value = el.checked ? 1 : 0 break case 'range': case 'select-one': value = el.value break case 'button': case 'submit': value = '1' break default: return } const query = `${
        baseHost}/control?var=${
        el.id}&val=${
        value}` fetch(query) .then(response => {
       console.log(`request to ${
        query} finished, status: ${
        response.status}`) }) } document .querySelectorAll('.close') .forEach(el => {
       el.onclick = () => {
       hide(el.parentNode) } }) // read initial values fetch(`${
        baseHost}/status`) .then(function (response) {
       return response.json() }) .then(function (state) {
       document .querySelectorAll('.default-action') .forEach(el => {
       updateValue(el, state[el.id], false) }) }) const view = document.getElementById('stream') const viewContainer = document.getElementById('stream-container') const stillButton = document.getElementById('get-still') const streamButton = document.getElementById('toggle-stream') const enrollButton = document.getElementById('face_enroll') const closeButton = document.getElementById('close-stream') const stopStream = () => {
       window.stop(); streamButton.innerHTML = 'Start Stream' } const startStream = () => {
       view.src = `${
        streamUrl}/stream` show(viewContainer) streamButton.innerHTML = 'Stop Stream' } // Attach actions to buttons stillButton.onclick = () => {
       stopStream() view.src = `${
        baseHost}/capture?_cb=${
        Date.now()}` show(viewContainer) } closeButton.onclick = () => {
       stopStream() hide(viewContainer) } streamButton.onclick = () => {
       const streamEnabled = streamButton.innerHTML === 'Stop Stream' if (streamEnabled) {
       stopStream() } else {
       startStream() } } enrollButton.onclick = () => {
       updateConfig(enrollButton) } // Attach default on change action document .querySelectorAll('.default-action') .forEach(el => {
       el.onchange = () => updateConfig(el) }) // Custom actions // Gain const agc = document.getElementById('agc') const agcGain = document.getElementById('agc_gain-group') const gainCeiling = document.getElementById('gainceiling-group') agc.onchange = () => {
       updateConfig(agc) if (agc.checked) {
       show(gainCeiling) hide(agcGain) } else {
       hide(gainCeiling) show(agcGain) } } // Exposure const aec = document.getElementById('aec') const exposure = document.getElementById('aec_value-group') aec.onchange = () => {
       updateConfig(aec) aec.checked ? hide(exposure) : show(exposure) } // AWB const awb = document.getElementById('awb_gain') const wb = document.getElementById('wb_mode-group') awb.onchange = () => {
       updateConfig(awb) awb.checked ? show(wb) : hide(wb) } // Detection and framesize const detect = document.getElementById('face_detect') const recognize = document.getElementById('face_recognize') const framesize = document.getElementById('framesize') framesize.onchange = () => {
       updateConfig(framesize) if (framesize.value > 5) {
       updateValue(detect, false) updateValue(recognize, false) } } detect.onchange = () => {
       if (framesize.value > 5) {
       alert("Please select CIF or lower resolution before enabling this feature!"); updateValue(detect, false) return; } updateConfig(detect) if (!detect.checked) {
       disable(enrollButton) updateValue(recognize, false) } } recognize.onchange = () => {
       if (framesize.value > 5) {
       alert("Please select CIF or lower resolution before enabling this feature!"); updateValue(recognize, false) return; } updateConfig(recognize) if (recognize.checked) {
       enable(enrollButton) updateValue(detect, true) } else {
       disable(enrollButton) } } }) </script>
    

</body></html>
data = pd.read_csv(
    'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())

2. The server reads get request

The code is as follows ( Example ):

 String var = String(variable);// obtain get Requested id
    int val = atoi(value);// obtain get The value of the request 
    // Print out the transmitted instructions here 
     Serial.printf("var=%s\n",var);
     Serial.printf("val=%d\n",val);
    sensor_t * s = esp_camera_sensor_get();
    int res = 0;

    if(!strcmp(variable, "framesize")) {
    
        if(s->pixformat == PIXFORMAT_JPEG) res = s->set_framesize(s, (framesize_t)val);
    }
    else if(!strcmp(variable, "quality")){
    
    res = s->set_quality(s, val);// This is based on id and value Set it up , The key 
    }else if(!strcmp(variable, "on")){
    // If the received string is "on"
      
    controlLamp(true);// turn on the light 
    httpd_resp_set_type(req, "text/html");// I joined in 
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    return httpd_resp_send(req, "on ok", 5);
    
    }else if(!strcmp(variable, "off")){
    
      
    controlLamp(false);// Turn off the lights 
    httpd_resp_set_type(req, "text/html");// I joined in 
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    return httpd_resp_send(req, "off ok", 6);
   
    }else if(!strcmp(variable, "check")){
    // Check the status of the lamp 
      
     int LAMP_flag= digitalRead(LAMP_PIN);// Read the status of the pin , And back to HIGH  or LOW
     httpd_resp_set_type(req, "text/html");// I joined in 
     httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");  
       if(LAMP_flag==HIGH){
    
         return httpd_resp_send(req, "LAMP is on", 10);
       }else if(LAMP_flag==LOW){
    
        return httpd_resp_send(req, "LAMP is off", 11);
       }
    }

3. Operation and debugging

The interface starts as follows :
 Insert picture description here
View the video below
 Insert picture description here

summary

     This project is also an attempt to make ESP32 An attempt to become an intelligent gateway , The interface is clean and simple , But the function is not simple , Every step of the logic is carefully designed by me , Although the gateway can only respond to the requests of one client at the same time , But it's only a matter of a few lines of code to change , Although this microcontroller is currently used by few users , Most of them are used by foreign program developers . There is not much information about this module in China , Only by playing slowly can we stimulate the real use of this powerful module , Again , This project is not ESP32-CAM Module evaluation , It is a real open source project . Mobile phones will be added to the next project APP And ESP32 Interaction or JSP Services and ESP32 Interactive projects , Coming soon .

Code download address :https://www.cirmall.com/circuit/19372/
Jump straight to

原网站

版权声明
本文为[daodanjishui]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206231034532691.html