I shorten the code and show below, I guess I know the cause of crash,
it's while(true) loop in play_animation() .
- when I comment out // music can play and stop, but start field animation can play only 1 time and after delete task, it never run again after creat task.
- when I included loop while(true) , it crased and return the error "assert bla bla bla"
so I 'm sure it's all about while(true) loop,
Full Sketch please download here -> freertos_starfield
snapshot -> Picture
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <TFT_eSPI.h>
#include <esp_task_wdt.h>
//Pin configuration
#define BUZZER_PIN 26//speaker
#define SELECTOR_PIN 27//push button
// setting PWM properties
#define backlightChannel 0
#define buzzerChannel 2
#include "music.h"
#include "nes_audio.h"
Cartridge player(BUZZER_PIN);//not specified 4 pin , use 1 pin at buzzer pin
// Use hardware SPI
TFT_eSPI tft = TFT_eSPI();
// With 1024 stars the update rate is ~65 frames per second
#define NSTARS 1024
uint8_t sx[NSTARS] = {};
uint8_t sy[NSTARS] = {};
uint8_t sz[NSTARS] = {};
uint8_t za, zb, zc, zx;
TaskHandle_t TaskHandle0 = NULL;
uint8_t rng() {
zx++;
za = (za^zc^zx);
zb = (zb+za);
zc = ((zc+(zb>>1))^za);
return zc;
}
void TaskStarField(void *pvParameters) // This is a task.
{
esp_task_wdt_init(30, false);
while(true) {
unsigned long t0 = micros();
uint8_t spawnDepthVariation = 255;
for(int i = 0; i < NSTARS; ++i)
{
if (sz[i] <= 1)
{
sx[i] = 160 - 120 + rng();
sy[i] = rng();
sz[i] = spawnDepthVariation--;
}
else
{
int old_screen_x = ((int)sx[i] - 160) * 256 / sz[i] + 160;
int old_screen_y = ((int)sy[i] - 120) * 256 / sz[i] + 120;
// This is a faster pixel drawing function for occassions where many single pixels must be drawn
tft.drawPixel(old_screen_x, old_screen_y,TFT_BLACK);
sz[i] -= 2;
if (sz[i] > 1)
{
int screen_x = ((int)sx[i] - 160) * 256 / sz[i] + 160;
int screen_y = ((int)sy[i] - 120) * 256 / sz[i] + 120;
if (screen_x >= 0 && screen_y >= 0 && screen_x < 320 && screen_y < 240)
{
uint8_t r, g, b;
r = g = b = 255 - sz[i];
tft.drawPixel(screen_x, screen_y, tft.color565(r,g,b));
}
else
sz[i] = 0; // Out of screen, die.
}
}
}
tft.setTextColor(TFT_YELLOW);
tft.drawCentreString("Star Field Animation",159,50,4);
tft.drawFastHLine(0,80,320,TFT_RED);
tft.setTextColor(TFT_BLACK,TFT_WHITE);
tft.drawCentreString("[- Press button to exit -]",159,180,2);
// Calcualte frames per second
unsigned long t1 = micros();
Serial.println(1.0/((t1 - t0)/1000000.0));
}
}
void play_animation() {//control configuration menu
while(true) { //when I uncomment while true, ESP32 crashed
xTaskCreatePinnedToCore(//create task
&TaskStarField
, "TaskStarField" // A name just for humans
, 1024 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, &TaskHandle0
, 0);
player.play_nes(starwars , true, 0.5); //play nes music, loop, volume 0.5
//there is if (digitalRead(27) == LOW) break; inside play_nes to exit from play
//music loop in nes_audio.cpp
vTaskDelete(TaskHandle0);//delete task.
}
}
// the setup function runs once when you press reset or power the board
void setup() {
za = random(256);
zb = random(256);
zc = random(256);
zx = random(256);
//pin configuration
pinMode(BUZZER_PIN,OUTPUT);//speaker
pinMode(SELECTOR_PIN,INPUT_PULLUP);//button
//pwm setup
ledcSetup(buzzerChannel, 1500, 10);//buzzer 10 bit
ledcSetup(backlightChannel, 12000, 8);//backlight 8 bit
ledcAttachPin(BUZZER_PIN, buzzerChannel);//attach buzzer
Serial.begin(115200);
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
tft.setSwapBytes(true);
}
void loop()
{
if (digitalRead(SELECTOR_PIN) == LOW) {//button pressed
Serial.println("BEGIN");
delay(200);//delay avoid bounce
play_animation();//open config menu
Serial.println("END");
delay(200);//delay avoid bounce
}
}