{"id":2360,"date":"2017-02-16T19:53:54","date_gmt":"2017-02-17T03:53:54","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=2360"},"modified":"2017-05-26T10:31:58","modified_gmt":"2017-05-26T17:31:58","slug":"creating-a-basic-http-server-with-esp32","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/esp32\/http\/","title":{"rendered":"Creating a Basic HTTP Server with ESP32"},"content":{"rendered":"<p>This tutorial shows how to create a basic &#8220;HTTP Server&#8221; application for the ESP32 chip and debug it with VisualGDB. We will use the <a href=\"https:\/\/www.sparkfun.com\/products\/13907\">Sparkfun ESP32 Thing<\/a> board with the Olimex ARM-USB-OCD-H JTAG programmer to program and debug the board.<\/p>\n<p>Before you begin, install VisualGDB 5.2 or later. We also recommend following the <a href=\"http:\/\/visualgdb.com\/tutorials\/esp32\/\">basic ESP32 tutorial<\/a> to check that the JTAG connection with your device is working properly.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-demoprjname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2361\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-demoprjname.png\" alt=\"01-demoprjname\" width=\"941\" height=\"653\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-demoprjname.png 941w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-demoprjname-300x208.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-demoprjname-392x272.png 392w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-demoprjname-130x90.png 130w\" sizes=\"(max-width: 941px) 100vw, 941px\" \/><\/a><\/li>\n<li>Proceed with the default settings on the first page:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-msbuild1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2362\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-msbuild1.png\" alt=\"02-msbuild\" width=\"822\" height=\"642\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-msbuild1.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-msbuild1-300x234.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Select the ESP32 toolchain and the regular ESP32 device:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-esp321.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2363\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-esp321.png\" alt=\"03-esp32\" width=\"786\" height=\"565\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-esp321.png 786w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-esp321-300x216.png 300w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/a><\/li>\n<li>On the Sample Selection page select the &#8220;HTTP Server&#8221; sample and optionally change the subnet number:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-server.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2364\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-server.png\" alt=\"04-server\" width=\"822\" height=\"642\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-server.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-server-300x234.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Finally select the interface you want to use for debugging. If you are using one of the Olimex JTAG debuggers, enable the &#8220;set explicit speed&#8221; checkbox:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-debug2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2365\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-debug2.png\" alt=\"05-debug\" width=\"786\" height=\"565\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-debug2.png 786w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-debug2-300x216.png 300w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to generate your project. Before you can build it, open the Project Properties and change the optimization level for the debug configuration from -O0 to -Og as the default -O0 level prevents the ESP-IDF code from working correctly:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-optimize1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2366\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-optimize1.png\" alt=\"06-optimize\" width=\"822\" height=\"558\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-optimize1.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-optimize1-300x204.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>The project generated by VisualGDB does 3 vital steps. First it enables the DHCP server so that the devices connecting to its Wi-Fi network will automatically get assigned IP addresses:\n<pre class=\"\">\u00a0\u00a0\u00a0 tcpip_adapter_init();\r\n\u00a0\u00a0\u00a0 tcpip_adapter_ip_info_t info = { 0, };\r\n\u00a0\u00a0\u00a0 IP4_ADDR(&amp;info.ip, 192, 168, 123, 1);\r\n\u00a0\u00a0\u00a0 IP4_ADDR(&amp;info.gw, 192, 168, 123, 1);\r\n\u00a0\u00a0\u00a0 IP4_ADDR(&amp;info.netmask, 255, 255, 255, 0);\r\n\u00a0\u00a0\u00a0 ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP));\r\n\u00a0\u00a0\u00a0 ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &amp;info));\r\n\u00a0\u00a0\u00a0 ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP));<\/pre>\n<p>Then it starts the Wi-Fi hardware in the Access Point mode:<\/p>\n<pre class=\"\">\u00a0\u00a0\u00a0 wifi_config_t wifi_config;\r\n\u00a0\u00a0\u00a0 memset(&amp;wifi_config, 0, sizeof(wifi_config));\r\n\u00a0\u00a0\u00a0 strcpy(wifi_config.ap.ssid, \"ESP32_VisualGDB\");\r\n\u00a0\u00a0\u00a0 wifi_config.ap.ssid_len = strlen(wifi_config.ap.ssid);\r\n\u00a0\u00a0\u00a0 wifi_config.ap.max_connection = 4;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));\r\n\u00a0\u00a0\u00a0 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &amp;wifi_config));\r\n\u00a0\u00a0\u00a0 ESP_ERROR_CHECK(esp_wifi_start());<\/pre>\n<p>Finally it creates a thread that listens for connections on port 80 and responds to each one. Note that the last part uses the regular socket functions like <strong>bind()<\/strong> and <strong>accept()<\/strong> to work with the sockets:<\/p>\n<pre class=\"\">void ServerTask(void *pvParameters)\r\n{\r\n\u00a0\u00a0 \u00a0struct sockaddr_in server_addr, client_addr;\r\n\u00a0\u00a0\u00a0 int server_sock;\r\n\u00a0\u00a0\u00a0 socklen_t sin_size = sizeof(client_addr);\r\n\u00a0\u00a0\u00a0 bzero(&amp;server_addr, sizeof(struct sockaddr_in));\r\n\u00a0\u00a0\u00a0 server_addr.sin_family = AF_INET;\r\n\u00a0\u00a0\u00a0 server_addr.sin_addr.s_addr = INADDR_ANY;\r\n\u00a0\u00a0\u00a0 server_addr.sin_port = htons(80);\r\n\r\n\u00a0\u00a0\u00a0 server_sock = socket(AF_INET, SOCK_STREAM, 0);\r\n\u00a0\u00a0\u00a0 bind(server_sock, (struct sockaddr *)(&amp;server_addr), sizeof(struct sockaddr));\r\n\u00a0\u00a0\u00a0 listen(server_sock, 5);\r\n\u00a0\u00a0\u00a0 for (;;) \r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 int client_sock = accept(server_sock, (struct sockaddr *) &amp;client_addr, &amp;sin_size);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/...\r\n\u00a0\u00a0 \u00a0}\r\n}<\/pre>\n<\/li>\n<li>The project is based on the open-source <a href=\"https:\/\/github.com\/espressif\/esp-idf\/\">ESP-IDF<\/a> framework, so you can use features like Go-to-definition and Code Map to quickly explore how different functions interact:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/codemap.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2372\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/codemap.png\" alt=\"codemap\" width=\"1072\" height=\"362\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/codemap.png 1072w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/codemap-300x101.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/codemap-1024x346.png 1024w\" sizes=\"(max-width: 1072px) 100vw, 1072px\" \/><\/a><\/li>\n<li>Build the project via Build-&gt;Build Solution:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-build1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2367\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-build1.png\" alt=\"07-build\" width=\"977\" height=\"646\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-build1.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-build1-300x198.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Now press F5 to automatically program the SPI FLASH and begin debugging your project:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-load.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2368\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-load.png\" alt=\"08-load\" width=\"977\" height=\"646\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-load.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-load-300x198.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Once the project is running, connect to the ESP32_VisualGDB Wi-Fi network from your device:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-wifi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2369\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-wifi.png\" alt=\"09-wifi\" width=\"283\" height=\"342\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-wifi.png 283w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-wifi-248x300.png 248w\" sizes=\"(max-width: 283px) 100vw, 283px\" \/><\/a><\/li>\n<li>Once the connection is successful, open <strong>192.168.&lt;subnet&gt;.1<\/strong> in your browser:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-page.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2370\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-page.png\" alt=\"10-page\" width=\"671\" height=\"299\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-page.png 671w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-page-300x134.png 300w\" sizes=\"(max-width: 671px) 100vw, 671px\" \/><\/a><\/li>\n<li>Set a breakpoint after the call to read() and refresh your browser page. The breakpoint will hit and you will see the HTTP request sent your the browser to the device:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-watch.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2371\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-watch.png\" alt=\"11-watch\" width=\"977\" height=\"646\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-watch.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-watch-300x198.png 300w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a>Note that the ESP32 tools have several known limitations. Please refer to <a href=\"https:\/\/sysprogs.com\/w\/limitations-of-the-esp32-debugging\/\">this post<\/a> for a discussion on known issues and workarounds.<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to create a basic &#8220;HTTP Server&#8221; application for the ESP32 chip and debug it with VisualGDB.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[142],"tags":[138,101,102],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2360"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=2360"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2360\/revisions"}],"predecessor-version":[{"id":2373,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2360\/revisions\/2373"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=2360"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=2360"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=2360"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}