Hallo zusammen,
ich habe mal das Projekt reduziert, um verschiedene Punkte auszuschließen.
Natürlich gibt es, da der Webserver genutzt wird, noch eine "index.html" und eine "style.css". Darin steht jetzt aber nichts wichtiges, die index.html habe ich sinnlos auf 70kb aufgefüllt, damit beim Abruf über den Browser auch nennenswert Daten übertragen werden. Aber es ist letztlich nur Text.
// Try to avoid random color pixels
// https://github.com/FastLED/FastLED/wiki/Interrupt-problems
#define FASTLED_ALLOW_INTERRUPTS 0
#define FASTLED_INTERRUPT_RETRY_COUNT 0
#include <FastLED.h>
#include <WiFi.h>
// Include WPS library for ESP
#include "esp_wps.h"
// Use library for web server
// from https://github.com/me-no-dev/ESPAsyncWebServer
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
// Include support for SPI File System
#include "SPIFFS.h"
// Task handle
TaskHandle_t handleLEDLoop;
TaskHandle_t handleMainLoop;
// ##########################################
// Data pin for LED strip
#define DATA_PIN 18
// LED strip definition
#define COLUMNS 16
#define ROWS 9
#define NUM_LEDS (COLUMNS * ROWS)
#define BRIGHTNESSDEFAULT 20
uint8_t brightness = BRIGHTNESSDEFAULT;
// Fading steps, bigger steps result in less smoothing but faster handling
#define FADERSTEPSDEFAULT 1
uint8_t fadersteps = FADERSTEPSDEFAULT;
TickType_t leddelay;
// White factor definitions, simulating a warm white light
#define REDFACTOR 1.0
#define GREENFACTOR 0.7
#define BLUEFACTOR 0.3
// LED array
CRGB leds[ NUM_LEDS ];
// ##########################################
WiFiUDP wifiUdp;
#define ESP_WPS_MODE WPS_TYPE_PBC
#define ESP_MANUFACTURER "ESPRESSIF"
#define ESP_MODEL_NUMBER "ESP32"
#define ESP_MODEL_NAME "ESPRESSIF IOT"
#define ESP_DEVICE_NAME "LEDTEST"
static esp_wps_config_t config;
// Network name
const char* hostname = ESP_DEVICE_NAME;
// ##########################################
// Timer definitions
volatile bool timerInterrupt = false;
// ##########################################
// Web server on port 80 / http default
AsyncWebServer server(80);
void setup()
{
Serial.begin( 115200 );
while( !Serial )
vTaskDelay( 100 / portTICK_PERIOD_MS );
Serial.println( "setup(): Initializing LED strip" );
fill_solid( leds, NUM_LEDS, CRGB::Black );
FastLED.addLeds<WS2812B, DATA_PIN, GRB>( leds, NUM_LEDS );
FastLED.setBrightness( 0 );
FastLED.show();
// Initialize SPIFFS
if( !SPIFFS.begin( true ) )
{
Serial.println( "setup(): An Error has occurred while mounting SPIFFS" );
return;
}
// Just deliver index.html, do not check for parameters
server.on( "/", HTTP_GET, []( AsyncWebServerRequest *request )
{
Serial.print("server.on(): Executing on core " );
Serial.println( xPortGetCoreID() );
request->send( SPIFFS, "/index.html", String(), false, processor );
}
);
// Route to load style.css file
server.on( "/style.css", HTTP_GET, []( AsyncWebServerRequest *request )
{
request->send( SPIFFS, "/style.css", "text/css" );
}
);
xTaskCreatePinnedToCore(
LEDLoop, // Task function.
"LEDLoop", // name of task.
10000, // Stack size of task
NULL, // parameter of the task
1, // priority of the task
&handleLEDLoop, // Task handle to keep track of created task
0 ); // pin task to core 0
xTaskCreatePinnedToCore(
MainLoop, // Task function.
"MainLoop", // name of task.
10000, // Stack size of task
NULL, // parameter of the task
1, // priority of the task
&handleMainLoop, // Task handle to keep track of created task
1 ); // pin task to core 0
}
void loop()
{
vTaskDelete( NULL );
}
// ##########################################
// Main loop
void MainLoop( void * parameter )
{
uint32_t waitingTime = 20000;
Serial.print("MainLoop(): Executing on core " );
Serial.println( xPortGetCoreID() );
vTaskDelay( waitingTime / portTICK_PERIOD_MS );
for(;;)
{
Serial.println( "MainLoop(): Connecting to WiFi." );
ConnectToWifi();
vTaskDelay( waitingTime / portTICK_PERIOD_MS );
Serial.println( "MainLoop(): Starting WEB Server." );
server.begin();
vTaskDelay( waitingTime / portTICK_PERIOD_MS );
Serial.println( "MainLoop(): Stopping WEB Server." );
server.end();
vTaskDelay( waitingTime / portTICK_PERIOD_MS );
Serial.println( "MainLoop(): Disconnecting to WiFi." );
WiFi.disconnect();
vTaskDelay( waitingTime / portTICK_PERIOD_MS );
}
}
void LEDLoop( void * parameter )
{
Serial.print("LEDLoop(): Executing on core " );
Serial.println( xPortGetCoreID() );
// Initialize variables
uint8_t column = 2; // Current processed main column
int16_t cell; // Current single LED
uint8_t bright; // Brightness for fading out
uint8_t r, g, b; // RGB values calculated with current correction factor for warm white simulation
uint64_t fpssum, counter;
uint32_t timebefore, timeafter, durationsum;
// Turn off all LEDs, which means to set each LED to black
fill_solid( leds, NUM_LEDS, CRGB::Black );
FastLED.setBrightness( brightness );
FastLED.show();
// Calculate delay
leddelay = 3 * fadersteps / portTICK_PERIOD_MS;
// Set two columns to white
for( uint8_t i = 0; i < ROWS; i++ )
{
r = (uint8_t)( 255 * REDFACTOR );
g = (uint8_t)( 255 * GREENFACTOR );
b = (uint8_t)( 255 * BLUEFACTOR );
// Set the current column to white
leds[ COLUMNS * i + column ] = CRGB( r , g, b );
// Set the next column to white, check for overflow
cell = COLUMNS * i + column + 1;
if( cell > NUM_LEDS )
cell = 0;
leds[ cell ] = CRGB( r , g, b );
}
FastLED.show();
for(;;)
{
fpssum = 0;
counter = 0;
durationsum = 0;
// Fade in right and out left
for( uint8_t j = 0; j < ( 256 - fadersteps ); j += fadersteps )
{
r = (uint8_t)( j * REDFACTOR );
g = (uint8_t)( j * GREENFACTOR );
b = (uint8_t)( j * BLUEFACTOR );
// Fade in right
for( uint8_t i = 0; i < ROWS; i++ )
{
cell = COLUMNS * i + column + 2;
if( cell >= NUM_LEDS )
cell -= NUM_LEDS;
if( cell >= NUM_LEDS ) Serial.println( "LEDLoop(): a cell: " + String( cell ) );
leds[ cell ] = CRGB( r, g, b );
}
// Fade out left
r = (uint8_t)(( 255 - j ) * REDFACTOR );
g = (uint8_t)(( 255 - j ) * GREENFACTOR );
b = (uint8_t)(( 255 - j ) * BLUEFACTOR );
if( r <= fadersteps ) r = 0;
if( g <= fadersteps ) g = 0;
if( b <= fadersteps ) b = 0;
for( uint8_t i = 0; i < ROWS ; i++ )
{
cell = COLUMNS * i + column - 1;
if( column == 0 )
cell += COLUMNS;
if( column < 0 ) Serial.println( "LEDLoop(): b cell: " + String( cell ) );
leds[ cell ] = CRGB( r, g, b );
}
timebefore = micros();
FastLED.show();
timeafter = micros();
durationsum += timeafter - timebefore;
fpssum += FastLED.getFPS();
counter++;
vTaskDelay( leddelay );
}
Serial.print( "LEDLoop(): FPS: " );
Serial.println( fpssum / counter );
Serial.print( "LEDLoop(): Duration sum: " );
Serial.println( durationsum );
// Go to next column
column++;
if( column >= COLUMNS )
column = 0;
}
}
// ##########################################
void wpsInitConfig()
{
config.crypto_funcs = &g_wifi_default_wps_crypto_funcs;
config.wps_type = ESP_WPS_MODE;
strcpy( config.factory_info.manufacturer, ESP_MANUFACTURER );
strcpy( config.factory_info.model_number, ESP_MODEL_NUMBER );
strcpy( config.factory_info.model_name, ESP_MODEL_NAME );
strcpy( config.factory_info.device_name, ESP_DEVICE_NAME );
}
// ##########################################
// Handle WiFi events
void WiFiEvent( WiFiEvent_t event, system_event_info_t info )
{
switch( event )
{
case SYSTEM_EVENT_STA_START:
break;
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println( "WiFiEvent(): Connected to :" + String( WiFi.SSID() ) );
Serial.print( "WiFiEvent(): Got IP: " );
Serial.println( WiFi.localIP() );
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println( "WiFiEvent(): Disconnected from station, attempting reconnection" );
WiFi.reconnect();
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
Serial.println( "WiFiEvent(): WPS successfull, stopping WPS and connecting to: " + String( WiFi.SSID() ) );
esp_wifi_wps_disable();
delay( 10 );
WiFi.begin();
break;
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
Serial.println( "WiFiEvent(): WPS failed, retrying" );
esp_wifi_wps_disable();
esp_wifi_wps_enable( &config );
esp_wifi_wps_start( 0 );
break;
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
Serial.println( "WiFiEvent(): WPS timed out, retrying" );
esp_wifi_wps_disable();
esp_wifi_wps_enable( &config );
esp_wifi_wps_start( 0 );
break;
case SYSTEM_EVENT_STA_WPS_ER_PIN:
break;
default:
break;
}
}
// Connect to WiFi
void ConnectToWifi()
{
uint8_t counter = 30;
WiFi.disconnect();
WiFi.config( INADDR_NONE, INADDR_NONE, INADDR_NONE );
WiFi.setHostname( hostname );
WiFi.begin();
while( WiFi.status() != WL_CONNECTED )
{
if( counter > 0 )
{
counter--;
Serial.print( "." );
vTaskDelay( 500 / portTICK_PERIOD_MS );
}
else
{
Serial.println( "." );
break;
}
}
// Check if connection was successfull
if( WiFi.status() != WL_CONNECTED )
{
// No connection esablished
WiFi.onEvent( WiFiEvent );
WiFi.mode( WIFI_MODE_STA );
Serial.println( "Starting WPS - wpsInitConfig();" );
wpsInitConfig();
esp_wifi_wps_enable( &config );
esp_wifi_wps_start( 0 );
while (WiFi.status() != WL_CONNECTED )
{
Serial.print( "." );
delay( 500 );
}
Serial.println( "Starting WPS - done" );
}
else
{
Serial.print( "ConnectToWifi(): WiFi status: " );
Serial.println( WiFi.status() );
Serial.print( "ConnectToWifi(): WiFi IP address: " );
Serial.println( WiFi.localIP() );
Serial.print( "ConnectToWifi(): WiFi signal strength: " );
Serial.println( WiFi.RSSI() );
}
}
// HTML processor for variable replacement
String processor( const String& var )
{
if( var == "xxx" )
return "XxXxXxX";
return String();
}
In der Funktion LEDLoop wird ein Lauflicht mit ein- und ausblenden simuliert. Nach jedem Schritt lasse ich die Frames per Second als Schnitt ausgeben, weiterhin wird über das komplette Ein- und Ausblenden die Dauer von "FastLED.show()" addiert und ebenfalls ausgegeben.
Damit sehe ich schon, ohne dass LEDs angeschlossen sind, wie diese Zeit beim Aktivieren von WiFi oder Abrufen der index.html über den Web-Server doch deutlich länger wird. Ohne jetzt auch die LEDs überhaupt am Strom zu haben.
Aber ja, ein Elko ist angeschlossen, Strom kommt am Anfang und am Ende hinzu. Und da ich den LED-Streifen aktuell als Spirale um eine Papprolle gewickelt habe, ist die Zuleitung an beiden Seiten kurz.
Gruß
Nils