diff --git a/README.md b/README.md index 46fad96f..7f6ba7b0 100644 --- a/README.md +++ b/README.md @@ -1,543 +1,107 @@ # **NodeMCU 1.5.1** # -[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://img.shields.io/gitter/room/badges/shields.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) -[![Documentation Status](https://readthedocs.org/projects/nodemcu/badge/?version=newdocs)](http://nodemcu.readthedocs.org/en/newdocs/?badge=newdocs) +[![Documentation Status](https://readthedocs.org/projects/nodemcu/badge/?version=dev)](http://nodemcu.readthedocs.org/en/newdocs/?badge=dev) +[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://github.com/nodemcu/nodemcu-firmware/blob/master/LICENSE) -###A lua based firmware for wifi-soc esp8266 - - Build on [ESP8266 NONOS SDK 1.5.1](http://bbs.espressif.com/viewtopic.php?f=46&p=5315) - - Lua core based on [eLua project](http://www.eluaproject.net/) - - cjson based on [lua-cjson](https://github.com/mpx/lua-cjson) - - File system based on [spiffs](https://github.com/pellepl/spiffs) - - Open source development kit for NodeMCU [nodemcu-devkit-v0.9](https://github.com/nodemcu/nodemcu-devkit) [nodemcu-devkit-v1.0](https://github.com/nodemcu/nodemcu-devkit-v1.0) +### A Lua based firmware for ESP8266 WiFi SOC + +NodeMCU is an [eLua](http://www.eluaproject.net/) based firmware for the [ESP8266 WiFi SOC from Espressif](http://espressif.com/en/products/esp8266/). The firmware is based on the [Espressif NON-OS SDK 1.5.1](http://bbs.espressif.com/viewtopic.php?f=46&p=5315) and uses a file system based on [spiffs](https://github.com/pellepl/spiffs). The code repository consists of 98.1% C-code that glues the thin Lua veneer to the SDK. + +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. # Summary -- Easy to program wireless node and/or Access Point -- Based on Lua 5.1.4 (without *debug, os* module.) -- Event-driven programming model preferred -- Built-in modules: node, json, file, timer, pwm, i2c, spi, onewire, net, mqtt, coap, gpio, wifi, adc, uart, bit, u8g, ucg, ws2801, ws2812, crypto, dht, rtc, sntp, bmp085, tls2561, hx711 and system api. -- Both Integer (less memory usage) and Float version firmware provided. +- Easy to program wireless node and/or access point +- Based on Lua 5.1.4 (without *debug, os* modules) +- Asynchronous event-driven programming model +- 35+ [built-in modules](https://github.com/nodemcu/nodemcu-firmware/wiki/Module-list) +- Firmware available with or without floating point support (integer-only uses less memory) +- Up-to-date documentation at [https://nodemcu.readthedocs.org](https://nodemcu.readthedocs.org) -## Useful links +# Programming Model -| Resource | Location | -| -------------- | -------------- | -| Developer Wiki | https://github.com/nodemcu/nodemcu-firmware/wiki | -| API docs | [NodeMCU api](https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en) | -| Home | [nodemcu.com](http://www.nodemcu.com) | -| BBS | [Chinese BBS](http://bbs.nodemcu.com) | -| Docs | [NodeMCU docs](http://www.nodemcu.com/docs/) | -| Tencent QQ group | 309957875 | -| Windows flash tool | [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) | -| Linux flash tool | [Esptool](https://github.com/themadinventor/esptool) | -| ESPlorer GUI | https://github.com/4refr0nt/ESPlorer | -| NodeMCU Studio GUI | https://github.com/nodemcu/nodemcu-studio-csharp | - -# Programming Examples - -Because Lua is a high level language and several modules are built into the firmware, you can very easily program your ESP8266. Here are some examples! - -## Connect to your AP +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`](lua_examples) folder in the repository on GitHub. ```lua - ip = wifi.sta.getip() - print(ip) - --nil - wifi.setmode(wifi.STATION) - wifi.sta.config("SSID", "password") - ip = wifi.sta.getip() - print(ip) - --192.168.18.110 -``` - -## Manipulate hardware like an Arduino - -```lua - pin = 1 - gpio.mode(pin, gpio.OUTPUT) - gpio.write(pin, gpio.HIGH) - print(gpio.read(pin)) -``` - -## Write a network application in Node.js style - -```lua - -- A simple http client - conn=net.createConnection(net.TCP, 0) - conn:on("receive", function(conn, payload) print(payload) end) - conn:connect(80, "115.239.210.27") - conn:send("GET / HTTP/1.1\r\nHost: www.baidu.com\r\n" - .. "Connection: keep-alive\r\nAccept: */*\r\n\r\n") -``` - -## Or a simple HTTP server - -```lua - -- A simple http server - srv=net.createServer(net.TCP) - srv:listen(80, function(conn) - conn:on("receive", function(conn,payload) - print(payload) - conn:send("

Hello, NodeMCU.

") - end) - conn:on("sent", function(conn) conn:close() end) - end) -``` - -## Connect to MQTT broker - -```lua --- init mqtt client with keepalive timer 120sec -m = mqtt.Client("clientid", 120, "user", "password") - --- setup Last Will and Testament (optional) --- Broker will publish a message with qos = 0, retain = 0, data = "offline" --- to topic "/lwt" if client doesn't send keepalive packet -m:lwt("/lwt", "offline", 0, 0) - -m:on("connect", function(con) print("connected") end) -m:on("offline", function(con) print("offline") end) - --- on publish message receive event -m:on("message", function(conn, topic, data) - print(topic .. ":") - if data ~= nil then - print(data) - end +-- a simple HTTP server +srv = net.createServer(net.TCP) +srv:listen(80, function(conn) + conn:on("receive", function(conn, payload) + print(payload) + conn:send("

Hello, NodeMCU.

") + end) + conn:on("sent", function(conn) conn:close() end) end) - --- m:connect(host, port, secure, auto_reconnect, function(client) end) --- for secure: m:connect("192.168.11.118", 1880, 1, 0) --- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1) -m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end) - --- subscribe to topic with qos = 0 -m:subscribe("/topic", 0, function(conn) print("subscribe success") end) --- or subscribe multiple topics (topic/0, qos = 0; topic/1, qos = 1; topic2, qos = 2) --- m:subscribe({["topic/0"]=0,["topic/1"]=1,topic2=2}, function(conn) print("subscribe success") end) --- publish a message with data = hello, QoS = 0, retain = 0 -m:publish("/topic", "hello", 0, 0, function(conn) print("sent") end) - -m:close(); -- if auto-reconnect == 1, it will disable auto-reconnect and then disconnect from host. --- you can call m:connect again - ``` - -## UDP client and server - ```lua --- a udp server -s=net.createServer(net.UDP) -s:on("receive", function(s, c) print(c) end) -s:listen(5683) - --- a udp client -cu=net.createConnection(net.UDP) -cu:on("receive", function(cu, c) print(c) end) -cu:connect(5683, "192.168.18.101") -cu:send("hello") +-- connect to WiFi access point +wifi.setmode(wifi.STATION) +wifi.sta.config("SSID", "password") ``` -## Do something shiny with an RGB LED +# Documentation -```lua - function led(r, g, b) - pwm.setduty(1, r) - pwm.setduty(2, g) - pwm.setduty(3, b) - end - pwm.setup(1, 500, 512) - pwm.setup(2, 500, 512) - pwm.setup(3, 500, 512) - pwm.start(1) - pwm.start(2) - pwm.start(3) - led(512, 0, 0) -- red - led(0, 0, 512) -- blue -``` +The entire [NodeMCU documentation](https://nodemcu.readthedocs.org) is maintained right in this repository at [/docs](docs). The fact that the API documentation is mainted in the same repository as the code that *provides* the API ensures consistency between the two. With every commit the documentation is rebuilt by Read the Docs and thus transformed from terse Markdown into a nicely browsable HTML site at [https://nodemcu.readthedocs.org](https://nodemcu.readthedocs.org). -## And blink it +- How to [build the firmware](https://nodemcu.readthedocs.org/en/dev/en/build/) +- How to [flash the firmware](https://nodemcu.readthedocs.org/en/dev/en/flash/) +- How to [upload code and NodeMCU IDEs](https://nodemcu.readthedocs.org/en/dev/en/upload/) +- API documentation for every module -```lua - lighton=0 - tmr.alarm(1, 1000, 1, function() - if lighton==0 then - lighton=1 - led(512, 512, 512) - else - lighton=0 - led(0, 0, 0) - end - end) -``` +# Support -## If you want to run something when the system boots +See [https://nodemcu.readthedocs.org/en/dev/en/support/](https://nodemcu.readthedocs.org/en/dev/en/support/). -```lua - --init.lua will be executed - file.open("init.lua", "w") - file.writeline([[print("Hello, do this at the beginning.")]]) - file.close() - node.restart() -- this will restart the module. -``` +# License -## Add a simple telnet server to the Lua interpreter +[MIT](https://github.com/nodemcu/nodemcu-firmware/blob/master/LICENSE) © [zeroday](https://github.com/NodeMCU)/[nodemcu.com](http://nodemcu.com/index_en.html) -```lua - -- a simple telnet server - s=net.createServer(net.TCP, 180) - s:listen(2323, function(c) - function s_output(str) - if(c~=nil) - then c:send(str) - end - end - node.output(s_output, 0) -- re-direct output to function s_ouput. - c:on("receive", function(c, l) - node.input(l) -- works like pcall(loadstring(l)) but support multiples separate lines - end) - c:on("disconnection", function(c) - node.output(nil) -- un-register the redirect output function, output goes to serial - end) - print("Welcome to NodeMCU world.") - end) -``` +# Build Options -# Building the firmware +The following sections explain some of the options you have if you want to [build your own NodeMCU firmware](http://nodemcu.readthedocs.org/en/dev/en/build/). -There are several options for building the NodeMCU firmware. +### Select Modules -## Online firmware custom build +Disable modules you won't be using to reduce firmware size and free up some RAM. The ESP8266 is quite limited in available RAM and running out of memory can cause a system panic. -Please try Marcel's [NodeMCU custom build](http://nodemcu-build.com) cloud service and you can choose only the modules you need, and download the firmware once built. - -NodeMCU custom builds can build from all active branches (with the latest fixes). - -## Docker containerised build - -See [https://hub.docker.com/r/marcelstoer/nodemcu-build/](https://hub.docker.com/r/marcelstoer/nodemcu-build/) - -This Docker image includes the build toolchain and SDK. You just run the Docker image with your checked-out NodeMCU firmware repository (this one). - -You will need to see BUILD OPTIONS below, to configure the firmware before building. - -## Build it yourself - -See BUILD OPTIONS below, to configure the firmware before building. - -### Minimum requirements: - - - unrar - - GNU autoconf, automake, libtool - - GNU gcc, g++, make - - GNU flex, bison, gawk, sed - - python, python-serial, libexpat-dev - - srecord - - The esp-open-sdk from https://github.com/pfalcon/esp-open-sdk - -### Build instructions: - -Assuming NodeMCU firmware is checked-out to `/opt/nodemcu-firmware`: - -```sh -git clone --recursive https://github.com/pfalcon/esp-open-sdk.git /opt/esp-open-sdk -cd /opt/esp-open-sdk -make STANDALONE=y -PATH=/opt/esp-open-sdk/xtensa-lx106-elf/bin:$PATH -cd /opt/nodemcu-firmware -make -``` - -# BUILD OPTIONS - -Disable modules you won't be using, to reduce firmware size on flash and -free more RAM. The ESP8266 is quite limited in available RAM, and running -out can cause a system panic. - -## Edit `app/include/user_modules.h` - -Comment-out the #define statement for unused modules. Example: +Edit `app/include/user_modules.h` and comment-out the `#define` statement for modules you don't need. Example: ```c -#ifdef LUA_USE_MODULES -#define LUA_USE_MODULES_NODE -#define LUA_USE_MODULES_FILE -#define LUA_USE_MODULES_GPIO -#define LUA_USE_MODULES_WIFI -#define LUA_USE_MODULES_NET -#define LUA_USE_MODULES_PWM -#define LUA_USE_MODULES_I2C -#define LUA_USE_MODULES_SPI -#define LUA_USE_MODULES_TMR -#define LUA_USE_MODULES_ADC -#define LUA_USE_MODULES_UART -#define LUA_USE_MODULES_OW -#define LUA_USE_MODULES_BIT +... #define LUA_USE_MODULES_MQTT // #define LUA_USE_MODULES_COAP // #define LUA_USE_MODULES_U8G -// #define LUA_USE_MODULES_WS2801 -// #define LUA_USE_MODULES_WS2812 -// #define LUA_USE_MODULES_CJSON -#define LUA_USE_MODULES_CRYPTO -#define LUA_USE_MODULES_RC -#define LUA_USE_MODULES_DHT -#define LUA_USE_MODULES_RTCMEM -#define LUA_USE_MODULES_RTCTIME -#define LUA_USE_MODULES_RTCFIFO -#define LUA_USE_MODULES_SNTP -// #define LUA_USE_MODULES_BMP085 -#define LUA_USE_MODULES_TSL2561 -// #define LUA_USE_MODULES_HX711 -#define LUA_USE_MODULES_HTTP - -#endif /* LUA_USE_MODULES */ +... ``` -## Tagging your build +### Tag Your Build Identify your firmware builds by editing `app/include/user_version.h` ```c #define NODE_VERSION "NodeMCU 1.5.1+myname" #ifndef BUILD_DATE -#define BUILD_DATE "YYYYMMDD" +#define BUILD_DATE "YYYYMMDD" #endif ``` -## Setting the boot time serial interface rate +### Set UART Bit Rate -The initial baud rate at boot time is 9600 bps, but you can change this by -editing `app/include/user_config.h` and change BIT_RATE_DEFAULT, e.g.: +The initial baud rate at boot time is 9600bps. You can change this by +editing `BIT_RATE_DEFAULT` in `app/include/user_config.h`: ```c #define BIT_RATE_DEFAULT BIT_RATE_115200 ``` -## Debugging +### Debugging -To enable runtime debug messages to serial console, edit `app/include/user_config.h` +To enable runtime debug messages to serial console edit `app/include/user_config.h` ```c #define DEVELOP_VERSION ``` -`DEVELOP_VERSION` changes the startup baud rate to 74880. - -# Flash the firmware - -## Flash tools for Windows - -You can use the [nodemcu-flasher](https://github.com/nodemcu/nodemcu-flasher) to burn the firmware. - -## Flash tools for Linux - -Esptool is a python utility which can read and write the flash in an ESP8266 device. See https://github.com/themadinventor/esptool - -## Preparing the hardware for firmware upgrade - -To enable ESP8266 firmware flashing, the GPIO0 pin must be pulled low before -the device is reset. Conversely, for a normal boot, GPIO0 must be pulled high -or floating. - -If you have a [NodeMCU Development Kit](http://www.nodemcu.com/index_en.html) then -you don't need to do anything, as the USB connection can pull GPIO0 -low by asserting DTR, and reset your board by asserting RTS. - -If you have an ESP-01 or other device without inbuilt USB, you will need to -enable flashing yourself by pulling GPIO0 low or pressing a "flash" switch. - -## Files to burn to the flash - -If you got your firmware from [NodeMCU custom builds](http://nodemcu-build.com) then you can flash that file directly to address 0x00000. - -Otherwise, if you built your own firmware from source code: - - bin/0x00000.bin to 0x00000 - - bin/0x10000.bin to 0x10000 - -Also, in some special circumstances, you may need to flash `blank.bin` or `esp_init_data_default.bin` to various addresses on the flash (depending on flash size and type). - -If upgrading from `spiffs` version 0.3.2 to 0.3.3 or later, or after flashing any new firmware (particularly one with a much different size), you may need to run `file.format()` to re-format your flash filesystem. -You will know if you need to do this because your flash files disappeared, or they exist but seem empty, or data cannot be written to new files. - -# Connecting to your NodeMCU device - -NodeMCU serial interface uses 9600 baud at boot time. To increase the speed after booting, issue `uart.setup(0,115200,8,0,1,1)` (ESPlorer will do this automatically when changing the speed in the dropdown list). - -If the device panics and resets at any time, errors will be written to the serial interface at 115200 bps. - -# User Interface tools - -## ESPlorer - -Victor Brutskiy's [ESPlorer](https://github.com/4refr0nt/ESPlorer) is written in Java, is open source and runs on most platforms such as Linux, Windows, Mac OS, etc. - -#### Features - - - Edit Lua scripts and run on the ESP8266 and save to its flash - - Serial console log - - Also supports original AT firmware (reading and setting WiFi modes, etc) - -## NodeMCU Studio - -[NodeMCU Studio](https://github.com/nodemcu/nodemcu-studio-csharp) is written in C# and supports Windows. This software is open source and can write lua files to filesystem. - -# OPTIONAL MODULES - -####Use DS18B20 module extends your esp8266 -```lua - -- read temperature with DS18B20 - node.compile("ds18b20.lua") -- run this only once to compile and save to "ds18b20.lc" - t=require("ds18b20") - t.setup(9) - addrs=t.addrs() - -- Total DS18B20 numbers, assume it is 2 - print(table.getn(addrs)) - -- The first DS18B20 - print(t.read(addrs[1],t.C)) - print(t.read(addrs[1],t.F)) - print(t.read(addrs[1],t.K)) - -- The second DS18B20 - print(t.read(addrs[2],t.C)) - print(t.read(addrs[2],t.F)) - print(t.read(addrs[2],t.K)) - -- Just read - print(t.read()) - -- Just read as centigrade - print(t.read(nil,t.C)) - -- Don't forget to release it after use - t = nil - ds18b20 = nil - package.loaded["ds18b20"]=nil -``` - -####Control a WS2812 based light strip -```lua - -- set the color of one LED on GPIO2 to red - ws2812.writergb(4, string.char(255, 0, 0)) - -- set the color of 10 LEDs on GPIO0 to blue - ws2812.writergb(3, string.char(0, 0, 255):rep(10)) - -- first LED green, second LED white - ws2812.writergb(4, string.char(0, 255, 0, 255, 255, 255)) -``` - -####coap client and server -```lua --- use copper addon for firefox -cs=coap.Server() -cs:listen(5683) - -myvar=1 -cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1 - -all='[1,2,3]' -cs:var("all", coap.JSON) -- sets content type to json - --- function should tack one string, return one string. -function myfun(payload) - print("myfun called") - respond = "hello" - return respond -end -cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun - -cc = coap.Client() -cc:get(coap.CON, "coap://192.168.18.100:5683/.well-known/core") -cc:post(coap.NON, "coap://192.168.18.100:5683/", "Hello") -``` - -####cjson -```lua --- Note that when cjson deal with large content, it may fails a memory allocation, and leaks a bit of memory. --- so it's better to detect that and schedule a restart. --- --- Translate Lua value to/from JSON --- text = cjson.encode(value) --- value = cjson.decode(text) -json_text = '[ true, { "foo": "bar" } ]' -value = cjson.decode(json_text) --- Returns: { true, { foo = "bar" } } -value = { true, { foo = "bar" } } -json_text = cjson.encode(value) --- Returns: '[true,{"foo":"bar"}]' -``` - -####HTTP client -```lua --- Support HTTP and HTTPS, For example --- HTTP POST Example with JSON header and body -http.post("http://somewhere.acceptjson.com/", - "Content-Type: application/json\r\n", - "{\"hello\":\"world\"}", - function(code, data) - print(code) - print(data) - end) --- HTTPS GET Example with NULL header -http.get("https://www.vowstar.com/nodemcu/","", - function(code, data) - print(code) - print(data) - end) --- You will get --- > 200 --- hello nodemcu --- HTTPS DELETE Example with NULL header and body -http.delete("https://10.0.0.2:443","","", - function(code, data) - print(code) - print(data) - end) --- HTTPS PUT Example with NULL header and body -http.put("https://testput.somewhere/somewhereyouput.php","","", - function(code, data) - print(code) - print(data) - end) --- HTTP RAW Request Example, use more HTTP/HTTPS request method -http.request("http://www.apple.com:80/library/test/success.html","GET","","", - function(code, data) - print(code) - print(data) - end) - -``` - -####Read an HX711 load cell ADC. -Note: currently only chanel A with gain 128 is supported. -The HX711 is an inexpensive 24bit ADC with programmable 128x, 64x, and 32x gain. -```lua - -- Initialize the hx711 with clk on pin 5 and data on pin 6 - hx711.init(5,6) - -- Read ch A with 128 gain. - raw_data = hx711.read(0) -``` - -####Universal DHT Sensor support -Support DHT11, DHT21, DHT22, DHT33, DHT44, etc. -Use all-in-one function to read DHT sensor. -```lua - -pin = 5 -status,temp,humi,temp_decimial,humi_decimial = dht.readxx(pin) -if( status == dht.OK ) then - -- Integer firmware using this example - print( - string.format( - "DHT Temperature:%d.%03d;Humidity:%d.%03d\r\n", - math.floor(temp), - temp_decimial, - math.floor(humi), - humi_decimial - ) - ) - -- Float firmware using this example - print("DHT Temperature:"..temp..";".."Humidity:"..humi) -elseif( status == dht.ERROR_CHECKSUM ) then - print( "DHT Checksum error." ); -elseif( status == dht.ERROR_TIMEOUT ) then - print( "DHT Time out." ); -end - -``` +`DEVELOP_VERSION` changes the startup baud rate to 74880bps. \ No newline at end of file