Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HARDWARE RMT ESP32 support... #152

Closed
sticilface opened this issue Jan 10, 2017 · 86 comments
Closed

HARDWARE RMT ESP32 support... #152

sticilface opened this issue Jan 10, 2017 · 86 comments
Assignees
Labels
enhancement pending Pending new release; already merged but not released in a version

Comments

@sticilface
Copy link

You probably knew this would come.... :) ESP32 support

any chance?

@Makuna
Copy link
Owner

Makuna commented Jan 10, 2017

I haven't received my Esp32 yet; but it is on the list.

@Makuna Makuna self-assigned this Jan 10, 2017
@sticilface
Copy link
Author

:) I just ordered mine from someone in london. not cheap, but same as getting it from china!

@sticilface
Copy link
Author

so much RAM!

@AdySan
Copy link

AdySan commented Feb 11, 2017

It's been a month, so just checking, I'd really appreciate if this library would work with esp32 arduino port, or better esp-idf itself!

@Makuna
Copy link
Owner

Makuna commented Apr 5, 2017

Actively working on this now.

@AdySan
Copy link

AdySan commented Apr 5, 2017

Yay!

@Makuna
Copy link
Owner

Makuna commented Apr 6, 2017

#167
This adds bitbang method as the default, which can support pins below 32.
Hardware support is next

@Snigelson
Copy link

Do you know yet which pin it will be on?

@Makuna
Copy link
Owner

Makuna commented May 3, 2017

Hardware support will be able to also work on pins below 32. There are at least two outstanding issues on the esp32 core iot libraries that need to be addressed before I can publish the hardware support; otherwise the "shared" RMT hardware can only be used by one system at a time (NeoPixel, IR receive, IR transmit, only one at a time, etc).

Current work is waiting on the following two Esp32 IOF issues.
espressif/esp-idf#514
espressif/esp-idf#517

@Buffalchill
Copy link

good to hear you are working on it ! Realy would like to see the ESP32 do the Neopixel while receiving data over wifi

@Makuna
Copy link
Owner

Makuna commented May 11, 2017

@Buffalchill Have you tried the current Esp32 support while doing WiFi? Theoretically it should work as the Esp32 is dual core. Its just going to take a lot of the CPU resources.

@Buffalchill
Copy link

Buffalchill commented May 12, 2017

@Makuna since yesterday i am trying out the ESP8266 with your WS2812B driver. It seems to work better than the Neopixel.h Thumbs up realy good work 👍

*edit: i had an older version of the libraray. i will check out the ESP32 asap.
Tanks a lot for sharing this lib !!!

@Makuna
Copy link
Owner

Makuna commented May 12, 2017

@Buffalchill Standard data needed: What device/board are you selecting? What version of NeoPixelBus library is installed? Are you using the Arduino IDE or something else? What version is the IDE?

@Jorgen-VikingGod
Copy link

I just tried the lib (=master) with my ESP32 devboard and is running fine

@Buffalchill
Copy link

Buffalchill commented May 12, 2017

Hi! I had an older Lib. now it runs.
But with the ESP8266 my rainbow fader runs well, with the ESP32 it is fading but also blinking pretty strange :-(

edit: I added a delay(2); after I call the strip.show routine... then it stoped flickering...

I guess the WS2812b need more time inbetween updating the pixels ? 2ms are fine now

@Jorgen-VikingGod
Copy link

@Buffalchill did you connect it directly on GPIO or through level shifter?
To get stable signals it is always better to serve 5V data line. And of course a 100-220 Ohm resistor is also a good idea as "low-pass" filter to cut the noise.

@PedroScreamerovsky
Copy link

PedroScreamerovsky commented May 12, 2017

I'm also having some problems with the ESP32. I'm using a NeoPixel Jewel, and the 4th led is blinking green, with all the example sketches. I've tried with a level shifter but still no luck. Also adding the delay didn't resolved the problem

edit: i've also tried the adafruit neopixel library and it works without this issue
edit2: using the NeoEsp32BitBang400KbpsMethod almost resolved the problem (there's just a bit of flickering on all pixels)

@Makuna
Copy link
Owner

Makuna commented May 12, 2017

@PedroScreamerovsky What actual LED model are you using? WS2813 will require a specific method.

@Buffalchill
Copy link

Buffalchill commented May 12, 2017

I got the same issues with the ESP32 like PedroScreamerovsky.
Now i added a level shifter and a resistor but this didnt realy help. With the ESP8266 the code runs pretty well, but on the ESP32 its flickering on the whole stripe :-/

I am using this for the ESP32: NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod>
is that the right method ?

i am using the WS2812b stripes

@PedroScreamerovsky
Copy link

PedroScreamerovsky commented May 12, 2017

I'm using these: https://www.adafruit.com/product/2859 (grbw)
I've tried Neo800KbpsMethod, then NeoEsp32BitBang800KbpsMethod (with all the pixels working well except one, that has the green channel doing weird things), and finally the NeoEsp32BitBang400KbpsMethod, that resolves the issue of the green led, but creates lot of random flickering.
As for Buffalchill, the esp8266 is working fine with the same sketch.
i think my LEDs are WS2812b as well

@Makuna
Copy link
Owner

Makuna commented May 12, 2017

One more piece of information, how many are in strip?
(the hardware version is pending some improvements from espresif)

@PedroScreamerovsky
Copy link

PedroScreamerovsky commented May 13, 2017

It's 7 leds in my setup

@Buffalchill
Copy link

150 leds... pretty much flickering on the stripe

@sebastius
Copy link

sebastius commented May 17, 2017

NeoEsp32BitBang800KbpsMethod

NeoEsp32BitBang800KbpsMethod supports any available pin below 32.

Hi, why 'any pin BELOW 32'? Guess who has a board with SK6812 RGBWs on gpio 32...

@Makuna
Copy link
Owner

Makuna commented May 20, 2017

@sebastius Pin 32 and above are handled differently. The hardware version will use the built in pin matrix switching (allowing hardware to use more pins unlike the esp8266) which also doesn't support 32 and above.

@Makuna
Copy link
Owner

Makuna commented Jun 7, 2017

BTW, I just read that the newer WS2812b coming off production are the same as the ws2813, so if the delay after calling show fixes it for you, switch to use the ws2813 method and the delay should not be needed anymore. They changed the spec so it requires a longer reset time, but didn't change the model number.

@rcaceiro
Copy link

rcaceiro commented Jun 11, 2017

I got the same issues with the ESP32 like Buffalchill.
Now i added a level shifter and a resistor but this didnt realy help. With the ESP8266 the code runs pretty well, but on the ESP32 its flickering on the whole stripe :-/

I am using this for the ESP32:
NeoPixelBus<NeoGrbFeature, NeoEsp32BitBang800KbpsMethod> strip(PixelCount,13);
i am using the WS2812b stripes

ESP32 as some port like ESP8266 that works fine, because using ESP8266 has especific port otherwise strip flickering too.

How can fix it and what is the correct pin to use?

@Makuna
Copy link
Owner

Makuna commented Jun 11, 2017

use this instead...

NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBangWs2813Method> strip(PixelCount,13);

AND NOTE: Hardware support for Esp32 is still pending on changes to RMT core library.

@PeterOFre
Copy link

Hi all, I am new in GitHub and new in ESP32. Have created a Light Painting Stick based on an Arduino Uno and the Adafruit Data Logging Shield following the Adafruit Tutorial and it is working fine except the conflict with the I2C LCD Display. Have thought I am using ESP32 and bought a M5Stack Module with inbuild SD card, Display and 3 buttons. The NeoPixelBus demo is working fine on the M5Stack, but again, the LCD Display and SD Card reader stop working when the strip.Begin() and strip.Show(); command has reached. Is there a way to have NeoPixel and LCD + SD Card working in parallel ? I could upload the Arduino sketch if needed.

@Makuna
Copy link
Owner

Makuna commented Jun 16, 2018

@PeterOFre please use gitter (see readme, wiki) to ask questions that are not specific to this issue.

@SoundsSerious
Copy link

SoundsSerious commented Jun 25, 2018

@Makuna Been testing this code out. Using the default i get flickering on the lights when serial is sending. Is anyone else experiencing something like this?

I was thinking that this method was supposed to avoid the bit bang issues with wifi & other interrupts

@Makuna
Copy link
Owner

Makuna commented Jun 25, 2018

I have not heard of any issues. Can you provide a minimum sketch that reproduces the problem? With the minimum sized strip if that also is a culprit.

@Xonotron
Copy link

While evaluating different libraries for a project, I stumbled upon an issue with ESP32, SK6812 LEDs and NeoPixelBus.

I reduced my project to the most simple code that reproduces the problem: strip.Show() seems to be ignored every now and then (1 out of 10 roughly) unless I call strip.Begin() every time prior to that. NeoEsp32BitBang800KbpsMethod works as expected.

Here's the code:

#include <NeoPixelBus.h>

NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(1, 4);

int brightness=32;
RgbColor yellow(brightness, brightness/4*3, 0);
RgbColor blue(0, 0, brightness);

portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
unsigned long interruptTime=millis();
bool blinkNow=false;
unsigned int resetTimer=millis();
bool resetLed=false;


void IRAM_ATTR handleInterrupt() {
  portENTER_CRITICAL_ISR(&mux);
  if(millis()>interruptTime+200) {
    interruptTime=millis();
    blinkNow=true;
  }
  portEXIT_CRITICAL_ISR(&mux);
}

void setup() {
  pinMode(12, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(12), handleInterrupt, FALLING);

  strip.Begin();
  strip.Show();
}

void loop() {
  if(blinkNow) {
    portENTER_CRITICAL(&mux);
    blinkNow=false;
    portEXIT_CRITICAL(&mux);
    
    resetLed=true;
    resetTimer=millis();
    //strip.Begin();
    strip.SetPixelColor(0, yellow);
    strip.Show();
  }
  if(resetLed) {
    if(resetTimer+100<millis()) {
      //strip.Begin();
      strip.SetPixelColor(0, blue);
      strip.Show();
      resetLed=false;
    }
  }
}

...and the hardware setup:
esp32_setup_

@me-no-dev said that NeoPixelBus uses an early version of the I2s driver (adafruit/Adafruit_NeoPixel#139 (comment)), could this be an issue there?

@Makuna
Copy link
Owner

Makuna commented Aug 19, 2018

@Xonotron This issue is about having support for Esp32 at all, not really a general issue to ask questions about something not working correctly. There are a lot of pitfalls with using NeoPixels and if you glance at the Wiki FAQ, you can see solutions to most of them.
The gitter channel is the best place to start in asking for help and then creating an issue once it has been identified to be a real issue. The i2s version I have works great and this issue is tracking RMT version I plan to include.

@r1dd1ck
Copy link

r1dd1ck commented Aug 21, 2018

@Makuna
If you want, I can provide my implementation. It's fairly clean, single file, no globals used, handles reset times natively (eg. not timer-based), and also comes with free-channel autoselect.

Just let me know and I can do a fork PR, or push it directly if given access.

@Makuna
Copy link
Owner

Makuna commented Aug 21, 2018

@r1dd1ck implementation for what? RMT? Already have Pull 202 but I am waiting for latest support to be issues in an official Esp32 Arduino release.

@r1dd1ck
Copy link

r1dd1ck commented Aug 21, 2018

@Makuna
Yes RMT. #202 is for the pre-#517 "fix" (IDF) version, using the old method rmt_write_items to push LED data - and to be honest, it is one big mess (no offense to anyone, all effort is of course appreciated).

All the required updates to RMT driver are part of the official arduino-esp32 package for a couple of months already, and now that v1.0.0 of the ESP32 arduino core was oficially released (with board manager support), I really see no reason why to wait any longer..

But if you already have your own version waiting for release (or just want to do it all by yourself) - I can understand that. Just wanted to offer some help in case you don't have enough spare time to throw at it at the moment, as I have a full-fledged NeoPixelBus RMT implementation readily available, tested & polished :-)

@Makuna
Copy link
Owner

Makuna commented Aug 22, 2018

@r1dd1ck That's great! Go ahead and create a pull. While I did start one (that lead to idf requests) I haven't updated it yet and I suspect it will require some significant changes.

@me-no-dev
Copy link

the RMT driver for Arduino is in PR still. If you use the IDF api, you risk to clash with the Arduino API.

@r1dd1ck
Copy link

r1dd1ck commented Aug 22, 2018

@me-no-dev
can you please explain what exactly you mean by "clash with the Arduino API"?

Isn't the upcomming Arduino RMT "driver" supposed to be just a wrapper for the IDF stuff, with the sole purpose to make it "easier to use" for the average arduino user? Or are there some aspects to it which will render the use of the native API a "high-risk" endeavour?

I would certainly hope that's not the case, and that the final version will be sanitized enough to avoid any such conflicts..

@me-no-dev
Copy link

when you control the same resource from two different places, you can surely end up in position where your stuff does not work. I personally can go just fine with a mix of IDF, Arduino and my own code, but many users will have issues if peripherals are used by libs and hide away the choices that they made for pins, channels and so on. The Arduino RMT driver actually keeps track of the used channels and memory and will not allow two libs to try to use the same channel and will in fact give then different resorces so both can function. Arduino and IDF users are different in skills and more.

@r1dd1ck
Copy link

r1dd1ck commented Aug 22, 2018

@me-no-dev

hide away the choices that they made for pins, channels and so on

• there is no sane case of "hiding away of pin choice" I could possibly think of.. and
• channel conflicts can be safely sanitized (I know because I'm already doing it in my code)

So to me it seems that the real problem here is not whether my code is going to clash with the Arduino API (because my code is already sufficiently sanitized for this), but rather whether the Arduino API is going to clash with my code ... Splendid :-D

I hope most of these possible "clashes" will be resolved in the Arduino RMT API before it gets finally pushed to master .

But I think the bottom line here is - that even if the Arduino API is not sanitized to avoid conflict with the native API, nothing is stopping us from updating our code to automatically "register" the used RMT resources within the Arduino RMT API, once it becomes available..

@Makuna
What's your take on this?
Want to wait for the Arduino implementation (with all the added overhead)?
or would it be OK to use the native approach - which will later get adjusted to avoid possible clashes with the Arduino API once it becomes available (in case the Arduino API does not implement these checks) ?

Let me know :-)

@me-no-dev
Copy link

I don't think we understand each other :) I strongly believe that the RMT Arduino lib is much better and easier to use by Arduino users. I am not really sure about what overhead you are talking about... In the case of arduino RMT, you ask for RMT channel and amount of RMT memory that you need and the lib gives you the next available channel with that much memory. You do not need to care what other libs are using RMT, how much memory they have dedicated to their channel and so on. AMF I plan to do the same for LedC and any other such lib in Arduino.

@r1dd1ck
Copy link

r1dd1ck commented Aug 22, 2018

@me-no-dev

I strongly believe that the RMT Arduino lib is much better and easier to use by Arduino users.

and I did not question that aspect at all. I, too, believe it will.

I am not really sure about what overhead you are talking about.

all the overhead a wrapper usually takes. Unless it is not a wrapper, and you are re-writing the whole driver from scratch, doing it in a more efficient way than the native API (unlikely).

You do not need to care what other libs are using RMT, how much memory they have dedicated to their channel and so on.

Oh I believe you do have to care, because all the currently available libs already use the native approach, and you can't simply expect all of the maintainers to promptly rewrite their code just to avoid "clashes" with some newly introduced API's. The point is, that if the new API is not properly sanitized, it will make all those libraries which already make use of the RMT peripheral potentially unstable - and I think this is a scenario the Arduino-ESP32 team should be trying to avoid.

Don't understand me wrong, I fully support the idea to offer easier ways for Arduino users to utilize the potential of all the available peripherals - but I also think it should be done in a "transparent" way that does not necessarily introduce conflicts with the native API.

@r1dd1ck
Copy link

r1dd1ck commented Aug 22, 2018

@me-no-dev
to reduce the whole matter down to the most important point:

Make sure the new Arduino API's don't "clash" with resources allocated by the native approach (IDF), and all will be fine.

:-)

@Makuna
Copy link
Owner

Makuna commented Aug 22, 2018

My take on this:
I spotted the power of RMT, but also the conflict and pain when two library writers use it, so I avoided creating a bigger problem down the road by seeking improvement (the issue to fix it) rather than jumping on it to use. These problems are what they are fixing and I support that.

Further, the Bitbang was working well enough; until it didn't. But I now have i2s hardware support so there is no strong need to force conflict and have RMT support.

As a library writer, its my problem if I work around standard APIs (or non-existent). While its fun to hack something together and I don't blame people for doing so, I understand the risk of it becoming incompatible and it will require me to "fix" it. Other library writers should understand this also. So I believe a low priority should be on the API creators to keep it compatible with my workarounds (within the context of Arduino support) as long as they are solving the issues of sharing and functionality. I don't want them creating "crap" APIs due to some library writer doing something completely wrong.

But it seems the new stuff could just require an include for the header that is unqiue, like "Esp32Rmt.h" or even "ArduinoEsp32Rmt.h" and at least there is no compile conflicts; just the harder to find runtime conflicts ;-)

SO, I will hold off support for it until the new stuff arrives.

@r1dd1ck
Copy link

r1dd1ck commented Aug 22, 2018

@Makuna
I don't think I would call usage of the native API a "workaround", or even "doing something completely wrong" - as you state. However I understand your concerns about including something that could become broken by some future changes to the Arduino-ESP32 package (as hinted by @me-no-dev earlier), so fair enough.

These problems are what they are fixing and I support that.

Yes, although I'm afraid those "problems" will probably remain as there is alot of libraries out there succesfully using RMT natively already. ESP32 might be obsolete by the time most of them do the switch (if ever) :-/

Further, the Bitbang was working well enough; until it didn't.

I would say that strongly depends on your definition of "well enough" :-D

But I now have i2s hardware support so there is no strong need to force conflict and have RMT support.

Can't really compare the max. 2 channels of I2S with the seamless 8 of RMT. A couple hundred pixels is simply not enough for any larger projects. I wish the china-men would release a higher bitrate version of the pixels already, with at least 12bit+ resolution :-/

@Makuna
Copy link
Owner

Makuna commented Aug 23, 2018

@r1dd1ck I created a new branch, labeled Esp32RMTExperimental, that you can create a pull against with your RMT code. This will allow advanced users to play with it until we get the offical Arduino support. This will limit exposure from the novice users and thus save me some support effort.

@r1dd1ck
Copy link

r1dd1ck commented Aug 24, 2018

Just had a look at the proposed Arduino RMT driver and..

It seems they are completely rewriting the API from scratch into a new Arduino incarnation, which for the most part essentially just mirrors the native API including data structures (just under different names) - so any added value in this sole regard is escaping me.

There are of course benefits, like the already mentioned resource management, introduction of simpler methods for init, and to a certain extent also send & receive. So that's a plus.

But I am sad to inform that, at least in its current incarnation, it will be barely usable for any meaningful NeoPixel use :-/ Not going much into detail here as the reasons should be more than obvious after a quick glance at the source. I will only hint that it is "back to square # 1", rewinding to a state the native API was roughly 1.5 years ago..

Holding off judgement until the final version appears though. Fingers crossed :-)

@me-no-dev
Copy link

yet one of the examples in that PR is exactly neo pixels and on top of that the lib was written to be able to stream large amounts of pixel data (which the IDF implementation does not really do well). In any case... neo pixels are working for me with both i2s and rmt ;)

@r1dd1ck
Copy link

r1dd1ck commented Aug 24, 2018

yet one of the examples in that PR is exactly neo pixels and on top of that the lib was written to be able to stream large amounts of pixel data (which the IDF implementation does not really do well).

OK. Funny you mention the example from PR, because that was exactly the trigger which prompted me to investigate further on it.

I just hope that @Makuna will have more success in spotting what your magnifficient take on re-inventing the wheel is missing, cause I surely ain't gonna spill the beans now :-)

@Makuna Makuna changed the title HARDWARE ESP32 support... HARDWARE RMT ESP32 support... Feb 5, 2019
@Makuna
Copy link
Owner

Makuna commented Feb 5, 2019

i2s hardware support has been present for awhile now. Updated title to track adding RMT support

@Makuna
Copy link
Owner

Makuna commented Jun 10, 2019

#272

example of using the new RMT# method

NeoPixelBus<NeoGrbFeature, NeoEsp32Rmt0Ws2812xMethod> strip(PixelCount, PixelPin);
  through
NeoPixelBus<NeoGrbFeature, NeoEsp32Rmt7Ws2812xMethod> strip(PixelCount, PixelPin);

You can instance eight of these, using a different method Rmt0 - Rmt7; so eight channels for this, and another two channels for i2s support, gives you 10 channels on Esp32!

@Makuna Makuna added the pending Pending new release; already merged but not released in a version label Jun 10, 2019
@Makuna
Copy link
Owner

Makuna commented Jun 12, 2019

Just a link before I close this as the solution is now live. Just a little problem noted in RMT apis cause some non-optimum perfromance, but it still works with all 8 channels.

espressif/arduino-esp32#2885

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement pending Pending new release; already merged but not released in a version
Projects
None yet
Development

No branches or pull requests