esp32 + ws2801 - Need help.

andrewroom
Posts: 4
Joined: Mon Jan 07, 2019 7:56 am

esp32 + ws2801 - Need help.

Postby andrewroom » Mon Jan 07, 2019 8:04 am

Hi!

I bought two esp32 (https://www.amazon.de/gp/product/B071P98VTG) and a led-strip (https://www.amazon.de/gp/product/B01MCQKC2I).

The installation and a few example projects (wifi, webserver) are working fine. But i cant get the led-strip working! I spent a whole day without success.

I think the problem is the PIN-Layout. With my arduino the led strip is working.

Can someone help me, pls. I used the fastLED-Module for testing...

Best regards

Andrew

richhas
Posts: 5
Joined: Sun Jan 22, 2017 5:56 am

Re: esp32 + ws2801 - Need help.

Postby richhas » Tue Jan 08, 2019 5:05 am

Hi Andrew,

I just did an ESP32 xmas lights project with 600 leds. My suggestion would be for you to use https://github.com/Makuna/NeoPixelBus/

I used this after having used much slower (non-DMA) approached. I have run my on AdaFruit and Expressif ESP32s. This worked great.

If you need more help, I can send you my working app source.

Best,

Rich

andrewroom
Posts: 4
Joined: Mon Jan 07, 2019 7:56 am

Re: esp32 + ws2801 - Need help.

Postby andrewroom » Tue Jan 08, 2019 8:45 am

Hi Rich,

thx for the reply.

Yes, please, send me your example-script. That would help me a lot!

I will try it today.

Thank you

Andrew

Edje11
Posts: 18
Joined: Thu May 17, 2018 10:33 am
Contact:

Re: esp32 + ws2801 - Need help.

Postby Edje11 » Tue Jan 08, 2019 8:43 pm

Keep in mind that your led's stips require 5V power supply.

richhas
Posts: 5
Joined: Sun Jan 22, 2017 5:56 am

Re: esp32 + ws2801 - Need help.

Postby richhas » Wed Jan 09, 2019 9:22 am

Work in progress - ie code not cleaned up yet. Also note the first comment wrt hardware requirements... And yes the output pin needs to be level shifted to 5VDC.

Good luck.

Rich







#include <NeoPixelBus.h>
#include <WiFi.h>
#include "soc/cpu.h"
#include <atomic>

enum Mode
{
None,
Twinkle,
CandyCane,
Worm
};

//NeoPixelBus<NeoRgbFeature, Neo400KbpsMethod> strip(PixelCount, PixelPin);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
[/color]#define PIN 21
volatile int stripLEDs = 600;
volatile int numberOfBands = 20;
volatile int brightnessFactor = 15;
int stripLEDsConfig = 600;
int numberOfBandsConfig = 20;
int brightnessFactorConfig = 15;

NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(stripLEDs, PIN);

const char* ssid = "*******";
const char* password = "******";

WiFiServer server(23);
WiFiClient client;
bool clientActive = false;
volatile bool rotateModeOn = false;
volatile long rotateFreqInSecs = 0;
volatile bool goNoStop = true;
volatile bool doApply = false;
Mode mode = Mode::None;
Mode modeConfig = Mode::Worm;



#define traceOut Serial

// for def all command processors
void ProcessHelp(int Argc, char* Args[]);
void ProcessStop(int Argc, char* Args[]);
void ProcessGo(int Argc, char* Args[]);
void ProcessRestart(int Argc, char* Args[]);
void ProcessSetStripSize(int Argc, char* Args[]);
void ProcessSetNumberOfBands(int Argc, char* Args[]);
void ProcessSetBrightness(int Argc, char* Args[]);
void ProcessApply(int Argc, char* Args[]);
void ProcessStatus(int Argc, char* Args[]);
void ProcessSetMode(int Argc, char* Args[]);
void ProcessSetRotateMode(int Argc, char* Args[]);



typedef void (*CommandProcessor)(int Argc, char* Args[]);
struct CmdDesc
{
char* CmdStr;
CommandProcessor Processor;
char* HelpStr;
};

CmdDesc cmdDescs[] =
{
{"?", ProcessHelp, " - Get this display"},
{"s", ProcessStop, " - Stop the display rotation"},
{"g", ProcessGo, " - Start the display rotation"},
{"r", ProcessRestart, " - Restart the controller"},
{"setstripsize", ProcessSetStripSize, " - setStripSize <number of leds>"},
{"setbandcount", ProcessSetNumberOfBands, " - setBandCount <number of bands>"},
{"brightness", ProcessSetBrightness, " - brightness <divisor>"},
{"mode", ProcessSetMode, " - mode <band | twinkle | worm>"},
{"apply", ProcessApply, " - apply the set config"},
{"status", ProcessStatus, " - status - display system status"},
{"rotate", ProcessSetRotateMode, " - rotate on <secs> | off"},
};
static const int numberOfCmds = sizeof(cmdDescs) / sizeof(CmdDesc);

String NextToken(String& In, int& StartAt)
{
while (StartAt < In.length())
{
if (!isWhitespace(In[StartAt]))
break;

StartAt++;
}

int endAt = StartAt;
while (endAt < In.length())
{
if (isWhitespace(In[endAt]))
break;

endAt++;
}

auto result = In.substring(StartAt, endAt);
result.toLowerCase();
StartAt = endAt + 1;
return result;
}

void ProcessCommand(String& CmdStr)
{
static const int MaxCmdSize = 128;
static const int MaxArgs = 20;

if (CmdStr.length() > MaxCmdSize)
{
client.printf("Error: command too long\n\r");
return;
}

Serial.printf("Cmd: '%s' ", CmdStr.c_str());
for (int i = 0; i < CmdStr.length(); i++)
{
Serial.printf("0x%02X ", CmdStr);
}

Serial.printf("\n");

char stringStorage[MaxCmdSize];
char* freePtr = &stringStorage[0];
char* args[MaxArgs];
int argc = 0;

int start = 0;
while (start < CmdStr.length())
{
auto arg = NextToken(CmdStr, start);
if (arg.length() > 0)
{
printf("Arg (%i): '%s'\n", start, arg.c_str());
memcpy(freePtr, arg.c_str(), arg.length()+1);
args[argc] = freePtr;
freePtr += arg.length()+1;
argc++;
}
}

for (int ix = 0; ix < argc; ix++)
{
printf("Arg(%i) = '%s'\n", ix, args[ix]);
}

// Lookup and dispatch cmd
if (argc > 0)
{
for (int ix = 0; ix < numberOfCmds; ix++)
{
if (strcmp(cmdDescs[ix].CmdStr, args[0]) == 0)
{
cmdDescs[ix].Processor(argc, args);
return;
}
}
client.printf("'%s' is not a valid command\n\r", args[0]);
}
}

// Command processors
void ProcessHelp(int Argc, char* Args[])
{
client.printf("Help:\n\r");
for (int ix = 0; ix < numberOfCmds; ix++)
{
client.printf(" %s %s\n\r", cmdDescs[ix].CmdStr, cmdDescs[ix].HelpStr);
}
}

void ProcessStop(int Argc, char* Args[])
{
goNoStop = false;
client.printf("\n\rStopping\n\r");
}

void ProcessGo(int Argc, char* Args[])
{
goNoStop = true;
client.printf("Starting\n\r");
}

void ProcessRestart(int Argc, char* Args[])
{
client.printf("Restarting\n\r");
client.flush();
ESP.restart();
}

void ProcessSetStripSize(int Argc, char* Args[])
{
if (Argc != 2)
{
client.printf("Syntax errror\n\r");
return;
}
stripLEDsConfig = String(Args[1]).toInt();
}

void ProcessSetNumberOfBands(int Argc, char* Args[])
{
if (Argc != 2)
{
client.printf("Syntax errror\n\r");
return;
}
numberOfBandsConfig = String(Args[1]).toInt();
}

void ProcessSetBrightness(int Argc, char* Args[])
{
if (Argc != 2)
{
client.printf("Syntax errror\n\r");
return;
}
brightnessFactorConfig = String(Args[1]).toInt();
}

void ProcessApply(int Argc, char* Args[])
{
doApply = true;
}

void ProcessStatus(int Argc, char* Args[])
{
client.printf("Status:\n\r");
client.printf(" Strip Size: Active: %u; Config: %u\n\r", stripLEDs, stripLEDsConfig);
client.printf(" Number of bands: Active: %u; Config: %u\n\r", numberOfBands, numberOfBandsConfig);
client.printf(" Brightness: Active: %u; Config: %u\n\r", brightnessFactor, brightnessFactorConfig);
client.printf(" Mode: Active: %u; Config: %u\n\r", mode, modeConfig);
if (rotateModeOn)
{
client.printf(" Rotate: 'on' %lu secs cycle duration\n\r", rotateFreqInSecs);
}
else
{
client.printf(" Rotate: 'off'\n\r");
}
client.printf("\n\r");
}

void ProcessSetMode(int Argc, char* Args[])
{
if (Argc != 2)
{
client.printf("Syntax errror\n\r");
return;
}

if (strcmp(Args[1], "band") == 0)
{
modeConfig = Mode::CandyCane;
}
else if (strcmp(Args[1], "twinkle") == 0)
{
modeConfig = Mode::Twinkle;
}
else if (strcmp(Args[1], "worm") == 0)
{
modeConfig = Mode::Worm;
}
else
{
client.printf("Syntax errror\n\r");
return;
}

client.printf("mode staged - 'apply' when ready\n\r");
}

void ProcessSetRotateMode(int Argc, char* Args[])
{
if (Argc < 2)
{
client.printf("Syntax errror\n\r");
return;
}

if (strcmp(Args[1], "on") == 0)
{
rotateModeOn = false;
if (Argc > 2)
{
rotateFreqInSecs = atoi(Args[2]);
}
rotateModeOn = true;
}
else if (strcmp(Args[1], "off") == 0)
{
rotateModeOn = false;
}
else
{
client.printf("Syntax errror\n\r");
return;
}
}

// WiFi Task
void ForceWiFiConnect(void*)
{
String cmd;

Serial.printf("ForceWiFiConnect: active\n");
while (true)
{
if (WiFi.status() != WL_CONNECTED)
{
digitalWrite(LED_BUILTIN, LOW);
client.stop();
WiFi.disconnect();
Serial.print("Attempting to connect to SSID: ");
traceOut.println(ssid);

WiFi.begin(ssid, password);

// wait 10 seconds for connection:
delay(4000);
if (WiFi.status() == WL_CONNECTED)
{
traceOut.print("IP Address: ");
traceOut.println(WiFi.localIP());
server.begin();
clientActive = false;
digitalWrite(LED_BUILTIN, HIGH);
cmd = "";
}
}
else
{
if (!client)
{
if (clientActive)
{
clientActive = false;
traceOut.println("**Client dropped");
cmd = "";
}
client = server.available();
if (client)
{
traceOut.println("**Client connected: Before flush");
client.flush();
clientActive = true;
traceOut.println("**Client connected");
client.printf("**Welcome **\r\n");
cmd = "";
}
}
else
{
if (client.available() > 0)
{
char cmdChar = client.read();
if (cmdChar == '\n')
{
ProcessCommand(cmd);
cmd = "";
}
else
{
if (cmdChar != '\r')
{
cmd += cmdChar;
}
}
}
}
}
delay(100);
yield();
}
}

void InitStrip()
{
stripLEDs = stripLEDsConfig;
numberOfBands = numberOfBandsConfig;
brightnessFactor = brightnessFactorConfig;
mode = modeConfig;

int colorBandWidth = stripLEDs / numberOfBands;

strip.ClearTo(RgbColor(0, 0, 0));
strip.Show(); // Initialize all pixels to 'off'

if (mode == Mode::CandyCane)
{
for (int i = 0; i < stripLEDs; i += 2 * colorBandWidth)
{
for (int y = 0; y < colorBandWidth; y++)
{
if ((i+y) < stripLEDs)
{
// red band
strip.SetPixelColor(i+y, RgbColor(0xFF / brightnessFactor, 0, 0));
}
}
for (int y = colorBandWidth; y < (2*colorBandWidth); y++)
{
if ((i+y) < stripLEDs)
{
// white band
strip.SetPixelColor(i+y, RgbColor(255/brightnessFactor, 255/brightnessFactor, 255/brightnessFactor));
}
}
}
}
else if (mode == Mode::Worm)
{
for (int i = 0; i < colorBandWidth; i++)
{
uint8_t val = (uint8_t)(colorBandWidth * (1 - ((float)i / colorBandWidth)));
//printf("ix = %u; val = %u\n", i, val);
strip.SetPixelColor((colorBandWidth - i) -1, RgbColor(val, 0, 0));
}
}
else if (mode == Mode::Twinkle)
{
for (int i =0; i < stripLEDs; i++)
{
if (!goNoStop || doApply)
break;

strip.SetPixelColor(i, RgbColor(random(1, 256) / random(1, 50), random(1, 256) / random(1, 50), random(1, 256) / random(1, 50)));
}
}
strip.Show();
// while (true) {}
}


void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(119200);
while (!Serial) {}

strip.Begin();
strip.Show(); // Initialize all pixels to 'off'
InitStrip();

Serial.printf("Main TaskId: %08X; #Tasks: %u\n", (uint32_t)xTaskGetCurrentTaskHandle(), uxTaskGetNumberOfTasks());

TaskHandle_t xHandle;
if (xTaskCreate(ForceWiFiConnect, "WifiTask", 4096, nullptr, configMAX_PRIORITIES / 2, &xHandle) != pdPASS )
{
Serial.printf("WiFiTask could not be created\n");
}
Serial.printf("After WiFiTask created: Main TaskId: %08X; #Tasks: %u\n", (uint32_t)xTaskGetCurrentTaskHandle(), uxTaskGetNumberOfTasks());

}

void loop()
{
if ((mode == Mode::CandyCane) || (mode == Mode::Worm))
{
if (goNoStop)
{
for (int i =0; i < stripLEDs; i++)
{
if (!goNoStop || doApply)
break;

strip.RotateRight(1);
strip.Show();

if (mode == Mode::Worm)
{
delay(0);
}
}
}
}
else if (mode == Mode::Twinkle)
{
int skipSize = random(1, 20);
for (int i =0; i < stripLEDs; i += skipSize)
{
if (!goNoStop || doApply)
break;

strip.SetPixelColor(i, RgbColor(random(1, 256) / random(1, 50), random(1, 256) / random(1, 50), random(1, 256) / random(1, 50)));
}
strip.Show();
delay(random(100));
}

if (doApply)
{
doApply = false;
InitStrip();
}

if (rotateModeOn)
{
static long nextRotateTime = 0;

if (nextRotateTime < millis())
{
static Mode modes[] = {Mode::Worm, Mode::Twinkle, Mode::CandyCane};
static const int nbrOfModes = sizeof(modes) / sizeof(Mode);
static uint8_t ix = 0;

modeConfig = modes[ix];
InitStrip();
ix++;
if (ix == nbrOfModes)
{
ix = 0;
}
printf("{%lu}: New Mode = %u\n", millis(), mode);
nextRotateTime = millis() + (rotateFreqInSecs * 1000); // switch again in 10secs
}
}
}

richhas
Posts: 5
Joined: Sun Jan 22, 2017 5:56 am

Re: esp32 + ws2801 - Need help.

Postby richhas » Wed Jan 09, 2019 9:24 am

Let me try an attachment...
Attachments
xmas-lights-ESP32.ino.txt
(12.76 KiB) Downloaded 257 times

andrewroom
Posts: 4
Joined: Mon Jan 07, 2019 7:56 am

Re: esp32 + ws2801 - Need help.

Postby andrewroom » Wed Jan 09, 2019 9:26 am

Thx a lot!!!

Will try it out tomorrow.

Regards

Andrew

ddnn88
Posts: 3
Joined: Wed Jan 16, 2019 9:36 am

Re: esp32 + ws2801 - Need help.

Postby ddnn88 » Wed Jan 16, 2019 9:43 am

Hi, take a look also at my project at hackster.io where I present how to use RGB LED strips and host http server accessible over the internet in the same time: https://www.hackster.io/donowak/interne ... ino-2ca8a9 .

As Rich mentioned https://github.com/Makuna/NeoPixelBus/ is the best library to use WS28xx LEDs with ESP32. I tested a few and that one works the best.

I hope you'll find it interesting.

Best,
Dominik

andrewroom
Posts: 4
Joined: Mon Jan 07, 2019 7:56 am

Re: esp32 + ws2801 - Need help.

Postby andrewroom » Wed Jan 16, 2019 10:48 am

Thx bro Ill try your project.

My problem is solved. The esp32-module got a problem. I used another one and all is fine. Was a hardware problem...

Thx for your help.

Regards

Andreas

Who is online

Users browsing this forum: No registered users and 8 guests