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

ESP32 x8 Parallel with a RGBW doesn't output the W channel #868

Open
Makuna opened this issue Jan 8, 2025 · 12 comments
Open

ESP32 x8 Parallel with a RGBW doesn't output the W channel #868

Makuna opened this issue Jan 8, 2025 · 12 comments
Assignees
Labels
bug investigating Currently under investigation for more understanding of the problem.

Comments

@Makuna
Copy link
Owner

Makuna commented Jan 8, 2025

Describe the bug
WLED Issue 4380.
The W channel is always empty with i2s parallel, but is present with RMT.

Development environment (please complete the following information):
Pending: determining which NeoPixelBus version is being used as it was noted that previous versions it worked.

@Makuna Makuna added bug investigating Currently under investigation for more understanding of the problem. labels Jan 8, 2025
@Makuna Makuna self-assigned this Jan 8, 2025
@DedeHai
Copy link

DedeHai commented Jan 8, 2025

I tested this on WLED with NPB 2.8.0 as well as 2.8.3, both show the issue on ESP32.
However, testing it on ESP32 S2 with parallel I2S output with 5 outputs, SK6812, 10 LEDs per bus the white channel works.

@Makuna
Copy link
Owner Author

Makuna commented Jan 11, 2025

At first glance through the changes, I don't see any obvious issues.
The big change was to move to the 3Step Cadence to save memory. It still supports 4Step Cadence, but it requires a compile time flag (NPB_CONF_4STEP_CADENCE). Does WLED use 4 or 3 step?
The interesting thing is that S2 had a ton of changes here, as I discovered that the something in the HW abstraction layer i2s API changed the byte order of the DMA data (probably a bug fix in their abstraction layer for a flag to data layout that I needed to adjust too).

@blazoncek
Copy link

@DedeHai S2 code had an issue and was not actually using parallel I2S. Will push modifications so please retest when you can.

@Makuna I do not specifically set cadence, whatever is default.

@blazoncek
Copy link

blazoncek commented Jan 11, 2025

@Makuna I've now finally managed to set up my test unit and can indeed confirm that White channel is missing on SK6812 strip when using parallel I2S (I2S1 on ESP32).

I am using mixed LEDs on the same I2S bus:

  • 1st bus 200 WS2812
  • 2nd bus 200 WS2812
  • 3rd bus 25 SK6812

Buses are created using new and after last bus is created Begin() is called for each bus.
Something like:

bus1 = new NeoPixelBusLg<NeoGrbFeature, X8Ws2812xMethod, NeoGammaNullMethod>(len1, pin1);
bus2 = new NeoPixelBusLg<NeoGrbFeature, X8Ws2812xMethod, NeoGammaNullMethod>(len2, pin2);
bus3 = new NeoPixelBusLg<NeoGrbFeature, X8Sk6812Method, NeoGammaNullMethod>(len3, pin3);
bus1->Begin();
bus2->Begin();
bus3->Begin();

EDIT: Adding

#define NPB_CONF_4STEP_CADENCE
#include "NeoPixelBusLg.h"

has no effect.

@DedeHai
Copy link

DedeHai commented Jan 12, 2025

@blazoncek I retested the S2: 5xSK6812 outputs, 10 LEDs each using your esp-now-search branch. White channel still works.

@blazoncek
Copy link

@DedeHai you need 6 or more outputs on S2 (5 or more on S3). You will be able to achieve that by toggling "User parallel I2S" in LED settings.
S2 and S3 will use RMT for first 4 outputs. S2 will use single mode I2S if parallel is not selected for 5th output. You should not be able to configure more than 5 outputs on S2 if you do not select "Use parallel I2S".

@Makuna
Copy link
Owner Author

Makuna commented Jan 13, 2025

I can't reproduce with Arduino IDE with ESP32 board support v3.1.1

There may be something specific missing in the sketch to trigger the issue. Can we start with this sketch below and modify to get the problem to show.

Sample Sketch:

#include <NeoPixelBusLg.h>

const uint16_t PixelCount = 10; 
const uint8_t DebugPin = 6; // used for logic anaylyser trigger capture 

typedef NeoRgbwFeature NeoFeature;
typedef NeoEsp32I2s0X8Ws2812xMethod NeoMethod;
#define NeoBus NeoPixelBusLg
//#define INCLUDE_ALL_EIGHT 

//typedef NeoEsp32I2s1X8DblWs2812xMethod NeoMethod;


// moved construction into Setup() so we can capture log output into Serial
//
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip0;
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip1;
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip2;
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip3;

#if defined(INCLUDE_ALL_EIGHT)
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip4;
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip5;
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip6;
NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>* strip7;
#endif

void ResetPinMatrix()
{
  const uint8_t reset_pins[] = {2,4,5,12,13,14,15,16,17,18,19,21,22,23,25,26,27,32,33};
  const uint32_t MATRIX_DETACH_OUT_SIG = 0x100;
  for (uint8_t pin = 0; pin < (sizeof(reset_pins)/sizeof(reset_pins[0])); pin++)
  {
        gpio_matrix_out(reset_pins[pin], MATRIX_DETACH_OUT_SIG, false, false);
  }
}

void setup() 
{
//  ResetPinMatrix();
    Serial.begin(115200);
    while (!Serial); // wait for serial attach
    
    Serial.println();
    Serial.println("Initializing...");
    Serial.flush();

    strip0 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 5);
    strip1 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 4);
    strip2 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 3);
    strip3 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 2);
      
#if defined(INCLUDE_ALL_EIGHT)
    strip4 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 1);
    strip5 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 9);
    strip6 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 8);
    strip7 = new NeoBus<NeoFeature, NeoMethod, NeoGammaNullMethod>(PixelCount, 7);
#endif

    strip0->Begin();
    Serial.println(" 1");
    strip1->Begin();
    Serial.println(" 2");
    strip2->Begin();
    Serial.println(" 3");
    strip3->Begin();
    Serial.println(" 4");


#if defined(INCLUDE_ALL_EIGHT)
    strip4->Begin();
    Serial.println(" 5");
    strip5->Begin();
    Serial.println(" 6");
    strip6->Begin();
    Serial.println(" 7");
    strip7->Begin();
    Serial.println(" 8");
#endif

    pinMode(DebugPin, OUTPUT);
    digitalWrite(DebugPin, LOW);
  
    Serial.println();
    Serial.println("Running...");
}

const RgbwColor testColor = {'R', 'G', 'B', 'W'};

void loop() {
   delay(5000);

    Serial.println("Update ...");

    strip0->SetPixelColor(PixelCount - 1, testColor);
    strip0->SetPixelColor(0, testColor);
    strip1->SetPixelColor(0, testColor);
    strip2->SetPixelColor(0, testColor);
    strip3->SetPixelColor(0, testColor);

#if defined(INCLUDE_ALL_EIGHT)
    strip4->SetPixelColor(0, testColor);
    strip5->SetPixelColor(0, testColor);
    strip6->SetPixelColor(0, testColor);
    strip7->SetPixelColor(0, testColor);
#endif

    digitalWrite(DebugPin, HIGH);
    
    strip0->Show();
    strip1->Show();
    strip2->Show();
    strip3->Show();

#if defined(INCLUDE_ALL_EIGHT)
    strip4->Show();
    strip5->Show();
    strip6->Show();
    strip7->Show();
#endif

    digitalWrite(DebugPin, LOW);
}

results captured:
Front of stream (only showing first three busses in capture)
image

Back of stream
image

@blazoncek
Copy link

@Makuna I will try to debug more on WLED side and report back as I do not have logic analyser or oscilloscope.

@Makuna
Copy link
Owner Author

Makuna commented Jan 13, 2025

@Makuna I will try to debug more on WLED side and report back as I do not have logic analyser or oscilloscope.

What versions of the ESP32 core (Arduino board support?) are you using?

@blazoncek
Copy link

It looks like a very old one for ESP32.

platform = [email protected]
platform_packages = framework-arduinoespressif32 @ https://github.com/Aircoookie/arduino-esp32.git#1.0.6.4

While S2, S3 & C3 are using:

platform = espressif32@ ~6.3.2
platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0    ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them)

This is mostly due to image file size since when using newer core/framework we are running out of flash storage.

@Makuna
Copy link
Owner Author

Makuna commented Jan 13, 2025

My tests above where on a ESP32-S2. It was mentioned it was demonstrated on an S2 also.
Not sure how to get that information for the Arduino ESP32 board support 8-/

It might be IDF v5.3.

@blazoncek
Copy link

FYI currently we are facing total freeze of CPU on ESP32-S2 if we enable parallel I2S. It looks to me like some sort of memory depletion as with WLED free heap goes as low as 6k.

I'm not sure but I think we use IDF 4.3.2 for ESP32 and IDF 5.0.2 for other ESP32-XX chips (embedded in PlatformIO platforms).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug investigating Currently under investigation for more understanding of the problem.
Projects
None yet
Development

No branches or pull requests

3 participants