In my project logging data from BME-280 and DS18B20 I found problems with the SD card and the TFT display.
ESP32 wroom32 dev.kit v1 DOIT wonderfull.
BME-280 and DS18B20 sensors.
Combined SD and TFT module 1.8 TFT SPI 128x160 with Async webserver,OTA,SPIFFS
The display works fine with OliKraus library Ucglib on Ucglib_ST7735_18x128x160 ( test )
The whole build together will give a malfunction on the SD card???
Both SW_SPI and HW_SPI Oli Kraus GrapicsTest.ino works fine.
HW_SPI cd=4 , cs=15 , rst=12 note: only display
SW_SPI sclk=18 , data=23 , cd=4 , cs=15 , rst=12 note: only display
Combine test SD and Display
HW_SPI same pin as above used SD write and read works display came on delayed for 10 sec??
SW_SPI same ….. SD write and read works display will not work stay blank???????
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun 8 2016 00:22:57
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac
SD Card Type: SDHC
SD Card Size: 3829MB
Listing directory: /
DIR : /System Volume Information
FILE: /-.CSV SIZE: 2233
FILE: /test.txt SIZE: 1048576
FILE: /foo.txt SIZE: 13
Creating Dir: /mydir
Dir created
Listing directory: /
DIR : /System Volume Information
FILE: /-.CSV SIZE: 2233
FILE: /test.txt SIZE: 1048576
FILE: /foo.txt SIZE: 13
DIR : /mydir
Removing Dir: /mydir
Dir removed
Listing directory: /
DIR : /System Volume Information
Listing directory: /System Volume Information
FILE: /System Volume Information/WPSettings.dat SIZE: 12
FILE: /System Volume Information/IndexerVolumeGuid SIZE: 76
FILE: /-.CSV SIZE: 2233
FILE: /test.txt SIZE: 1048576
FILE: /foo.txt SIZE: 13
Writing file: /hello.txt
File written
Appending to file: /hello.txt
Message appended
Reading file: /hello.txt
Read from file: Hello World!
Deleting file: /foo.txt
File deleted
Renaming file /hello.txt to /foo.txt
File renamed
Reading file: /foo.txt
Read from file: Hello World!
1048576 bytes read for 3009 ms
1048576 bytes written for 5634 ms
Total space: 3821MB
Used space: 1MB
In my program I used the HW_SPI for SD and display will not work together.
[code// ****************** AsyncWebserver ******************
#include <AsyncEventSource.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
// *************** DALLAS temp. *****************
#include <OneWire.h>
#include <DallasTemperature.h>
//***** WIFI *************
#include <WiFi.h>
#include <WiFiUdp.h> // nodig voor de tijd NTP
//***** OTA *************
#include <ArduinoOTA.h> // Over the air programming
//****** SPIFFS *******
#include <SPIFFS.h> // SPIFFS file flashen
//*********ESPmDNS **********
#include <ESPmDNS.h>
//************* FS ****************
#include <FS.h>
#include <FSImpl.h>
#include <vfs_api.h>
//*********** DISPLAY ************************
#include "Ucglib.h"
Ucglib_ST7735_18x128x160_HWSPI ucg(/*cd=*/ 4, /*cs=*/ 15, /*reset=*/ 12);
//Ucglib_ST7735_18x128x160_SWSPI ucg(/*sclk=*/ 18, /*data=*/ 23, /*cd=*/ 4, /*cs=*/ 15, /*reset=*/ 12);
// ***** SD ****************
#include <SD.h>
#include <sd_defines.h>
#include <sd_diskio.h>
#include <SPI.h>
#define CS_PIN 2 // chipselect pin gedefinieerd SD card
File dataFile;
File filename;
//***** TIME *****
#include <time.h>
long timezone = 1;
byte daysavetime = 1;
//*********** DALLAS temp. *************
#define TEMP_SENSOR_PIN 5
OneWire oneWire(TEMP_SENSOR_PIN); // Set up a OneWire instance to communicate with OneWire devices
DallasTemperature sensors(&oneWire); // Create an instance of the temperature sensor class
//*************** BME280*************************
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C SDA=21 en SCL=22
//********* OTA *************
const char *OTAName = "ESP8266"; // A name and a password for the OTA service
const char *OTAPassword = "esp8266";
const char* mdnsName = "esp8266"; // Domain name for the mDNS responder
const char* ssid = "mmmmm"; // Replace with your network credentials
const char* password = "nnnnn";
const int ledPin = 13; // Set LED GPIO13
String ledState; // Stores LED state
String yy;
String mm;
String dd;
String hr;
String mi;
String se;
String dataMessage; // met gegevens om te loggen
String headerMessage; // file header met colom gegevens datum, tijd, tempbi,hum,press,tempbu
String tempbi; // van BME
String humidity; // van BME
String pressure; // van BME
String tempbu;
String temperature;
//************** FS ***********************
File fsUploadFile; // a File variable to temporarily store the received file
//************* WIFI server *******************
AsyncWebServer server(80);
// ********************* BME-280 *********************************
String getTemperature() { // Variable to store the HTTP request String header;
float temperature = bme.readTemperature();
Serial.println(temperature);
return String(temperature);
}
String getHumidity() {
float humidity = bme.readHumidity();
Serial.println(humidity);
return String(humidity);
}
String getPressure() {
float pressure = bme.readPressure()/ 100.0F;
Serial.println(pressure);
return String(pressure);
}
//********************** DS18B20 *************************************************
String readDSTemperatureC() { // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
sensors.requestTemperatures();
float tempbu = sensors.getTempCByIndex(0);
Serial.println(tempbu);
return String(tempbu);
}
//************************** LED etc.*******************************************
String processor(const String& var){ // Replaces placeholder with LED state value
Serial.println(var);
if(var == "STATE"){ // var in index.html page (id)
if(digitalRead(ledPin)){
ledState = "ON";
}
else{
ledState = "OFF";
}
Serial.print(ledState);
return ledState;
}
else if (var == "TEMPERATURE"){ // var in index.html page (id)
return getTemperature(); // BME-280 temperature binnen
}
else if (var == "HUMIDITY"){ // var in index.html page (id)
return getHumidity();
}
else if (var == "PRESSURE"){ // var in index.html page (id)
return getPressure();
}
else if (var == "TEMPBU"){ // var in index.html page (id)
return readDSTemperatureC(); // DS18B20 buiten
}
}
//**************** SET-UP *******************
void setup(){
Serial.begin(115200);
pinMode(ledPin, OUTPUT); // bool status;
pinMode(2, OUTPUT);
SPI.begin();
sensors.begin(); // Start up the DS18B20 library
bme.begin();
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
startSD();
startWIFI();
ucg.begin(UCG_FONT_MODE_TRANSPARENT); // maakt achtergrond
ucg.setColor(0, 120, 0, 0);
ucg.setColor(2, 0, 120, 0);
ucg.setColor(1, 120, 0, 120);
ucg.setColor(3, 0, 120, 120);
ucg.drawGradientBox(0, 0, ucg.getWidth(), ucg.getHeight());
ArduinoOTA
.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
if(!SPIFFS.begin()){ // Initialize SPIFFS
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ // Route for root / web page
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){ // was /favicon.ico
request->send(SPIFFS, "/favicon.png", "image/png");
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to load style.css file
request->send(SPIFFS, "/style.css", "text/css");
});
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to set GPIO to HIGH
digitalWrite(ledPin, HIGH);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to set GPIO to LOW
digitalWrite(ledPin, LOW);
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to the BME Temperature
request->send_P(200, "text/plain", getTemperature().c_str());
});
server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to the BME Humidity
request->send_P(200, "text/plain", getHumidity().c_str());
});
server.on("/pressure", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to the BME Pressure
request->send_P(200, "text/plain", getPressure().c_str());
});
server.on("/tempbu", HTTP_GET, [](AsyncWebServerRequest *request){ // Route to the DS18B20 Temperature
request->send_P(200, "text/plain", readDSTemperatureC().c_str());
});
server.begin(); // Start server
}
//******************* LOOP *********************
void loop(){
ArduinoOTA.handle();
startTIME();
getReadings();
getBME();
useDisplay();
logSDCard();
}
//*************** VOIDS ***************
void startSD() {
SD.begin(2);
Serial.print("Initializing SD card...");
if (!SD.begin(2))
{
Serial.println("Card failed, or not present"); // see if the card is present and can be initialized:
while (1) ; // don't do anything more: nu mag door ook als er geen kaart is
}
Serial.println("card initialized.");
delay(10);
Serial.println("\r\n");
}
void startWIFI() {
WiFi.begin(ssid, password); // Connect to Wi-Fi
WiFi.mode(WIFI_STA);
while (WiFi.status() != WL_CONNECTED) {
delay(100); // was 1000
Serial.println("Connecting to WiFi..");
}
Serial.println(WiFi.localIP()); // Print ESP32 Local IP Address
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void getReadings(){ // Function to get DS18B20 temperature
sensors.requestTemperatures();
tempbu = sensors.getTempCByIndex(0); // Temperature in Celsius
}
void getBME() { // BME-280 readings
tempbi = bme.readTemperature();
humidity = bme.readHumidity();
pressure = bme.readPressure()/ 100.0F;
}
void logSDCard() {
String path = "/" + mm + "-" + dd + ".csv";
headerMessage = "Tijd, Tempbu, \n";
dataMessage = String(dd) + String(tempbu)+"\r\n";
File file = SD.open(path.c_str());
if(!file) {
Serial.println("File doens't exist");
Serial.println("Creating file...");
writeFile(SD, path.c_str(), headerMessage.c_str());
}
else {
Serial.println("File already exists");
}
file.close();
if (dd != dd) { // nieuwe dag
writeFile(SD, path.c_str(), headerMessage.c_str());
}
else {
appendFile(SD, path.c_str(), dataMessage.c_str());
}
}
void useDisplay(){
float tempbu = sensors.getTempCByIndex(0);
delay(20);
ucg_int_t y = 0;
ucg_int_t h = 14;
ucg.setRotate270();
y += h;
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setPrintPos(4,y);
ucg.setFont(ucg_font_helvB08_tr);
ucg.print("Pressure:");
ucg.setFontMode(UCG_FONT_MODE_SOLID);
ucg.setFont(ucg_font_7x13_mr);
ucg.setColor(0, 255, 255, 255); // use white as main color for the font
ucg.setColor(1, 64, 64, 255); // use blue as background for SOLID mode
ucg.setPrintPos(80,y);
ucg.print(pressure);
y += h;
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setPrintPos(4,y);
ucg.setFont(ucg_font_helvB08_tr);
ucg.print("Humidity:");
ucg.setFontMode(UCG_FONT_MODE_SOLID);
ucg.setFont(ucg_font_helvB08_tr);
ucg.setColor(0, 255, 255, 255); // use white as main color for the font
ucg.setColor(1, 64, 64, 255); // use blue as background for SOLID mode
ucg.setPrintPos(80,y);
ucg.print(humidity);
y += h;
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setPrintPos(4,y);
ucg.setFont(ucg_font_helvB08_tr);
ucg.print("Temperature:");
ucg.setFontMode(UCG_FONT_MODE_SOLID);
ucg.setFont(ucg_font_helvB08_tr);
ucg.setColor(0, 255, 255, 255); // use white as main color for the font
ucg.setColor(1, 64, 64, 255); // use blue as background for SOLID mode
ucg.setPrintPos(80,y);
ucg.print(tempbi);
y += h;
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setPrintPos(4,y);
ucg.setFont(ucg_font_helvB08_tr);
ucg.print("Temp. buiten:");
if (tempbu <= 20 ) {
ucg.setColor(0, 255, 40, 80);
ucg.setColor(1, 0, 255, 0);
ucg.setColor(2, 255, 0, 0);
ucg.setColor(3, 65, 255, 40);// 3,65,255,40
ucg.drawGradientBox(80-2, y-10, 40, 12);// red to green bar will erase the previous value
} else if(tempbu >20) {
ucg.setColor(3, 255, 40, 80);// 3,255,40,80
ucg.setColor(2, 0, 255, 0);
ucg.setColor(1, 255, 0, 0);
ucg.setColor(0, 65, 255, 40);
ucg.drawGradientBox(80-2, y-10, 40, 12);
}
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setFont(ucg_font_7x13_mr);
ucg.setColor(0, 255, 255, 255); // use white as main color for the font
ucg.setPrintPos(80,y);
ucg.print(tempbu);
y += h;
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setPrintPos(4,y);
ucg.setFont(ucg_font_helvB08_tr);
ucg.print("Status LED:");
if (digitalRead(ledPin )) {
ucg.setColor(3, 255, 40, 80);
ucg.setColor(2, 0, 255, 0);
ucg.setColor(1, 255, 0, 0);
ucg.setColor(0, 65, 255, 40);
ucg.drawGradientBox(80-2, y-10, 40, 12); // red to green bar will erase the previous value
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setFont(ucg_font_7x13_mr);
ucg.setColor(0, 255, 255, 255); // use white as main color for the font
ucg.setPrintPos(80,y);
ucg.print("ON");
} else {
ucg.setColor(0, 255, 40, 80);
ucg.setColor(1, 0, 255, 0);
ucg.setColor(2, 255, 0, 0);
ucg.setColor(3, 65, 255, 40);
ucg.drawGradientBox(80-2, y-10, 40, 12);
ucg.setFontMode(UCG_FONT_MODE_TRANSPARENT);
ucg.setFont(ucg_font_7x13_mr);
ucg.setColor(0, 255, 255, 255); // use white as main color for the font
ucg.setPrintPos(100,y);
ucg.print("OFF");
}
}
void startmDNS() {
// Set up mDNS responder:
// - first argument is the domain name, in this example
// the fully-qualified domain name is "esp8266.local"
// - second argument is the IP address to advertise
// we send our IP address on the WiFi network
if (!MDNS.begin("esp32")) {
Serial.println("Error setting up MDNS responder!");
while(1) {
delay(100);
}
}
Serial.println("mDNS responder started");
server.begin(); // Start TCP (HTTP) server
Serial.println("TCP server started");
MDNS.addService("http", "tcp", 80); // Add service to MDNS-SD
}
void appendFile(fs::FS &fs, const char * path, const char * message) { // Append data to the SD card (DON'T MODIFY THIS FUNCTION)
Serial.println("");
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file) {
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)) {
Serial.println("Message");
Serial.print(dataMessage.c_str());
Serial.println("Appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void writeFile(fs::FS &fs, const char * path, const char * message) { // Write to the SD card (DON'T MODIFY THIS FUNCTION)
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file) {
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)) {
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
void startTIME() {
Serial.println("Contacting Time Server");
configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
struct tm tmstruct ;
delay(100);
hr = (tmstruct.tm_hour);
mi = (tmstruct.tm_min);
se = (tmstruct.tm_sec);
tmstruct.tm_year = 0;
getLocalTime(&tmstruct, 5000);
Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1900,( tmstruct.tm_mon)+1, tmstruct.tm_mday,tmstruct.tm_hour , tmstruct.tm_min, tmstruct.tm_sec);
Serial.println("");
int yy = (tmstruct.tm_year)+1900;
String year;
year=String(yy);
Serial.println(year);
int mm = (tmstruct.tm_mon)+1;
String month;
month=String(mm);
Serial.println(month);
int dd = (tmstruct.tm_mday);
String day;
day=String(dd);
Serial.println(day);
}
//********* HELPER FUNCTIES **************************************
String formatBytes(size_t bytes) { // convert sizes in bytes to KB and MB
if (bytes < 1024) {
return String(bytes) + "B";
} else if (bytes < (1024 * 1024)) {
return String(bytes / 1024.0) + "KB";
} else if (bytes < (1024 * 1024 * 1024)) {
return String(bytes / 1024.0 / 1024.0) + "MB";
}
}
String getContentType(String filename) { // determine the filetype of a given filename, based on the extension
if (filename.endsWith(".html")) return "text/html";
else if (filename.endsWith(".css")) return "text/css";
else if (filename.endsWith(".js")) return "application/javascript";
else if (filename.endsWith(".ico")) return "image/x-icon";
else if (filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}][/code]
I already looked into the postings related to SD problems withgout any luck s.a SdFat from Greig.
Any help on this issue is more than welcome.
Like to hear,
ilioSS