From 92b6bad1e429db389419be46bd608ea37829f123 Mon Sep 17 00:00:00 2001 From: Suraj151 <32166791+Suraj151@users.noreply.github.com> Date: Mon, 16 Oct 2017 01:47:53 +0530 Subject: [PATCH 01/14] Swap reading y and z values (#2133) As per hmc5883l datasheet 2nd and 3rd bytes are of z axis rather than y. --- app/modules/hmc5883l.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/modules/hmc5883l.c b/app/modules/hmc5883l.c index ec6029668a..f1f69982e5 100644 --- a/app/modules/hmc5883l.c +++ b/app/modules/hmc5883l.c @@ -44,7 +44,6 @@ static int hmc5883_setup(lua_State* L) { if ((devid_a != 0x48) || (devid_b != 0x34) || (devid_c != 0x33)) { return luaL_error(L, "device not found"); } - // 8 sample average, 15 Hz update rate, normal measurement w8u(hmc5883_i2c_id, 0x00, 0x70); @@ -58,7 +57,6 @@ static int hmc5883_setup(lua_State* L) { } static int hmc5883_init(lua_State* L) { - uint32_t sda; uint32_t scl; @@ -96,8 +94,8 @@ static int hmc5883_read(lua_State* L) { platform_i2c_send_stop(hmc5883_i2c_id); x = (int16_t) ((data[0] << 8) | data[1]); - y = (int16_t) ((data[2] << 8) | data[3]); - z = (int16_t) ((data[4] << 8) | data[5]); + z = (int16_t) ((data[2] << 8) | data[3]); + y = (int16_t) ((data[4] << 8) | data[5]); lua_pushinteger(L, x); lua_pushinteger(L, y); From 443e8219527f5b2190324a969a4586f9d3d731bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Sun, 15 Oct 2017 23:03:45 +0200 Subject: [PATCH 02/14] Revert "Swap reading y and z values (#2133)" (#2135) This reverts commit 92b6bad1e429db389419be46bd608ea37829f123. --- app/modules/hmc5883l.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/modules/hmc5883l.c b/app/modules/hmc5883l.c index f1f69982e5..ec6029668a 100644 --- a/app/modules/hmc5883l.c +++ b/app/modules/hmc5883l.c @@ -44,6 +44,7 @@ static int hmc5883_setup(lua_State* L) { if ((devid_a != 0x48) || (devid_b != 0x34) || (devid_c != 0x33)) { return luaL_error(L, "device not found"); } + // 8 sample average, 15 Hz update rate, normal measurement w8u(hmc5883_i2c_id, 0x00, 0x70); @@ -57,6 +58,7 @@ static int hmc5883_setup(lua_State* L) { } static int hmc5883_init(lua_State* L) { + uint32_t sda; uint32_t scl; @@ -94,8 +96,8 @@ static int hmc5883_read(lua_State* L) { platform_i2c_send_stop(hmc5883_i2c_id); x = (int16_t) ((data[0] << 8) | data[1]); - z = (int16_t) ((data[2] << 8) | data[3]); - y = (int16_t) ((data[4] << 8) | data[5]); + y = (int16_t) ((data[2] << 8) | data[3]); + z = (int16_t) ((data[4] << 8) | data[5]); lua_pushinteger(L, x); lua_pushinteger(L, y); From d8d7381a38befec96803984735a378e8dd7b8cdd Mon Sep 17 00:00:00 2001 From: Pawel Jasinski Date: Sun, 24 Dec 2017 23:21:09 +0100 Subject: [PATCH 03/14] host field in HTTP header is no longer limited to 31 charcters (#2205) * host field in HTTP header is no longer limited to 31 charcters * added description for magic values --- app/http/httpclient.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/http/httpclient.c b/app/http/httpclient.c index 094c5ece13..6c8d97c064 100644 --- a/app/http/httpclient.c +++ b/app/http/httpclient.c @@ -215,20 +215,23 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg ) ua_len = strlen(ua_header); } - char host_header[32] = ""; + char * host_header = ""; int host_len = 0; if ( os_strstr( req->headers, "Host:" ) == NULL && os_strstr( req->headers, "host:" ) == NULL) { + int max_header_len = 9 + strlen(req->hostname); // 9 is fixed size of "Host:[space][cr][lf]\0" if ((req->port == 80) #ifdef CLIENT_SSL_ENABLE || ((req->port == 443) && ( req->secure )) #endif ) { + host_header = alloca(max_header_len); os_sprintf( host_header, "Host: %s\r\n", req->hostname ); } else { + host_header = alloca(max_header_len + 6); // 6 is worst case of ":port" where port is maximum 5 digits os_sprintf( host_header, "Host: %s:%d\r\n", req->hostname, req->port ); } host_len = strlen(host_header); From 5073c199c01d4d7bbbcd0ae1f761ecc4687f7217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Sun, 24 Dec 2017 23:22:03 +0100 Subject: [PATCH 04/14] Revert "host field in HTTP header is no longer limited to 31 charcters (#2205)" (#2208) This reverts commit d8d7381a38befec96803984735a378e8dd7b8cdd. --- app/http/httpclient.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/http/httpclient.c b/app/http/httpclient.c index 6c8d97c064..094c5ece13 100644 --- a/app/http/httpclient.c +++ b/app/http/httpclient.c @@ -215,23 +215,20 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg ) ua_len = strlen(ua_header); } - char * host_header = ""; + char host_header[32] = ""; int host_len = 0; if ( os_strstr( req->headers, "Host:" ) == NULL && os_strstr( req->headers, "host:" ) == NULL) { - int max_header_len = 9 + strlen(req->hostname); // 9 is fixed size of "Host:[space][cr][lf]\0" if ((req->port == 80) #ifdef CLIENT_SSL_ENABLE || ((req->port == 443) && ( req->secure )) #endif ) { - host_header = alloca(max_header_len); os_sprintf( host_header, "Host: %s\r\n", req->hostname ); } else { - host_header = alloca(max_header_len + 6); // 6 is worst case of ":port" where port is maximum 5 digits os_sprintf( host_header, "Host: %s:%d\r\n", req->hostname, req->port ); } host_len = strlen(host_header); From 8181c3be7aed9f0a0ceb73ac8137c1a519e8a8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Fri, 22 Jun 2018 12:10:42 +0200 Subject: [PATCH 05/14] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 6533c44a09..d499f6177a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,5 +1,5 @@ Make sure you read and understand http://nodemcu.readthedocs.io/en/dev/en/support/. -Use one of the two templates below and delete the rest. +Use one of the two templates below and **DELETE THE REST**. 8<------------------------ BUG REPORT ----------------------------------------- ### Expected behavior From f111162a6a958e43cb306c8b34033c7bfdc39340 Mon Sep 17 00:00:00 2001 From: Tim Godfrey <37b95tfuwa@snkmail.com> Date: Sat, 18 Aug 2018 12:26:18 -0500 Subject: [PATCH 06/14] FAQ update for io.write clarification (#2463) --- docs/en/lua-developer-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/lua-developer-faq.md b/docs/en/lua-developer-faq.md index 497a95186d..58bbd763dc 100644 --- a/docs/en/lua-developer-faq.md +++ b/docs/en/lua-developer-faq.md @@ -43,7 +43,7 @@ Whilst the Lua standard distribution includes a stand-alone Lua interpreter, Lua The ESP8266 was designed and is fabricated in China by [Espressif Systems](http://espressif.com/new-sdk-release/). Espressif have also developed and released a companion software development kit (SDK) to enable developers to build practical IoT applications for the ESP8266. The SDK is made freely available to developers in the form of binary libraries and SDK documentation. However this is in a *closed format*, with no developer access to the source files, so anyone developing ESP8266 applications must rely solely on the SDK API (and the somewhat Spartan SDK API documentation). (Note that for the ESP32, Espressif have moved to an open-source approach for its ESP-IDF.) -The NodeMCU Lua firmware is an ESP8266 application and must therefore be layered over the ESP8266 SDK. However, the hooks and features of Lua enable it to be seamlessly integrated without losing any of the standard Lua language features. The firmware has replaced some standard Lua modules that don't align well with the SDK structure with ESP8266-specific versions. For example, the standard `io` and `os` libraries don't work, but have been largely replaced by the NodeMCU `node` and `file` libraries. The `debug` and `math` libraries have also been omitted to reduce the runtime footprint (`modulo` can be done via `%`, `power` via `^`). +The NodeMCU Lua firmware is an ESP8266 application and must therefore be layered over the ESP8266 SDK. However, the hooks and features of Lua enable it to be seamlessly integrated without losing any of the standard Lua language features. The firmware has replaced some standard Lua modules that don't align well with the SDK structure with ESP8266-specific versions. For example, the standard `io` and `os` libraries don't work, but have been largely replaced by the NodeMCU `node` and `file` libraries. The `debug` and `math` libraries have also been omitted to reduce the runtime footprint (`modulo` can be done via `%`, `power` via `^`). Note that the `io.write()` function described in Lua's [Simple I/O Model](https://www.lua.org/pil/21.1.html) is not replaced by the `file` library. To write to the same serial port that the `print(string)` function uses by default, use `uart.write(0,string)`. NodeMCU Lua is based on [eLua](http://www.eluaproject.net/overview), a fully featured implementation of Lua 5.1 that has been optimized for embedded system development and execution to provide a scripting framework that can be used to deliver useful applications within the limited RAM and Flash memory resources of embedded processors such as the ESP8266. One of the main changes introduced in the eLua fork is to use read-only tables and constants wherever practical for library modules. On a typical build this approach reduces the RAM footprint by some 20-25KB and this makes a Lua implementation for the ESP8266 feasible. This technique is called LTR and this is documented in detail in an eLua technical paper: [Lua Tiny RAM](http://www.eluaproject.net/doc/master/en_arch_ltr.html). From f99f295d97ac3a4e147f601802d5869d9d2d3012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Sat, 18 Aug 2018 21:50:39 +0200 Subject: [PATCH 07/14] Revert "FAQ update for io.write clarification (#2463)" This reverts commit f111162a6a958e43cb306c8b34033c7bfdc39340. --- docs/en/lua-developer-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/lua-developer-faq.md b/docs/en/lua-developer-faq.md index 58bbd763dc..497a95186d 100644 --- a/docs/en/lua-developer-faq.md +++ b/docs/en/lua-developer-faq.md @@ -43,7 +43,7 @@ Whilst the Lua standard distribution includes a stand-alone Lua interpreter, Lua The ESP8266 was designed and is fabricated in China by [Espressif Systems](http://espressif.com/new-sdk-release/). Espressif have also developed and released a companion software development kit (SDK) to enable developers to build practical IoT applications for the ESP8266. The SDK is made freely available to developers in the form of binary libraries and SDK documentation. However this is in a *closed format*, with no developer access to the source files, so anyone developing ESP8266 applications must rely solely on the SDK API (and the somewhat Spartan SDK API documentation). (Note that for the ESP32, Espressif have moved to an open-source approach for its ESP-IDF.) -The NodeMCU Lua firmware is an ESP8266 application and must therefore be layered over the ESP8266 SDK. However, the hooks and features of Lua enable it to be seamlessly integrated without losing any of the standard Lua language features. The firmware has replaced some standard Lua modules that don't align well with the SDK structure with ESP8266-specific versions. For example, the standard `io` and `os` libraries don't work, but have been largely replaced by the NodeMCU `node` and `file` libraries. The `debug` and `math` libraries have also been omitted to reduce the runtime footprint (`modulo` can be done via `%`, `power` via `^`). Note that the `io.write()` function described in Lua's [Simple I/O Model](https://www.lua.org/pil/21.1.html) is not replaced by the `file` library. To write to the same serial port that the `print(string)` function uses by default, use `uart.write(0,string)`. +The NodeMCU Lua firmware is an ESP8266 application and must therefore be layered over the ESP8266 SDK. However, the hooks and features of Lua enable it to be seamlessly integrated without losing any of the standard Lua language features. The firmware has replaced some standard Lua modules that don't align well with the SDK structure with ESP8266-specific versions. For example, the standard `io` and `os` libraries don't work, but have been largely replaced by the NodeMCU `node` and `file` libraries. The `debug` and `math` libraries have also been omitted to reduce the runtime footprint (`modulo` can be done via `%`, `power` via `^`). NodeMCU Lua is based on [eLua](http://www.eluaproject.net/overview), a fully featured implementation of Lua 5.1 that has been optimized for embedded system development and execution to provide a scripting framework that can be used to deliver useful applications within the limited RAM and Flash memory resources of embedded processors such as the ESP8266. One of the main changes introduced in the eLua fork is to use read-only tables and constants wherever practical for library modules. On a typical build this approach reduces the RAM footprint by some 20-25KB and this makes a Lua implementation for the ESP8266 feasible. This technique is called LTR and this is documented in detail in an eLua technical paper: [Lua Tiny RAM](http://www.eluaproject.net/doc/master/en_arch_ltr.html). From c54fbcfe8e9c07b3b527ed95178ca8e9753f6af5 Mon Sep 17 00:00:00 2001 From: Terry Ellison Date: Mon, 17 Sep 2018 17:55:11 +0100 Subject: [PATCH 08/14] Add Getting Started page (#2487) (#2490) - Added Marcel's Getting Started page - Added reference to getting-started.md --- docs/css/extra.css | 51 +++++- docs/de/index.md | 6 - docs/en/flash.md | 4 +- docs/en/getting-started.md | 328 +++++++++++++++++++++++++++++++++++ docs/en/index.md | 53 ------ docs/en/lfs.md | 59 +------ docs/en/lua-developer-faq.md | 2 +- docs/index.md | 58 ++++++- mkdocs.yml | 162 +++++++++-------- 9 files changed, 512 insertions(+), 211 deletions(-) delete mode 100644 docs/de/index.md create mode 100644 docs/en/getting-started.md delete mode 100644 docs/en/index.md diff --git a/docs/css/extra.css b/docs/css/extra.css index dbe505ae15..2a6642fc90 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -39,4 +39,53 @@ table.docutils td code { .wy-plain-list-disc, .rst-content .section ul, .rst-content .toctree-wrapper ul, article ul { line-height: 20px; margin-bottom: 16px; -} \ No newline at end of file +} + +table#gs td { + text-align: center; +} + +table#gs { + border-collapse: collapse; + border-spacing: 0; + border-color: #ccc; +} + +table#gs td { + font-size: 14px; + padding: 10px 5px; + color: #333; + background-color: #fff; +} + +table#gs th { + font-size: 14px; + font-weight: bold; + padding: 10px 5px; + white-space: nowrap; + color: #333; + background-color: #f0f0f0; + vertical-align: top; +} + +table#gs td.select { + background-color: #d9edf7; +} + +table#gs th div.icon { + margin-left: 5px; + display: inline-block; + width:24px; + height:24px; + background-size: 24px; +} + +.windowsIcon { + background:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDUxMiA1MTIiIGlkPSJMYXllcl8xIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48Zz48cGF0aCBkPSJNNDk1LjMsMTMzLjdjMCwzNS41LTAuMSw3MSwwLjEsMTA2LjRjMCw0LjgtMS4yLDYuOC02LDYuMmMtMC44LTAuMS0xLjcsMC0yLjUsMCAgIGMtNjEuNiwwLjMtMTIzLjIsMC42LTE4NC45LDFjLTIwLjEsMC4xLTQwLjMsMC4zLTYwLjQsMC43Yy00LjksMC4xLTYuNi0xLjMtNi42LTYuNWMwLjItNTkuMywwLjItMTE4LjYsMC0xNzcuOSAgIGMwLTUuMSwxLjEtNy4yLDYuNy03LjhjMjIuNS0yLjcsNDQuOC01LjksNjcuMi05YzMxLTQuNCw2MS45LTksOTIuOC0xMy40YzI5LjUtNC4yLDU5LTguMSw4OC41LTEyLjNjNC43LTAuNyw1LjIsMS4zLDUuMiw1LjIgICBDNDk1LjMsNjIsNDk1LjMsOTcuOSw0OTUuMywxMzMuN3oiIGZpbGw9IiMwMEFDRUUiLz48cGF0aCBkPSJNMjEzLjEsMTU0LjRjMCwyOS4zLDAsNTguNywwLDg4YzAsNi40LDAsNi40LTYuNiw2LjRjLTEyLjIsMC4xLTI0LjMsMC4xLTM2LjUsMC4yICAgYy00OC44LDAuMy05Ny42LDAuNi0xNDYuNCwxYy03LjEsMC03LjEsMC4xLTcuMS02LjljMC00OS44LDAtOTkuNiwwLTE0OS41YzAtNi45LDAuMS02LjYsNi45LTcuNmMxNy42LTIuNCwzNS4yLTUuMSw1Mi44LTcuNiAgIGMxMy41LTEuOSwyNy4xLTMuNSw0MC42LTUuM2MyNy4yLTMuNyw1NC40LTcuNiw4MS41LTExLjRjMy45LTAuNiw3LjgtMS43LDExLjgtMS43YzIuMSwwLDMuMSwwLjcsMywyLjljLTAuMSwxLjcsMCwzLjMsMCw1ICAgQzIxMy4xLDk2LjcsMjEzLjEsMTI1LjUsMjEzLjEsMTU0LjR6IE0yMTAsMTUzLjhjMC0yOC42LTAuMS01Ny4zLDAuMS04NS45YzAtNC4yLTEuNS01LjEtNS4yLTQuOWMtMy4xLDAuMi01LjUsMi04LjYsMi4yICAgYy02LjYsMC40LTEzLjEsMS42LTE5LjcsMi41Yy0xMi45LDEuOC0yNS45LDMuNC0zOC43LDUuNGMtNy44LDEuMi0xNS45LDEuMS0yMy40LDQuMmMtMS4zLDAuNS0yLjYsMC45LTMuOSwwLjQgICBjLTQuMi0xLjctOC41LTAuMi0xMi4yLDAuN2MtOS40LDIuNC0xOS4xLDMtMjguNyw0LjNjLTgsMS4xLTE2LDIuNy0yNC4xLDNjLTYuOCwwLjItMTIuOSwzLjctMTkuOSwzLjRjLTYtMC4zLTYuOCwwLjgtNi44LDcgICBjMCw0OCwwLDk1LjksMCwxNDMuOWMwLDYuNSwwLjcsNyw3LjIsNy4xYzMxLjksMC41LDYzLjktMS41LDk1LjgtMS4xYzI2LjYsMC4zLDUzLjMsMC4xLDc5LjksMGM3LjcsMCw4LjEtMC4zLDguMS04LjMgICBDMjEwLDIwOS43LDIxMCwxODEuOCwyMTAsMTUzLjh6IiBmaWxsPSIjMzVBQkQ1Ii8+PHBhdGggZD0iTTIxMy4xLDM2NS4zYzAsMjkuNS0wLjEsNTksMC4xLDg4LjVjMCw0LjUtMC45LDYuMS01LjcsNS4zYy0xNC40LTIuMy0yOC45LTQuMy00My40LTYuMyAgIGMtMTUtMi4xLTMwLTMuOC00NS02Yy0yMS4yLTMtNDIuNC02LjMtNjMuNy05LjNjLTExLjItMS42LTIyLjQtMy4yLTMzLjYtNC40Yy00LTAuNC01LjQtMS43LTUuNC01LjhjMC4xLTUwLjgsMC4xLTEwMS42LDAtMTUyLjUgICBjMC00LjMsMS4xLTYuMyw1LjctNS41YzIuMSwwLjMsNC4zLDAuMSw2LjUsMC4xYzU5LjgsMC4zLDExOS42LDAuNywxNzkuNCwwLjljNC4zLDAsNS4zLDEuNCw1LjIsNS40ICAgQzIxMywzMDUuNiwyMTMuMSwzMzUuNCwyMTMuMSwzNjUuM3ogTTIxMCwzNjUuNGMwLTI4LTAuMi01NiwwLjEtODMuOWMwLjEtNy4zLTMuMi04LjQtOC42LTguNGMtOC4yLDAtMTYuMywwLjQtMjQuNiwwLjIgICBjLTM2LjYtMS03My4yLDAuNy0xMDkuOC0xLjFjLTEzLjgtMC43LTI3LjYtMC4xLTQxLjUtMC4xYy02LjEsMC02LjgsMC44LTYuOCw3YzAsNDguMSwwLDk2LjMsMCwxNDQuNGMwLDYuNSwxLDcuMSw3LjQsNy43ICAgYzkuOSwwLjksMTkuOCwxLjcsMjkuNSwzLjZjMTIuMiwyLjMsMjQuNSwzLjYsMzYuOCw1LjNjNi40LDAuOSwxMywxLjEsMTkuMSwyLjZjOC43LDIsMTcuNSwyLjYsMjYuMiw0YzkuNSwxLjYsMTkuMywyLjgsMjksMy44ICAgYzEyLjQsMS40LDI0LjksMi44LDM3LjIsNS41YzQsMC45LDUuOS0wLjMsNS45LTUuMUMyMDkuOSw0MjIuMywyMTAsMzkzLjgsMjEwLDM2NS40eiIgZmlsbD0iIzM1QUJENSIvPjxwYXRoIGQ9Ik00OTUuNywzODUuN2MwLDM1LjMsMCw3MC42LDAsMTA2YzAsNy43LDAsNy44LTcuOSw2LjdjLTE4LjgtMi43LTM3LjUtNS41LTU2LjMtOC4xICAgYy0yNS45LTMuNi01MS44LTctNzcuNi0xMC43Yy0yNC41LTMuNC00OS4xLTYuOS03My42LTEwLjZjLTEzLjYtMi4xLTI3LjQtMy4yLTQxLTUuN2MtNC4zLTAuOC00LjQtMi43LTQuNC01LjljMC0zMi41LDAtNjUsMC05Ny41ICAgYzAtMjcuNywwLTU1LjMsMC04M2MwLTYuMSwwLjItNi41LDYuNi02LjRjODMuMSwxLjQsMTY2LjIsMS40LDI0OS4zLDEuOGM0LjIsMCw0LjksMS43LDQuOSw1LjMgICBDNDk1LjcsMzEzLjcsNDk1LjcsMzQ5LjcsNDk1LjcsMzg1LjdDNDk1LjcsMzg1LjcsNDk1LjcsMzg1LjcsNDk1LjcsMzg1Ljd6IE00OTQsMzg0LjdjMC0yNy4zLDAtNTQuNywwLTgyYzAtNy44LDAtMTUuNywwLTIzLjUgICBjMC0yLDAuNC00LjEtMi43LTQuM2MtMy41LTAuMi02LjktMC44LTEwLjQtMC45Yy0zNC44LTAuNi02OS42LDAtMTA0LjQtMC44Yy00NC4xLTEtODguMy0wLjMtMTMyLjUtMC4zYy03LDAtNywwLTcsNi44ICAgYzAsNTUuMywwLDExMC42LDAsMTY2YzAsNCwwLjEsOCwwLDEyYy0wLjEsMywxLjIsNCw0LjIsNC4yYzQuOCwwLjMsOS41LDEuNCwxNC4zLDEuNWM4LjMsMC4yLDE2LjIsMy4xLDI0LjYsMy41ICAgYzguMSwwLjQsMTYuMSwxLjUsMjQuMSwyLjVjOS41LDEuMywxOC45LDQsMjguNCw0LjFjMTAuNywwLjEsMjAuOSwzLjQsMzEuNSw0YzkuOSwwLjYsMTkuNiwyLjksMjkuNCw0LjMgICBjMTEuNiwxLjYsMjMuMywyLjgsMzQuOSw0LjdjOSwxLjUsMTgsMi4yLDI3LDMuNGM5LjQsMS4zLDE4LjYsMy41LDI4LjEsM2MwLjcsMCwxLjUsMC43LDIuMiwxYzUuOCwyLjUsOC4zLDAuOSw4LjMtNS41ICAgQzQ5NCw0NTQsNDk0LDQxOS40LDQ5NCwzODQuN3oiIGZpbGw9IiMzNUFCRDUiLz48cGF0aCBkPSJNMjEwLDE1My44YzAsMjgsMCw1NiwwLDgzLjljMCw4LTAuMyw4LjMtOC4xLDguM2MtMjYuNiwwLTUzLjMsMC4zLTc5LjksMGMtMzItMC40LTYzLjksMS41LTk1LjgsMS4xICAgYy02LjUtMC4xLTcuMi0wLjctNy4yLTcuMWMwLTQ4LDAtOTUuOSwwLTE0My45YzAtNi4yLDAuOC03LjMsNi44LTdjNi45LDAuNCwxMy4xLTMuMiwxOS45LTMuNGM4LjEtMC4yLDE2LjEtMS45LDI0LjEtMyAgIGM5LjUtMS4zLDE5LjItMS44LDI4LjctNC4zYzMuNy0xLDgtMi40LDEyLjItMC43YzEuMywwLjUsMi42LDAuMSwzLjktMC40YzcuNS0zLjEsMTUuNi0zLDIzLjQtNC4yYzEyLjktMiwyNS44LTMuNywzOC43LTUuNCAgIGM2LjUtMC45LDEzLjEtMi4xLDE5LjctMi41YzMuMS0wLjIsNS42LTIsOC42LTIuMmMzLjgtMC4yLDUuMiwwLjgsNS4yLDQuOUMyMTAsOTYuNSwyMTAsMTI1LjEsMjEwLDE1My44eiIgZmlsbD0iIzAwQUNFRSIvPjxwYXRoIGQ9Ik0yMTAsMzY1LjRjMCwyOC41LTAuMSw1NywwLjEsODUuNGMwLDQuOC0xLjksNi01LjksNS4xYy0xMi4zLTIuNy0yNC44LTQuMi0zNy4yLTUuNSAgIGMtOS43LTEuMS0xOS41LTIuMy0yOS0zLjhjLTguNy0xLjQtMTcuNS0yLTI2LjItNGMtNi4xLTEuNC0xMi43LTEuNy0xOS4xLTIuNmMtMTIuMy0xLjctMjQuNi0zLTM2LjgtNS4zICAgYy05LjctMS45LTE5LjYtMi43LTI5LjUtMy42Yy02LjUtMC42LTcuNC0xLjEtNy40LTcuN2MwLTQ4LjEsMC05Ni4zLDAtMTQ0LjRjMC02LjMsMC43LTcsNi44LTdjMTMuOCwwLDI3LjctMC42LDQxLjUsMC4xICAgYzM2LjYsMS44LDczLjIsMCwxMDkuOCwxLjFjOC4yLDAuMiwxNi40LTAuMSwyNC42LTAuMmM1LjQsMCw4LjcsMS4xLDguNiw4LjRDMjA5LjgsMzA5LjQsMjEwLDMzNy40LDIxMCwzNjUuNHoiIGZpbGw9IiMwMEFDRUUiLz48cGF0aCBkPSJNNDk0LDM4NC43YzAsMzQuNywwLDY5LjMsMCwxMDRjMCw2LjQtMi41LDgtOC4zLDUuNWMtMC44LTAuMy0xLjUtMS0yLjItMWMtOS41LDAuNS0xOC44LTEuNy0yOC4xLTMgICBjLTktMS4yLTE4LTEuOS0yNy0zLjRjLTExLjYtMi0yMy4zLTMuMS0zNC45LTQuN2MtOS44LTEuNC0xOS42LTMuNy0yOS40LTQuM2MtMTAuNi0wLjctMjAuNy0zLjktMzEuNS00ICAgYy05LjUtMC4xLTE4LjktMi44LTI4LjQtNC4xYy04LTEuMS0xNi4xLTIuMS0yNC4xLTIuNWMtOC4zLTAuNC0xNi4yLTMuMy0yNC42LTMuNWMtNC44LTAuMS05LjUtMS4yLTE0LjMtMS41ICAgYy0yLjktMC4yLTQuMi0xLjMtNC4yLTQuMmMwLjEtNCwwLTgsMC0xMmMwLTU1LjMsMC0xMTAuNiwwLTE2NmMwLTYuOCwwLTYuOCw3LTYuOGM0NC4yLDAsODguMy0wLjcsMTMyLjUsMC4zICAgYzM0LjgsMC44LDY5LjYsMC4yLDEwNC40LDAuOGMzLjUsMC4xLDYuOSwwLjcsMTAuNCwwLjljMy4xLDAuMSwyLjcsMi4zLDIuNyw0LjNjMCw3LjgsMCwxNS43LDAsMjMuNSAgIEM0OTQsMzMwLjEsNDk0LDM1Ny40LDQ5NCwzODQuN3oiIGZpbGw9IiMwMEFDRUUiLz48L2c+PC9zdmc+') +} +.appleIcon { + background:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjE3MHB4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzAgMTcwIiB2ZXJzaW9uPSIxLjEiIGhlaWdodD0iMTcwcHgiPgogPHBhdGggZD0ibTE1MC4zNyAxMzAuMjVjLTIuNDUgNS42Ni01LjM1IDEwLjg3LTguNzEgMTUuNjYtNC41OCA2LjUzLTguMzMgMTEuMDUtMTEuMjIgMTMuNTYtNC40OCA0LjEyLTkuMjggNi4yMy0xNC40MiA2LjM1LTMuNjkgMC04LjE0LTEuMDUtMTMuMzItMy4xOC01LjE5Ny0yLjEyLTkuOTczLTMuMTctMTQuMzQtMy4xNy00LjU4IDAtOS40OTIgMS4wNS0xNC43NDYgMy4xNy01LjI2MiAyLjEzLTkuNTAxIDMuMjQtMTIuNzQyIDMuMzUtNC45MjkgMC4yMS05Ljg0Mi0xLjk2LTE0Ljc0Ni02LjUyLTMuMTMtMi43My03LjA0NS03LjQxLTExLjczNS0xNC4wNC01LjAzMi03LjA4LTkuMTY5LTE1LjI5LTEyLjQxLTI0LjY1LTMuNDcxLTEwLjExLTUuMjExLTE5LjktNS4yMTEtMjkuMzc4IDAtMTAuODU3IDIuMzQ2LTIwLjIyMSA3LjA0NS0yOC4wNjggMy42OTMtNi4zMDMgOC42MDYtMTEuMjc1IDE0Ljc1NS0xNC45MjVzMTIuNzkzLTUuNTEgMTkuOTQ4LTUuNjI5YzMuOTE1IDAgOS4wNDkgMS4yMTEgMTUuNDI5IDMuNTkxIDYuMzYyIDIuMzg4IDEwLjQ0NyAzLjU5OSAxMi4yMzggMy41OTkgMS4zMzkgMCA1Ljg3Ny0xLjQxNiAxMy41Ny00LjIzOSA3LjI3NS0yLjYxOCAxMy40MTUtMy43MDIgMTguNDQ1LTMuMjc1IDEzLjYzIDEuMSAyMy44NyA2LjQ3MyAzMC42OCAxNi4xNTMtMTIuMTkgNy4zODYtMTguMjIgMTcuNzMxLTE4LjEgMzEuMDAyIDAuMTEgMTAuMzM3IDMuODYgMTguOTM5IDExLjIzIDI1Ljc2OSAzLjM0IDMuMTcgNy4wNyA1LjYyIDExLjIyIDcuMzYtMC45IDIuNjEtMS44NSA1LjExLTIuODYgNy41MXptLTMxLjI2LTEyMy4wMWMwIDguMTAyMS0yLjk2IDE1LjY2Ny04Ljg2IDIyLjY2OS03LjEyIDguMzI0LTE1LjczMiAxMy4xMzQtMjUuMDcxIDEyLjM3NS0wLjExOS0wLjk3Mi0wLjE4OC0xLjk5NS0wLjE4OC0zLjA3IDAtNy43NzggMy4zODYtMTYuMTAyIDkuMzk5LTIyLjkwOCAzLjAwMi0zLjQ0NiA2LjgyLTYuMzExMyAxMS40NS04LjU5NyA0LjYyLTIuMjUxNiA4Ljk5LTMuNDk2OCAxMy4xLTMuNzEgMC4xMiAxLjA4MzEgMC4xNyAyLjE2NjMgMC4xNyAzLjI0MDl6Ii8+Cjwvc3ZnPgo=') +} +.linuxIcon { + background:url('data:image/png;base64,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') +} diff --git a/docs/de/index.md b/docs/de/index.md deleted file mode 100644 index aa8cf10e0a..0000000000 --- a/docs/de/index.md +++ /dev/null @@ -1,6 +0,0 @@ -# NodeMCU Dokumentation - -NodeMCU ist eine [eLua](http://www.eluaproject.net/)-basierende firmware für den [ESP8266 WiFi SOC von Espressif](http://espressif.com/en/products/esp8266/). Dies ist ein Partnerprojekt für die beliebten [NodeMCU dev kits](https://github.com/nodemcu/nodemcu-devkit-v1.0) - open source NodeMCU boards mit ESP8266-12E chips. - -Diese firmware nutzt das Espressif NON-OS SDK, das Dateisystem basiert auf [spiffs](https://github.com/pellepl/spiffs). - diff --git a/docs/en/flash.md b/docs/en/flash.md index fcf3d210fa..7897624a36 100644 --- a/docs/en/flash.md +++ b/docs/en/flash.md @@ -22,9 +22,9 @@ Supported platforms: OS X, Linux, Windows, anything that runs Python Run the following command to flash an *aggregated* binary as is produced for example by the [cloud build service](build.md#cloud-build-service) or the [Docker image](build.md#docker-image). -`esptool.py --port write_flash -fm 0x00000 .bin` +`esptool.py --port write_flash -fm 0x00000 .bin` -[`mode`](https://github.com/espressif/esptool/#flash-modes) is `qio` for most ESP8266 ESP-01/07 (512 kByte modules) and `dio` for most ESP32 and ESP8266 ESP-12 (>=4 MByte modules). ESP8285 requires `dout`. +[`flash-mode`](https://github.com/espressif/esptool/#flash-modes) is `qio` for most ESP8266 ESP-01/07 (512 kByte modules) and `dio` for most ESP32 and ESP8266 ESP-12 (>=4 MByte modules). ESP8285 requires `dout`. **Gotchas** diff --git a/docs/en/getting-started.md b/docs/en/getting-started.md new file mode 100644 index 0000000000..3d1a1c784b --- /dev/null +++ b/docs/en/getting-started.md @@ -0,0 +1,328 @@ +# Getting Started aka NodeMCU Quick Start + +The basic process to get started with NodeMCU consists of the following three steps. + +1. [Build the firmware](build.md) with the modules you need +1. [Flash the firmware](flash.md) to the chip +1. [Upload code](upload.md) to the device. + +You will typically do steps 1 and 2 only once, but then repeat step 3 as you develop your application. If your application outgrows the limited on-chip RAM then you can use the [Lua Flash Store](lfs.md) (LFS) to move your Lua code into flash memory, freeing a lot more RAM for variable data. This is why it is a good idea to enable LFS for step 1 if you are developing a larger application. As documented below there is a different approach to uploading Lua code. + + +!!! caution + There's more than one way to skin a cat. For each of the tasks you have a number of choices with regards to tooling. The colored boxes represent an opinionated path to start your journey - the quickest way to success so to speak. Feel free to follow the links above to get more detailed information. + +### Task / OS selector + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Task \ OSWindows
macOS
Linux
Build firmwarecloud buildercloud buildercloud builder
DockerDockerDocker
native
Flash firmwareNodeMCU PyFlasherNodeMCU PyFlasher
esptool.pyesptool.pyesptool.py
Upload codeESPlorer (Java)ESPlorer (Java)ESPlorer (Java)
NodeMCU-Tool (Node.js)NodeMCU-Tool (Node.js)NodeMCU-Tool (Node.js)
LFS tasks below
Build LFS
enabled firmware
cloud buildercloud buildercloud builder
DockerDockerDocker
native
Build luac.crossnot needed if you use Terry's webservice or Docker to later compile LFS imagenot needed if you use Terry's webservice or Docker to later compile LFS imagenot needed if you use Terry's webservice or Docker to later compile LFS image
nativenativenative
Compile Lua into
LFS image
webservicewebservicewebservice
DockerDockerDocker
nativenativenative
Upload LFS imagegenericgenericgeneric
+ +**How to read this** + +Use case: you're just starting with NodeMCU and your OS of choice is Windows (and you are not using LFS), then the blue boxes in the 'Windows' column are your guideline. You: + +- build the firmware on the cloud builder +- download and run the NodeMCU PyFlasher to transfer the firmware to the device +- download and run ESPlorer, which requires Java, to transfer Lua files from your system to the device + +**Missing tools?** + +Our intention is to introduce you to programming in Lua on the ESP8266 as quickly as possible, so we have kept the number of tools mentioned here to a minimum; [frightanic.com: Tools and IDEs](https://frightanic.com/iot/tools-ides-nodemcu/) discusses other tools and options. + +!!! caution + The below chapters are not meant to be followed one-by-one. Pick a task from the matrix above and it will take you to the relevant chapter. + +## Cloud Builder + +The cloud builder at [https://nodemcu-build.com](https://nodemcu-build.com) allows to pick NodeMCU branch, modules and a few other configuration options (e.g. SSL yes/no). After the build is completed you will receive an email with two links to download your custom firmware: + +- one for NodeMCU with floating support +- one for NodeMCU *without* floating support i.e. an integer-only binary + +We recommend using the floating point build, even though the integer variant uses less RAM for storing variables, as there is little runtime difference between the two variants. Furthermore, the floating point variant handles non-integer values properly and this greatly simplifies numeric calculations. + +For everything else the cloud builder GUI is self-explanatory. Hence, no need for further explanations here. + +### For LFS + +1. Expand the "LFS options" panel +1. Select an LFS size, 64KB is likely going to be large enough +1. Select other options and build + +[↑ back to matrix](#task-os-selector) + +_Note that this service is not maintained by the NodeMCU team. It's run by a NodeMCU team member as an individual, though._ + +## NodeMCU PyFlasher + +[Self-contained NodeMCU flasher](https://github.com/marcelstoer/nodemcu-pyflasher) with GUI based on Python, esptool.py (see below) and wxPython. A runnable .exe is available for Windows and a .dmg for macOS. + +**No installation required on Windows and macOS!** Instructions how to run it on other platforms are available on the project site. + +![](https://github.com/marcelstoer/nodemcu-pyflasher/raw/master/images/gui.png) + +1. [Install drivers for USB-to-serial](https://docs.thingpulse.com/how-tos/install-drivers/). Which driver you need depends on the ESP8266 module or USB-to-serial converter you use. +1. Connect USB cable to device and computer. +1. [Download](https://github.com/marcelstoer/nodemcu-pyflasher) then start PyFlasher +1. Select serial port, browse for firmware binary and set the flash options. + +[↑ back to matrix](#task-os-selector) + +_Note that this tool is not an official NodeMCU offering. It's maintained by a NodeMCU team member as an individual, though._ + +## esptool.py + +[esptool.py](https://github.com/espressif/esptool) was started as a ESP8266 community effort but has since been adopted by Espressif. It's their officially recommended way to flash firmware to ESPxxx chips. + +1. [Install drivers for USB-to-serial](https://docs.thingpulse.com/how-tos/install-drivers/). Which driver you need depends on the ESP8266 module or USB-to-serial converter you use. +1. Install [either Python 2.7 or Python >=3.4](https://www.python.org/downloads/) on your system if it's not available yet. +1. Connect USB cable to device and computer. +1. `$ pip install esptool` (also installs pySerial) +1. `$ esptool.py --port --baud write_flash -fm 0x00000 .bin` + +[`flash-mode`](https://github.com/espressif/esptool/#flash-modes) is `qio` for most ESP8266 ESP-01/07 (512 kByte modules) and `dio` for most ESP32 and ESP8266 ESP-12 (>=4 MByte modules). ESP8285 requires `dout`. + +The [default baud rate](https://github.com/espressif/esptool#baud-rate) is 115200. Most hardware configurations should work with 230400 dependent on OS, driver, and module. NodeMCU and WeMos modules are usually ok with 921600. + +More details available on esptool.py GitHub repo. + +[↑ back to matrix](#task-os-selector) + +## ESPlorer + +TBD [https://github.com/4refr0nt/ESPlorer](https://github.com/4refr0nt/ESPlorer) + +[↑ back to matrix](#task-os-selector) + +## NodeMCU-Tool + +Arguably [NodeMCU-Tool](https://github.com/andidittrich/NodeMCU-Tool), which requires Node.js, is the better code upload & execution tool than ESPlorer. Also, in contrast to the former it is very well maintained. However, we also understand that Windows users in general prefer GUI over command line. + +The [list of features](https://github.com/andidittrich/NodeMCU-Tool#tool-summary) is quite long but essentially NodeMCU-Tool offers: + +- upload (Lua) files from your host system to the device +- manage the device file system (delete, up-/download, etc.) +- run files on NodeMCU and display the output over UART/serial + +Quick start: + +1. [Install Node.js and NPM](https://nodejs.org/en/download/) if not available yet +1. Install NodeMCU-Tool globally `$ npm install nodemcu-tool -g` +1. Verify installation by runnin `$ nodemcu-tool --version` +1. Upload a Lua file `$ nodemcu-tool upload --port=/dev/ttyUSB0 helloworld.lua` +1. Run it `$ nodemcu-tool run helloworld.lua` + +Note that you may need to use the `sudo` prefix to install the tool at step 2, and also possibly add the `–unsafe-perm` flag after the install command. + +[↑ back to matrix](#task-os-selector) + +## Docker + +The [Docker NodeMCU build image](https://github.com/marcelstoer/docker-nodemcu-build) is the easiest method to build NodeMCU related components locally on your preferred platform. + +Offering: + +- build NodeMCU firmware based on locally cloned sources and configuration +- cross-compile Lua files into LFS image locally + +Detailed instructions available in the image's README. As for available config options [check the documentation](build.md#build-options) and study the comments in `app/include/user_config.h`. + +### For LFS + +1. In `app/include/user_config.h` uncomment `#define LUA_FLASH_STORE 0x10000` and adjust the size if necessary. +2. Build as you would otherwise build with this image (i.e. see its README) + +[↑ back to matrix](#task-os-selector) + +_Note that this Docker image is not an official NodeMCU offering. It's maintained by a NodeMCU team member as an individual, though._ + +## Build `luac.cross` + +A local copy of `luac.cross` is only needed if you want to compile the Lua files into an LFS image yourself and you are _not_ using Docker. + +### Windows +Windows 10 users can install and use the Windows Subsystem for Linux (WSL). Alternatively all Windows users can [install Cygwin](https://www.cygwin.com/install.html) (only Cygwin core + **gcc-core** + **gnu make**). Either way, you will need a copy of the `luac.cross` compiler: + +- You can either download this from Terry's fileserver. The [ELF variant](http://files.ellisons.org.uk/esp8266/luac.cross) is used for all recent Linux and WSL flavours, or the [cygwin binary](http://files.ellisons.org.uk/esp8266/luac.cross.cygwin)) for the Cygwin environment. +- Or you can compile it yourself by downloading the current NodeMCU sources (this [ZIPfile](https://github.com/nodemcu/nodemcu-firmware/archive/master.zip)); edit the `app/includes/user_config.h` file and then `cd` to the `app/lua/luac_cross` and run make to build the compiler in the NodeMCU firmware root directory. Note that the `luac.cross` make only needs the host toolchain which is installed by default. + +### macOS + +TBD + +1. `$ cd app/lua/luac_cross` +2. `$ make` + +### Linux + +TBD + +1. `$ cd app/lua/luac_cross` +2. `$ make` + +[↑ back to matrix](#task-os-selector) + +## Compile Lua into LFS image + +### Select Lua files to be run from LFS + +The easiest approach is to maintain all the Lua files for your project in a single directory on your host. (These files will be compiled by `luac.cross` to build the LFS image in next step.) + +For example to run the Telnet and FTP servers from LFS, put the following files in your project directory: + +* [lua_examples/lfs/_init.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/lfs/_init.lua). LFS helper routines and functions. +* [lua_examples/lfs/dummy_strings.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/lfs/dummy_strings.lua). Moving common strings into LFS. +* [lua_examples/telnet/telnet.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/telnet/telnet.lua). A simple **telnet** server. +* [lua_modules/ftp/ftpserver.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_modules/ftp/ftpserver.lua). A simple **FTP** server. + +You should always include the first two modules, but the remaining files would normally be replaced by your own project files. Also remember that these are examples and that you are entirely free to modify or to replace them for your own application needs. + +### Terry's LFS Lua Cross-Compile Web Service + +[https://blog.ellisons.org.uk/article/nodemcu/a-lua-cross-compile-web-service/](https://blog.ellisons.org.uk/article/nodemcu/a-lua-cross-compile-web-service/) + +Note: read up on [selecting Lua files](#select-lua-files-to-be-run-from-lfs) first + +Upload a ZIP file with all your Lua files ready for LFS. The webservice will cross-compile them into a `.img` ready to be uploaded to the device. It supports LFS images for both floating point and integer firmware variants. + +Further details available on the service site. + +_Note that this service is not maintained by the NodeMCU team. It's run by a NodeMCU team member as an individual, though._ + +### Docker + +Note: read up on [selecting Lua files](#select-lua-files-to-be-run-from-lfs) first + +The same Docker image you used to build the NodeMCU firmware can be used to [compile Lua files into an LFS image](https://github.com/marcelstoer/docker-nodemcu-build#run-this-image-with-docker-to-create-an-lfs-image). + +1. `$ cd ` +1. `$ docker run --rm -ti -v `pwd`:/opt/nodemcu-firmware -v {PathToLuaSourceFolder}:/opt/lua marcelstoer/nodemcu-build lfs-image` + +### Native on OS + +Note: read up on [selecting Lua files](#select-lua-files-to-be-run-from-lfs) first + +For Windows you will do this from within the WSL / Cygwin command window, both of which use the `bash` shell. + +1. `$ cd ` +1. `$ luac.cross -o lfs.img -f *.lua` + +You will need to adjust the `img` and `lua` paths according to their location, and ensure that `luac.cross` is in your `$PATH` search list. For example if you are using WSL and your project files are in `D:\myproject` then the Lua path would be `/mnt/d/myproject/*.lua` (For cygwin replace `mnt` by `cygwin`). This will create the `lfs.img` file if there are no Lua compile errors (again specify an explicit directory path if needed). + +You might also want to add a simple one-line script file to your `~/bin` directory to wrap this command up. + +[↑ back to matrix](#task-os-selector) + +## Upload LFS image + +The compiled LFS image file (e.g. `lfs.img`) is uploaded as a regular file to the device file system (SPIFFS). You do this just like with Lua files with e.g. [ESPlorer](#esplorer) or [NodeMCU-Tool](#nodemcu-tool). There is also a new example, [HTTP_OTA.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/lfs/HTTP_OTA.lua), in `lua_examples` that can retrieve images from a standard web service. + +Once the LFS image file is on SPIFFS, you can execute the [node.flashreload()](../modules/node/#nodeflashreload) command and the loader will then load it into flash and immediately restart the ESP module with the new LFS loaded, if the image file is valid. However, the call will return with an error _if_ the file is found to be invalid, so your reflash code should include logic to handle such an error return. + +### Edit your `init.lua` file + +`init.lua` is the file that is first executed by the NodeMCU firmware. Usually it setups the WiFi connection and executes the main Lua application. Assuming that you have included the `_init` file discussed above, then executing this will add a simple API for LFS module access: + +- Individual functions can be executed directly, e.g. `LFS.myfunc(a,b)` +- LFS is now in the require path, so `require 'myModule'` works as expected. + +Do a protected call of this `_init` code: `pcall(node.flashindex("_init"))` and check the error status. See [Programming Techniques and Approachs](lfs.md#programming-techniques-and-approachs) in the LFS whitepaper for a more detailed description. + +[↑ back to matrix](#task-os-selector) \ No newline at end of file diff --git a/docs/en/index.md b/docs/en/index.md deleted file mode 100644 index ba964decf0..0000000000 --- a/docs/en/index.md +++ /dev/null @@ -1,53 +0,0 @@ -# NodeMCU Documentation - -NodeMCU is an open source [Lua](https://www.lua.org/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/) and uses an on-module flash-based [SPIFFS](https://github.com/pellepl/spiffs) file system. NodeMCU is implemented in C and is layered on the [Espressif NON-OS SDK](https://github.com/espressif/ESP8266_NONOS_SDK). - -The firmware was initially developed as is a companion project to the popular ESP8266-based [NodeMCU development modules](https://github.com/nodemcu/nodemcu-devkit-v1.0), but the project is now community-supported, and the firmware can now be run on _any_ ESP module. - -## Programming Model -The NodeMCU programming model is similar to that of [Node.js](https://en.wikipedia.org/wiki/Node.js), only in Lua. It is asynchronous and event-driven. Many functions, therefore, have parameters for callback functions. To give you an idea what a NodeMCU program looks like study the short snippets below. For more extensive examples have a look at the `/lua_examples` folder in the repository on GitHub. - -```lua --- a simple HTTP server -srv = net.createServer(net.TCP) -srv:listen(80, function(conn) - conn:on("receive", function(sck, payload) - print(payload) - sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

Hello, NodeMCU.

") - end) - conn:on("sent", function(sck) sck:close() end) -end) -``` -```lua --- connect to WiFi access point -wifi.setmode(wifi.STATION) -wifi.sta.config("SSID", "password") -``` - -```lua --- register event callbacks for WiFi events -wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_state) - if(previous_state==wifi.STA_GOTIP) then - print("Station lost connection with access point. Attempting to reconnect...") - else - print("STATION_CONNECTING") - end -end) -``` - -```lua --- manipulate hardware like with Arduino -pin = 1 -gpio.mode(pin, gpio.OUTPUT) -gpio.write(pin, gpio.HIGH) -print(gpio.read(pin)) -``` -### Lua Flash Store (LFS) -In July 2018 support for a [Lua Flash Store (LFS)](lfs.md) was introduced. LFS allows Lua code and its associated constant data to be executed directly out of flash-memory; just as the firmware itself is executed. This now enables NodeMCU developers to create Lua applications with up to 256Kb Lua code and read-only constants executing out of flash. All of the RAM is available for read-write data! - -## Getting Started -1. [Build the firmware](build.md) with the modules you need. -1. [Flash the firmware](flash.md) to the chip. -1. [Upload code](upload.md) to the firmware. - - diff --git a/docs/en/lfs.md b/docs/en/lfs.md index 580f36362a..6067591f6f 100644 --- a/docs/en/lfs.md +++ b/docs/en/lfs.md @@ -10,67 +10,12 @@ The Lua Flash Store (**LFS**) patch modifies the Lua RTS to support a modified H Unfortunately, the ESP architecture provides very restricted write operations to flash memory (writing to NAND flash involves bulk erasing complete 4Kb memory pages, before overwriting each erased page with any new content). Whilst it is possible to develop a R/W file system within this constraint (as SPIFFS demonstrates), this makes impractical to modify Lua code pages on the fly. Hence the LFS patch works within a reflash-and-restart paradigm for reloading the LFS, and does this by adding two API new calls: one to reflash the LFS and restart the processor, and one to access LFS stored functions. The patch also addresses all of the technical issues 'under the hood' to make this magic happen. -The remainder of this paper is split into two parts. The first provides an overview for Lua developers wanting to use LFS effectively at an application programming level, and as most of our developers use a Windows platform, it gives a quick start for these developers before covering some of application issues in more detail. The second part is for those who want to understand a little of how this magic happens, and gives more details on the technical issues that were addressed in order to implement the patch. +The remainder of this paper is for those who want to understand a little of how this magic happens, and gives more details on the technical issues that were addressed in order to implement the patch. +If you're just interested in learning how to quickly get started with LFS then please read the respective chapters in the [Getting Started](./getting-started.md) overview. ## Using LFS -### A Quick Start for Windows Developers - -This is a simple step-by-step guide for ESP8266 Lua developers who want to start to use `luac.cross` on a Windows development environment. - -#### Get and flash LFS enabled firmware - -Use the [NodeMCU Build](https://nodemcu-build.com/) service to build the firmware. In the "LFS options" section choose the size of the LFS partition (64 KB should be fine). The SPIFFS default settings will be fine. See section [selecting the firmware](#selecting-the-firmware) for further details. Once you have received the build confirmation email and downloaded the flash image, you can then [flash the firmware](flash.md) to your ESP8266. - -#### Build or download your local copy of `luac.cross` - -Windows 10 users can install and use the Windows Subsystem for Linux (WSL). Alternatively all Windows users can [install Cygwin](https://www.cygwin.com/install.html). (You will only need the Cygwin core). Either way, you will need a copy of the `luac.cross` compiler: -- You can either download this from my fileserver. The [ELF variant](http://files.ellisons.org.uk/esp8266/luac.cross) is used for all recent Linux and WSL flavours, or the [cygwin binary](http://files.ellisons.org.uk/esp8266/luac.cross.cygwin)) for the Cygwin environment. -- Or you can compile it yourself by downloading the current NodeMCU sources (this [ZIPfile](https://github.com/nodemcu/nodemcu-firmware/archive/master.zip)); edit the `app/includes/user_config.h` file and the `cd` to the `app/lua/luac_cross` and run make to build the compiler in the NodeMCU firmware root directory. Note that the `luac.cross` make only needs the host toolchain which is installed by default in WSL, but in Cygwin you will need to tick the _gcc-core_ + _gnu make_ options during setup. - -#### Select Lua files to be run from LFS - -The easiest approach is to maintain all the Lua files for your project in a single directory on your host. (These files will be compiled by `luac.cross` to build the LFS image in next step.) - -For example to run the Telnet and FTP servers from LFS, put the following files in your project directory: - -* [lua_examples/lfs/_init.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/lfs/_init.lua). LFS helper routines and functions. -* [lua_examples/lfs/dummy_strings.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/lfs/dummy_strings.lua). Moving common strings into LFS. -* [lua_examples/telnet/telnet.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/telnet/telnet.lua). A simple **telnet** server. -* [lua_modules/ftp/ftpserver.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_modules/ftp/ftpserver.lua). A simple **FTP** server. - -You should always include the first two modules, but the remaining files would normally be replaced by your own project files. Also remember that these are examples and that you are entirely free to modify or to replace them for your own application needs. - -#### Compile the LFS image - -You will do this from within the WSL or Cygwin command window, both of which use the `bash` shell; do a `cd` to the project directory, and execute the command: - -```bash -luac.cross -o lfs.img -f *.lua -``` - -You will need to adjust the `img` and `lua` paths according to their location, and ensure that `luac.cross` is in your `$PATH` search list. For example if you are using WSL and your project files are in `D:\myproject` then the Lua path would be `/mnt/d/myproject/*.lua` (For cygwin replace `mnt` by `cygwin`). This will create the `lfs.img` file if there are no Lua compile errors (again specify an explicit directory path if needed). - -You might also want to add a simple one-line script file to your ~/bin directory to wrap this command up. - -#### Upload the LFS image and flash it to the LFS region - -Now upload the compiled LFS image file (`lfs.img` in this case) as a normal SPIFFS file. Several tools are available to upload the files from host to SPIFFS, including [ESPlorer](https://github.com/4refr0nt/ESPlorer). There is also a new example, [HTTP_OTA.lua](https://github.com/nodemcu/nodemcu-firmware/tree/dev/lua_examples/lfs/HTTP_OTA.lua), in `lua_examples` that can retrieve images from a standard web service. - -Once the LFS image file is on SPIFFS, you can execute the [node.flashreload()](/en/dev/en/modules/node/#nodeflashreload) command and the loader will then load it into flash and immediately restart the ESP module with the new LFS loaded, if the image file is valid. However, the call will return with an error _if_ the file is found to be invalid, so your reflash code should include logic to handle such an error return. - -#### Edit your `init.lua` file - -`init.lua` is the file that is first executed by the NodeMCU firmware. Usually it setups the WiFi connection and executes the main Lua application. Assuming that you have included the `_init` file discussed above, then executing this will add a simple API for LFS module access: - -- Individual functions can be executed directly, e.g. `LFS.myfunc(a,b)` -- LFS is now in the require path, so `require 'myModule'` works as expected. - -Do a protected call of this `_init` code: `pcall(node.flashindex("_init"))` and check the error status. See [Programming Techniques and Approachs](#programming-techniques-and-approachs) below for a more detailed description. - -The remainder of this section describes how to use LFS in further detail. - ### Selecting the firmware Power developers might want to use Docker or their own build environment as per our [Building the firmware](https://nodemcu.readthedocs.io/en/master/en/build/) documentation, and so `app/include/user_config.h` has now been updated to include the necessary documentation on how to select the configuration options to make an LFS firmware build. diff --git a/docs/en/lua-developer-faq.md b/docs/en/lua-developer-faq.md index fb7575689e..58bbd763dc 100644 --- a/docs/en/lua-developer-faq.md +++ b/docs/en/lua-developer-faq.md @@ -8,7 +8,7 @@ This FAQ does not aim to help you to learn to program or even how to program in ## What has changed since the first version of this FAQ? -The [NodeMCU company](http://NodeMCU.com/index_en.html) was set up by [Zeroday](mailto:zeroday@nodemcu.com) to develop and to market a set of Lua firmware-based development boards which employ the Espressif ESP8266 SoC. The initial development of the firmware was done by Zeroday and a colleague, Vowstar, in-house with the firmware being first open-sourced on Github in late 2014. In mid-2015, Zeroday decided to open the firmware development to a wider group of community developers, so the core group of developers now comprises 6 community developers (including this author), and we are also supported by another dozen or so active contributors, and two NodeMCU originators. +The [NodeMCU company](http://NodeMCU.com/index_en.html) was set up by [Zeroday](zeroday@nodemcu.com) to develop and to market a set of Lua firmware-based development boards which employ the Espressif ESP8266 SoC. The initial development of the firmware was done by Zeroday and a colleague, Vowstar, in-house with the firmware being first open-sourced on Github in late 2014. In mid-2015, Zeroday decided to open the firmware development to a wider group of community developers, so the core group of developers now comprises 6 community developers (including this author), and we are also supported by another dozen or so active contributors, and two NodeMCU originators. This larger active team has allowed us to address most of the outstanding issues present at the first version of this FAQ. These include: diff --git a/docs/index.md b/docs/index.md index 13e6c15070..264b2c814c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,15 +1,55 @@ # NodeMCU Documentation -NodeMCU is an [eLua](http://www.eluaproject.net/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/). The NodeMCU *firmware* is a companion project to the popular [NodeMCU dev kits](https://github.com/nodemcu/nodemcu-devkit-v1.0), ready-made open source development boards with ESP8266-12E chips. +NodeMCU is an open source [Lua](https://www.lua.org/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/) and uses an on-module flash-based [SPIFFS](https://github.com/pellepl/spiffs) file system. NodeMCU is implemented in C and is layered on the [Espressif NON-OS SDK](https://github.com/espressif/ESP8266_NONOS_SDK). -## Up-To-Date Documentation -At the moment the only up-to-date documentation maintained by the current NodeMCU team is in [English](en/index.md). It is part of the source code repository (`/docs` subfolder) and kept in sync with the code. +The firmware was initially developed as is a companion project to the popular ESP8266-based [NodeMCU development modules]((https://github.com/nodemcu/nodemcu-devkit-v1.0)), but the project is now community-supported, and the firmware can now be run on _any_ ESP module. + +## Programming Model +The NodeMCU programming model is similar to that of [Node.js](https://en.wikipedia.org/wiki/Node.js), only in Lua. It is asynchronous and event-driven. Many functions, therefore, have parameters for callback functions. To give you an idea what a NodeMCU program looks like study the short snippets below. For more extensive examples have a look at the [`/lua_examples`](https://github.com/nodemcu/nodemcu-firmware/tree/master/lua_examples) folder in the repository on GitHub. + +```lua +-- a simple HTTP server +srv = net.createServer(net.TCP) +srv:listen(80, function(conn) + conn:on("receive", function(sck, payload) + print(payload) + sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

Hello, NodeMCU.

") + end) + conn:on("sent", function(sck) sck:close() end) +end) +``` +```lua +-- connect to WiFi access point +wifi.setmode(wifi.STATION) +wifi.sta.config("SSID", "password") +``` + +```lua +-- register event callbacks for WiFi events +wifi.sta.eventMonReg(wifi.STA_CONNECTING, function(previous_state) + if(previous_state==wifi.STA_GOTIP) then + print("Station lost connection with access point. Attempting to reconnect...") + else + print("STATION_CONNECTING") + end +end) +``` -We encourage you to help transferring the outdated translations (see below) into the repository. +```lua +-- manipulate hardware like with Arduino +pin = 1 +gpio.mode(pin, gpio.OUTPUT) +gpio.write(pin, gpio.HIGH) +print(gpio.read(pin)) +``` +## Lua Flash Store (LFS) +In September 2018 support for a [Lua Flash Store (LFS)](en/lfs.md) was introduced. LFS allows Lua code and its associated constant data to be executed directly out of flash-memory; just as the firmware itself is executed. This now enables NodeMCU developers to create Lua applications with up to 256Kb Lua code and read-only constants executing out of flash. All of the RAM is available for read-write data! -## Outdated And Sparse Documentation -The following translations are based on outdated documentation, use them with caution. The links point to the [NodeMCU wiki on GitHub](https://github.com/nodemcu/nodemcu-firmware/wiki). +## Releases -- Chinese, [中文](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_cn) -- Russian, [русский](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru) -- Spanish, [español](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_es) \ No newline at end of file +This project uses two main branches, `master` and `dev`. `dev` is actively worked on and it's also where PRs should be created against. `master` thus can be considered "stable" even though there are no automated regression tests. The goal is to merge back to `master` roughly every 2 months. Depending on the current "heat" (issues, PRs) we accept changes to `dev` for 5-6 weeks and then hold back for 2-3 weeks before the next snap is completed. + +A new tag is created every time `dev` is merged back to `master`. They are listed in the [releases section on GitHub](https://github.com/nodemcu/nodemcu-firmware/releases). Tag names follow the `-master_yyyymmdd` pattern. + +## Up-To-Date Documentation +At the moment the only up-to-date documentation maintained by the current NodeMCU team is in [English](en/index.md). It is part of the source code repository (`/docs` subfolder) and kept in sync with the code. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 2e4579e948..8579b5684a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,89 +21,87 @@ extra_javascript: pages: - Overview: 'index.md' -- English: - - Home: 'en/index.md' +- Basics: + - Getting started: 'en/getting-started.md' - Building the firmware: 'en/build.md' - Flashing the firmware: 'en/flash.md' - Uploading code: 'en/upload.md' - Support: 'en/support.md' - - FAQs: - - Lua Developer FAQ: 'en/lua-developer-faq.md' - - Extension Developer FAQ: 'en/extn-developer-faq.md' - - Hardware FAQ: 'en/hardware-faq.md' - - Whitepapers: - - Filesystem on SD card: 'en/sdcard.md' - - Internal filesystem: 'en/spiffs.md' - - Lua Compact Debug (LCD): 'en/lcd.md' - - Lua Flash Store (LFS): 'en/lfs.md' - - Modules: - - 'adc': 'en/modules/adc.md' - - 'ads1115' : 'en/modules/ads1115.md' - - 'adxl345': 'en/modules/adxl345.md' - - 'am2320': 'en/modules/am2320.md' - - 'apa102': 'en/modules/apa102.md' - - 'bit': 'en/modules/bit.md' - - 'bloom' : 'en/modules/bloom.md' - - 'bme280': 'en/modules/bme280.md' - - 'bme680': 'en/modules/bme680.md' - - 'bmp085': 'en/modules/bmp085.md' - - 'cjson': 'en/modules/cjson.md' - - 'coap': 'en/modules/coap.md' - - 'color-utils': 'en/modules/color-utils.md' - - 'cron': 'en/modules/cron.md' - - 'crypto': 'en/modules/crypto.md' - - 'dht': 'en/modules/dht.md' - - 'ds18b20': 'en/modules/ds18b20.md' - - 'encoder': 'en/modules/encoder.md' - - 'enduser setup': 'en/modules/enduser-setup.md' - - 'file': 'en/modules/file.md' - - 'gdbstub': 'en/modules/gdbstub.md' - - 'gpio': 'en/modules/gpio.md' - - 'hdc1080': 'en/modules/hdc1080.md' - - 'hmc5883l': 'en/modules/hmc5883l.md' - - 'http': 'en/modules/http.md' - - 'hx711' : 'en/modules/hx711.md' - - 'i2c' : 'en/modules/i2c.md' - - 'l3g4200d' : 'en/modules/l3g4200d.md' - - 'mcp4725': 'en/modules/mcp4725.md' - - 'mdns': 'en/modules/mdns.md' - - 'mqtt': 'en/modules/mqtt.md' - - 'net': 'en/modules/net.md' - - 'node': 'en/modules/node.md' - - 'ow (1-Wire)': 'en/modules/ow.md' - - 'pcm' : 'en/modules/pcm.md' - - 'perf': 'en/modules/perf.md' - - 'pwm' : 'en/modules/pwm.md' - - 'rc' : 'en/modules/rc.md' - - 'rfswitch' : 'en/modules/rfswitch.md' - - 'rotary' : 'en/modules/rotary.md' - - 'rtcfifo': 'en/modules/rtcfifo.md' - - 'rtcmem': 'en/modules/rtcmem.md' - - 'rtctime': 'en/modules/rtctime.md' - - 'si7021' : 'en/modules/si7021.md' - - 'sigma delta': 'en/modules/sigma-delta.md' - - 'sjson': 'en/modules/sjson.md' - - 'sntp': 'en/modules/sntp.md' - - 'somfy': 'en/modules/somfy.md' - - 'spi': 'en/modules/spi.md' - - 'sqlite3': 'en/modules/sqlite3.md' - - 'struct': 'en/modules/struct.md' - - 'switec': 'en/modules/switec.md' - - 'tcs34725': 'en/modules/tcs34725.md' - - 'tls': 'en/modules/tls.md' - - 'tm1829': 'en/modules/tm1829.md' - - 'tmr': 'en/modules/tmr.md' - - 'tsl2561': 'en/modules/tsl2561.md' - - 'u8g2': 'en/modules/u8g2.md' - - 'uart': 'en/modules/uart.md' - - 'ucg': 'en/modules/ucg.md' - - 'websocket': 'en/modules/websocket.md' - - 'wifi': 'en/modules/wifi.md' - - 'wifi.monitor': 'en/modules/wifi_monitor.md' - - 'wps': 'en/modules/wps.md' - - 'ws2801': 'en/modules/ws2801.md' - - 'ws2812': 'en/modules/ws2812.md' - - 'ws2812-effects': 'en/modules/ws2812-effects.md' - - 'xpt2046': 'en/modules/xpt2046.md' -#- Deutsch: -# - Home: 'de/index.md' +- FAQs: + - Lua Developer FAQ: 'en/lua-developer-faq.md' + - Extension Developer FAQ: 'en/extn-developer-faq.md' + - Hardware FAQ: 'en/hardware-faq.md' +- Whitepapers: + - Filesystem on SD card: 'en/sdcard.md' + - Internal filesystem: 'en/spiffs.md' + - Lua Compact Debug (LCD): 'en/lcd.md' + - Lua Flash Store (LFS): 'en/lfs.md' +- Modules: + - 'adc': 'en/modules/adc.md' + - 'ads1115' : 'en/modules/ads1115.md' + - 'adxl345': 'en/modules/adxl345.md' + - 'am2320': 'en/modules/am2320.md' + - 'apa102': 'en/modules/apa102.md' + - 'bit': 'en/modules/bit.md' + - 'bloom' : 'en/modules/bloom.md' + - 'bme280': 'en/modules/bme280.md' + - 'bme680': 'en/modules/bme680.md' + - 'bmp085': 'en/modules/bmp085.md' + - 'cjson': 'en/modules/cjson.md' + - 'coap': 'en/modules/coap.md' + - 'color-utils': 'en/modules/color-utils.md' + - 'cron': 'en/modules/cron.md' + - 'crypto': 'en/modules/crypto.md' + - 'dht': 'en/modules/dht.md' + - 'ds18b20': 'en/modules/ds18b20.md' + - 'encoder': 'en/modules/encoder.md' + - 'enduser setup': 'en/modules/enduser-setup.md' + - 'file': 'en/modules/file.md' + - 'gdbstub': 'en/modules/gdbstub.md' + - 'gpio': 'en/modules/gpio.md' + - 'hdc1080': 'en/modules/hdc1080.md' + - 'hmc5883l': 'en/modules/hmc5883l.md' + - 'http': 'en/modules/http.md' + - 'hx711' : 'en/modules/hx711.md' + - 'i2c' : 'en/modules/i2c.md' + - 'l3g4200d' : 'en/modules/l3g4200d.md' + - 'mcp4725': 'en/modules/mcp4725.md' + - 'mdns': 'en/modules/mdns.md' + - 'mqtt': 'en/modules/mqtt.md' + - 'net': 'en/modules/net.md' + - 'node': 'en/modules/node.md' + - 'ow (1-Wire)': 'en/modules/ow.md' + - 'pcm' : 'en/modules/pcm.md' + - 'perf': 'en/modules/perf.md' + - 'pwm' : 'en/modules/pwm.md' + - 'rc' : 'en/modules/rc.md' + - 'rfswitch' : 'en/modules/rfswitch.md' + - 'rotary' : 'en/modules/rotary.md' + - 'rtcfifo': 'en/modules/rtcfifo.md' + - 'rtcmem': 'en/modules/rtcmem.md' + - 'rtctime': 'en/modules/rtctime.md' + - 'si7021' : 'en/modules/si7021.md' + - 'sigma delta': 'en/modules/sigma-delta.md' + - 'sjson': 'en/modules/sjson.md' + - 'sntp': 'en/modules/sntp.md' + - 'somfy': 'en/modules/somfy.md' + - 'spi': 'en/modules/spi.md' + - 'sqlite3': 'en/modules/sqlite3.md' + - 'struct': 'en/modules/struct.md' + - 'switec': 'en/modules/switec.md' + - 'tcs34725': 'en/modules/tcs34725.md' + - 'tls': 'en/modules/tls.md' + - 'tm1829': 'en/modules/tm1829.md' + - 'tmr': 'en/modules/tmr.md' + - 'tsl2561': 'en/modules/tsl2561.md' + - 'u8g2': 'en/modules/u8g2.md' + - 'uart': 'en/modules/uart.md' + - 'ucg': 'en/modules/ucg.md' + - 'websocket': 'en/modules/websocket.md' + - 'wifi': 'en/modules/wifi.md' + - 'wifi.monitor': 'en/modules/wifi_monitor.md' + - 'wps': 'en/modules/wps.md' + - 'ws2801': 'en/modules/ws2801.md' + - 'ws2812': 'en/modules/ws2812.md' + - 'ws2812-effects': 'en/modules/ws2812-effects.md' + - 'xpt2046': 'en/modules/xpt2046.md' From c708828bbe853764b9de58fb8113a70f5a24002d Mon Sep 17 00:00:00 2001 From: Bruno Vernay Date: Sun, 30 Sep 2018 19:28:43 +0200 Subject: [PATCH 09/14] Fix broken link to flashchips.h (#2499) --- docs/en/flash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/flash.md b/docs/en/flash.md index 7897624a36..4e5cb44b7b 100644 --- a/docs/en/flash.md +++ b/docs/en/flash.md @@ -126,6 +126,6 @@ Connecting... Manufacturer: e0 Device: 4016 ``` -The chip ID can then be looked up in [https://code.coreboot.org/p/flashrom/source/tree/HEAD/trunk/flashchips.h](https://code.coreboot.org/p/flashrom/source/tree/HEAD/trunk/flashchips.h). This leads to a manufacturer name and a chip model name/number e.g. `AMIC_A25LQ032`. That information can then be fed into your favorite search engine to find chip descriptions and data sheets. +The chip ID can then be looked up in [https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h](https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h). This leads to a manufacturer name and a chip model name/number e.g. `AMIC_A25LQ032`. That information can then be fed into your favorite search engine to find chip descriptions and data sheets. By convention the last two or three digits in the module name denote the capacity in megabits. So, `A25LQ032` in the example above is a 32Mb(=4MB) module. From 4095c408e6a8cc9718cb06007b408d0aad15d9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnim=20L=C3=A4uger?= Date: Wed, 24 Oct 2018 22:48:50 +0200 Subject: [PATCH 10/14] u8g2: include "large" fonts (#2531) --- app/u8g2lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/u8g2lib/Makefile b/app/u8g2lib/Makefile index 4e1fa79c9b..1343a949f5 100644 --- a/app/u8g2lib/Makefile +++ b/app/u8g2lib/Makefile @@ -24,7 +24,7 @@ STD_CFLAGS=-std=gnu11 -Wimplicit # makefile at its root level - these are then overridden # for a subtree within the makefile rooted therein # -DEFINES += -DU8X8_USE_PINS +DEFINES += -DU8X8_USE_PINS -DU8G2_USE_LARGE_FONTS ############################################################# # Recursion Magic - Don't touch this!! From c16adb5dfb8c02b692034bbd553502765b9733cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Fri, 7 Jun 2019 21:48:04 +0200 Subject: [PATCH 11/14] Integrate stale bot --- .github/stale.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000000..2f26275d71 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,18 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 730 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 14 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security + - governance +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false From 68c425c0451f72fcabb1b2d6d31a8555f087371b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Sun, 21 Jul 2019 08:46:49 +0200 Subject: [PATCH 12/14] Lower the stale threshold to 1y --- .github/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/stale.yml b/.github/stale.yml index 2f26275d71..dead686322 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,5 +1,5 @@ # Number of days of inactivity before an issue becomes stale -daysUntilStale: 730 +daysUntilStale: 360 # Number of days of inactivity before a stale issue is closed daysUntilClose: 14 # Issues with these labels will never be considered stale From 71a182caa7841cbb478ed90ede526dc881943c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20St=C3=B6r?= Date: Mon, 6 Jan 2020 14:09:24 +0100 Subject: [PATCH 13/14] Use new GitHub issue templates --- .github/ISSUE_TEMPLATE.md | 33 ----------------------- .github/ISSUE_TEMPLATE/bug_report.md | 24 +++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 17 ++++++++++++ .github/ISSUE_TEMPLATE/question.md | 16 +++++++++++ 4 files changed, 57 insertions(+), 33 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index c2032970bd..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,33 +0,0 @@ -Make sure you read and understand http://nodemcu.readthedocs.io/en/dev/en/support/. -Use one of the two templates below and **DELETE THE REST**. - -8<------------------------ BUG REPORT ----------------------------------------- -### Expected behavior - -### Actual behavior - -### Test code -Provide a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) which will reproduce the problem. -```Lua --- add code here -``` -### NodeMCU version -Which branch are you on? If you know the Git revision then add it here as well. - -### Hardware -Describe which ESP8266 device you use and document any special hardware setup -required to reproduce the problem. - -8<------------------------ END BUG REPORT ------------------------------------- - - -8<------------------------ FEATURE REQUEST ------------------------------------ -### Missing feature - -### Justification -Tell us why you would like to see this feature added. - -### Workarounds -Are there any workarounds you currently have in place because the feature is missing? - -8<------------------------ END FEATURE REQUEST -------------------------------- diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..0f1f4a347a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,24 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +### Expected behavior + +### Actual behavior + +### Test code +Provide a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) which will reproduce the problem. +```Lua +-- add code here +``` +### NodeMCU startup banner +You MUST include the firmware startup banner to describe the version you are using. We reserve the right to immediately close any bug that doesn't. + +### Hardware +Describe which ESP8266/ESP32 device you use and document any special hardware setup +required to reproduce the problem. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..516a5c98b1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +### Missing feature +See issue #1010 and note that we reserve the right to close feature requests if the originating poster is not proposing to resource the development him or herself. + +### Justification +Tell us why you would like to see this feature added. + +### Workarounds +Are there any workarounds you currently have in place because the feature is missing? diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000000..8c043611ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,16 @@ +--- +name: Question +about: Use Stack Overflow instead +title: "\U0001F649" +labels: '' +assignees: '' + +--- + +🛑 𝙎𝙏𝙊𝙋 + +This issue tracker is not the place for questions! + +If you want to ask how to do something, or to understand why something isn't working the way you expect it to, see https://nodemcu.readthedocs.io/en/latest/support/ + +We close all questions without reading them. \ No newline at end of file From 3d917850180f67adc7f2c6b5d00f27c152e7194c Mon Sep 17 00:00:00 2001 From: Edvinas Date: Sun, 23 Feb 2020 19:46:35 +0200 Subject: [PATCH 14/14] Bugfix conn metatable method call (#3012) Here `conn` is net.socket instance, so it should be called as one. Otherwise request is very likely to end up with crash and PANIC. --- lua_modules/http/httpserver.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua_modules/http/httpserver.lua b/lua_modules/http/httpserver.lua index ba2696036e..f2e0c48c6d 100644 --- a/lua_modules/http/httpserver.lua +++ b/lua_modules/http/httpserver.lua @@ -89,7 +89,7 @@ do local buf = "" local method, url local ondisconnect = function(conn) - conn.on("sent", nil) + conn:on("sent", nil) collectgarbage("collect") end -- header parser