{"id":1858,"date":"2015-01-01T00:58:14","date_gmt":"2015-01-01T00:58:14","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=1858"},"modified":"2015-01-01T00:58:14","modified_gmt":"2015-01-01T00:58:14","slug":"esp8266-client-mode-connect-remote-host-simple-example","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2015\/01\/esp8266-client-mode-connect-remote-host-simple-example\/","title":{"rendered":"esp8266 client mode (connect to remote host) simple example"},"content":{"rendered":"<p><a href=\"http:\/\/41j.com\/blog\/wp-content\/uploads\/2015\/01\/esp8266run.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/41j.com\/blog\/wp-content\/uploads\/2015\/01\/esp8266run-768x1024.jpg\" alt=\"esp8266run\" width=\"700\" height=\"933\" class=\"aligncenter size-large wp-image-1862\" srcset=\"https:\/\/41j.com\/blog\/wp-content\/uploads\/2015\/01\/esp8266run-768x1024.jpg 768w, https:\/\/41j.com\/blog\/wp-content\/uploads\/2015\/01\/esp8266run-225x300.jpg 225w, https:\/\/41j.com\/blog\/wp-content\/uploads\/2015\/01\/esp8266run.jpg 960w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n<p>Today I&#8217;ve been looking at getting the esp8266 working as a Wifi client and seeing if I could fetch some data. This builds on my <a href=\"http:\/\/41j.com\/blog\/2014\/12\/esp8266-notes\/\">previous notes<\/a> on flashing the esp8266. There&#8217;s some great info <a href=\"http:\/\/www.limpkin.fr\/index.php?post\/2014\/12\/07\/First-Steps-with-the-ESP8266-03-Development-Board\">here<\/a> which the code below is based on, with modifications to fetch a page from a remote host.<\/p>\n<p>Setting the SSID and password for the host network is pretty easy, and I based the code below on the &#8220;basic_example&#8221;, supplied with the SDK. Once configured the board will get an IP over DHCP, and configure it&#8217;s resolver. It will also respond to ping requesting, which can be a useful debugging tool.<\/p>\n<p>In order to try things out, I wrote a simple program which fetches the google homepage a prints it out over the serial port. The complete tarball can be downloaded <a href=\"http:\/\/41j.com\/blog\/wp-content\/uploads\/2015\/01\/get_google.tar\">here<\/a>. And when run it will print out the following:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nIP: 192.168.0.8looklokkDST: 173.194.126.178conncendsentrecvHTTP\/1.0 302 Found\r\nCache-Control: private\r\nContent-Type: text\/html; charset=UTF-8\r\nLocation: http:\/\/www.google.co.jp\/?gfe_rd=cr&amp;ei=BBmkVMK6NKGT8QfRqIDwAw\r\nContent-Length: 261\r\nDate: Wed, 31 Dec 2014 15:40:52 GMT\r\nServer: GFE\/2.0\r\nAlternate-Protocol: 80:quic,p=0.02\r\n&lt;HTML&gt;&lt;HEAD&gt;&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text\/html;charset=utf-8&quot;&gt;\r\n                                                                              &lt;T&gt;\r\n                                                                                &gt;\r\n                                                                                d\r\n                                                                                .\r\n&lt;\/BODY&gt;&lt;\/HTML&gt;\r\ndcon\r\n<\/pre>\n<p>You&#8217;ll need to change user_config.h to contain your networks SSID and password e.g.:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#define SSID &quot;NETWORKNAME&quot;\r\n#define SSID_PASSWORD &quot;NETWORKPASSWORD&quot;\r\n<\/pre>\n<p>user_main.c is also reproduced below for reference. You also need the uart code from the SDK and uart.c needs to be compiled in. There were a few gotcha when writing this, the first is that the serial port seems to be configured for a rather odd 77Kbps. So it makes sense to reconfigure the serial port to a more sensible value straight away (I used 9600). It&#8217;s also not yet clear to me where the os_printf output goes. I used uart0_tx_buffer for all my debug output.<\/p>\n<p>Another issue I had is that the esp8266 seems to be quite finicky about how it&#8217;s various pins are set at boot. I couldn&#8217;t get the board to come up with my FTDI serial cable attached. I had to first boot the device from a bench supply (using the &#8220;run&#8221; board in my <a href=\"http:\/\/41j.com\/blog\/2014\/12\/esp8266-notes\/\">previous notes<\/a>). And then connect the serial cable after it started booting. Luckily there&#8217;s just enough time before it completes it&#8217;s wifi connection to do this so I can see the debug output (only just though, it boots and gets connected to wifi very quickly).<\/p>\n<p>Anyway for reference, here&#8217;s the code. If you want to try it out checkout the tarball linked above.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &quot;ets_sys.h&quot;\r\n#include &quot;osapi.h&quot;\r\n#include &quot;gpio.h&quot;\r\n#include &quot;os_type.h&quot;\r\n#include &quot;user_config.h&quot;\r\n#include &quot;user_interface.h&quot;\r\n#include &quot;uart.h&quot;\r\n\r\n#include &quot;c_types.h&quot;\r\n#include &quot;espconn.h&quot;\r\n#include &quot;mem.h&quot;\r\n\/\/#include &quot;user_network.h&quot;\r\n\/\/#include &quot;user_display.h&quot;\r\n\r\n#define user_procTaskPrio        0\r\n#define user_procTaskQueueLen    1\r\nos_event_t    user_procTaskQueue&#x5B;user_procTaskQueueLen];\r\nstatic void loop(os_event_t *events);\r\n\r\n\/\/Main code function\r\nstatic void ICACHE_FLASH_ATTR\r\nloop(os_event_t *events)\r\n{\r\n    os_printf(&quot;Hello\\n\\r&quot;);\r\n    os_delay_us(10000);\r\n    system_os_post(user_procTaskPrio, 0, 0 );\r\n}\r\n\r\nstatic void ICACHE_FLASH_ATTR networkConnectedCb(void *arg);\r\nstatic void ICACHE_FLASH_ATTR networkDisconCb(void *arg);\r\nstatic void ICACHE_FLASH_ATTR networkReconCb(void *arg, sint8 err);\r\nstatic void ICACHE_FLASH_ATTR networkRecvCb(void *arg, char *data, unsigned short len);\r\nstatic void ICACHE_FLASH_ATTR networkSentCb(void *arg);\r\nvoid ICACHE_FLASH_ATTR network_init();\r\n\r\nLOCAL os_timer_t network_timer;\r\n\r\nstatic void ICACHE_FLASH_ATTR networkServerFoundCb(const char *name, ip_addr_t *ip, void *arg) {\r\n  static esp_tcp tcp;\r\n  struct espconn *conn=(struct espconn *)arg;\r\n  if (ip==NULL) {\r\n    os_printf(&quot;Nslookup failed :\/ Trying again...\\n&quot;);\r\n    uart0_tx_buffer(&quot;lfai&quot;,4);\r\n    network_init();\r\n  }\r\n\r\n  uart0_tx_buffer(&quot;lokk&quot;,4);\r\n  char page_buffer&#x5B;20];\r\n  os_sprintf(page_buffer,&quot;DST: %d.%d.%d.%d&quot;,\r\n  *((uint8 *)&amp;ip-&gt;addr), *((uint8 *)&amp;ip-&gt;addr + 1),\r\n  *((uint8 *)&amp;ip-&gt;addr + 2), *((uint8 *)&amp;ip-&gt;addr + 3));\r\n  uart0_tx_buffer(page_buffer,strlen(page_buffer));\r\n\r\n  conn-&gt;type=ESPCONN_TCP;\r\n  conn-&gt;state=ESPCONN_NONE;\r\n  conn-&gt;proto.tcp=&amp;tcp;\r\n  conn-&gt;proto.tcp-&gt;local_port=espconn_port();\r\n  conn-&gt;proto.tcp-&gt;remote_port=80;\r\n  os_memcpy(conn-&gt;proto.tcp-&gt;remote_ip, &amp;ip-&gt;addr, 4);\r\n  espconn_regist_connectcb(conn, networkConnectedCb);\r\n  espconn_regist_disconcb(conn, networkDisconCb);\r\n  espconn_regist_reconcb(conn, networkReconCb);\r\n  espconn_regist_recvcb(conn, networkRecvCb);\r\n  espconn_regist_sentcb(conn, networkSentCb);\r\n  espconn_connect(conn);\r\n}\r\n\r\nstatic void ICACHE_FLASH_ATTR networkSentCb(void *arg) {\r\n  uart0_tx_buffer(&quot;sent&quot;,4);\r\n}\r\n\r\nstatic void ICACHE_FLASH_ATTR networkRecvCb(void *arg, char *data, unsigned short len) {\r\n\r\n  uart0_tx_buffer(&quot;recv&quot;,4);\r\n  \r\n  struct espconn *conn=(struct espconn *)arg;\r\n  int x;\r\n  uart0_tx_buffer(data,len);\r\n  \/\/for (x=0; x&lt;len; x++) networkParseChar(conn, data&#x5B;x]);\r\n}\r\n\r\nstatic void ICACHE_FLASH_ATTR networkConnectedCb(void *arg) {\r\n\r\n  uart0_tx_buffer(&quot;conn&quot;,4);\r\n  struct espconn *conn=(struct espconn *)arg;\r\n\r\n  char *data = &quot;GET \/ HTTP\/1.0\\r\\n\\r\\n\\r\\n&quot;;\r\n  sint8 d = espconn_sent(conn,data,strlen(data));\r\n\r\n  espconn_regist_recvcb(conn, networkRecvCb);\r\n  uart0_tx_buffer(&quot;cend&quot;,4);\r\n}\r\n\r\nstatic void ICACHE_FLASH_ATTR networkReconCb(void *arg, sint8 err) {\r\n  uart0_tx_buffer(&quot;rcon&quot;,4);\r\n\/\/  os_printf(&quot;Reconnect\\n\\r&quot;);\r\n\/\/  network_init();\r\n}\r\n\r\nstatic void ICACHE_FLASH_ATTR networkDisconCb(void *arg) {\r\n  uart0_tx_buffer(&quot;dcon&quot;,4);\r\n\/\/  os_printf(&quot;Disconnect\\n\\r&quot;);\r\n\/\/  network_init();\r\n}\r\n\r\n\r\nvoid ICACHE_FLASH_ATTR network_start() {\r\n  static struct espconn conn;\r\n  static ip_addr_t ip;\r\n  os_printf(&quot;Looking up server...\\n&quot;);\r\n    uart0_tx_buffer(&quot;look&quot;,4);\r\n  espconn_gethostbyname(&amp;conn, &quot;www.google.com&quot;, &amp;ip, networkServerFoundCb);\r\n}\r\n\r\nvoid ICACHE_FLASH_ATTR network_check_ip(void) {\r\n  struct ip_info ipconfig;\r\n  os_timer_disarm(&amp;network_timer);\r\n  wifi_get_ip_info(STATION_IF, &amp;ipconfig);\r\n  if (wifi_station_get_connect_status() == STATION_GOT_IP &amp;&amp; ipconfig.ip.addr != 0) {\r\n    char page_buffer&#x5B;20];\r\n    os_sprintf(page_buffer,&quot;IP: %d.%d.%d.%d&quot;,IP2STR(&amp;ipconfig.ip));\r\n    uart0_tx_buffer(page_buffer,strlen(page_buffer));\r\n    network_start();\r\n  } else {\r\n    os_printf(&quot;No ip found\\n\\r&quot;);\r\n    os_timer_setfn(&amp;network_timer, (os_timer_func_t *)network_check_ip, NULL);\r\n    os_timer_arm(&amp;network_timer, 1000, 0);\r\n  }\r\n}\r\n\r\nvoid ICACHE_FLASH_ATTR network_init() {\r\n  os_timer_disarm(&amp;network_timer);\r\n  os_timer_setfn(&amp;network_timer, (os_timer_func_t *)network_check_ip, NULL);\r\n  os_timer_arm(&amp;network_timer, 1000, 0);\r\n}\r\n\r\n\/\/Init function \r\nvoid ICACHE_FLASH_ATTR user_init() {\r\n\r\n    uart_init(BIT_RATE_9600,BIT_RATE_9600);\r\n    char ssid&#x5B;32] = SSID;\r\n    char password&#x5B;64] = SSID_PASSWORD;\r\n    struct station_config stationConf;\r\n\r\n    \/\/Set station mode\r\n    wifi_set_opmode( 0x1 );\r\n\r\n    \/\/Set ap settings\r\n    os_memcpy(&amp;stationConf.ssid, ssid, 32);\r\n    os_memcpy(&amp;stationConf.password, password, 64);\r\n    wifi_station_set_config(&amp;stationConf);\r\n\r\n    uart0_tx_buffer(&quot;init&quot;,4);\r\n\r\n    \/\/Start os task\r\n    system_os_task(loop, user_procTaskPrio,user_procTaskQueue, user_procTaskQueueLen);\r\n\r\n    system_os_post(user_procTaskPrio, 0, 0 );\r\n\r\n    network_init();\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Today I&#8217;ve been looking at getting the esp8266 working as a Wifi client and seeing if I could fetch some data. This builds on my previous notes on flashing the esp8266. There&#8217;s some great info here which the code below is based on, with modifications to fetch a page from a remote host. Setting the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-1858","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-tY","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1858","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=1858"}],"version-history":[{"count":2,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1858\/revisions"}],"predecessor-version":[{"id":1863,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1858\/revisions\/1863"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=1858"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=1858"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=1858"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}