Hi,
I'm doing a project with a ESP32 board in the Arduino IDE.
I have a SD card attached to my board and I have to read in the appropriate file which can be selected by the user.
My program crashes when I want to change the file with the following command for the SECOND time.
"File file = SD.open("/TB-" + String(soundToPlay) + "Hz.wav");"
So the variable, which is controlled, is soundToPlay. This is also ran in the setup() and the program starts smoothly and produces the sound.
I've done some searching by printing 'test' to check where the program crashes but can't figure out what I should change to make it work.
In short:
- First run of "File file = SD.open("/TB-" + String(soundToPlay) + "Hz.wav");" works
- Second run of "File file = SD.open("/TB-" + String(soundToPlay) + "Hz.wav");" crashes the program
The error is see is:
abort() was called at PC 0x40081d6d on core 1
Backtrace: 0x40089e34:0x3ffbe490 0x4008a061:0x3ffbe4b0 0x40081d6d:0x3ffbe4d0 0x40081e99:0x3ffbe500 0x4000be35:0x3ffbe520 0x40001e0e:0x3ffbe540 0x40001e93:0x3ffbe560 0x400df90c:0x3ffbe580 0x400df9a8:0x3ffbe5b0 0x400d1ae6:0x3ffbe5d0 0x400d1e17:0x3ffbe600 0x400d2079:0x3ffbe640 0x400d176f:0x3ffbe6c0 0x400d178e:0x3ffbe6f0 0x400d138b:0x3ffbe710 0x400d15d6:0x3ffbe760 0x400d1613:0x3ffbe780 0x40080ed5:0x3ffbe7a0 0x400823c9:0x3ffbe7c0 0x400f4cdb:0x3ffbc5a0 0x400e14fb:0x3ffbc5c0 0x40087cf6:0x3ffbc5e0 0x40085e49:0x3ffbc600
[// **** TO DO **** //
// - Dummy proof maken
// - Output volgorde als E-stim vroeger start dan het einde van de Audio
// - Output volgorde als E-stim later eindigt dan de start van het nieuwe Audio signaal
#include "I2S.h"
#include <FS.h>
#include <SD.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// PARAMETERS
int amountOfParameters = 4;
enum parameter {intTime, lengthTime, sepTime, sound};
int soundFile[] = {250, 500, 1000, 1500, 2000, 3000, 4000, 5000};
int audioSignal = 50; // USER PARAM
int audioStartTime = 0;
int tensStartTime = 0;
int tensStopTime = 0;
int intervalStartTime = 0;
int intStart = 100; // USER PARAM
int intStep = 1; // USER PARAM
int intEnd = 200; // USER PARAM
int intAct = intStart;
int lengthStart = 5; // USER PARAM
int lengthStep = 1; // USER PARAM
int lengthEnd = 15; // USER PARAM
int lengthAct = lengthStart;
int sepStart = 60; // USER PARAM
int sepStep = 1; // USER PARAM
int sepEnd = 150; // USER PARAM
int sepAct = sepStart;
// PARAMETER SELECTION
parameter parameterActive = intTime;
int up = 0;
int down = 0;
int prev_interrupt_time = 0;
// SD
#define SD_CS 4 // Chiçp select pin
#define AMP_SD 32 // Amplifier shut down pin
// PUSH BUTON
#define PUSH 34 // Push button
int count1 = 0; // Counter to select parameter
// ENCODER
int encA2 = 0;
int encB2 = 2;
int count2 = 0;
int prev_c2 = 0;
// TENS
#define tens_relais 5
#define ground_relais 15
// LCD
#define SDA 21 // i2c port
#define SCL 22 // i2c port
LiquidCrystal_I2C lcd(0x3F, SCL, SDA);
// WAV FILE
int sound_index = 2;
int soundToPlay = soundFile[sound_index];
const int offset = 0x2C;
char data[13400];
// OUTPUT CONTROL
bool shutDownOutput = 0;
void setup() {
Serial.begin(115200);
I2S_Init();
lcd.init();
lcd.backlight();
pinMode(tens_relais, OUTPUT);
digitalWrite(tens_relais, LOW);
pinMode(ground_relais, OUTPUT);
digitalWrite(ground_relais, HIGH);
pinMode(SD_CS, OUTPUT);
digitalWrite(SD_CS, HIGH);
pinMode(PUSH, INPUT_PULLUP);
attachInterrupt(PUSH, paramSelect, RISING);
pinMode(encA2, INPUT_PULLUP);
pinMode(encB2, INPUT_PULLUP);
attachInterrupt(encA2, doEncoder2, RISING);
loadSound(soundToPlay);
xTaskCreatePinnedToCore(output, "output", 10000, NULL, 1, NULL, 0);
Serial.println("Setup done ----------------------");
}
void output (void * parameters) {
Serial.printf("Output loop pinned to core \t %d\n", xPortGetCoreID());
while (!shutDownOutput) {
// Start interval
intervalStartTime = millis();
// Play audio
audioStartTime = millis();
I2S_Write(data, sizeof(data));
Serial.printf("Audio played for %d milliseconds.\n", millis() - audioStartTime);
// Wait for separation time
while (millis() - audioStartTime < sepAct) {
}
// Put tens on
Serial.printf("Tens signal set high at %d milliseconds.\n", millis() - audioStartTime);
tensStartTime = millis();
digitalWrite(tens_relais, HIGH);
delay(2);
digitalWrite(ground_relais, LOW);
// Wait for tens stimulus time
while (millis() + 1 - tensStartTime < lengthAct) {
}
// Put tens low
digitalWrite(ground_relais, HIGH);
delay(2);
digitalWrite(tens_relais, LOW);
Serial.printf("Tens signal high for %d milliseconds.\n", millis() - tensStartTime);
// Wait for interval time
while (millis() - intervalStartTime < intAct) {
}
Serial.printf("Interval ended at %d milliseconds.\n", millis() - intervalStartTime);
}
}
void loop() {
for (int i = 0; i < amountOfParameters; i++) {
if (i == parameterActive) {
lcd.setCursor(0, i);
lcd.printf(">");
}
else {
lcd.setCursor(0, i);
lcd.printf("-");
}
}
lcd.setCursor(2, 0);
lcd.printf("Interval:");
lcd.setCursor(12, 0);
lcd.printf("%d ", intAct);
lcd.setCursor(2, 1);
lcd.printf("E-stim:");
lcd.setCursor(12, 1);
lcd.printf("%d ", lengthAct);
lcd.setCursor(2, 2);
lcd.printf("Delay:");
lcd.setCursor(12, 2);
lcd.printf("%d ", sepAct);
lcd.setCursor(2, 3);
lcd.printf("Sound:");
lcd.setCursor(12, 3);
lcd.printf("%d ", soundToPlay);
/*
if (tensStopTime > intAct) {
lcd.setCursor(0, 3);
lcd.printf("ERROR!");
}
else {
lcd.setCursor(0, 3);
lcd.printf(" ");
}
*/
delay(200);
}
void paramSelect() {
if (millis() - prev_interrupt_time > 200) {
if (count1 < amountOfParameters - 1) {
count1++;
}
else if (count1 = amountOfParameters - 1) {
count1 = 0;
}
parameterActive = (parameter) count1;
prev_interrupt_time = millis();
}
}
void doEncoder2() {
if (digitalRead(encB2) == LOW) {
up = 1;
down = 0;
// parameterActive = (parameter) count1;
paramUpdate();
}
if (digitalRead(encB2) == HIGH) {
up = 0;
down = 1;
// parameterActive = (parameter) count1;
paramUpdate();
}
}
void paramUpdate() {
switch (parameterActive) {
case intTime:
if (up == 1 && down == 0 && intAct < intEnd) {
intAct = intAct + intStep;
}
else if (intAct > intStart) {
intAct = intAct - intStep;
}
break;
case lengthTime:
if (up == 1 && down == 0 && lengthAct < lengthEnd) {
lengthAct = lengthAct + lengthStep;
}
else if (lengthAct > lengthStart) {
lengthAct = lengthAct - lengthStep;
}
break;
case sepTime:
if (up == 1 && down == 0 && sepAct < sepEnd) {
sepAct = sepAct + sepStep;
}
else if (sepAct > sepStart) {
sepAct = sepAct - sepStep;
}
break;
case sound:
if (up == 1 && down == 0 && sound_index < sizeof(soundFile) / sizeof(int) - 1) {
sound_index++;
soundToPlay = soundFile[sound_index];
}
else if (sound_index > 0) {
sound_index--;
soundToPlay = soundFile[sound_index];
}
loadSound(soundToPlay);
break;
}
}
void loadSound (int soundToPlay) {
if (!SD.begin(SD_CS)) {
Serial.println("SD mount failed!");
}
else {
Serial.println("SD mount succes!");
}
Serial.print("test ");
Serial.print("Sound loaded: ");
Serial.println("/TB-" + String(soundToPlay) + "Hz.wav");
File file = SD.open("/TB-" + String(soundToPlay) + "Hz.wav");
Serial.print("test ");
file.seek(offset);
Serial.print("test ");
file.readBytes(data, sizeof(data));
Serial.print("test ");
file.close();
}
//Serial.printf("...... function pinned to core \t %d\n", xPortGetCoreID());/code]