{"id":247,"date":"2021-02-28T15:15:03","date_gmt":"2021-02-28T20:15:03","guid":{"rendered":"https:\/\/blog.openmyr.com\/blog\/?p=247"},"modified":"2021-02-28T16:00:23","modified_gmt":"2021-02-28T21:00:23","slug":"customizing-open-myr-esp32-motors-webpages","status":"publish","type":"post","link":"https:\/\/blog.openmyr.com\/blog\/2021\/02\/customizing-open-myr-esp32-motors-webpages\/","title":{"rendered":"Customizing Open MYR ESP32-Motors webpages"},"content":{"rendered":"\n<p>In this post we will show how you can customize the Open MYR ESP32-Motors embedded webpages to give your own style or functionality.<\/p>\n\n\n\n<p>The ESP32-Motors code uses the ESP Async WebServer library to server webpages from the onboard flash and SPIFFS filesystem.<\/p>\n\n\n\n<p>Before we make a new webpage, we need to understand how the code serves webpages.<\/p>\n\n\n\n<p>Everything the web browser needs to render the page is stored in SPIFFS and sent by the ESP32 web server.<\/p>\n\n\n\n<p>When you navigate to the device\u2019s IP address in a web browser the following page is served.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/github.com\/OpenMYR\/ESP32-Motors\/wiki\/images\/OpenMYR_Home.jpg\" alt=\"\" width=\"577\" height=\"626\"\/><figcaption>Default ESP32-Motor index.html page<\/figcaption><\/figure>\n\n\n\n<p>The webserver.cpp configures the devices webserver.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-webserver-1024x814.jpg\" alt=\"\" class=\"wp-image-251\" width=\"577\" height=\"458\" srcset=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-webserver-1024x814.jpg 1024w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-webserver-300x239.jpg 300w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-webserver-768x611.jpg 768w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-webserver.jpg 1308w\" sizes=\"auto, (max-width: 577px) 100vw, 577px\" \/><figcaption>webServer.cpp<\/figcaption><\/figure>\n\n\n\n<p>In webserver.cpp the following lines of code configure the webserver.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server.serveStatic(\"\/\", SPIFFS, MOTOR_TYPE == 0 ? \"\/web_srv\/\" : \"\/web_step\/\");\nserver.serveStatic(\"\/\", SPIFFS,  MOTOR_TYPE == 0 ? \"\/web_srv\/\" : \"\/web_step\/\").setDefaultFile(\"index.html\");\n<\/code><\/pre>\n\n\n\n<p>The first line configures the website root to be severed from the &#8220;web_srv&#8221; or &#8220;web_step&#8221; folder loading into SPIFFS. The &#8220;web_srv&#8221; folder contains the webpages for servo control and \u201cweb_step\u201d folder contains the webpages for stepper motor control.<\/p>\n\n\n\n<p>The second line set the default webpage to the \u201cindex.html\u201d file. This is the page loaded when you navigate to the device\u2019s IP address.<\/p>\n\n\n\n<p>For this example, we are going to add a button to the index.html file and replace the picture of the page for a stepper motor controller.<\/p>\n\n\n\n<p>In Visual Studio Code we open the ESP32-Motors project and navigate to and open the index.html file.<\/p>\n\n\n\n<p>Index.html located in the .\\ESP32-Motors\\data\\web_step\\ folder.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"814\" src=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-index_html-1024x814.jpg\" alt=\"\" class=\"wp-image-252\" srcset=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-index_html-1024x814.jpg 1024w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-index_html-300x239.jpg 300w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-index_html-768x611.jpg 768w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-index_html.jpg 1308w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>index.html<\/figcaption><\/figure><\/div>\n\n\n\n<p>In the html file we insert:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;button type=\"button\" onclick=\"sendDemoCommand(0)\"&gt;Demo Command&lt;\/button&gt;<\/code><\/pre>\n\n\n\n<p>Then we create or modify the index.js file to include the sendDemoCommand function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function sendDemoCommand(demoNumber) {\n    selectedDemo = demoNumber;\n    let out = {\n        commands: &#91;{\n                code: \"U\",\n                data: &#91;\n                    1,\n                    0,\n                    0,\n                    1,\n                ]\n            },\n            {\n                code: \"M\",\n                data: &#91;\n                    1,\n                    1,\n                    200,\n                    50,\n                ]\n            }\n        ]\n    };\n\n\n    let httpRequest = new XMLHttpRequest();\n    httpRequest.open(\"POST\", \"\/\", true);\n    httpRequest.setRequestHeader(\"Content-type\", \"application\/x-www-form-urlencoded\");\n    httpRequest.send(JSON.stringify(out));\n}\n<\/code><\/pre>\n\n\n\n<p>This code creates two JSON commands per the OPCODE interface and sends them via a http POST to the controller.<\/p>\n\n\n\n<p>As a reference the final JSON created by the function is :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"commands\":&#91;{\"code\":\"U\",\"data\":&#91;1,0,0,1]},{\"code\":\"M\",\"data\":&#91;1,1,200,50]}]}<\/code><\/pre>\n\n\n\n<p>Last we change the index.html to show this image:<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/upload.wikimedia.org\/wikipedia\/commons\/4\/4f\/Camera-pictogram.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>First we place the image into the .\\ESP32-Motors\\data\\web_step\\assets folder, we named it camera.jpg for this example.<\/p>\n\n\n\n<p>Then in the index.html we change<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;img id=logo src=\"assets\/logoText.svg\"&gt;<\/code><\/pre>\n\n\n\n<p>to<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;img id=logo src=\"assets\/camera.jpg\"&gt;<\/code><\/pre>\n\n\n\n<p>We can check that the html is correct by opening the local file in our web browser and ensuring it looks correct or just jump right to uploaded it to the device.<\/p>\n\n\n\n<p>Then we upload SPIFFS to the ESP32 device<\/p>\n\n\n\n<p>First ensure all the files we have been editing as saved to the latest version is uploaded.<\/p>\n\n\n\n<p>Then in Visual Studio Code run the appropriate \u201cPlatformIO: Upload Filesystem Image\u201d command.<\/p>\n\n\n\n<p>Once successfully uploaded, we navigate to the device\u2019s IP address in a web browser and the following page is served.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"945\" height=\"1024\" src=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-demo-page-945x1024.jpg\" alt=\"\" class=\"wp-image-254\" srcset=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-demo-page-945x1024.jpg 945w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-demo-page-277x300.jpg 277w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-demo-page-768x832.jpg 768w, https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Open-MYR-ESP32-demo-page.jpg 960w\" sizes=\"auto, (max-width: 945px) 100vw, 945px\" \/><figcaption>demo index.html<\/figcaption><\/figure>\n\n\n\n<p>Clicking the Demo button causes the motor to move.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1078\" height=\"826\" src=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Demo-Command-M-200-50-1-4.gif\" alt=\"\" class=\"wp-image-267\"\/><figcaption>Demo button movement<\/figcaption><\/figure>\n\n\n\n<p>The motor moved a bit slower then desired, so we can go back into the index.js file and update the OPCODE &#8216;M&#8217; parameters for faster movement as micro stepping is enabled by the first command OPCODE &#8216;U&#8217;.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>code: \"M\",\ndata: &#91;\n    1,\n    1,\n    2000,\n    500,\n]<\/code><\/pre>\n\n\n\n<p>Uploading the modified index.js gives the desired movement.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1084\" height=\"807\" src=\"https:\/\/blog.openmyr.com\/blog\/wp-content\/uploads\/2021\/02\/Demo-Button-M-2000-500-.gif\" alt=\"\" class=\"wp-image-256\"\/><figcaption>Fast Demo button movement<\/figcaption><\/figure>\n\n\n\n<p>Successes!! <\/p>\n\n\n\n<p>Now that we have the basic functionality of OPCODE control with a JSON POST we can further customize the webpages to provide the needed functionality of a project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we will show how you can customize the Open MYR ESP32-Motors embedded webpages to give your own style or functionality. The ESP32-Motors code uses the ESP Async WebServer library to server webpages from the onboard flash and &hellip; <a href=\"https:\/\/blog.openmyr.com\/blog\/2021\/02\/customizing-open-myr-esp32-motors-webpages\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":4,"featured_media":262,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,45,2],"tags":[],"class_list":["post-247","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","category-esp32","category-openmyr"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/posts\/247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/comments?post=247"}],"version-history":[{"count":4,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/posts\/247\/revisions"}],"predecessor-version":[{"id":275,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/posts\/247\/revisions\/275"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/media\/262"}],"wp:attachment":[{"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/media?parent=247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/categories?post=247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.openmyr.com\/blog\/wp-json\/wp\/v2\/tags?post=247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}