Changed the ws2812 byte order from GRB to RGB
There seems to be interest in using the more intuitive RGB byte order to specify the LED color. Also fixed the documentation.
This commit is contained in:
commit
484dbf2683
96
README.md
96
README.md
|
@ -156,7 +156,7 @@ baudrate:9600
|
|||
```
|
||||
|
||||
####Manipulate hardware like a arduino
|
||||
|
||||
|
||||
```lua
|
||||
pin = 1
|
||||
gpio.mode(pin,gpio.OUTPUT)
|
||||
|
@ -165,10 +165,10 @@ baudrate:9600
|
|||
```
|
||||
|
||||
####Write network application in nodejs style
|
||||
|
||||
|
||||
```lua
|
||||
-- A simple http client
|
||||
conn=net.createConnection(net.TCP, 0)
|
||||
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"
|
||||
|
@ -176,15 +176,15 @@ baudrate:9600
|
|||
```
|
||||
|
||||
####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)
|
||||
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)
|
||||
end)
|
||||
conn:on("sent",function(conn) conn:close() end)
|
||||
end)
|
||||
```
|
||||
|
@ -196,7 +196,7 @@ baudrate:9600
|
|||
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"
|
||||
-- Broker will publish a message with qos = 0, retain = 0, data = "offline"
|
||||
-- to topic "/lwt" if client don't send keepalive packet
|
||||
m:lwt("/lwt", "offline", 0, 0)
|
||||
|
||||
|
@ -204,8 +204,8 @@ 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 .. ":" )
|
||||
m:on("message", function(conn, topic, data)
|
||||
print(topic .. ":" )
|
||||
if data ~= nil then
|
||||
print(data)
|
||||
end
|
||||
|
@ -229,29 +229,29 @@ m:close();
|
|||
#### UDP client and server
|
||||
```lua
|
||||
-- a udp server
|
||||
s=net.createServer(net.UDP)
|
||||
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=net.createConnection(net.UDP)
|
||||
cu:on("receive",function(cu,c) print(c) end)
|
||||
cu:connect(5683,"192.168.18.101")
|
||||
cu:send("hello")
|
||||
```
|
||||
|
||||
####Do something shining
|
||||
```lua
|
||||
function led(r,g,b)
|
||||
pwm.setduty(1,r)
|
||||
pwm.setduty(2,g)
|
||||
pwm.setduty(3,b)
|
||||
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(1,500,512)
|
||||
pwm.setup(2,500,512)
|
||||
pwm.setup(3,500,512)
|
||||
pwm.start(1)
|
||||
pwm.start(2)
|
||||
pwm.start(1)
|
||||
pwm.start(2)
|
||||
pwm.start(3)
|
||||
led(512,0,0) -- red
|
||||
led(0,0,512) -- blue
|
||||
|
@ -261,13 +261,13 @@ cu:send("hello")
|
|||
```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
|
||||
if lighton==0 then
|
||||
lighton=1
|
||||
led(512,512,512)
|
||||
else
|
||||
lighton=0
|
||||
led(0,0,0)
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
|
@ -283,20 +283,20 @@ cu:send("hello")
|
|||
####With below code, you can telnet to your esp8266 now
|
||||
```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
|
||||
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)
|
||||
c:on("receive",function(c,l)
|
||||
node.input(l) -- works like pcall(loadstring(l)) but support multiple separate line
|
||||
end)
|
||||
c:on("disconnection",function(c)
|
||||
end)
|
||||
c:on("disconnection",function(c)
|
||||
node.output(nil) -- un-regist the redirect output function, output goes to serial
|
||||
end)
|
||||
end)
|
||||
print("Welcome to NodeMcu world.")
|
||||
end)
|
||||
```
|
||||
|
@ -325,7 +325,7 @@ cu:send("hello")
|
|||
-- Don't forget to release it after use
|
||||
t = nil
|
||||
ds18b20 = nil
|
||||
package.loaded["ds18b20"]=nil
|
||||
package.loaded["ds18b20"]=nil
|
||||
```
|
||||
|
||||
####Operate a display via I2c with u8glib
|
||||
|
@ -382,10 +382,10 @@ They'll be available as `u8g.<font_name>` in Lua.
|
|||
|
||||
####Control a WS2812 based light strip
|
||||
```lua
|
||||
-- set the color of one LED on GPIO 2 to red
|
||||
ws2812.write(4, string.char(0, 255, 0))
|
||||
-- set the color of 10 LEDs on GPIO 0 to blue
|
||||
ws2812.write(3, string.char(0, 0, 255):rep(10))
|
||||
-- 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.write(4, string.char(255, 0, 0, 255, 255, 255))
|
||||
ws2812.writergb(4, string.char(0, 255, 0, 255, 255, 255))
|
||||
```
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
#define LUA_USE_MODULES_BIT
|
||||
#define LUA_USE_MODULES_U8G
|
||||
#define LUA_USE_MODULES_MQTT
|
||||
// #define LUA_USE_MODULES_WS2812 // TODO: put this device specific module to device driver section.
|
||||
#define LUA_USE_MODULES_WS2812 // TODO: put this device specific module to device driver section.
|
||||
#endif /* LUA_USE_MODULES */
|
||||
|
||||
// TODO: put device specific module to device driver section.
|
||||
|
|
|
@ -128,18 +128,17 @@
|
|||
#if defined(LUA_USE_MODULES_WS2812)
|
||||
#define MODULES_WS2812 "ws2812"
|
||||
#define ROM_MODULES_WS2812 \
|
||||
_ROM(MODULES_WS2812, luaopen_ws2812, ws2812_map)
|
||||
_ROM(MODULES_WS2812, luaopen_ws2812, ws2812_map)
|
||||
#else
|
||||
#define ROM_MODULES_WS2812
|
||||
#endif
|
||||
|
||||
|
||||
#define LUA_MODULES_ROM \
|
||||
#define LUA_MODULES_ROM \
|
||||
ROM_MODULES_GPIO \
|
||||
ROM_MODULES_PWM \
|
||||
ROM_MODULES_WIFI \
|
||||
ROM_MODULES_PWM \
|
||||
ROM_MODULES_WIFI \
|
||||
ROM_MODULES_MQTT \
|
||||
ROM_MODULES_U8G \
|
||||
ROM_MODULES_I2C \
|
||||
ROM_MODULES_SPI \
|
||||
ROM_MODULES_TMR \
|
||||
|
@ -149,8 +148,8 @@
|
|||
ROM_MODULES_ADC \
|
||||
ROM_MODULES_UART \
|
||||
ROM_MODULES_OW \
|
||||
ROM_MODULES_BIT \
|
||||
ROM_MODULES_WS2812
|
||||
ROM_MODULES_BIT \
|
||||
ROM_MODULES_WS2812
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,47 +8,56 @@
|
|||
* from user Markus Gritsch.
|
||||
* I just put this code into its own module and pushed into a forked repo,
|
||||
* to easily create a pull request. Thanks to Markus Gritsch for the code.
|
||||
*
|
||||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// -- This WS2812 code must be compiled with -O2 to get the timing right.
|
||||
// -- This WS2812 code must be compiled with -O2 to get the timing right. Read this:
|
||||
// -- http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/
|
||||
// The ICACHE_FLASH_ATTR is there to trick the compiler and get the very first pulse width correct.
|
||||
// -- The ICACHE_FLASH_ATTR is there to trick the compiler and get the very first pulse width correct.
|
||||
static void ICACHE_FLASH_ATTR send_ws_0(uint8_t gpio) {
|
||||
uint8_t i;
|
||||
i = 4;
|
||||
while (i--)
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio);
|
||||
i = 9;
|
||||
while (i--)
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio);
|
||||
i = 4; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio);
|
||||
i = 9; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio);
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR send_ws_1(uint8_t gpio) {
|
||||
uint8_t i;
|
||||
i = 8;
|
||||
while (i--)
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio);
|
||||
i = 6;
|
||||
while (i--)
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio);
|
||||
i = 8; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, 1 << gpio);
|
||||
i = 6; while (i--) GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, 1 << gpio);
|
||||
}
|
||||
|
||||
// Lua: ws2812.write(pin, "string")
|
||||
// Byte triples in the string are interpreted as G R B values.
|
||||
// ws2812.write(4, string.char(0, 255, 0)) uses GPIO2 and sets the first LED red.
|
||||
// Byte triples in the string are interpreted as R G B values and sent to the hardware as G R B.
|
||||
// ws2812.write(4, string.char(255, 0, 0)) uses GPIO2 and sets the first LED red.
|
||||
// ws2812.write(3, string.char(0, 0, 255):rep(10)) uses GPIO0 and sets ten LEDs blue.
|
||||
// ws2812.write(4, string.char(255, 0, 0, 255, 255, 255)) first LED green, second LED white.
|
||||
static int ICACHE_FLASH_ATTR ws2812_write(lua_State* L) {
|
||||
// ws2812.write(4, string.char(0, 255, 0, 255, 255, 255)) first LED green, second LED white.
|
||||
static int ICACHE_FLASH_ATTR ws2812_writergb(lua_State* L)
|
||||
{
|
||||
const uint8_t pin = luaL_checkinteger(L, 1);
|
||||
size_t length;
|
||||
const char *buffer = luaL_checklstring(L, 2, &length);
|
||||
char *buffer = (char *)luaL_checklstring(L, 2, &length); // Cast away the constness.
|
||||
|
||||
// Initialize the output pin:
|
||||
platform_gpio_mode(pin, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT);
|
||||
platform_gpio_write(pin, 0);
|
||||
os_delay_us(10);
|
||||
|
||||
// Ignore incomplete Byte triples at the end of buffer:
|
||||
length -= length % 3;
|
||||
|
||||
// Rearrange R G B values to G R B order needed by WS2812 LEDs:
|
||||
size_t i;
|
||||
for (i = 0; i < length; i += 3) {
|
||||
const char r = buffer[i];
|
||||
const char g = buffer[i + 1];
|
||||
buffer[i] = g;
|
||||
buffer[i + 1] = r;
|
||||
}
|
||||
|
||||
// Do not remove these:
|
||||
os_delay_us(1);
|
||||
os_delay_us(1);
|
||||
|
||||
// Send the buffer:
|
||||
os_intr_lock();
|
||||
const char * const end = buffer + length;
|
||||
while (buffer != end) {
|
||||
|
@ -68,7 +77,7 @@ static int ICACHE_FLASH_ATTR ws2812_write(lua_State* L) {
|
|||
#include "lrodefs.h"
|
||||
const LUA_REG_TYPE ws2812_map[] =
|
||||
{
|
||||
{ LSTRKEY( "write" ), LFUNCVAL( ws2812_write )},
|
||||
{ LSTRKEY( "writergb" ), LFUNCVAL( ws2812_writergb )},
|
||||
{ LNILKEY, LNILVAL}
|
||||
};
|
||||
|
||||
|
@ -77,6 +86,3 @@ LUALIB_API int luaopen_ws2812(lua_State *L) {
|
|||
LREGISTER(L, "ws2812", ws2812_map);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue