Name: nodemcu-firmware-dali
Owner: stuttgart hackerspace
Description: lua based interactive firmware for mcu like esp8266 with a specific DALI flavour
Created: 2015-12-14 08:04:38.0
Updated: 2018-04-02 12:44:55.0
Pushed: 2016-02-06 22:55:21.0
Homepage: http://shackspace.de/wiki/doku.php?id=project:dali_nodemcu
Size: 87489
Language: C
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
«««< HEAD
| Resource | Location | | ————– | ————– | | Developer Wiki | https://github.com/nodemcu/nodemcu-firmware/wiki | | API docs | NodeMCU api | | Home | nodemcu.com | | BBS | Chinese BBS | | Docs | NodeMCU docs | | Tencent QQ group | 309957875 | | Windows flash tool | nodemcu-flasher | | Linux flash tool | Esptool | | ESPlorer GUI | https://github.com/4refr0nt/ESPlorer | | NodeMCU Studio GUI | https://github.com/nodemcu/nodemcu-studio-csharp |
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!
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
pin = 1
gpio.mode(pin, gpio.OUTPUT)
gpio.write(pin, gpio.HIGH)
print(gpio.read(pin))
-- 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")
-- A simple http server
srv=net.createServer(net.TCP)
srv:listen(80, function(conn)
conn:on("receive", function(conn,payload)
print(payload)
conn:send("<h1> Hello, NodeMCU.</h1>")
end)
conn:on("sent", function(conn) conn:close() end)
end)
nit mqtt client with keepalive timer 120sec
mqtt.Client("clientid", 120, "user", "password")
etup Last Will and Testament (optional)
roker will publish a message with qos = 0, retain = 0, data = "offline"
o topic "/lwt" if client doesn't send keepalive packet
t("/lwt", "offline", 0, 0)
("connect", function(con) print("connected") end)
("offline", function(con) print("offline") end)
n publish message receive event
("message", function(conn, topic, data)
int(topic .. ":")
data ~= nil then
print(data)
d
:connect(host, port, secure, auto_reconnect, function(client) end)
or secure: m:connect("192.168.11.118", 1880, 1, 0)
or auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1)
nnect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end)
ubscribe to topic with qos = 0
bscribe("/topic", 0, function(conn) print("subscribe success") end)
r subscribe multiple topics (topic/0, qos = 0; topic/1, qos = 1; topic2, qos = 2)
:subscribe({["topic/0"]=0,["topic/1"]=1,topic2=2}, function(conn) print("subscribe success") end)
ublish a message with data = hello, QoS = 0, retain = 0
blish("/topic", "hello", 0, 0, function(conn) print("sent") end)
ose(); -- if auto-reconnect == 1, it will disable auto-reconnect and then disconnect from host.
ou can call m:connect again
udp server
t.createServer(net.UDP)
("receive", function(s, c) print(c) end)
sten(5683)
udp client
et.createConnection(net.UDP)
n("receive", function(cu, c) print(c) end)
onnect(5683, "192.168.18.101")
end("hello")
nction led(r, g, b)
pwm.setduty(1, r)
pwm.setduty(2, g)
pwm.setduty(3, b)
d
m.setup(1, 500, 512)
m.setup(2, 500, 512)
m.setup(3, 500, 512)
m.start(1)
m.start(2)
m.start(3)
d(512, 0, 0) -- red
d(0, 0, 512) -- blue
ghton=0
r.alarm(1, 1000, 1, function()
if lighton==0 then
lighton=1
led(512, 512, 512)
else
lighton=0
led(0, 0, 0)
end
d)
init.lua will be executed
le.open("init.lua", "w")
le.writeline([[print("Hello, do this at the beginning.")]])
le.close()
de.restart() -- this will restart the module.
-- 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)
There are several options for building the NodeMCU firmware.
Please try Marcel's NodeMCU custom build 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).
See 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.
See BUILD OPTIONS below, to configure the firmware before building.
Assuming NodeMCU firmware is checked-out to /opt/nodemcu-firmware
:
clone --recursive https://github.com/pfalcon/esp-open-sdk.git /opt/esp-open-sdk
opt/esp-open-sdk
STANDALONE=y
=/opt/esp-open-sdk/xtensa-lx106-elf/bin:$PATH
opt/nodemcu-firmware
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.
app/include/user_modules.h
Comment-out the #define statement for unused modules. Example:
ef LUA_USE_MODULES
ine LUA_USE_MODULES_NODE
ine LUA_USE_MODULES_FILE
ine LUA_USE_MODULES_GPIO
ine LUA_USE_MODULES_WIFI
ine LUA_USE_MODULES_NET
ine LUA_USE_MODULES_PWM
ine LUA_USE_MODULES_I2C
ine LUA_USE_MODULES_SPI
ine LUA_USE_MODULES_TMR
ine LUA_USE_MODULES_ADC
ine LUA_USE_MODULES_UART
ine LUA_USE_MODULES_OW
ine LUA_USE_MODULES_BIT
ine 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
ine LUA_USE_MODULES_CRYPTO
ine LUA_USE_MODULES_RC
ine LUA_USE_MODULES_DHT
ine LUA_USE_MODULES_RTCMEM
ine LUA_USE_MODULES_RTCTIME
ine LUA_USE_MODULES_RTCFIFO
ine LUA_USE_MODULES_SNTP
define LUA_USE_MODULES_BMP085
ine LUA_USE_MODULES_TSL2561
define LUA_USE_MODULES_HX711
if /* LUA_USE_MODULES */
Identify your firmware builds by editing app/include/user_version.h
ine NODE_VERSION "NodeMCU 1.4.0+myname"
def BUILD_DATE
ine BUILD_DATE "YYYYMMDD"
if
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.:
ine BIT_RATE_DEFAULT BIT_RATE_115200
To enable runtime debug messages to serial console, edit app/include/user_config.h
ine DEVELOP_VERSION
DEVELOP_VERSION
changes the startup baud rate to 74880.
You can use the nodemcu-flasher to burn the firmware.
Esptool is a python utility which can read and write the flash in an ESP8266 device. See https://github.com/themadinventor/esptool
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 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.
If you got your firmware from NodeMCU custom builds then you can flash that file directly to address 0x00000.
Otherwise, if you built your own firmware from source code:
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.
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.
Victor Brutskiy's ESPlorer is written in Java, is open source and runs on most platforms such as Linux, Windows, Mac OS, etc.
NodeMCU Studio is written in C# and supports Windows. This software is open source and can write lua files to filesystem.
-- 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
u8glib is a graphics library with support for many different displays. The nodemcu firmware supports a subset of these. Both I2C and SPI:
SPI only:
U8glib v1.18.1
Hook up SDA and SCL to any free GPIOs. Eg. u8g_graphics_test.lua expects SDA=5 (GPIO14) and SCL=6 (GPIO12). They are used to set up nodemcu's I2C driver before accessing the display:
= 5
= 6
setup(0, sda, scl, i2c.SLOW)
The HSPI module is used, so certain pins are fixed:
All other pins can be assigned to any available GPIO:
Also refer to the initialization sequence eg in u8g_graphics_test.lua:
setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
The Lua bindings for this library closely follow u8glib's object oriented C++ API. Based on the u8g class, you create an object for your display type.
SSD1306 via I2C:
= 0x3c
= u8g.ssd1306_128x64_i2c(sla)
SSD1306 via SPI:
= 8 -- GPIO15, pull-down 10k to GND
= 4 -- GPIO2
= 0 -- GPIO16, RES is optional YMMV
= u8g.ssd1306_128x64_hw_spi(cs, dc, res)
This object provides all of u8glib's methods to control the display. Again, refer to u8g_graphics_test.lua to get an impression how this is achieved with Lua code. Visit the u8glib homepage for technical details.
I2C and HW SPI based displays with support in u8glib can be enabled. To get access to the respective constructors, add the desired entries to the I2C or SPI display tables in app/include/u8g_config.h:
ine U8G_DISPLAY_TABLE_I2C \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_i2c) \
ine U8G_DISPLAY_TABLE_SPI \
U8G_DISPLAY_TABLE_ENTRY(ssd1306_128x64_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcd8544_84x48_hw_spi) \
U8G_DISPLAY_TABLE_ENTRY(pcf8812_96x65_hw_spi) \
An exhaustive list of available displays can be found in the u8g module wiki entry.
u8glib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in app/include/u8g_config.h and recompile. Simply add the desired fonts to the font table:
ine U8G_FONT_TABLE \
U8G_FONT_TABLE_ENTRY(font_6x10) \
U8G_FONT_TABLE_ENTRY(font_chikita)
They'll be available as u8g.<font_name>
in Lua.
Bitmaps and XBMs are supplied as strings to drawBitmap()
and drawXBM()
. This off-loads all data handling from the u8g module to generic methods for binary files. See u8g_bitmaps.lua.
In contrast to the source code based inclusion of XBMs into u8glib, it's required to provide precompiled binary files. This can be performed online with Online-Utility's Image Converter: Convert from XBM to MONO format and upload the binary result with nodemcu-uploader.py.
Ucglib is a graphics library with support for color TFT displays.
Ucglib v1.3.3
The HSPI module is used, so certain pins are fixed:
All other pins can be assigned to any available GPIO:
Also refer to the initialization sequence eg in GraphicsTest.lua:
setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 8)
The Lua bindings for this library closely follow ucglib's object oriented C++ API. Based on the ucg class, you create an object for your display type.
ILI9341 via SPI:
= 8 -- GPIO15, pull-down 10k to GND
= 4 -- GPIO2
= 0 -- GPIO16, RES is optional YMMV
= ucg.ili9341_18x240x320_hw_spi(cs, dc, res)
This object provides all of ucglib's methods to control the display. Again, refer to GraphicsTest.lua to get an impression how this is achieved with Lua code. Visit the ucglib homepage for technical details.
To get access to the display constructors, add the desired entries to the display table in app/include/ucg_config.h:
ine UCG_DISPLAY_TABLE \
UCG_DISPLAY_TABLE_ENTRY(ili9341_18x240x320_hw_spi, ucg_dev_ili9341_18x240x320, ucg_ext_ili9341_18) \
UCG_DISPLAY_TABLE_ENTRY(st7735_18x128x160_hw_spi, ucg_dev_st7735_18x128x160, ucg_ext_st7735_18) \
ucglib comes with a wide range of fonts for small displays. Since they need to be compiled into the firmware image, you'd need to include them in app/include/ucg_config.h and recompile. Simply add the desired fonts to the font table:
ine UCG_FONT_TABLE \
UCG_FONT_TABLE_ENTRY(font_7x13B_tr) \
UCG_FONT_TABLE_ENTRY(font_helvB12_hr) \
UCG_FONT_TABLE_ENTRY(font_helvB18_hr) \
UCG_FONT_TABLE_ENTRY(font_ncenR12_tr) \
UCG_FONT_TABLE_ENTRY(font_ncenR14_hr)
They'll be available as ucg.<font_name>
in 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))
se copper addon for firefox
oap.Server()
isten(5683)
r=1
ar("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1
'[1,2,3]'
ar("all", coap.JSON) -- sets content type to json
unction should tack one string, return one string.
tion myfun(payload)
int("myfun called")
spond = "hello"
turn respond
unc("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun
coap.Client()
et(coap.CON, "coap://192.168.18.100:5683/.well-known/core")
ost(coap.NON, "coap://192.168.18.100:5683/", "Hello")
ote that when cjson deal with large content, it may fails a memory allocation, and leaks a bit of memory.
o it's better to detect that and schedule a restart.
ranslate Lua value to/from JSON
ext = cjson.encode(value)
alue = cjson.decode(text)
_text = '[ true, { "foo": "bar" } ]'
e = cjson.decode(json_text)
eturns: { true, { foo = "bar" } }
e = { true, { foo = "bar" } }
_text = cjson.encode(value)
eturns: '[true,{"foo":"bar"}]'
Note: currently only chanel A with gain 128 is supported. The HX711 is an inexpensive 24bit ADC with programmable 128x, 64x, and 32x gain.
-- 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)
Support DHT11, DHT21, DHT22, DHT33, DHT44, etc. Use all-in-one function to read DHT sensor.
= 5
us,temp,humi,temp_decimial,humi_decimial = dht.readxx(pin)
status == dht.OK ) then
Integer firmware using this example
int(
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
int("DHT Temperature:"..temp..";".."Humidity:"..humi)
if( status == dht.ERROR_CHECKSUM ) then
int( "DHT Checksum error." );
if( status == dht.ERROR_TIMEOUT ) then
int( "DHT Time out." );
=======
This repository is meant to provide an example for forking a repository on GitHub.
Creating a fork is producing a personal copy of someone else's project. Forks act as a sort of bridge between the original repository and your personal copy. You can submit Pull Requests to help make other people's projects better by offering your changes up to the original project. Forking is at the core of social coding at GitHub.
After forking this repository, you can make some changes to the project, and submit a Pull Request as practice.
For some more information on how to fork a repository, check out our guide, “Forking Projects””. Thanks! :sparkling_heart:
upstream/master