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:
Markus Gritsch 2015-03-03 14:51:49 +01:00
commit 484dbf2683
4 changed files with 86 additions and 81 deletions

View File

@ -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))
```

View File

@ -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.

View File

@ -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

View File

@ -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;
}
// ----------------------------------------------------------------------------