What happens when you try with the spare micro sd card reader?
What happens when you don't set the SD card reader pins, I dont' with...
Here is an application I use that works for me, perhaps it can provide you with a few hints.
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include "certs.h"
#include "sdkconfig.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#include <BMP388_DEV.h>
#include <ESP32Time.h>
//#include <LinearRegression2d.h>
#include "LinearRegression.h"
//#include "PeakDetection.h"
////
//PeakDetection peakDetection;
ESP32Time rtc;
WiFiClient wifiClient;
PubSubClient MQTTclient(mqtt_server, mqtt_port, wifiClient);
Adafruit_AMG88xx amgL;
Adafruit_AMG88xx amgR;
BMP388_DEV bmp388(15);
LinearRegression lr = LinearRegression();
////
const int pixels = 64;
const int toFileSize = 200;
const int payloadSize = 100;
int count = 0;
int mqttOK = 0;
float outsideTemperature = 0.0f;
bool TimeSet = false;
QueueHandle_t xQ_Message;
QueueHandle_t Q_toFIle;
////
struct stu_message
{
char payload [150] = {'\0'};
String topic;
} x_message;
////
SemaphoreHandle_t sema_MQTT_KeepAlive;
SemaphoreHandle_t sema_mqttOK;
SemaphoreHandle_t sema_SD;
////
////
void IRAM_ATTR mqttCallback(char* topic, byte * payload, unsigned int length)
{
// clear locations
memset( x_message.payload, '\0', 150 );
x_message.topic = ""; //clear string buffer
x_message.topic = topic;
int i = 0;
for ( i; i < length; i++)
{
x_message.payload[i] = ((char)payload[i]);
}
x_message.payload[i] = '\0';
xQueueOverwrite( xQ_Message, (void *) &x_message );// send data
} // void mqttCallback(char* topic, byte* payload, unsigned int length)
////
// interrupt service routine for WiFi events put into IRAM
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
switch (event) {
case SYSTEM_EVENT_STA_CONNECTED:
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
log_i("Disconnected from WiFi access point");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
log_i("WiFi client disconnected");
break;
default: break;
}
} // void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
////
void setup()
{
String toFile = "";
toFile.reserve( toFileSize );
Q_toFIle = xQueueCreate( 5, sizeof(toFile) );
x_message.topic.reserve(150);
xQ_Message = xQueueCreate( 1, sizeof(stu_message) );
//
sema_SD = xSemaphoreCreateBinary();
sema_mqttOK = xSemaphoreCreateBinary();
xSemaphoreGive( sema_mqttOK );
//
xTaskCreatePinnedToCore( fSendToFile, "fSendToFile", 9500, NULL, 3, NULL, 1 );
xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 3500, NULL, 4, NULL, 1 );
xTaskCreatePinnedToCore( fparseMQTT, "fparseMQTT", 12000, NULL, 3, NULL, 1 ); // assign all to core 1, WiFi in use.
xTaskCreatePinnedToCore( fmqttWatchDog, "fmqttWatchDog", 2000, NULL, 3, NULL, 1 ); // assign all to core 1
xTaskCreatePinnedToCore( fMain, "fMain", 20000, NULL, 5, NULL, 1 ); // assign all to core 1
} // setup()
////
void fMain( void *pvParameters )
{
int sensorDelay = 125; // 8 times a second
while ( !MQTTclient.connected() )
{
vTaskDelay( 250 );
}
bool status;
status = amgL.begin();
if (!status) {
log_i( "Could not find a valid AMG88xxL sensor, check wiring!" );
while (1);
}
status = amgR.begin( 0x68 );
if (!status) {
log_i( "Could not find a valid AMG88xxR sensor, check wiring!" );
while (1);
}
bmp388.begin(); // Default initialisation, place the BMP388 into SLEEP_MODE
bmp388.setTimeStandby(TIME_STANDBY_1280MS); // Set the standby time to 1.3 seconds
bmp388.startNormalConversion(); // Start NORMAL continuous conversion
//peakDetection.begin( 16, 4, 0.1); // 16 samples is 2 seconds, approx
///
float FrameL[pixels] = { 0.0f };
float FrameR[pixels] = { 0.0f };
float temperature = 0.0f;
float pressure = 0.0f;
float altitude = 0.0f; // Create the temperature, pressure and altitude variables
float amgAvg = 0.0f;
String toFile = "";
toFile.reserve( toFileSize );
double values[2];
float LastCorrelation = 0.0f;
//int peak = 0;
//
TickType_t xLastWakeTime = xTaskGetTickCount();
const TickType_t xFrequency = sensorDelay; //delay for mS
for (;;)
{
xSemaphoreTake( sema_SD, portMAX_DELAY );
bmp388.getMeasurements(temperature, pressure, altitude);
xSemaphoreGive( sema_SD );
//log_i( "%f", (temperature * 1.8f) + 32.0f );
amgL.readPixels( FrameL );
amgR.readPixels( FrameR );
toFile = "";
lr.Reset();
for (int i = 0; i < pixels; i++ )
{
// divide by 80 to normalize the data, 80 is the max range of the AMG88, 0 is the min range
//lr.learn( i, FrameR[i] / 80.0f, FrameL[i] / 80.0f );
//log_i( "%f %f", FrameR[i], FrameL[i] );
lr.Data( float(i), FrameR[i] );
lr.Data( float(i), FrameL[i] );
}
lr.Parameters( values );
//peakDetection.add( lr.correlation() );
//peak = peakDetection.getPeak();
//log_i( "peak %d", peak );
log_i( "Correlation: %f Values: Y=%f and *X + %f ", lr.Correlation(), values[0], values[1] );
//log_i( "percent of change %f:", 100*((LastCorrelation - lr.correlation()) / LastCorrelation) );
LastCorrelation = lr.Correlation() ;
toFile.concat( "Correlation: " + String(lr.Correlation(), 6) + " Values: Y=" + String(values[0], 6) + " and *X + " + String(values[0], 6) );
toFile.concat( " Temperature:" + String(temperature) + "\n" );
if ( toFile.length() != 0 )
{
toFile.concat( "\n" );
xQueueSend( Q_toFIle, (void *) &toFile, 1 );// send data to sd card handler
}
xLastWakeTime = xTaskGetTickCount();
vTaskDelayUntil( &xLastWakeTime, xFrequency );
//log_i( " high watermark %d", uxTaskGetStackHighWaterMark( NULL ) );
}
vTaskDelete ( NULL );
}
////
void fSendToFile( void * parameter )
{
if (!SD.begin())
{
log_i("Card Mount Failed");
} else {
xSemaphoreGive( sema_SD );
}
String toFile = "";
toFile.reserve( toFileSize );
for (;;)
{
if ( xQueueReceive(Q_toFIle, &toFile, portMAX_DELAY) == pdTRUE )
{
//log_i( "%s %d\n", toFile.c_str(), toFile.length() );
xSemaphoreTake( sema_SD, portMAX_DELAY );
appendFile(SD, "/data.txt", toFile.c_str() + '\n');
xSemaphoreGive( sema_SD );
toFile = "";
}
//log_i( " high watermark %d", uxTaskGetStackHighWaterMark( NULL ) );
}
vTaskDelete( NULL );
}
////
void fmqttWatchDog( void * paramater )
{
int UpdateImeTrigger = 86400; //seconds in a day
int UpdateTimeInterval = 86300; // 1st time update in 100 counts
int maxNonMQTTresponse = 60;
for (;;)
{
vTaskDelay( 1000 );
if ( mqttOK >= maxNonMQTTresponse )
{
ESP.restart();
}
xSemaphoreTake( sema_mqttOK, portMAX_DELAY );
mqttOK++;
xSemaphoreGive( sema_mqttOK );
UpdateTimeInterval++; // trigger new time get
if ( UpdateTimeInterval >= UpdateImeTrigger )
{
TimeSet = false; // sets doneTime to false to get an updated time after a days count of seconds
UpdateTimeInterval = 0;
}
//log_i( " high watermark %d", uxTaskGetStackHighWaterMark( NULL ) );
}
vTaskDelete( NULL );
}
//////
void fparseMQTT( void *pvParameters )
{
struct stu_message px_message;
for (;;)
{
if ( xQueueReceive(xQ_Message, &px_message, portMAX_DELAY) == pdTRUE )
{
if ( px_message.topic == topicOK )
{
xSemaphoreTake( sema_mqttOK, portMAX_DELAY );
mqttOK = 0; // clear mqtt ok count
xSemaphoreGive( sema_mqttOK );
}
if ( !TimeSet )
{
String temp = "";
temp = px_message.payload[0];
temp += px_message.payload[1];
temp += px_message.payload[2];
temp += px_message.payload[3];
int year = temp.toInt();
temp = "";
temp = px_message.payload[5];
temp += px_message.payload[6];
int month = temp.toInt();
temp = "";
temp = px_message.payload[8];
temp += px_message.payload[9];
int day = temp.toInt();
temp = "";
temp = px_message.payload[11];
temp += px_message.payload[12];
int hour = temp.toInt();
temp = "";
temp = px_message.payload[14];
temp += px_message.payload[15];
int min = temp.toInt();
rtc.setTime( 0, min, hour, day, month, year );
log_i( "%s ", rtc.getTime() );
TimeSet = true;
}
if ( px_message.topic == topicOutsideTemperature )
{
//startTheThing = true;
outsideTemperature = String(px_message.payload).toFloat();
}
}
//log_i( " high watermark %d", uxTaskGetStackHighWaterMark( NULL ) );
} //for(;;)
vTaskDelete ( NULL );
} // void fparseMQTT( void *pvParameters )
////
void MQTTkeepalive( void *pvParameters )
{
sema_MQTT_KeepAlive = xSemaphoreCreateBinary();
xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
// setting must be set before a mqtt connection is made, setting is done in void connectToMQTT()
//MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
for (;;)
{
//check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
{
xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
MQTTclient.loop();
xSemaphoreGive( sema_MQTT_KeepAlive );
}
else {
log_i( "MQTT keep alive found MQTT status %s WiFi status %s", String(wifiClient.connected()), String(WiFi.status()) );
if ( !(wifiClient.connected()) || !(WiFi.status() == WL_CONNECTED) )
{
connectToWiFi();
}
connectToMQTT();
}
vTaskDelay( 250 ); //task runs approx every 250 mS
//log_i( " high watermark %d", uxTaskGetStackHighWaterMark( NULL ) );
}
vTaskDelete ( NULL );
}
////
void connectToWiFi()
{
int TryCount = 0;
while ( WiFi.status() != WL_CONNECTED )
{
TryCount++;
WiFi.disconnect();
WiFi.begin( SSID, PASSWORD );
vTaskDelay( 4000 );
if ( TryCount == 10 )
{
ESP.restart();
}
}
WiFi.onEvent( WiFiEvent );
} // void connectToWiFi()
////
void connectToMQTT()
{
MQTTclient.setKeepAlive( 90 ); // needs be made before connecting
byte mac[5];
WiFi.macAddress(mac);
String clientID = String(mac[0]) + String(mac[4]) ; // use mac address to create clientID
while ( !MQTTclient.connected() )
{
// boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
MQTTclient.connect( clientID.c_str(), mqtt_username, mqtt_password, NULL , 1, true, NULL );
vTaskDelay( 250 );
}
MQTTclient.setCallback( mqttCallback );
MQTTclient.subscribe( topicOK );
MQTTclient.subscribe( mqtt_topic );
} // void connectToMQTT()
////
void writeFile(fs::FS &fs, const char * path, const char * message) {
File file = fs.open(path, FILE_WRITE);
if (!file) {
log_i("Failed to open file for writing");
return;
}
if (file.print(message)) {
log_i("File written");
} else {
log_i("Write failed");
}
}
////
void appendFile(fs::FS &fs, const char * path, const char * message) {
//log_i("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file)
{
log_i("Failed to open file for appending");
return;
} else {
file.print(message);
file.close();
}
}
////
void renameFile(fs::FS &fs, const char * path1, const char * path2) {
log_i("Renaming file %s to %s\n", path1, path2);
if (fs.rename(path1, path2)) {
log_i("File renamed");
} else {
log_i("Rename failed");
}
}
////
//void renameFile(fs::FS &fs, const char * path1, const char * path2) {
// log_i("Renaming file %s to %s\n", path1, path2);
// if (fs.rename(path1, path2)) {
// log_i("File renamed");
// } else {
// log_i("Rename failed");
// }
//}
////
void deleteFile(fs::FS &fs, const char * path) {
log_i("Deleting file: %s\n", path);
if (fs.remove(path)) {
log_i("File deleted");
} else {
log_i("Delete failed");
}
}
////
////
void loop() {}