WS2801 led strip

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
Deennoo
Normal user
Posts: 158
Joined: 07 Sep 2015, 13:03

WS2801 led strip

#1 Post by Deennoo » 18 Jan 2016, 11:06

As now we can great "dummy" rgbw switch on domoticz, does some one already work on a WS2801 led strip with Easyesp ?

Ger
Normal user
Posts: 71
Joined: 05 Sep 2015, 18:09

Re: WS2801 led strip

#2 Post by Ger » 18 Jan 2016, 15:52

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 );
}

Deennoo
Normal user
Posts: 158
Joined: 07 Sep 2015, 13:03

Re: WS2801 led strip

#3 Post by Deennoo » 18 Jan 2016, 20:37

Many thx for this, great solution for ws2812, unfortunaly i got ws2801who need clock pin

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: WS2801 led strip

#4 Post by tozett » 25 Jan 2016, 11:28

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

User avatar
costo
Normal user
Posts: 500
Joined: 21 Nov 2015, 15:03
Location: NL, zw-NB

Re: WS2801 led strip

#5 Post by costo » 27 Jan 2016, 15:20

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.

Martinus

Re: WS2801 led strip

#6 Post by Martinus » 27 Jan 2016, 16:13

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

NietGiftig
Normal user
Posts: 103
Joined: 16 Sep 2015, 20:32

Re: WS2801 led strip

#7 Post by NietGiftig » 27 Jan 2016, 17:52

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

tozett
Normal user
Posts: 734
Joined: 22 Dec 2015, 15:46
Location: Germany

Re: WS2801 led strip

#8 Post by tozett » 27 Jan 2016, 18:42

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

Ger
Normal user
Posts: 71
Joined: 05 Sep 2015, 18:09

Re: WS2801 led strip

#9 Post by Ger » 27 Jan 2016, 20:36

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.

Deennoo
Normal user
Posts: 158
Joined: 07 Sep 2015, 13:03

Re: WS2801 led strip

#10 Post by Deennoo » 29 Jan 2016, 00:36

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 ?

Ger
Normal user
Posts: 71
Joined: 05 Sep 2015, 18:09

Re: WS2801 led strip

#11 Post by Ger » 29 Jan 2016, 13:51

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

Ger
Normal user
Posts: 71
Joined: 05 Sep 2015, 18:09

Re: WS2801 led strip

#12 Post by Ger » 30 Jan 2016, 19:18

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

Ger
Normal user
Posts: 71
Joined: 05 Sep 2015, 18:09

Re: WS2801 led strip

#13 Post by Ger » 30 Jan 2016, 22:04

The message with the conf files is also soved, I flashed them without SPIFFS, with SPIFFS no problem :D

Deennoo
Normal user
Posts: 158
Joined: 07 Sep 2015, 13:03

Re: WS2801 led strip

#14 Post by Deennoo » 31 Jan 2016, 10:13

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

Dylantje
Normal user
Posts: 255
Joined: 11 Oct 2015, 16:51

Re: WS2801 led strip

#15 Post by Dylantje » 26 Oct 2016, 21:29

kick..
Someone have this working with the espeasy software?
Looking for a rgbw controller...
With a esp and with domoticz..

Ger
Normal user
Posts: 71
Joined: 05 Sep 2015, 18:09

Re: WS2801 led strip

#16 Post by Ger » 27 Oct 2016, 23:31

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

Dylantje
Normal user
Posts: 255
Joined: 11 Oct 2015, 16:51

Re: WS2801 led strip

#17 Post by Dylantje » 18 Nov 2016, 23:31

WS2801 perhaps working on the esp?

Post Reply

Who is online

Users browsing this forum: No registered users and 53 guests