Git Product home page Git Product logo

esp8266ws2812i2s's Introduction

ESP8266 I2S WS2812 Driver

Provides more reliable WS2812 driving... And a nifty websockets-based interface for the ESP8266.
If you want to watch a video about this project, click the video link below.

Note: Most of the functionality is imported from a submodule (esp82xx). The submodule is more regularly updated and most of the technical description and troubleshooting advice is located there. You might want to cd esp82xx; git pull origin master; to fix (or sometimes introduce new) errors. The dev branch of both esp9266ws2812i2 and esp82xx might even be more cutting etch.

Youtube: Using I2S on the ESP8266 to drive WS2812Bs

This project is based off of the Espressif I2S interface for an mp3 player

If you want more information about the build environment, etc. You should check out esp82xx.

This project is still jankey and needs some cleanup.
The way it currently works is to continuously send WS2812 frames and when new data comes in on port 7777, it just updates the frames.

I wanted to make it so it would stop doing all DMA proesses so it could save bus contention, but I couldn't figure out how to make that happen.
If I tried disabling and re-enabling, it seems to have caused the DMA to just freak out and turn off until chip reboot.

The WS2812 output is synthesized from the input buffer. Any time a 0 is to be transmitted, we need a .3us pulse high and .9us low.
If a 1, then we send a .9us high with a .3us low. The way we do this is we look at nibbles, i.e.:

0101 would convert into: 1000 1110 1000 1110 < bitstream that actually gets shipped out.

Unfortunately this does mean it takes up 4x the space in RAM to DMA the data... But, it is very fast and efficient.

Hardware Connection

Unfortunately the I2S Output pin is the same as RX1 (pin 25), which means if you are programming via the UART, it'll need to be unplugged any time you're testing. The positive side of this is that it is a pin that is exposed on most ESP8266 breakout boards.

Memory layout:

We use a bit of a modified take on the old memory layout since, while we support OTA upgrades, we do so in a different way than the normal way. Not that HTTP is limited on parts with <1M, and OTA flashing is not supported at all on parts with <512kB.

Address Size Name / Description
00000h 64k 0x00000.bin, IRAM Code
10000h 172k Normally unused, HTTP may be here if signature found. Only used if you have < 1M part.
3A000h 16k Device Configuration
3E000h 8k May be used by ESP SDK.
40000h 240k 0x40000.bin, Cached code.
7C000h 8k May be used by ESP SDK.
7E000h 8k May be WiFi configuration
80000h 512k Scratchpad (Temp only!)
100000h 1M+ HTTP data, 1M on W25Q16. HTTP Used here if signature found.

esp8266ws2812i2s's People

Contributors

bryant1410 avatar cnlohr avatar con-f-use avatar ricardomv avatar sigurg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp8266ws2812i2s's Issues

ESP32 compatibility?

Hi there,
anyone out there getting the ESP32 working with this nice project?
Any advice how to realise?

Br
JIP0815

Rework the ws2812_push command

I think the leftover command is wrong... I'm not sure how it works though.

Look into the code here:

	uint16_t leftover = buffersize & 0x1f;
	if( leftover ) leftover = 32 - leftover;
	for( place = 0; place < leftover; place++ )
	{
		*(bufferpl++) = 0;
		*(bufferpl++) = 0;
	}

Working --> Mem check fail --> Bootloop

Hey Charles-- love all your stuff!

Been using this project in one of my own for some months now. In the beginning it was working fine, but recently I started getting some flickering. I couldn't find any hardware issues so I plugged into the board and lo and behold it was crashing randomly. Reflashed the firmware and it got stuck in a boot loop. Figured it was a hardware malfunction and bought a replacement.

On the new one, I flashed it and found it to be crashing with a "MEM CHECK FAIL" error-- but only when I sent it UDP packets above a certain size. SSID/wifi functionality was working fine. I reflashed again and it too is now stuck in a boot loop.

These things were just sitting on a breadboard, in a setup which I had working great with 300+ lights for months. Do you have any advice for me to track this down? What should I look for to fix/what could be breaking it like this?

#if USE_2812_INTERRUPTS throws an undefined error

You probably mean #ifdef USE_2812_INTERRUPTS?

Your repo didn't compile for me (conflicting copies of strcat so I probably have a different sdk setup).
So I tried to replace ws2812.c (from your other repo) in my current project with ws2812_i2s.c.
It compiles when I replace the #if with an #ifdef. (also copied ws2812_i2s.h and some other headers of course).

NodeMCU

In your README.MD you are saying this uses the RX1 pin of the ESP8266 to shift out I2S bits.
Am i correct that this means that with any development boards where the USB serial bridge is hardwired (like. NodeMCU) I2S usage is impossible?

rough how-to would be great

Hey cnlohr,

thanks for sharing your work!
I'm trying to get it to work on a ordinary esp-01 breakout board. What I did so far:

what works: flashing
what doesn't work: I get this via serial when i power up the esp

Fatal exception 0(IllegalInstructionCause):
epc1=0x40251c3f, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 30088, room 16 
tail 8
chksum 0x77
load 0x3ffe8000, len 876, room 0 
tail 12
chksum 0x5b
ho 0 tail 12 room 4
load 0x3ffe8370, len 2504, room 12 
tail 12
chksum 0x44
csum 0x44
don't use rtc mem data
Fatal exception �d

are you asuming certain other bin files flashed to other areas of the memory? which?

thanks again!

Timing values are used incorrectly

Hi!

I think the values for WS_I2S_BCK and WS_I2S_DIV are incorrect.
Currently -1 is subtracted from both before setting the values.
Instead they should be used as is.

The calculation given in the code for the frequency is:
// 1600000000L/(div*bestbck), I assume there's one '0' too many :)
Which I would assume means:
160000000L / (WS_I2S_DIV * WS_I2S_BCK) = bit frequency in Hz

For an example I'll use WS2812_FOUR_SAMPLE, so:
#define WS_I2S_BCK 17
#define WS_I2S_DIV 4
And for the buffer sizes:
#define WS_BLOCKSIZE 4000
And 32 byte for the 'zero' buffer.
That's 4032 bytes for all the DMA buffers.

By triggering an interrupt on EOF on one of the buffers, I can quite accurately get the Hz of going through all the 4032 buffer bytes.
According to the caluculation and dividers this should be:
(160000000 / (4032 * 8) ) / (4 * 17) = 4960.317 / (4 * 17) = 72.94584500466853 Hz
But the value I measure is close to 103.3 Hz..
Now If I use the '-1' values instead: 3 and 16 we get:
4960.317 / (3 * 16) = 103.3399470899471 Hz
Which is pretty much identical to the measured value :)

So my suggestion is to not subtract -1 of the two values, and then use:
#define WS_I2S_BCK 16
#define WS_I2S_DIV 3
Which are the actual values used.
And correct the comment with the formula to:
// 160000000L / ( WS_I2S_DIV * WS_I2S_BCK )

Cheers :)

little flicker after power off

Hello, Nice work!

After taking off power i noticed that some leds have a flicker (often a little flash to red).
Have you ever had this kind of problem?

Thank you!

Reboot sometimes when receiving network data

I just tried it out myself and it seems that sometimes when I send ws2812 network data, the ESP crashes and reboots. This seems to happen frequently, every 2-3 seconds! I'll look into it more tonight, but, it looks to be recent changes. Anything @con-f-use could have done?

Safe to use?

Hi!

Quick question/remark, as issues cause I didn't see any contact details :)

Since this way of driving the WS2812's uses pin: RX1/(pin 25)/U0RXD/i2SO_DATA (lots of names for one pin :) ).
Which is also the RX pin when flashing the ESP8266.
Am I in any danger of breaking my ESP by flashing this firmware?

I'm worried about this because my serial interface might make it's TX high, at the same time the ESP boots with this firmware, which would set the pin as out and also make it high to set the leds to their initial state?

I'm not experienced enough to know if this is an issue or not, but I'm sure I remember never hooking up two outputs together ;)
Obviously once it's properly flashed I can remove the serial interface, and use OTA for further updates, but I'm worried about the short period inbetween :) Especially since I can't remember if the ESP reboots directly after flashing XD

Any suggestions/workarounds? :)
Thanks! :)

Cant make it build

I dont understand what I need to change to fix this ? I am using the toolchain installed from this:
https://github.com/esp8266/esp8266-wiki/wiki/Toolchain

jon@esp8266dev:~/esp8266-examples/esp8266ws2812i2s$ make
/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -mlongcalls -I/home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/include -Imyclib -Iinclude -Iuser -Os -I/home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/include/ -Icommon -DICACHE_FLASH driver/uart.c common/mystuff.c common/flash_rewriter.c common/http.c common/commonservices.c common/http_custom.c common/mdns.c common/mfs.c user/custom_commands.c user/ws2812_i2s.c user/user_main.c -flto -nostdlib -Wl,--relax -Wl,--gc-sections -L/home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib -L/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.2/libgcc.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/liblwip.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libssl.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libupgrade.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libnet80211.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/liblwip.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libwpa.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libnet80211.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libphy.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libcrypto.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libmain.a /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib/libpp.a ~/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.2/libgcc.a -T /home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/ld/eagle.app.v6.ld -B/home/jon/esp-open-sdk/esp_iot_sdk_v1.5.2/lib -o image.elf
FW 0x00000.bin
/home/jon/esp-open-sdk/esptool/esptool.py -eo image.elf -bo 0x00000.bin -bs .text -bs .data -bs .rodata -bc -ec
usage: esptool [-h] [--port PORT] [--baud BAUD]
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash,verify_flash,erase_flash}
...
esptool: error: argument operation: invalid choice: 'image.elf' (choose from 'load_ram', 'dump_mem', 'read_mem', 'write_mem', 'write_flash', 'run', 'image_info', 'make_image', 'elf2image', 'read_mac', 'chip_id', 'flash_id', 'read_flash', 'verify_flash', 'erase_flash')
Makefile:72: recipe for target '0x00000.bin' failed
make: *** [0x00000.bin] Error 2

Constant reboots on wsend

if I let wsend run and watch the usb serial port on 115200, I see the device reboot every time after it connects to the local wifi network and receives a udp packet from wsend.
on the webui however, it looks to do what it's supposed to without rebooting.

ets Jan  8 2013,rst cause:2, boot mode:(3,7)

load 0x40100000, len 32492, room 16
tail 12
chksum 0xf0
ho 0 tail 12 room 4
load 0x3ffe8000, len 884, room 12
tail 8
chksum 0x10
load 0x3ffe8380, len 2716, room 0
tail 12
chksum 0x39
csum 0x39
��r�l��H����2XX Web-GUI
Version: v0.5-14-g1d7d7-dev - Build sø. 11. sep. 00:13:34 +0200 2016 with -DICACHE_FLASH -DWEB_PORT=80 -DCOM_PORT=7777 -DBACKEND_PORT=7878  -DSLOWTICK_MS=5Loading Settings: af / 0 / 69 / 69
 Settings Loaded: ESP_881DBF / Default
Opmode: 1
Station mode: "MYSSID":"MYPASS" (bssid_set:0)
 Boot Ok.
IGMP Joining: 6b25a8c0 fb0000e0
 STAT: 5
IP: 192.168.37.107
NM: 255.255.255.0
GW: 192.168.37.1
WCFG: /MYSSID/MYPASS/
IGMP Joining: 6b25a8c0 fb0000e0
MFS Not found at regular address (ffffffff).
MFS Found at: 00010000

Doesn't seem to work at all, any debugging ideas?

esp8266ws2812i2s seems like exactly what i'm looking for, a way to have the esp8266 be a dumb front-end to a bunch of WS2812 LED's. Unfortunately I can't seem get the any output from it at all.

I've successfully got it running on the esp8266 and can access the website. When I run the top command, the website's LED display does cycle.

I've attempted to use both the THREE & FOUR sample types and have played with moving the WS_I2S_BCK up and down to no avail.

The fact that the LED's don't even flicker suggests to me that something's fundamentally mis-wired somewhere, but I am connecting the data-in line to the RX pin. The LED's do work with the neopixel library on the same device, (but on different PIN). I've had problems running neopixel in conjunction with network activity though, so I thought your library would be ideal.

Issue #2 mentions some debugging output. Can you provide some hints on how to access that? Since the serial RX port is busy with I2S, I don't think I can access the debug output that way.

Any idea's on other things to try?

wsend build error

../user/pattern.c: In function ‘hex_pattern’:
../user/pattern.c:52:37: error: ‘NULL’ undeclared (first use in this function)

if stdlib.h is included in pattern.c , it compiles fine.

I2S output does not look right

Hi Charles. I compiled the project with no changes and flashed it to my board. I used the 'top' application to send packets to the module but none of the LEDs flashed. I used a logic analyzer to see the signal coming out of the U0RXD_U/I2S0_DATA pin. This is before sending running 'top':
1

Zoomed in pulse:
2

After running the 'top':
3

Any idea what the problem is?

Ws2813 compatibility

Would this library work with ws2813, if not what do you recommend to be done to make it do so..

Add APA104

I'm trying to add APA104 support with another timings (T0H: 0.35µs, T0L: 1.36µs, T1H: 1.36µs, T1L: 0.35µs).

Can you explain your I²S frequency setup formula?

12000000 / (div * bestbck * 2)

WS2812B timings is
T0H: 0.4µs, T0L: 0.85µs, T1H: 0.8µs, T1L: 0.45µs
1,25µs per led / 3 sample = 0,416 µs per sample

Default settings is

define WS2812_THREE_SAMPLE

define WS_I2S_BCK 22

define WS_I2S_DIV 4

Then..
12000000 Hz — system frequency
2 — I²S frequency (half of system frequency)
4 — I²S frequency divider
22 — secondary I²S frequency divider

12000000 / (4 * 22 * 2) = 68181,81 Hz I²S bit speed
68181,81 / 1000000 = 0,0681 µs per bit

Aw, but there is 0,416 µs per sample.. Something goes wrong.

And why you need bitpattern arrays?

Noise from RX1

When connecting a led strip to the required pin the leds light up in the expected pattern, but with a lot of noise.
Up to 10 leds are flickering random colors and the whole strip flickers off and on.

UDP data format?

Thanks for making this I have been playing with it but I am having issues with sending data over UDP this is not an issue with your code but i am unsure of where to post it :)

If I look at the data going out via wsend it looks like 00ff00 but if I echo data to the UDP port
echo "00ff00ff00000000ff" > /dev/udp/192.168.4.1/7777

I get a different set of colors that affect more than the expected first 3 led's being red, green and blue?

any input on what I am doing wrong will be appreciated.

Web interface "File not found."

Dear Charles

I've managed to flash the bin files provided to my esp-12e and successfully blink some leds with the provided top program.

The only thing I can't make work is the web interface. Whenever I'm connected to the esp and browse to 192.168.4.1 I get

File not found.

Do I need to flash some additional files to the esp in order for the web interface to work properly?

Thanks a lot for the great work and your videos on youtube!
Cheers,
gabe0815

mDNS not working

i installed latest version and compiled with SDK 1.4.0, but i am unable to get mDNS to advertise.
this is my output:

esp8266 ws2812 driver
Settings Loaded: ESP_9E5F33 / Default
Opmode: 1
Station mode: "SSID":"pass" (bssid_set:0)
IGMP Joining: b60aa8c0 fb0000e0
STAT: 5
IP: 192.168.10.182
NM: 255.255.255.0
GW: 192.168.10.1
WCFG: /SSID/pass/
IGMP Joining: b60aa8c0 

So i see that JoinGropMDNS() was called but i cant find advertisement with commad avahi-browse -at from another linux station.

Your thoughts?

Hi!

I'm (slowly) trying to clean up/improve(?) your ws2812 i2s code:
https://github.com/cranphin/esp8266-dev/blob/master/esp8266-neo/dev/driver/ws2812_i2s.c

One thing I'd like to do is actually enable/use DMA interrupts.
This is certainly possible, someone has done this rather elegantly (I think) for the Arduino core:
https://github.com/Makuna/NeoPixelBus/blob/master/src/internal/NeoEsp8266DmaMethod.h#L282
But he has the benefit of the yield() method the Arduino core provides:
https://github.com/Makuna/NeoPixelBus/blob/master/src/internal/NeoEsp8266DmaMethod.h#L241
Which he uses to 'block' the update call until the DMA buffer has space, I don't think it's easy to do something like that in esp-open-sdk/Espressif NON-OS.

My current idea is to store the received/update bytes (just the RGB bytes) in a buffer, possibly a ring buffer size 2, with each part the length of the led string size. And then a far smaller DMA buffer (ring buffer as well I think, with at least 2 parts for converted RGB bytes), which is fed in small parts from the previous buffer in the interrupt, possibly in combination with a 'zero' buffer once it's done.
So the update method writes to the first buffer (overwriting the previous value if we get data faster then we can send it to the leds), And the interrupt moves it in small parts to the two DMA buffers, marking the first buffer done when it's finished.

Any thoughts on this? I'm really not used to working with interrupts and DMA, usually I work in Java :)
You seem pretty awesome at it though ;)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.