Page 1 of 1

WS2801 led strip

Posted: 18 Jan 2016, 11:06
by Deennoo
As now we can great "dummy" rgbw switch on domoticz, does some one already work on a WS2801 led strip with Easyesp ?

Re: WS2801 led strip

Posted: 18 Jan 2016, 15:52
by Ger
I am using a ESP8266 with a own modified version of the following https://github.com/cnlohr/ws2812esp8266
This is not arduino code but with the own SDK
I don´t know what you want to do with a ws2812 ledstrip.
I use it with static colors.
At the moment I send a string of codes with UDP to the ESP8266, this string is also stored in flash making it possible to power on and off the ESP8266 and not losing the configuration.
The string I send is an array of max 64 times the following:
char color R(red),G(green),B(Blue),W(White),U(Off),A(On) White is RGB same level (char uses 2 bytes)
int16 startpos (lednumber to start this command)
int16 endpos (lednumber to end this command)
uint8 startval (starting value of the color specified at color)
int8 change (value to increment or decrement the value for the next led)

for example if I send the following string RR 10 15 0 10 will have the following result:
10th LED red value 0
11th LED red value 10
12th LED red value 20
13th LED red value 30
14th LED red value 40
15th LED red value 50

I would like to implement this with espeasy using a webpage to create the configuration, but I also need a place to store the configuration (512 bytes)

chrismelba on github.com is using a ws2812 led strip with arduino code for a clock

below is the changed code

#include "mem.h"
#include "c_types.h"
#include "user_interface.h"
#include "ets_sys.h"
#include "driver/uart.h"
#include "osapi.h"
#include "espconn.h"
#include "mystuff.h"
#include "spi_flash.h"

#define PORT 7777
#define SERVER_TIMEOUT 1000
#define MAX_CONNS 5
#define MAX_FRAME 2000

#define procTaskPrio 0
#define procTaskQueueLen 1


static volatile os_timer_t some_timer;
static struct espconn *pUdpServer;

typedef struct {
char color;
int16_t start_pos;
int16_t end_pos;
uint8_t start_val;
int8_t change_val;
} ledstrip_type;

typedef struct {
ledstrip_type L[63];
} led_type;

led_type led;

char outbuffer[900];
int16_t buflen = 0;

os_event_t procTaskQueue[procTaskQueueLen];
static void ICACHE_FLASH_ATTR procTask(os_event_t *events){
system_os_post(procTaskPrio, 0, 0 );
if( events->sig == 0 && events->par == 0 ){
//Idle Event.
}
}

//Timer event.
static void ICACHE_FLASH_ATTR myTimer(void *arg){
uart0_sendStr(".");
}


void ICACHE_FLASH_ATTR led_read(){
spi_flash_read(0x3D000, &led, sizeof(led_type));
}

//char color R G B W;
//int16_t start_pos;
//int16_t end_pos;
//uint8_t start_val;
//int8_t change_val;

static void ICACHE_FLASH_ATTR schrijfbuffer(){
ets_wdt_disable();
os_intr_lock();
WS2812OutBuffer( outbuffer, buflen );
os_intr_unlock();
}

static void ICACHE_FLASH_ATTR fillbuffer(int16_t start_pos, int16_t end_pos, uint8_t start_val, int8_t change_val, int8_t RGB_offset ){
uint16_t pos;
uint16_t buf;
int8_t waarde;
int16_t waarde16;
waarde16 = start_val;
if (end_pos > 300){
end_pos = 300;}
if (start_pos > 300){
start_pos = 300; }
if (end_pos < 1){
end_pos = 1;}
if (start_pos < 1){
start_pos = 1; }
if (end_pos < start_pos) {
for( pos = start_pos; pos >= end_pos; pos-- ) {
buf = pos + pos + pos + RGB_offset - 3;
if (waarde16 > 255){
waarde16 = 255;}
if (waarde16 < 0){
waarde16 = 0;}
waarde = waarde16;
outbuffer[buf] = waarde;
if (buf > buflen){
buflen = buf;}
waarde16 = waarde16 + change_val;
}
}
if (end_pos > start_pos){
for( pos = start_pos; pos <= end_pos; pos++ ){
buf = pos + pos + pos + RGB_offset - 3;
if (waarde16 > 255){
waarde16 = 255;}
if (waarde16 < 0){
waarde16 = 0;}
waarde = waarde16;
outbuffer[buf] = waarde;
if (buf > buflen){
buflen = buf;}
waarde16 = waarde16 + change_val;
}
}
if (end_pos == start_pos){
pos = start_pos;
buf = pos + pos + pos + RGB_offset - 3;
waarde = waarde16;
outbuffer[buf] = waarde;
if (buf > buflen){
buflen = buf;}
}
}

static void ICACHE_FLASH_ATTR showled(void){
uint8_t buffer[MAX_FRAME];
uint8_t L;
for (L = 0; L < 63; L++ ){
if (led.L[L].color == 'U'){
uart0_sendStr("Uit");
fillbuffer( 1, 300, 0, 0, 0);
fillbuffer( 1, 300, 0, 0, 1);
fillbuffer( 1, 300, 0, 0, 2);}
if (led.L[L].color == 'R'){
fillbuffer( led.L[L].start_pos, led.L[L].end_pos, led.L[L].start_val, led.L[L].change_val, 1);}
if (led.L[L].color == 'G'){
fillbuffer( led.L[L].start_pos, led.L[L].end_pos, led.L[L].start_val, led.L[L].change_val, 0);}
if (led.L[L].color == 'B'){
fillbuffer( led.L[L].start_pos, led.L[L].end_pos, led.L[L].start_val, led.L[L].change_val, 2);}
if (led.L[L].color == 'W'){
fillbuffer( led.L[L].start_pos, led.L[L].end_pos, led.L[L].start_val, led.L[L].change_val, 0);
fillbuffer( led.L[L].start_pos, led.L[L].end_pos, led.L[L].start_val, led.L[L].change_val, 1);
fillbuffer( led.L[L].start_pos, led.L[L].end_pos, led.L[L].start_val, led.L[L].change_val, 2);}
}
schrijfbuffer();
}

//Called when new packet comes in.
//udpserver_recv(void *arg, char *pusrdata, unsigned short len)
static void ICACHE_FLASH_ATTR udpserver_recv(void *arg, char *pusrdata, unsigned short len){
struct espconn *pespconn = (struct espconn *)arg;
//Make sure watchdog is disabled. WS2812's take a while and can mess it up.
// WS2812OutBuffer( pusrdata, len )
uint8_t buffer[MAX_FRAME];
char uit;
uit = *pusrdata;
switch (uit){
case 'A':{
uart0_sendStr("A Aan");
led_read();
showled();
break;}
case 'U':{
uart0_sendStr("U Uit");
fillbuffer( 1, 300, 0, 0, 0);
fillbuffer( 1, 300, 0, 0, 1);
fillbuffer( 1, 300, 0, 0, 2);
schrijfbuffer();
break;}
default:{
uart0_sendStr("Default");
ETS_UART_INTR_DISABLE();
spi_flash_erase_sector(0x3D);
spi_flash_write(0x3D000, pusrdata, len);
ETS_UART_INTR_ENABLE();
led_read();
showled();
break;}
}
}

void ICACHE_FLASH_ATTR at_recvTask(){
//Called from UART.
}

static volatile os_timer_t client_timer;

static void ICACHE_FLASH_ATTR wait_for_ip(uint8 flag) {
LOCAL struct ip_info ipconfig;
LOCAL int status;
os_timer_disarm(&client_timer);
status = wifi_station_get_connect_status();
if (status == STATION_GOT_IP) {
wifi_get_ip_info(STATION_IF, &ipconfig);
if( ipconfig.ip.addr != 0) {
//Start UDP server
httpd_init();
} else {
os_timer_setfn(&client_timer, (os_timer_func_t *)wait_for_ip, NULL);
os_timer_arm(&client_timer, 100, 0);
}
} else if (status == STATION_CONNECTING) {
os_timer_setfn(&client_timer, (os_timer_func_t *)wait_for_ip, NULL);
os_timer_arm(&client_timer, 100, 0);
} else { //STATION_NO_AP_FOUND||STATION_CONNECT_FAIL||STATION_WRONG_PASSWORD
//Connection failed, somehow :(
system_restart();
//Bring up SOFTAP here
}
}

static void ICACHE_FLASH_ATTR system_is_done(void){
//Bringing up WLAN
wifi_station_connect();
//Wait for connection
os_timer_disarm(&client_timer);
os_timer_setfn(&client_timer, (os_timer_func_t *)wait_for_ip, NULL);
os_timer_arm(&client_timer, 100, 0);
}

void user_init(void){
uart_init(BIT_RATE_115200, BIT_RATE_115200);
int wifiMode = wifi_get_opmode();
uart0_sendStr("\r\nCustom Server\r\n");
struct station_config stconf;
memset(&stconf, 0, sizeof(stconf));
strcpy((char *)stconf.ssid,"SSID");
strcpy((char *)stconf.password,"PASSWORD");
wifi_station_set_auto_connect(0);
if (wifi_get_opmode() != STATION_MODE) {
wifi_set_opmode(STATION_MODE); //station
os_delay_us(500);
system_restart(); }
wifi_station_set_config(&stconf);
wifi_station_set_auto_connect(1);
led_read();
pUdpServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
ets_memset( pUdpServer, 0, sizeof( struct espconn ) );
espconn_create( pUdpServer );
pUdpServer->type = ESPCONN_UDP;
pUdpServer->proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
pUdpServer->proto.udp->local_port = 7777;
espconn_regist_recvcb(pUdpServer, udpserver_recv);
if( espconn_create( pUdpServer )){
while(1) {
uart0_sendStr( "\r\nFAULT\r\n" ); }
}
ets_wdt_disable();
int16_t i;
for (i = 0; i < 900; i++){
outbuffer = 0;}
WS2812OutBuffer( outbuffer, 900 ); //Initialize the output.
system_os_task(procTask, procTaskPrio, procTaskQueue, procTaskQueueLen);
showled();
//Timer example
os_timer_disarm(&some_timer);
os_timer_setfn(&some_timer, (os_timer_func_t *)myTimer, NULL);
os_timer_arm(&some_timer, 500, 1);
system_os_post(procTaskPrio, 0, 0 );
}

Re: WS2801 led strip

Posted: 18 Jan 2016, 20:37
by Deennoo
Many thx for this, great solution for ws2812, unfortunaly i got ws2801who need clock pin

Re: WS2801 led strip

Posted: 25 Jan 2016, 11:28
by tozett
i made this a feature-request...
would like to see as ws2812b as a device, too.. :D
http://www.esp8266.nu/forum/viewtopic.p ... =165#p3395

Re: WS2801 led strip

Posted: 27 Jan 2016, 15:20
by costo
tozett wrote:i made this a feature-request...
would like to see as ws2812b as a device, too.. :D
http://www.esp8266.nu/forum/viewtopic.p ... =165#p3395
I do not believe adding the WS2812 RGB led family as a ESPEasy device is a feaseble goal.
Controlling the datastream for a string of WS2812 leds needs very tight timing.
WDT must be disabled to get this done.

I think any attempt to do a ESPEasy with WS2812 integration would be a cause for instabilities.

Suggestion:
It is probably more logical to use a arduino board as ProMiniExtender device which can run the FASTLED or NEOPIXEL library to do the time-ctitical streaming of the RBG data.
This program can run in the mainloop of a arduino-pro-mini while it is connected to ESPEasy as a I2C slave device and accepting simple commands, afterall you can send integer numbers over I2C which can be used to control the program, in some way, to steer the WS2812 stuff.

Re: WS2801 led strip

Posted: 27 Jan 2016, 16:13
by Martinus
We're running a Neo Pixel word clock based on ESP Easy (plugin 101) and that seems to work. But I have not done any long term tests.
(but a reboot would not hurt in this application anyway, time is updated once/minute and you won't notice a reboot...)

Re: WS2801 led strip

Posted: 27 Jan 2016, 17:52
by NietGiftig
costo wrote: I think any attempt to do a ESPEasy with WS2812 integration would be a cause for instabilities.

Suggestion:
It is probably more logical to use a arduino board as ProMiniExtender device which can run the FASTLED or NEOPIXEL library to do the time-ctitical streaming of the RBG data.
This program can run in the mainloop of a arduino-pro-mini while it is connected to ESPEasy as a I2C slave device and accepting simple commands, afterall you can send integer numbers over I2C which can be used to control the program, in some way, to steer the WS2812 stuff.
costo gives here a good advice
Special for Fastled, this lib is very tight for using interrupts.

But it is the best library for ws2812 etc, much possibility's

Re: WS2801 led strip

Posted: 27 Jan 2016, 18:42
by tozett
costo wrote: Suggestion:
It is probably more logical to use a arduino board as ProMiniExtender device which can run the FASTLED or NEOPIXEL library to do the time-ctitical streaming of the RBG data.
the way i thought it too, secretly :oops:
+1, it will give this a try, soon...

Re: WS2801 led strip

Posted: 27 Jan 2016, 20:36
by Ger
In the H801 thread is a ESP hue emulator mentioned for WS2812 https://github.com/sticilface/Esp8266-Hue
I am experimenting with this bridge and it is working.
As far as I can see there are a couple of issues:
Philips Hue has a maximum of 63 lamps, the bridge is working with 255 lamps, but the more lamps you use the slower it gets.
It is only working with the IOS Philips Hue apps.

Re: WS2801 led strip

Posted: 29 Jan 2016, 00:36
by Deennoo
Ger wrote:In the H801 thread is a ESP hue emulator mentioned for WS2812 https://github.com/sticilface/Esp8266-Hue
I am experimenting with this bridge and it is working.
As far as I can see there are a couple of issues:
Philips Hue has a maximum of 63 lamps, the bridge is working with 255 lamps, but the more lamps you use the slower it gets.
It is only working with the IOS Philips Hue apps.
You doesn't get a succes connection with Domoticz after IOS app connection ?

Re: WS2801 led strip

Posted: 29 Jan 2016, 13:51
by Ger
I have not tested it yet with Domoticz.
What I did mean was that I have not yet found a working Android app ;)
The ESP gives still the message failed to open lights.conf and groups.conf

Re: WS2801 led strip

Posted: 30 Jan 2016, 19:18
by Ger
I have the hue bridge working with Domoticz realy very nice. :)
Next thing I am going to try is to extend the maximum to 300 led's

Re: WS2801 led strip

Posted: 30 Jan 2016, 22:04
by Ger
The message with the conf files is also soved, I flashed them without SPIFFS, with SPIFFS no problem :D

Re: WS2801 led strip

Posted: 31 Jan 2016, 10:13
by Deennoo
Ger wrote:The message with the conf files is also soved, I flashed them without SPIFFS, with SPIFFS no problem :D
grrrrr my ws2812b led strip still not here.....

Re: WS2801 led strip

Posted: 26 Oct 2016, 21:29
by Dylantje
kick..
Someone have this working with the espeasy software?
Looking for a rgbw controller...
With a esp and with domoticz..

Re: WS2801 led strip

Posted: 27 Oct 2016, 23:31
by Ger
Deennoo wrote:
Ger wrote:In the H801 thread is a ESP hue emulator mentioned for WS2812 https://github.com/sticilface/Esp8266-Hue
I am experimenting with this bridge and it is working.
As far as I can see there are a couple of issues:
Philips Hue has a maximum of 63 lamps, the bridge is working with 255 lamps, but the more lamps you use the slower it gets.
It is only working with the IOS Philips Hue apps.
You doesn't get a succes connection with Domoticz after IOS app connection ?
Yes after that you can use Domoticz

Re: WS2801 led strip

Posted: 18 Nov 2016, 23:31
by Dylantje
WS2801 perhaps working on the esp?