M0 adalogger not writing files to SD card

My project includes these parts from Core Electronics for a temperature monitoring device:
Adafruit Feather M0 Adalogger
DS3231 Precision RTC FeatherWing - RTC Add-on For Feather Boards
Adafruit FeatherWing OLED - 128x64 OLED Add-on For Feather - STEMMA QT / Qwiic
MicroSD Memory Card - 16GB Class 10 (formatted as FAT32)

These are stacked and connected through headers.

The problem:
Files are not created on and written to the SD card in my Arduino IDE sketch. I use Alarm1 to poll the probe (not connected, I am using dummy data until the probes arrive) and store a timestamp with temperature, however it fails to create a file at the line SD.open(fileName, FILE_WRITE). See code below. The SD card passes the if(!SD.begin(4)) test.
The CardInfo example sketch detects the card and displays specs + system files.
The Datalogger example sketch can create the “ANALOG00.TXT” file and subsequent increments (ANALOG01 etc.) but doesn’t write any data to the files.

I expected this microcontroller to work out of the box but it seems my code needs tweaking somewhere.
Two options I found online:

  1. Changing SPI speed. But the default is already 24 Mhz, the max SD functions can operate at.
  2. Changing the line SD.open(filename, FILE_WRITE): It was suggested using this line in setup() and FILE_APPEND in loop().

I have tried creating the file manually and running my sketch but it still fails to open the file for writing to. That is, for the line: if (myFile)… then write… but this is false and it outputs file error in the else test.

I have failed to do this myself and am at the end of my expertise, so I need assistance. Thank you.

Here is my code (apologies, the web interface does not recognise my backticks below):

#include <Wire.h>
#include <SD.h>
#include <Adafruit_SH110X.h>
#include <Adafruit_MAX31865.h>
#include "RTClib.h"

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Display definitions, Adafruit Feather OLED
#define SCREEN_ADDRESS 0x3C 
Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
#define cardSelect 4
#define detectcard 7

// Choose your own 128x64 logo
static const uint8_t PROGMEM grdc[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xc0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x61, 0xf0, 0x3c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7c, 0xf8, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3f, 0xf8, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x1f, 0xfc, 0x1e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x0f, 0xfe, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xfe, 0x0f, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xff, 0x0f, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xff, 0x8f, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0x87, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xc7, 0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x0f, 0xc7, 0xf3, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xc3, 0xf3, 0xf0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x43, 0xf9, 0xf0, 0x30, 0x00, 0x7f, 0x00, 0x7f, 0xe0, 0x0f, 0xf8, 0x00, 0x0f, 0xe0, 
    0xfe, 0x00, 0x03, 0xf9, 0xf8, 0x30, 0x01, 0xff, 0xc0, 0x7f, 0xf8, 0x0f, 0xff, 0x00, 0x3f, 0xf8, 
    0x3f, 0xe0, 0x01, 0xf9, 0xf8, 0x30, 0x03, 0xff, 0xe0, 0x7f, 0xfc, 0x0f, 0xff, 0x80, 0x7f, 0xfc, 
    0x0f, 0xfc, 0x01, 0xfd, 0xfc, 0x38, 0x07, 0xff, 0xe0, 0x7f, 0xfc, 0x0f, 0xff, 0xc0, 0xff, 0xfc, 
    0x03, 0xff, 0x80, 0xfd, 0xfc, 0x38, 0x0f, 0xc3, 0xe0, 0x78, 0x7c, 0x0f, 0x0f, 0xc1, 0xfc, 0x7c, 
    0x00, 0xff, 0xf0, 0xfc, 0xfe, 0x38, 0x0f, 0x81, 0x80, 0x78, 0x3e, 0x0f, 0x03, 0xe1, 0xf0, 0x38, 
    0x00, 0x3f, 0xfc, 0x7c, 0xfe, 0x3c, 0x0f, 0x00, 0x00, 0x78, 0x3e, 0x0f, 0x03, 0xe1, 0xf0, 0x00, 
    0x00, 0x1f, 0xff, 0x3c, 0xff, 0x3c, 0x0f, 0x1f, 0xf0, 0x7f, 0xfc, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x07, 0xff, 0xfc, 0x7f, 0x3e, 0x0f, 0x1f, 0xf0, 0x7f, 0xfc, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x01, 0xff, 0xfc, 0x7f, 0x3e, 0x0f, 0x1f, 0xf0, 0x7f, 0xf8, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x00, 0x7f, 0xf8, 0x7f, 0xbf, 0x0f, 0x9f, 0xf0, 0x7f, 0xf0, 0x0f, 0x03, 0xe1, 0xf0, 0x00, 
    0x00, 0x00, 0x1f, 0xf0, 0x3f, 0x9f, 0x0f, 0x81, 0xf0, 0x79, 0xf0, 0x0f, 0x03, 0xe1, 0xf0, 0x38, 
    0x07, 0xfe, 0x00, 0x00, 0x3f, 0x9f, 0x8f, 0xc1, 0xf0, 0x79, 0xf8, 0x0f, 0x0f, 0xe1, 0xf8, 0x7c, 
    0x03, 0xff, 0xfc, 0x00, 0x3f, 0x9f, 0x87, 0xff, 0xf0, 0x78, 0xf8, 0x0f, 0xff, 0xc0, 0xff, 0xfc, 
    0x00, 0x7f, 0xff, 0xc0, 0x1f, 0x9f, 0xc3, 0xff, 0xe0, 0x78, 0x7c, 0x0f, 0xff, 0x80, 0x7f, 0xfc, 
    0x00, 0x0f, 0xff, 0xf8, 0x1f, 0x8f, 0xc1, 0xff, 0xc0, 0x78, 0x7c, 0x0f, 0xff, 0x00, 0x3f, 0xf8, 
    0x00, 0x03, 0xff, 0xff, 0x0f, 0x8f, 0xe0, 0x7f, 0x00, 0x78, 0x3e, 0x0f, 0xf8, 0x00, 0x0f, 0xe0, 
    0x00, 0x00, 0xff, 0xff, 0xcf, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x3f, 0xff, 0xf7, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x0f, 0xff, 0xff, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x03, 0xff, 0xff, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0xff, 0xfe, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x1f, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x7f, 0xc0, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0xff, 0xff, 0x80, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x0f, 0xff, 0xfc, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x01, 0xff, 0xff, 0xc1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM cesar[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xfe, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x13, 0xf0, 0x0f, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x19, 0xe3, 0xe3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3c, 0xc7, 0xf1, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3e, 0x0f, 0x78, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x1e, 0x3c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x9e, 0x3c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x33, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x21, 0xc2, 0x7f, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x20, 0x00, 0x6c, 0x00, 
    0x7f, 0x21, 0xc2, 0x7f, 0x01, 0x98, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 
    0xff, 0x73, 0xe6, 0x7f, 0x03, 0x01, 0xe3, 0xc7, 0x9e, 0x0d, 0x99, 0x9e, 0xf7, 0x9e, 0x6c, 0xf0, 
    0x7f, 0x7e, 0x3e, 0x7f, 0x03, 0x03, 0x36, 0x68, 0xd8, 0x0d, 0x99, 0xb3, 0x66, 0x23, 0x6d, 0x18, 
    0x00, 0x7e, 0x3e, 0x00, 0x03, 0x03, 0x37, 0x03, 0xd8, 0x0d, 0x99, 0xb8, 0x66, 0x0f, 0x6c, 0x78, 
    0x00, 0x7e, 0x3e, 0x00, 0x03, 0x03, 0xf3, 0xc6, 0xd8, 0x0d, 0x99, 0x9e, 0x66, 0x1b, 0x6c, 0xd8, 
    0xff, 0x33, 0xe6, 0x7f, 0x03, 0x03, 0x00, 0xec, 0xd8, 0x1f, 0xd9, 0x87, 0x66, 0x33, 0x6d, 0x98, 
    0x7f, 0x21, 0xc2, 0x7f, 0x01, 0x9b, 0x36, 0x6c, 0xd8, 0x18, 0xdb, 0xb3, 0x66, 0x33, 0x6d, 0x98, 
    0x7f, 0x21, 0xc2, 0x7f, 0x00, 0xf1, 0xe3, 0xc7, 0xd8, 0x18, 0xcd, 0x9e, 0x36, 0x1f, 0x6c, 0xf8, 
    0x7f, 0x33, 0xe6, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x9f, 0x7c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x1e, 0x3c, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3e, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3c, 0x67, 0xf3, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x18, 0xf1, 0xc7, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x11, 0xf8, 0x0f, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM unimelb[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x41, 0xe7, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xbe, 0x78, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x93, 0xff, 0x96, 0x80, 0x3e, 0x89, 0xe2, 0x24, 0x5d, 0x17, 0x30, 0x4f, 0xf4, 0x41, 0x9f, 
    0x00, 0x7f, 0xff, 0xf8, 0x80, 0x2a, 0x89, 0x02, 0x24, 0x49, 0x14, 0x28, 0xa5, 0x54, 0x42, 0x49, 
    0x00, 0x4f, 0xef, 0xe0, 0x80, 0x08, 0x89, 0x02, 0x26, 0x49, 0x14, 0x24, 0x84, 0x44, 0x44, 0x28, 
    0x00, 0x48, 0x44, 0x18, 0x80, 0x08, 0x89, 0x02, 0x26, 0x49, 0x14, 0x24, 0x84, 0x42, 0x84, 0x28, 
    0x00, 0x44, 0x44, 0x61, 0x00, 0x08, 0xf9, 0xc2, 0x25, 0x48, 0xa7, 0x24, 0x44, 0x43, 0x84, 0x2e, 
    0x00, 0x62, 0x4d, 0x91, 0x00, 0x08, 0x89, 0x02, 0x25, 0x48, 0xa4, 0x38, 0x24, 0x41, 0x04, 0x28, 
    0x00, 0x64, 0x28, 0x22, 0x00, 0x08, 0x89, 0x02, 0x24, 0xc8, 0xa4, 0x28, 0x24, 0x41, 0x04, 0x28, 
    0x00, 0x72, 0x20, 0x42, 0x00, 0x08, 0x89, 0x22, 0x24, 0xc8, 0x64, 0x24, 0xa4, 0x41, 0x02, 0x48, 
    0x00, 0x71, 0x00, 0x86, 0x00, 0x08, 0x89, 0xe1, 0xc4, 0x5c, 0x47, 0x26, 0x4e, 0x43, 0x81, 0x88, 
    0x00, 0x6c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6a, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7b, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xa0, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6f, 0xf3, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x46, 0xcf, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6c, 0x43, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 
    0x00, 0x7e, 0x83, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xcb, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0x94, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x5d, 0xc9, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x48, 0x88, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x5d, 0xc4, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xc3, 0x3c, 0x00, 0x08, 0x10, 0xf9, 0xe3, 0xf0, 0x38, 0x3c, 0xe7, 0xc3, 0x87, 0x3f, 
    0x00, 0x7f, 0xc1, 0x1c, 0x00, 0x08, 0x10, 0xc0, 0xc1, 0x88, 0x64, 0x18, 0x46, 0x63, 0x82, 0x31, 
    0x00, 0x7f, 0xc8, 0x9c, 0x00, 0x08, 0x30, 0xc0, 0xc1, 0x88, 0xc2, 0x18, 0x46, 0x63, 0xc2, 0x30, 
    0x00, 0x7d, 0xce, 0xdc, 0x00, 0x0c, 0x30, 0xc0, 0xc1, 0x91, 0x81, 0x18, 0x46, 0x23, 0xe2, 0x30, 
    0x00, 0x38, 0xc2, 0x38, 0x00, 0x1c, 0x30, 0xc0, 0xc1, 0xa1, 0x81, 0x18, 0x46, 0x63, 0x62, 0x30, 
    0x04, 0x3d, 0xc0, 0x18, 0x40, 0x14, 0x50, 0xf8, 0xc1, 0xe1, 0x81, 0x18, 0x46, 0x43, 0x32, 0x3e, 
    0x3b, 0x3f, 0xff, 0x19, 0xb8, 0x16, 0x58, 0xf8, 0xc1, 0xb1, 0x81, 0x18, 0x47, 0xc3, 0x3a, 0x3e, 
    0x21, 0x1e, 0x00, 0xf1, 0x08, 0x12, 0x58, 0xc0, 0xc1, 0x99, 0x81, 0x18, 0x46, 0xc3, 0x1a, 0x30, 
    0x21, 0x0c, 0x38, 0x61, 0x08, 0x12, 0x98, 0xc0, 0xc1, 0x99, 0x81, 0x18, 0x46, 0x43, 0x0e, 0x30, 
    0x72, 0x99, 0xff, 0xb2, 0x9c, 0x13, 0x98, 0xc0, 0xc1, 0x89, 0x81, 0x18, 0x46, 0x63, 0x0e, 0x30, 
    0x0c, 0xa2, 0xfe, 0x4a, 0x60, 0x11, 0x18, 0xc0, 0xc1, 0x88, 0xc2, 0x18, 0x46, 0x23, 0x06, 0x30, 
    0x04, 0xcc, 0xfe, 0x26, 0x40, 0x11, 0x18, 0xc4, 0xc9, 0x88, 0x64, 0x18, 0xc6, 0x33, 0x02, 0x31, 
    0x07, 0xba, 0x7d, 0xdb, 0xc0, 0x31, 0x1c, 0xfd, 0xfb, 0xf0, 0x38, 0x0f, 0x87, 0x1f, 0x82, 0x7f, 
    0x05, 0xe5, 0x92, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x05, 0x08, 0x44, 0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x0d, 0x30, 0x38, 0x38, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xc0, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM batt[18] = {
    0xff, 0xf8, 
    0xff, 0xf8, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xf8, 
    0xff, 0xf8
};

static const uint8_t PROGMEM batt2[27] = {
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xf0
};

// MAX31865 initialization, CS pin configuration
Adafruit_MAX31865 PT100 = Adafruit_MAX31865(A0);

String print_time(DateTime timestamp) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.hour();
  int Minute = timestamp.minute();
  int Second = timestamp.second();

  sprintf(message, "%d-%d-%d %02d:%02d:%02d", Day, Month, Year, Hour, Minute, Second);

  return message;
}
int TIS = 10;
int bat;
uint8_t status;
uint16_t rREF, rPT;
double temperature;

float getBatteryVoltage() {

    pinMode(BUTTON_A, INPUT);
    float measuredvbat = analogRead(A7);
    delay(1);
    measuredvbat *= 2;    // we divided by 2, so multiply back
    measuredvbat *= 3.3;  // Multiply by 3.3V, our reference voltage
    measuredvbat /= 1024; // convert to voltage
    Serial.print("measuredvbat= ");
    Serial.println(measuredvbat);
    bat = ((measuredvbat - 3) / 1.14) * 100;
    pinMode(BUTTON_A, INPUT_PULLUP);
    return bat;
  }
void setup()   
{
  display.begin(0x3C, true); 
  display.setRotation(1);
 
  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);
  pinMode(detectcard, INPUT_PULLUP);
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0,0);
  
  rtc.disableAlarm(1);
  rtc.clearAlarm(1);
  
  if (rtc.lostPower()) {
    display.clearDisplay();
    display.setCursor(0,0); 
    display.println("RTC lost power. Reset the time!");
    display.display();
    rtc.adjust(DateTime(2021, 4, 22, 0, 0, 0));
  }
   
  // display initialization
  display.clearDisplay();
  display.drawBitmap(0, 0, grdc, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay();
  display.drawBitmap(0, 0, cesar, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay();
  display.drawBitmap(0, 0, unimelb, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay(); 
  display.setCursor(20,16);   
  display.println("PT100");
  display.setCursor(20,24);
  display.println("Temperature");
  display.setCursor(20,32);
  display.println("Logger");
  display.display();
  delay(3000);

  PT100.begin(MAX31865_3WIRE);

  //check probe for errors
  uint8_t status;
  PT100.readRTD();
  display.clearDisplay();
  display.setCursor(0,0);
  display.print("**INITIALIZING");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.println(".");
  display.display();
  delay(1000);
  if (PT100.readFault())
  {
    display.println("Probe failure");
    display.display();
    delay(1000);
  }
  else
  {
    display.println("Probe OK");
    display.display();
    delay(1000);
  }
  if (! rtc.begin()) 
  {
    display.println("RTC failure");
    display.display();
    delay(1000);
  }
  else
  {
    display.println("RTC OK");
    display.display();
    delay(1000);
  }
  if (! SD.begin(cardSelect))   // check SD card
  {
    display.println("SD failure");
    display.display();
    delay(1000 );
  }
  else
  {
    display.println("SD OK");
    display.display();
    delay(1000);
  }
  if (! analogRead(detectcard))   // check SD card
  {
    display.println("No SD card inserted");
    display.display();
    delay(1000 );
  }
  else
  {
    display.println("SD card inserted");
    display.display();
    delay(1000);
  }
  DateTime now = rtc.now();
  rtc.setAlarm2(now + TimeSpan(), DS3231_A2_PerMinute);

  getBatteryVoltage();
}  

void loop() {
  display.clearDisplay();
  DateTime now = rtc.now();
  rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS), DS3231_A1_Minute);
  //temperature = PT100.temperature(rPT, rREF);
  temperature = 30;
  status = PT100.readFault();
  
  //display current time and temperature on OLED
  display.setCursor(0,0);
  display.println(print_time(now));
  
  if (! status) {
    display.println(" >>>PT100 ERROR<<< ");
    }
    else
    {
      display.setTextSize(2);
      display.print(temperature);
      display.print(char(247));
      display.println("C  ");
      display.setTextSize(1);
    }
  display.println("Set logging interval:");
  display.print(TIS);
  display.print(" seconds");
  if (bat > 99) 
  {
    display.drawBitmap(106, 55, batt2, 22, 9, 1);
    display.setCursor(107,56);
    display.setTextColor(SH110X_BLACK);
    display.print(bat);  
    display.setTextColor(SH110X_WHITE);
  }
  else
  {
    display.drawBitmap(113, 55, batt, 15, 9, 1);
    display.setCursor(114,56);
    display.setTextColor(SH110X_BLACK);
    display.print(bat);  
    display.setTextColor(SH110X_WHITE);
  } 
  display.display();

  if (rtc.alarmFired(2) == true)
  { 
    getBatteryVoltage();
    rtc.clearAlarm(2); 
  }
  //BUTTON_A: Begin temp logging
  if (! digitalRead(BUTTON_A))
  {
    while (! digitalRead(BUTTON_A))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
      String fileName = "PT100_log_";
      bool loopFile = true;
      unsigned long i = 1;
      while (loopFile) 
      {
        if (!SD.exists(fileName+String(i)+".txt"))
        {
          display.setCursor(0,40);
          display.println("Creating new logfile");
          display.display();
          delay(1000);
          display.setTextColor(SH110X_BLACK);
          display.setCursor(0,40);
          display.println("Creating new logfile");
          display.display();
          display.setTextColor(SH110X_WHITE);
          loopFile = false;
        }
        else
        { 
          i += 1;
        }
        if (i==99)
        {
          loopFile = false;
        }
      }
      fileName += String(i) + ".txt";
      Serial.println(fileName);
      File myFile = SD.open(fileName, FILE_WRITE);  // FAILS HERE. IT DOES NOT OPEN THE FILE
      
      while(digitalRead(BUTTON_A))
      {
        DateTime now = rtc.now();
        display.clearDisplay();
        //temperature = PT100.temperature(rPT, rREF);
        temperature = 30; //DUMMY DATA
        status = PT100.readFault();
        
        //display current time and temperature on OLED
        display.setCursor(0,0);
        display.println(print_time(now));
        if (!status) {
          display.println(" >>>PT100 ERROR<<< ");
          }
          else
          {
            display.setTextSize(2);
            display.print(temperature);
            display.print(char(247));
            display.println("C  ");
            display.setTextSize(1);
          } 
        display.print("Logging at:");
        display.print(TIS);
        display.println("s int.");
        display.println("Writing to:");
        display.println(fileName);  
        if (bat > 99) 
        {
          display.drawBitmap(106, 55, batt2, 22, 9, 1);
          display.setCursor(107,56);
          display.setTextColor(SH110X_BLACK);
          display.print(bat);  
          display.setTextColor(SH110X_WHITE);
        }
        else
        {
          display.drawBitmap(113, 55, batt, 15, 9, 1);
          display.setCursor(114,56);
          display.setTextColor(SH110X_BLACK);
          display.print(bat);  
          display.setTextColor(SH110X_WHITE);
        }
        display.display(); 
        if (rtc.alarmFired(1) == true) //WRITE TEMP DATA TO SD
        {
          
        display.setCursor(0,56);
        if (myFile) //ALWAYS EQUATES TO FALSE, EVEN IF THE FILE EXISTS
        {
          myFile.println("test");
          myFile.print(print_time(now));
          myFile.print(",");
          myFile.println(temperature);
          display.println("Data written!");
          display.display();
          delay(1000);
        }
        else
        {
          display.println("File error!"); //ALWAYS EQUATES TO TRUE
          display.display();
          delay(1000);
        }
        myFile.flush();  // always write completed lines
        myFile.close();
        rtc.clearAlarm(1); 
        rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS), DS3231_A1_Minute);                 
      }
    }
    while (! digitalRead(BUTTON_A))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
    display.setCursor(0,48);
    display.print("Logging stopped");
    display.display();
    delay(1000);
  }//****END BUTTON_A****

  //BUTTON_B: increment time interval
  if (! digitalRead(BUTTON_B)) 
  {
    display.setCursor(0,32);
    display.setTextColor(SH110X_BLACK);
    display.print(TIS);
    TIS++;
    display.setCursor(0,32);
    display.setTextColor(SH110X_WHITE);
    display.print(TIS);  
    display.display();
    while (! digitalRead(BUTTON_B))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
  }
  //End BUTTON_B
  
  //BUTTON_C: deccrement time interval
  if (! digitalRead(BUTTON_C)) 
  {
    display.setCursor(0,32);
    display.setTextColor(SH110X_BLACK);
    display.print(TIS);
    TIS--;
    if (TIS<5)
    {
      display.setTextColor(SH110X_WHITE);
      display.setCursor(0,40);
      display.println("Can't go below 5");
      display.display();
      TIS = 5;
      delay(2000);
    }
    display.setCursor(0,32);
    display.setTextColor(SH110X_WHITE);
    display.print(TIS);    
    display.display();
    while (! digitalRead(BUTTON_C))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
  }  //END BUTTON_C
}
1 Like

Update:
The datalogger code below works fine with the RTC and OLED plugged in. Is it possible one of the devices is conflicting with the SD card in my code? The line SD.open(fileName, FILE_WRITE) doesn’t complete successfully in my sketch. I’ll try swapping out fileName for a quoted string. This is the only thing left I can think of.

/*
  SD card datalogger

 This example shows how to log data from three analog sensors
 to an SD card using the SD library.

 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

 created  24 Nov 2010
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */

#include <SPI.h>
#include <SD.h>

const int chipSelect = 4;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}

void loop() {
  // make a string for assembling the data to log:
  String dataString = "this is a test";

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}
1 Like

Update:
Removing fileName and replacing it with “datalog.txt” works. It can now write to the file. This means two things:

  1. It cannot handle my specific file name: “PT100_log_1.txt”. Are the underscores an issue?
  2. If it can handle those characters, is it unable to commit the fileName to memory fast enough before SD.open is called? Do I need to add a delay to let the fileName be read by SD.open?
1 Like

Update:

The file name “PT100_log_1.txt” is invalid for some reason.
datalog.csv and datalog1.csv work fine.

I’ll now attempt to use “datalog” and append incremental file numbers to it instead of “PT100_log_”.

1 Like

Update:

After successfully writting data to incrementing files with the base name “datalog#.csv” (so datalog1.csv then datalog2.csv) I thought I could try just creating a file name with a timestamp:
PT100log 26-4-2021 14-21-45.csv for example.
However, SD.h doesn’t seem to accept this file name. It also doesn’t accept “datalog 26-4-2021 14-21-45.csv”.
I will have to look up file name conventions in SD.h

1 Like

OK. Very simple solution here: Arduino - SDCardNotes
SD.h follows FAT 8.3 file format. File names cannot be longer than 8 char long.

Surprised nobody replied to save me days of figuring this out.

1 Like

Hi James - sorry for the delay in getting back to you! I’m glad to see you managed to get this one sorted and thanks so much for posting the solution.

Some of the guys here were trying to chase this down for you and had pulled some stock to try and reproduce but didn’t manage to get far enough along in time - sorry for not keeping you updated!

Thanks anyway. I know you guys are busy.

I’m currently optimising it to keep the filename short. Quite frustrating. Are there any libraries that allow long filenames?

Jason

1 Like

Hmm, not sure off the top of my head, but I know FAT32 can handle up to 255 characters so something able to read/write FAT32 is where I’ll start looking.

SdFat.h Adafruit extension is supposed to support long file names.
So I implemented it. See code below. I concatenate “PT100 Datalog 26-4-2021 14_30_21.csv” for example. This file name successfully prints to the OLED. However, I don’t get that far to test it.
I get an SD failure now when initializing the card. My code “if (!SD.begin(cardselect))” is exactly like others I have downloaded to inspect for the M0 adalogger (example: Instructions | Automated mouse homecage two-bottle choice test v2 | Hackaday.io)
Do I need to change the clock speed?
My code:

//Created by Jason Axford 2021

#include <Wire.h>
#include <SdFat.h>
#include <Adafruit_SH110X.h>
#include <Adafruit_MAX31865.h>
#include <RTClib.h
>

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Display definitions, Adafruit Feather OLED
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
#define cardSelect 4
#define detectcard 7

// Choose your own 128x64 logo
static const uint8_t PROGMEM grdc[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xc0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x61, 0xf0, 0x3c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7c, 0xf8, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3f, 0xf8, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x1f, 0xfc, 0x1e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x0f, 0xfe, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xfe, 0x0f, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xff, 0x0f, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xff, 0x8f, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0x87, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xc7, 0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x0f, 0xc7, 0xf3, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xc3, 0xf3, 0xf0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x43, 0xf9, 0xf0, 0x30, 0x00, 0x7f, 0x00, 0x7f, 0xe0, 0x0f, 0xf8, 0x00, 0x0f, 0xe0, 
    0xfe, 0x00, 0x03, 0xf9, 0xf8, 0x30, 0x01, 0xff, 0xc0, 0x7f, 0xf8, 0x0f, 0xff, 0x00, 0x3f, 0xf8, 
    0x3f, 0xe0, 0x01, 0xf9, 0xf8, 0x30, 0x03, 0xff, 0xe0, 0x7f, 0xfc, 0x0f, 0xff, 0x80, 0x7f, 0xfc, 
    0x0f, 0xfc, 0x01, 0xfd, 0xfc, 0x38, 0x07, 0xff, 0xe0, 0x7f, 0xfc, 0x0f, 0xff, 0xc0, 0xff, 0xfc, 
    0x03, 0xff, 0x80, 0xfd, 0xfc, 0x38, 0x0f, 0xc3, 0xe0, 0x78, 0x7c, 0x0f, 0x0f, 0xc1, 0xfc, 0x7c, 
    0x00, 0xff, 0xf0, 0xfc, 0xfe, 0x38, 0x0f, 0x81, 0x80, 0x78, 0x3e, 0x0f, 0x03, 0xe1, 0xf0, 0x38, 
    0x00, 0x3f, 0xfc, 0x7c, 0xfe, 0x3c, 0x0f, 0x00, 0x00, 0x78, 0x3e, 0x0f, 0x03, 0xe1, 0xf0, 0x00, 
    0x00, 0x1f, 0xff, 0x3c, 0xff, 0x3c, 0x0f, 0x1f, 0xf0, 0x7f, 0xfc, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x07, 0xff, 0xfc, 0x7f, 0x3e, 0x0f, 0x1f, 0xf0, 0x7f, 0xfc, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x01, 0xff, 0xfc, 0x7f, 0x3e, 0x0f, 0x1f, 0xf0, 0x7f, 0xf8, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x00, 0x7f, 0xf8, 0x7f, 0xbf, 0x0f, 0x9f, 0xf0, 0x7f, 0xf0, 0x0f, 0x03, 0xe1, 0xf0, 0x00, 
    0x00, 0x00, 0x1f, 0xf0, 0x3f, 0x9f, 0x0f, 0x81, 0xf0, 0x79, 0xf0, 0x0f, 0x03, 0xe1, 0xf0, 0x38, 
    0x07, 0xfe, 0x00, 0x00, 0x3f, 0x9f, 0x8f, 0xc1, 0xf0, 0x79, 0xf8, 0x0f, 0x0f, 0xe1, 0xf8, 0x7c, 
    0x03, 0xff, 0xfc, 0x00, 0x3f, 0x9f, 0x87, 0xff, 0xf0, 0x78, 0xf8, 0x0f, 0xff, 0xc0, 0xff, 0xfc, 
    0x00, 0x7f, 0xff, 0xc0, 0x1f, 0x9f, 0xc3, 0xff, 0xe0, 0x78, 0x7c, 0x0f, 0xff, 0x80, 0x7f, 0xfc, 
    0x00, 0x0f, 0xff, 0xf8, 0x1f, 0x8f, 0xc1, 0xff, 0xc0, 0x78, 0x7c, 0x0f, 0xff, 0x00, 0x3f, 0xf8, 
    0x00, 0x03, 0xff, 0xff, 0x0f, 0x8f, 0xe0, 0x7f, 0x00, 0x78, 0x3e, 0x0f, 0xf8, 0x00, 0x0f, 0xe0, 
    0x00, 0x00, 0xff, 0xff, 0xcf, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x3f, 0xff, 0xf7, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x0f, 0xff, 0xff, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x03, 0xff, 0xff, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0xff, 0xfe, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x1f, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x7f, 0xc0, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0xff, 0xff, 0x80, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x0f, 0xff, 0xfc, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x01, 0xff, 0xff, 0xc1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM cesar[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xfe, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x13, 0xf0, 0x0f, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x19, 0xe3, 0xe3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3c, 0xc7, 0xf1, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3e, 0x0f, 0x78, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x1e, 0x3c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x9e, 0x3c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x33, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x21, 0xc2, 0x7f, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x20, 0x00, 0x6c, 0x00, 
    0x7f, 0x21, 0xc2, 0x7f, 0x01, 0x98, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 
    0xff, 0x73, 0xe6, 0x7f, 0x03, 0x01, 0xe3, 0xc7, 0x9e, 0x0d, 0x99, 0x9e, 0xf7, 0x9e, 0x6c, 0xf0, 
    0x7f, 0x7e, 0x3e, 0x7f, 0x03, 0x03, 0x36, 0x68, 0xd8, 0x0d, 0x99, 0xb3, 0x66, 0x23, 0x6d, 0x18, 
    0x00, 0x7e, 0x3e, 0x00, 0x03, 0x03, 0x37, 0x03, 0xd8, 0x0d, 0x99, 0xb8, 0x66, 0x0f, 0x6c, 0x78, 
    0x00, 0x7e, 0x3e, 0x00, 0x03, 0x03, 0xf3, 0xc6, 0xd8, 0x0d, 0x99, 0x9e, 0x66, 0x1b, 0x6c, 0xd8, 
    0xff, 0x33, 0xe6, 0x7f, 0x03, 0x03, 0x00, 0xec, 0xd8, 0x1f, 0xd9, 0x87, 0x66, 0x33, 0x6d, 0x98, 
    0x7f, 0x21, 0xc2, 0x7f, 0x01, 0x9b, 0x36, 0x6c, 0xd8, 0x18, 0xdb, 0xb3, 0x66, 0x33, 0x6d, 0x98, 
    0x7f, 0x21, 0xc2, 0x7f, 0x00, 0xf1, 0xe3, 0xc7, 0xd8, 0x18, 0xcd, 0x9e, 0x36, 0x1f, 0x6c, 0xf8, 
    0x7f, 0x33, 0xe6, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x9f, 0x7c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x1e, 0x3c, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3e, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3c, 0x67, 0xf3, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x18, 0xf1, 0xc7, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x11, 0xf8, 0x0f, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM unimelb[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x41, 0xe7, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xbe, 0x78, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x93, 0xff, 0x96, 0x80, 0x3e, 0x89, 0xe2, 0x24, 0x5d, 0x17, 0x30, 0x4f, 0xf4, 0x41, 0x9f, 
    0x00, 0x7f, 0xff, 0xf8, 0x80, 0x2a, 0x89, 0x02, 0x24, 0x49, 0x14, 0x28, 0xa5, 0x54, 0x42, 0x49, 
    0x00, 0x4f, 0xef, 0xe0, 0x80, 0x08, 0x89, 0x02, 0x26, 0x49, 0x14, 0x24, 0x84, 0x44, 0x44, 0x28, 
    0x00, 0x48, 0x44, 0x18, 0x80, 0x08, 0x89, 0x02, 0x26, 0x49, 0x14, 0x24, 0x84, 0x42, 0x84, 0x28, 
    0x00, 0x44, 0x44, 0x61, 0x00, 0x08, 0xf9, 0xc2, 0x25, 0x48, 0xa7, 0x24, 0x44, 0x43, 0x84, 0x2e, 
    0x00, 0x62, 0x4d, 0x91, 0x00, 0x08, 0x89, 0x02, 0x25, 0x48, 0xa4, 0x38, 0x24, 0x41, 0x04, 0x28, 
    0x00, 0x64, 0x28, 0x22, 0x00, 0x08, 0x89, 0x02, 0x24, 0xc8, 0xa4, 0x28, 0x24, 0x41, 0x04, 0x28, 
    0x00, 0x72, 0x20, 0x42, 0x00, 0x08, 0x89, 0x22, 0x24, 0xc8, 0x64, 0x24, 0xa4, 0x41, 0x02, 0x48, 
    0x00, 0x71, 0x00, 0x86, 0x00, 0x08, 0x89, 0xe1, 0xc4, 0x5c, 0x47, 0x26, 0x4e, 0x43, 0x81, 0x88, 
    0x00, 0x6c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6a, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7b, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xa0, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6f, 0xf3, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x46, 0xcf, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6c, 0x43, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 
    0x00, 0x7e, 0x83, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xcb, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0x94, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x5d, 0xc9, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x48, 0x88, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x5d, 0xc4, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xc3, 0x3c, 0x00, 0x08, 0x10, 0xf9, 0xe3, 0xf0, 0x38, 0x3c, 0xe7, 0xc3, 0x87, 0x3f, 
    0x00, 0x7f, 0xc1, 0x1c, 0x00, 0x08, 0x10, 0xc0, 0xc1, 0x88, 0x64, 0x18, 0x46, 0x63, 0x82, 0x31, 
    0x00, 0x7f, 0xc8, 0x9c, 0x00, 0x08, 0x30, 0xc0, 0xc1, 0x88, 0xc2, 0x18, 0x46, 0x63, 0xc2, 0x30, 
    0x00, 0x7d, 0xce, 0xdc, 0x00, 0x0c, 0x30, 0xc0, 0xc1, 0x91, 0x81, 0x18, 0x46, 0x23, 0xe2, 0x30, 
    0x00, 0x38, 0xc2, 0x38, 0x00, 0x1c, 0x30, 0xc0, 0xc1, 0xa1, 0x81, 0x18, 0x46, 0x63, 0x62, 0x30, 
    0x04, 0x3d, 0xc0, 0x18, 0x40, 0x14, 0x50, 0xf8, 0xc1, 0xe1, 0x81, 0x18, 0x46, 0x43, 0x32, 0x3e, 
    0x3b, 0x3f, 0xff, 0x19, 0xb8, 0x16, 0x58, 0xf8, 0xc1, 0xb1, 0x81, 0x18, 0x47, 0xc3, 0x3a, 0x3e, 
    0x21, 0x1e, 0x00, 0xf1, 0x08, 0x12, 0x58, 0xc0, 0xc1, 0x99, 0x81, 0x18, 0x46, 0xc3, 0x1a, 0x30, 
    0x21, 0x0c, 0x38, 0x61, 0x08, 0x12, 0x98, 0xc0, 0xc1, 0x99, 0x81, 0x18, 0x46, 0x43, 0x0e, 0x30, 
    0x72, 0x99, 0xff, 0xb2, 0x9c, 0x13, 0x98, 0xc0, 0xc1, 0x89, 0x81, 0x18, 0x46, 0x63, 0x0e, 0x30, 
    0x0c, 0xa2, 0xfe, 0x4a, 0x60, 0x11, 0x18, 0xc0, 0xc1, 0x88, 0xc2, 0x18, 0x46, 0x23, 0x06, 0x30, 
    0x04, 0xcc, 0xfe, 0x26, 0x40, 0x11, 0x18, 0xc4, 0xc9, 0x88, 0x64, 0x18, 0xc6, 0x33, 0x02, 0x31, 
    0x07, 0xba, 0x7d, 0xdb, 0xc0, 0x31, 0x1c, 0xfd, 0xfb, 0xf0, 0x38, 0x0f, 0x87, 0x1f, 0x82, 0x7f, 
    0x05, 0xe5, 0x92, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x05, 0x08, 0x44, 0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x0d, 0x30, 0x38, 0x38, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xc0, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM batt[18] = {
    0xff, 0xf8, 
    0xff, 0xf8, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xf8, 
    0xff, 0xf8
};

static const uint8_t PROGMEM batt2[27] = {
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xf0
};

// MAX31865 initialization, CS pin configuration
Adafruit_MAX31865 PT100 = Adafruit_MAX31865(A0);

String print_time(DateTime timestamp) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.hour();
  int Minute = timestamp.minute();
  int Second = timestamp.second();

  sprintf(message, "%d-%d-%d %02d:%02d:%02d", Day, Month, Year, Hour, Minute, Second);

  return message;
}
String print_time2(DateTime timestamp) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.hour();
  int Minute = timestamp.minute();
  int Second = timestamp.second();

  sprintf(message, "%d-%d-%d %02d_%02d_%02d", Day, Month, Year, Hour, Minute, Second);

  return message;
}
int TIS = 10;
int bat;
uint8_t status;
uint16_t rREF, rPT;
double temperature;
SdFat SD;
File dataFile;
char fileName[35];

float getBatteryVoltage() {

    pinMode(BUTTON_A, INPUT);
    float measuredvbat = analogRead(A7);
    delay(1);
    measuredvbat *= 2;    // we divided by 2, so multiply back
    measuredvbat *= 3.3;  // Multiply by 3.3V, our reference voltage
    measuredvbat /= 1024; // convert to voltage
    Serial.print("measuredvbat= ");
    Serial.println(measuredvbat);
    bat = ((measuredvbat - 3) / 1.14) * 100;
    pinMode(BUTTON_A, INPUT_PULLUP);
    return bat;
  }
void setup()   
{
  display.begin(0x3C, true); // Address 0x3C default  // display init, I2C addr 0x3C (for the 128x32)
  display.setRotation(1);
 
  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);
  pinMode(detectcard, INPUT_PULLUP);
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0,0);
  
  rtc.disableAlarm(1);
  rtc.clearAlarm(1);
  
  if (rtc.lostPower()) {
    display.clearDisplay();
    display.setCursor(0,0); 
    display.println("RTC lost power. Reset the time!");
    display.display();
    rtc.adjust(DateTime(2021, 4, 22, 0, 0, 0));
  }
  rtc.adjust(DateTime(2021, 4, 26, 14, 20, 0));
  //set all SPI CS pins to high, precaution
  pinMode(4,OUTPUT);
  //pinMode(10,OUTPUT);
  //pinMode(20,OUTPUT);
  //pinMode(21,OUTPUT);
  digitalWrite(4,HIGH);
  //digitalWrite(10,HIGH);
  //digitalWrite(20,HIGH);
  //digitalWrite(21,HIGH);
  
  
  // display initialization
  display.clearDisplay();
  display.drawBitmap(0, 0, grdc, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay();
  display.drawBitmap(0, 0, cesar, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay();
  display.drawBitmap(0, 0, unimelb, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay(); 
  display.setCursor(20,16);   
  display.println("PT100");
  display.setCursor(20,24);
  display.println("Temperature");
  display.setCursor(20,32);
  display.println("Logger");
  display.display();
  delay(3000);

  PT100.begin(MAX31865_3WIRE);

  //check probe for errors
  uint8_t status;
  PT100.readRTD();
  display.clearDisplay();
  display.setCursor(0,0);
  display.print("**INITIALIZING");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.println(".");
  display.display();
  delay(1000);
  if (PT100.readFault())
  {
    display.println("Probe failure");
    display.display();
    delay(1000);
  }
  else
  {
    display.println("Probe OK");
    display.display();
    delay(1000);
  }
  if (!rtc.begin()) 
  {
    display.println("RTC failure");
    display.display();
    delay(1000);
  }
  else
  {
    display.println("RTC OK");
    display.display();
    delay(1000);
  }
  if (!SD.begin(cardSelect))   // check SD card , SD_SCK_MHZ(24)
  {
    display.println("SD failure");
    display.display();
    delay(1000 );
  }
  else
  {
    display.println("SD OK");
    display.display();
    delay(1000);
  }
  if (!analogRead(detectcard))   // check SD card
  {
    display.println("No SD card inserted");
    display.display();
    delay(1000 );
  }
  else
  {
    display.println("SD card inserted");
    display.display();
    delay(1000);
  }
  DateTime now = rtc.now();
  rtc.setAlarm2(now + TimeSpan(), DS3231_A2_PerMinute);

  getBatteryVoltage();
}  

void loop() {
  display.clearDisplay();
  DateTime now = rtc.now();
  rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS), DS3231_A1_Minute);
  //temperature = PT100.temperature(rPT, rREF);
  temperature = 30;
  status = PT100.readFault();
  
  //display current time and temperature on OLED
  display.setCursor(0,0);
  display.println(print_time(now));
  
  if (! status) {
    display.println(" >>>PT100 ERROR<<< ");
    }
    else
    {
      display.setTextSize(2);
      display.print(temperature);
      display.print(char(247));
      display.println("C  ");
      display.setTextSize(1);
    }
  display.println("Set logging interval:");
  display.print(TIS);
  display.print(" seconds");
  if (bat > 99) 
  {
    display.drawBitmap(106, 55, batt2, 22, 9, 1);
    display.setCursor(107,56);
    display.setTextColor(SH110X_BLACK);
    display.print(bat);  
    display.setTextColor(SH110X_WHITE);
  }
  else
  {
    display.drawBitmap(113, 55, batt, 15, 9, 1);
    display.setCursor(114,56);
    display.setTextColor(SH110X_BLACK);
    display.print(bat);  
    display.setTextColor(SH110X_WHITE);
  } 
  display.display();

  if (rtc.alarmFired(2) == true)
  { 
    getBatteryVoltage();
    rtc.clearAlarm(2); 
  }
  //BUTTON_A: Begin temp logging
  if (! digitalRead(BUTTON_A))
  {
    while (! digitalRead(BUTTON_A))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
      memset(fileName, 0, sizeof(fileName)); 
      sprintf(fileName, "PT100 Datalog ");
      //char timenow [20];
      //strncpy(timenow, print_time(now).c_str);
      strcat(fileName, print_time2(now).c_str());
      strcat(fileName, ".csv");
      //bool loopFile = true;
      //unsigned long i = 1;
      
      //while (loopFile)  // create new file T_log_XX.txt every time, maximum T_log_99.txt
      //{
        //if (!SD.exists(fileName))    //+String(i)+".csv"))
       // {
        //  display.setCursor(0,40);
       //   display.println("Creating new logfile");
       //   display.display();
       //   delay(1000);
       //   display.setTextColor(SH110X_BLACK);
       //   display.setCursor(0,40);
       //   display.println("Creating new logfile");
       //   display.display();
       //   display.setTextColor(SH110X_WHITE);
          //loopFile = false;
      //  }
      //  else
      //  { 
      //    i += 1;
      //  }
      //  if (i==99)
      //  {
       //   display.setCursor(0,40);
       //   display.println("Max files reached");
       //   display.display();
      //    delay(1000);
      //    display.setTextColor(SH110X_BLACK);
      //    display.setCursor(0,40);
      //    display.println("Max files reached");
      //    display.display();
       //   display.setTextColor(SH110X_WHITE);
       //   loopFile = false;
     //   }
     // }
      //fileName = "test.csv"; //+= String(i) + ".csv";
      
      while(digitalRead(BUTTON_A))
      {
        DateTime now = rtc.now();
        display.clearDisplay();
        //temperature = PT100.temperature(rPT, rREF);
        temperature = 30;
        status = PT100.readFault();
        
        //display current time and temperature on OLED
        display.setCursor(0,0);
        display.println(print_time(now));
        if (!status) {
          display.println(">>>PT100 ERROR<<<");
          }
          else
          {
            display.setTextSize(2);
            display.print(temperature);
            display.print(char(247));
            display.println("C  ");
            display.setTextSize(1);
          } 
        display.print("Logging at:");
        display.print(TIS);
        display.println("s int.");
        display.println("Writing to:");
        display.println(fileName);  
        if (bat > 99) 
        {
          display.drawBitmap(106, 55, batt2, 22, 9, 1);
          display.setCursor(107,56);
          display.setTextColor(SH110X_BLACK);
          display.print(bat);  
          display.setTextColor(SH110X_WHITE);
        }
        else
        {
          display.drawBitmap(113, 55, batt, 15, 9, 1);
          display.setCursor(114,56);
          display.setTextColor(SH110X_BLACK);
          display.print(bat);  
          display.setTextColor(SH110X_WHITE);
        }
        display.display(); 
        if (rtc.alarmFired(1) == true)
        {
          dataFile = SD.open(fileName, FILE_WRITE);
          if (dataFile) 
          {
            dataFile.print(print_time(now));
            dataFile.print(",");
            dataFile.println(temperature);
            display.println("Data written!");
            display.display();
            dataFile.close();
            delay(1000);
          }
          else
          {
            display.println("File error!");
            display.display();
            delay(1000);
          }
        rtc.clearAlarm(1); 
        rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS), DS3231_A1_Minute);                 
      }
    }
    while (! digitalRead(BUTTON_A))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
    display.setCursor(0,48);
    display.print("Logging stopped");
    display.display();
    delay(1000);
  }//****END BUTTON_A****

  //BUTTON_B: increment time interval
  if (! digitalRead(BUTTON_B)) 
  {
    display.setCursor(0,32);
    display.setTextColor(SH110X_BLACK);
    display.print(TIS);
    TIS++;
    display.setCursor(0,32);
    display.setTextColor(SH110X_WHITE);
    display.print(TIS);  
    display.display();
    while (! digitalRead(BUTTON_B))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
  }
  //End BUTTON_B
  
  //BUTTON_C: deccrement time interval
  if (! digitalRead(BUTTON_C)) 
  {
    display.setCursor(0,32);
    display.setTextColor(SH110X_BLACK);
    display.print(TIS);
    TIS--;
    if (TIS<5)
    {
      display.setTextColor(SH110X_WHITE);
      display.setCursor(0,40);
      display.println("Can't go below 5");
      display.display();
      TIS = 5;
      delay(2000);
    }
    display.setCursor(0,32);
    display.setTextColor(SH110X_WHITE);
    display.print(TIS);    
    display.display();
    while (! digitalRead(BUTTON_C))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
  }  //END BUTTON_C
}
2 Likes

The card was initialized after setting SPI to half:

if (!SD.begin(cardSelect, SPI_HALF_SPEED))

However, the long file name is not being written. I reduced it to “PT100.csv”. A file was written with one line of data printed “26-4-2021 14:20:36,30.00” and “Data written!” printed to the OLED once. But it stops there and doesn’t continue to store anything but the loop is still going. Reducing SPI speed may have made it unstable. I might add a file.flush() command or delays. I have the SdFat.h forked for Adafruit library installed. If anyone can alter my code to get it to communicate reliably with the SD, that would be great. I’ll continue editing.

2 Likes

Another update:
It managed to open and write to the file “PT100datalog 26-4-2021 14_20_45.csv” once and that was it. I repeatedly initiated data logging with the button on the OLED but no more datalogs were written to the SD card. It is unreliable. I might need to reduce SPI speed even further.

2 Likes

I’d suggest stripping right back to basics and working your way forward. Go to a bare minimum file read/write example - get that working then build up from there.

1 Like

I modified the read/write code below, and it works fine.

I tried incorporating the core parts into my code but no luck.
Now the RTC is losing power and resetting during setup(). Something about the RTC (I2C) and SdFat.h is interfering with SD communication over SPI.

// Ported to SdFat from the native Arduino SD library example by Bill Greiman
// On the Ethernet Shield, CS is pin 4. SdFat handles setting SS
const int chipSelect = 4;
/*
 SD card read/write
  
 This example shows how to read and write data to and from an SD card file   
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 created   Nov 2010
 by David A. Mellis
 updated 2 Dec 2010
 by Tom Igoe
 modified by Bill Greiman 11 Apr 2011
 This example code is in the public domain.
   
 */
#include <SdFat.h>
SdFat sd;
SdFile myFile;

void setup() {
  Serial.begin(9600);
  while (!Serial) {}  // wait for Leonardo
  Serial.println("Type any character to start");
  while (Serial.read() <= 0) {}
  delay(400);  // catch Due reset problem
  
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!myFile.open("PT100datalog 26-4-2021 14_20_45.csv", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to PT100datalog 26-4-2021 14_20_45.csv...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
  Serial.println("done.");

  // re-open the file for reading:
  if (!myFile.open("PT100datalog 26-4-2021 14_20_45.csv", O_READ)) {
    sd.errorHalt("opening PT100datalog 26-4-2021 14_20_45.csv.txt for read failed");
  }
  Serial.println("PT100datalog 26-4-2021 14_20_45.csv:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) Serial.write(data);
  // close the file:
  myFile.close();
}

void loop() {
 if (!myFile.open("PT100datalog 26-4-2021 14_20_45.csv", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening PT100datalog 26-4-2021 14_20_45.csv for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to PT100datalog 26-4-2021 14_20_45.csv...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
 
  if (!myFile.open("PT100datalog 26-4-2021 14_20_45.csv", O_READ)) {
    sd.errorHalt("opening PT100datalog 26-4-2021 14_20_45.csv.txt for read failed");
  }
  Serial.println("PT100datalog 26-4-2021 14_20_45.csv:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) Serial.write(data);
  // close the file:
  myFile.close();    
  Serial.println("done.");
}
1 Like

My code works if I remove the rtc.alarmFired(1) == true if test and print data every second to the SD card. For some reason, the rtc alarm 1 is not firing. Even if I trigger an alarm event and just print a check to serial (“alarm1 triggered”), nothing appears.

This is odd since is was triggering data storage when using SD.h.
Alarm2 is working fine and outputs battery voltage every minute.
But now Alarm 1 does not work.
I will now run standalone code with the alarms being triggered to test the RTC.

1 Like

Getting closer to the problem.
Tested Alarm1 function in standalone code. Works fine.
Found this code that may be important:

// stop oscillating signals at SQW Pin
    // otherwise setAlarm1 will fail
    rtc.writeSqwPinMode(DS3231_OFF);

Tested setting Alarm 1 separate to writing data to files: resulting in alarm function interference.
SD function was perfect if it isn’t triggered by Alarm 1. However, I get only two instances where Alarm 1 is triggered, which outputs to serial “alarm1 triggered” but the timing is off (not equal to what the new Alarm 1 is set to).

I think I need to set an SQW triggered interrupt to run a high priority function (data logging).
Can you please advise if I need to physically wire an interrupt pin from the M0 adalogger to the SQW pin on the DS3231 board to obtain the square wave signal?

2 Likes

Solved.

The process of storing data over SPI to the SD card was interfering with resetting alarm1. I found this by serendipitously moving these two lines of code

rtc.clearAlarm(1); 
rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS+1), DS3231_A1_Minute); 

above the code for storing data.
If anyone can provide more technical knowledge as to why the signal for resetting the alarm is interfered by SD communication then please let me know.
My final code:

//Created by Jason Axford 2021

#include <Wire.h>
#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_SH110X.h>
#include <Adafruit_MAX31865.h>
#include <RTClib.h>

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Display definitions, Adafruit Feather OLED
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SH110X display = Adafruit_SH110X(64, 128, &Wire);
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
#define cardSelect 4
#define detectcard 7

// Choose your own 128x64 logo
static const uint8_t PROGMEM grdc[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xc0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x61, 0xf0, 0x3c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7c, 0xf8, 0x1c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3f, 0xf8, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x1f, 0xfc, 0x1e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x0f, 0xfe, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xfe, 0x0f, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xff, 0x0f, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xff, 0x8f, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0x87, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xc7, 0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x0f, 0xc7, 0xf3, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xc3, 0xf3, 0xf0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x43, 0xf9, 0xf0, 0x30, 0x00, 0x7f, 0x00, 0x7f, 0xe0, 0x0f, 0xf8, 0x00, 0x0f, 0xe0, 
    0xfe, 0x00, 0x03, 0xf9, 0xf8, 0x30, 0x01, 0xff, 0xc0, 0x7f, 0xf8, 0x0f, 0xff, 0x00, 0x3f, 0xf8, 
    0x3f, 0xe0, 0x01, 0xf9, 0xf8, 0x30, 0x03, 0xff, 0xe0, 0x7f, 0xfc, 0x0f, 0xff, 0x80, 0x7f, 0xfc, 
    0x0f, 0xfc, 0x01, 0xfd, 0xfc, 0x38, 0x07, 0xff, 0xe0, 0x7f, 0xfc, 0x0f, 0xff, 0xc0, 0xff, 0xfc, 
    0x03, 0xff, 0x80, 0xfd, 0xfc, 0x38, 0x0f, 0xc3, 0xe0, 0x78, 0x7c, 0x0f, 0x0f, 0xc1, 0xfc, 0x7c, 
    0x00, 0xff, 0xf0, 0xfc, 0xfe, 0x38, 0x0f, 0x81, 0x80, 0x78, 0x3e, 0x0f, 0x03, 0xe1, 0xf0, 0x38, 
    0x00, 0x3f, 0xfc, 0x7c, 0xfe, 0x3c, 0x0f, 0x00, 0x00, 0x78, 0x3e, 0x0f, 0x03, 0xe1, 0xf0, 0x00, 
    0x00, 0x1f, 0xff, 0x3c, 0xff, 0x3c, 0x0f, 0x1f, 0xf0, 0x7f, 0xfc, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x07, 0xff, 0xfc, 0x7f, 0x3e, 0x0f, 0x1f, 0xf0, 0x7f, 0xfc, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x01, 0xff, 0xfc, 0x7f, 0x3e, 0x0f, 0x1f, 0xf0, 0x7f, 0xf8, 0x0f, 0x01, 0xe1, 0xe0, 0x00, 
    0x00, 0x00, 0x7f, 0xf8, 0x7f, 0xbf, 0x0f, 0x9f, 0xf0, 0x7f, 0xf0, 0x0f, 0x03, 0xe1, 0xf0, 0x00, 
    0x00, 0x00, 0x1f, 0xf0, 0x3f, 0x9f, 0x0f, 0x81, 0xf0, 0x79, 0xf0, 0x0f, 0x03, 0xe1, 0xf0, 0x38, 
    0x07, 0xfe, 0x00, 0x00, 0x3f, 0x9f, 0x8f, 0xc1, 0xf0, 0x79, 0xf8, 0x0f, 0x0f, 0xe1, 0xf8, 0x7c, 
    0x03, 0xff, 0xfc, 0x00, 0x3f, 0x9f, 0x87, 0xff, 0xf0, 0x78, 0xf8, 0x0f, 0xff, 0xc0, 0xff, 0xfc, 
    0x00, 0x7f, 0xff, 0xc0, 0x1f, 0x9f, 0xc3, 0xff, 0xe0, 0x78, 0x7c, 0x0f, 0xff, 0x80, 0x7f, 0xfc, 
    0x00, 0x0f, 0xff, 0xf8, 0x1f, 0x8f, 0xc1, 0xff, 0xc0, 0x78, 0x7c, 0x0f, 0xff, 0x00, 0x3f, 0xf8, 
    0x00, 0x03, 0xff, 0xff, 0x0f, 0x8f, 0xe0, 0x7f, 0x00, 0x78, 0x3e, 0x0f, 0xf8, 0x00, 0x0f, 0xe0, 
    0x00, 0x00, 0xff, 0xff, 0xcf, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x3f, 0xff, 0xf7, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x0f, 0xff, 0xff, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x03, 0xff, 0xff, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0xff, 0xfe, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x1f, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x7f, 0xc0, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0xff, 0xff, 0x80, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x0f, 0xff, 0xfc, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x01, 0xff, 0xff, 0xc1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x7f, 0xff, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM cesar[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xfe, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x13, 0xf0, 0x0f, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x19, 0xe3, 0xe3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3c, 0xc7, 0xf1, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3e, 0x0f, 0x78, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x1e, 0x3c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x9e, 0x3c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x33, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x21, 0xc2, 0x7f, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x20, 0x00, 0x6c, 0x00, 
    0x7f, 0x21, 0xc2, 0x7f, 0x01, 0x98, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 
    0xff, 0x73, 0xe6, 0x7f, 0x03, 0x01, 0xe3, 0xc7, 0x9e, 0x0d, 0x99, 0x9e, 0xf7, 0x9e, 0x6c, 0xf0, 
    0x7f, 0x7e, 0x3e, 0x7f, 0x03, 0x03, 0x36, 0x68, 0xd8, 0x0d, 0x99, 0xb3, 0x66, 0x23, 0x6d, 0x18, 
    0x00, 0x7e, 0x3e, 0x00, 0x03, 0x03, 0x37, 0x03, 0xd8, 0x0d, 0x99, 0xb8, 0x66, 0x0f, 0x6c, 0x78, 
    0x00, 0x7e, 0x3e, 0x00, 0x03, 0x03, 0xf3, 0xc6, 0xd8, 0x0d, 0x99, 0x9e, 0x66, 0x1b, 0x6c, 0xd8, 
    0xff, 0x33, 0xe6, 0x7f, 0x03, 0x03, 0x00, 0xec, 0xd8, 0x1f, 0xd9, 0x87, 0x66, 0x33, 0x6d, 0x98, 
    0x7f, 0x21, 0xc2, 0x7f, 0x01, 0x9b, 0x36, 0x6c, 0xd8, 0x18, 0xdb, 0xb3, 0x66, 0x33, 0x6d, 0x98, 
    0x7f, 0x21, 0xc2, 0x7f, 0x00, 0xf1, 0xe3, 0xc7, 0xd8, 0x18, 0xcd, 0x9e, 0x36, 0x1f, 0x6c, 0xf8, 
    0x7f, 0x33, 0xe6, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x9f, 0x7c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x7f, 0x1e, 0x3c, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3e, 0x0e, 0x38, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x3c, 0x67, 0xf3, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x18, 0xf1, 0xc7, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x11, 0xf8, 0x0f, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM unimelb[1024] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x41, 0xe7, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0xbe, 0x78, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x93, 0xff, 0x96, 0x80, 0x3e, 0x89, 0xe2, 0x24, 0x5d, 0x17, 0x30, 0x4f, 0xf4, 0x41, 0x9f, 
    0x00, 0x7f, 0xff, 0xf8, 0x80, 0x2a, 0x89, 0x02, 0x24, 0x49, 0x14, 0x28, 0xa5, 0x54, 0x42, 0x49, 
    0x00, 0x4f, 0xef, 0xe0, 0x80, 0x08, 0x89, 0x02, 0x26, 0x49, 0x14, 0x24, 0x84, 0x44, 0x44, 0x28, 
    0x00, 0x48, 0x44, 0x18, 0x80, 0x08, 0x89, 0x02, 0x26, 0x49, 0x14, 0x24, 0x84, 0x42, 0x84, 0x28, 
    0x00, 0x44, 0x44, 0x61, 0x00, 0x08, 0xf9, 0xc2, 0x25, 0x48, 0xa7, 0x24, 0x44, 0x43, 0x84, 0x2e, 
    0x00, 0x62, 0x4d, 0x91, 0x00, 0x08, 0x89, 0x02, 0x25, 0x48, 0xa4, 0x38, 0x24, 0x41, 0x04, 0x28, 
    0x00, 0x64, 0x28, 0x22, 0x00, 0x08, 0x89, 0x02, 0x24, 0xc8, 0xa4, 0x28, 0x24, 0x41, 0x04, 0x28, 
    0x00, 0x72, 0x20, 0x42, 0x00, 0x08, 0x89, 0x22, 0x24, 0xc8, 0x64, 0x24, 0xa4, 0x41, 0x02, 0x48, 
    0x00, 0x71, 0x00, 0x86, 0x00, 0x08, 0x89, 0xe1, 0xc4, 0x5c, 0x47, 0x26, 0x4e, 0x43, 0x81, 0x88, 
    0x00, 0x6c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6a, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7b, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xa0, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6f, 0xf3, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x46, 0xcf, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x6c, 0x43, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 
    0x00, 0x7e, 0x83, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xcb, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0x94, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x5d, 0xc9, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x48, 0x88, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x5d, 0xc4, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x7f, 0xc3, 0x3c, 0x00, 0x08, 0x10, 0xf9, 0xe3, 0xf0, 0x38, 0x3c, 0xe7, 0xc3, 0x87, 0x3f, 
    0x00, 0x7f, 0xc1, 0x1c, 0x00, 0x08, 0x10, 0xc0, 0xc1, 0x88, 0x64, 0x18, 0x46, 0x63, 0x82, 0x31, 
    0x00, 0x7f, 0xc8, 0x9c, 0x00, 0x08, 0x30, 0xc0, 0xc1, 0x88, 0xc2, 0x18, 0x46, 0x63, 0xc2, 0x30, 
    0x00, 0x7d, 0xce, 0xdc, 0x00, 0x0c, 0x30, 0xc0, 0xc1, 0x91, 0x81, 0x18, 0x46, 0x23, 0xe2, 0x30, 
    0x00, 0x38, 0xc2, 0x38, 0x00, 0x1c, 0x30, 0xc0, 0xc1, 0xa1, 0x81, 0x18, 0x46, 0x63, 0x62, 0x30, 
    0x04, 0x3d, 0xc0, 0x18, 0x40, 0x14, 0x50, 0xf8, 0xc1, 0xe1, 0x81, 0x18, 0x46, 0x43, 0x32, 0x3e, 
    0x3b, 0x3f, 0xff, 0x19, 0xb8, 0x16, 0x58, 0xf8, 0xc1, 0xb1, 0x81, 0x18, 0x47, 0xc3, 0x3a, 0x3e, 
    0x21, 0x1e, 0x00, 0xf1, 0x08, 0x12, 0x58, 0xc0, 0xc1, 0x99, 0x81, 0x18, 0x46, 0xc3, 0x1a, 0x30, 
    0x21, 0x0c, 0x38, 0x61, 0x08, 0x12, 0x98, 0xc0, 0xc1, 0x99, 0x81, 0x18, 0x46, 0x43, 0x0e, 0x30, 
    0x72, 0x99, 0xff, 0xb2, 0x9c, 0x13, 0x98, 0xc0, 0xc1, 0x89, 0x81, 0x18, 0x46, 0x63, 0x0e, 0x30, 
    0x0c, 0xa2, 0xfe, 0x4a, 0x60, 0x11, 0x18, 0xc0, 0xc1, 0x88, 0xc2, 0x18, 0x46, 0x23, 0x06, 0x30, 
    0x04, 0xcc, 0xfe, 0x26, 0x40, 0x11, 0x18, 0xc4, 0xc9, 0x88, 0x64, 0x18, 0xc6, 0x33, 0x02, 0x31, 
    0x07, 0xba, 0x7d, 0xdb, 0xc0, 0x31, 0x1c, 0xfd, 0xfb, 0xf0, 0x38, 0x0f, 0x87, 0x1f, 0x82, 0x7f, 
    0x05, 0xe5, 0x92, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x05, 0x08, 0x44, 0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x0d, 0x30, 0x38, 0x38, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x07, 0xc0, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const uint8_t PROGMEM batt[18] = {
    0xff, 0xf8, 
    0xff, 0xf8, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xfe, 
    0xff, 0xf8, 
    0xff, 0xf8
};

static const uint8_t PROGMEM batt2[27] = {
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xfc, 
    0xff, 0xff, 0xf0, 
    0xff, 0xff, 0xf0
};

// MAX31865 initialization, CS pin configuration
Adafruit_MAX31865 PT100 = Adafruit_MAX31865(A0);

String print_time(DateTime timestamp) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.hour();
  int Minute = timestamp.minute();
  int Second = timestamp.second();

  sprintf(message, "%d-%d-%d %02d:%02d:%02d", Day, Month, Year, Hour, Minute, Second);

  return message;
}
String print_time2(DateTime timestamp) {
  char message[120];

  int Year = timestamp.year();
  int Month = timestamp.month();
  int Day = timestamp.day();
  int Hour = timestamp.hour();
  int Minute = timestamp.minute();
  int Second = timestamp.second();

  sprintf(message, "%d-%d-%d %02d_%02d_%02d", Day, Month, Year, Hour, Minute, Second);

  return message;
}
int TIS = 10;
int bat;
uint8_t status;
uint16_t rREF, rPT;
double temperature;
SdFat sd;
SdFile dataFile;
char fileName[35];

float getBatteryVoltage() {

    pinMode(BUTTON_A, INPUT);
    float measuredvbat = analogRead(A7);
    delay(1);
    measuredvbat *= 2;    // we divided by 2, so multiply back
    measuredvbat *= 3.3;  // Multiply by 3.3V, our reference voltage
    measuredvbat /= 1024; // convert to voltage
    Serial.print("measuredvbat= ");
    Serial.println(measuredvbat);
    bat = ((measuredvbat - 3) / 1.14) * 100;
    pinMode(BUTTON_A, INPUT_PULLUP);
    return bat;
  }
void setup()   
{
  display.begin(0x3C, true); // Address 0x3C default  // display init, I2C addr 0x3C (for the 128x32)
  display.setRotation(1);
 
  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);
  pinMode(detectcard, INPUT_PULLUP);
  
  // text display tests
  display.setTextSize(1);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0,0);
  
  rtc.clearAlarm(1);
  rtc.clearAlarm(2);
  //rtc.writeSqwPinMode(DS3231_OFF);
    
  if (rtc.lostPower()) {
    display.clearDisplay();
    display.setCursor(0,0); 
    display.println("RTC lost power. Reset the time!");
    display.display();
    rtc.adjust(DateTime(2021, 4, 22, 0, 0, 0));
  }
  //rtc.adjust(DateTime(2021, 4, 27, 17, 9, 0));
   
  // display initialization
  display.clearDisplay();
  display.drawBitmap(0, 0, grdc, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay();
  display.drawBitmap(0, 0, cesar, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay();
  display.drawBitmap(0, 0, unimelb, 128, 64, 1);
  display.display();
  delay(3000);
  display.clearDisplay(); 
  display.setCursor(20,16);   
  display.println("PT100");
  display.setCursor(20,24);
  display.println("Temperature");
  display.setCursor(20,32);
  display.println("Logger");
  display.display();
  delay(3000);

  PT100.begin(MAX31865_3WIRE);

  //check probe for errors
  uint8_t status;
  PT100.readRTD();
  display.clearDisplay();
  display.setCursor(0,0);
  display.print("**INITIALIZING");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.print(".");
  display.display();
  delay(1000);
  display.println(".");
  display.display();
  delay(1000);
  if (PT100.readFault())
  {
    display.println("Probe failure");
    display.display();
    delay(1000);
  }
  else
  {
    display.println("Probe OK");
    display.display();
    delay(1000);
  }
  if (!rtc.begin()) 
  {
    display.println("RTC failure");
    display.display();
    delay(1000);
  }
  else
  {
    display.println("RTC OK");
    display.display();
    delay(1000);
  }
  if (!sd.begin(cardSelect, SPI_HALF_SPEED))   // check SD card  , SPI_QUARTER_SPEED
  {
    display.println("SD failure");
    display.display();
    delay(1000 );
  }
  else
  {
    display.println("SD OK");
    display.display();
    delay(1000);
  }
  if (!analogRead(detectcard))   // check SD card
  {
    display.println("No SD card inserted");
    display.display();
    delay(1000 );
  }
  else
  {
    display.println("SD card inserted");
    display.display();
    delay(1000);
  }
  DateTime now = rtc.now();
  rtc.setAlarm2(now + TimeSpan(), DS3231_A2_PerMinute);

  getBatteryVoltage();
}  

void loop() {
  display.clearDisplay();
  DateTime now = rtc.now();
  
  //temperature = PT100.temperature(rPT, rREF);
  temperature = 30;
  status = PT100.readFault();
  
  //display current time and temperature on OLED
  display.setCursor(0,0);
  display.println(print_time(now));
  
  if (! status) {
    display.println(" >>>PT100 ERROR<<< ");
    }
    else
    {
      display.setTextSize(2);
      display.print(temperature);
      display.print(char(247));
      display.println("C  ");
      display.setTextSize(1);
    }
  display.println("Set logging interval:");
  display.print(TIS);
  display.print(" seconds");
  if (bat > 99) 
  {
    display.drawBitmap(106, 55, batt2, 22, 9, 1);
    display.setCursor(107,56);
    display.setTextColor(SH110X_BLACK);
    display.print(bat);  
    display.setTextColor(SH110X_WHITE);
  }
  else
  {
    display.drawBitmap(113, 55, batt, 15, 9, 1);
    display.setCursor(114,56);
    display.setTextColor(SH110X_BLACK);
    display.print(bat);  
    display.setTextColor(SH110X_WHITE);
  } 
  display.display();

  if (rtc.alarmFired(2) == true)
  { 
    getBatteryVoltage();
    rtc.clearAlarm(2); 
  }
  //BUTTON_A: Begin temp logging
  if (! digitalRead(BUTTON_A))
  {
    while (! digitalRead(BUTTON_A))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
      rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS+1), DS3231_A1_Minute);
      memset(fileName, 0, sizeof(fileName)); 
      sprintf(fileName, "PT100datalog ");
      strcat(fileName, print_time2(now).c_str());
      strcat(fileName, ".csv");
            
      while(digitalRead(BUTTON_A))
      {
        DateTime now = rtc.now();
        display.clearDisplay();
        //temperature = PT100.temperature(rPT, rREF);
        temperature = 30;
        status = PT100.readFault();
        
        //display current time and temperature on OLED
        display.setCursor(0,0);
        display.println(print_time(now));
        if (!status) {
          display.println(">>>PT100 ERROR<<<");
          }
          else
          {
            display.setTextSize(2);
            display.print(temperature);
            display.print(char(247));
            display.println("C  ");
            display.setTextSize(1);
          } 
        display.print("Logging at:");
        display.print(TIS);
        display.println("s int.");
        display.println("Writing to:");
        display.println(fileName);  
        if (bat > 99) 
        {
          display.drawBitmap(106, 55, batt2, 22, 9, 1);
          display.setCursor(107,56);
          display.setTextColor(SH110X_BLACK);
          display.print(bat);  
          display.setTextColor(SH110X_WHITE);
        }
        else
        {
          display.drawBitmap(113, 55, batt, 15, 9, 1);
          display.setCursor(114,56);
          display.setTextColor(SH110X_BLACK);
          display.print(bat);  
          display.setTextColor(SH110X_WHITE);
        }
        display.display(); 
        if (rtc.alarmFired(1) == true)
        {
          Serial.println("alarm1 triggered"); 
          rtc.clearAlarm(1); 
          rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS+1), DS3231_A1_Minute); 
          if (!dataFile.open(fileName, O_RDWR | O_CREAT | O_AT_END))
          {
            sd.errorHalt("opening test.txt for write failed");
            display.setCursor(0,56);
            display.println("File error!");
            display.display();
            delay(1000);
          }
          else
          {
            dataFile.print(print_time(now));
            dataFile.print(",");
            dataFile.println(temperature);
            display.setCursor(0,56);
            display.println("Data written!");
            Serial.println("Data written!");
            display.display();
            //dataFile.flush();
            dataFile.close();
            delay(2000);
          }
        // rtc.clearAlarm(1); 
        //  rtc.setAlarm1(now + TimeSpan(0, 0, 0, TIS), DS3231_A1_Minute);                 
        }
    if (rtc.alarmFired(2) == true)
    { 
      getBatteryVoltage();
      rtc.clearAlarm(2); 
    }
    }
    while (! digitalRead(BUTTON_A))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
    display.setCursor(0,48);
    display.print("Logging stopped");
    display.display();
    delay(1000);
  }//****END BUTTON_A****

  //BUTTON_B: increment time interval
  if (! digitalRead(BUTTON_B)) 
  {
    display.setCursor(0,32);
    display.setTextColor(SH110X_BLACK);
    display.print(TIS);
    TIS++;
    display.setCursor(0,32);
    display.setTextColor(SH110X_WHITE);
    display.print(TIS);  
    display.display();
    while (! digitalRead(BUTTON_B))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
  }
  //End BUTTON_B
  
  //BUTTON_C: deccrement time interval
  if (! digitalRead(BUTTON_C)) 
  {
    display.setCursor(0,32);
    display.setTextColor(SH110X_BLACK);
    display.print(TIS);
    TIS--;
    if (TIS<5)
    {
      display.setTextColor(SH110X_WHITE);
      display.setCursor(0,40);
      display.println("Can't go below 5");
      display.display();
      TIS = 5;
      delay(2000);
    }
    display.setCursor(0,32);
    display.setTextColor(SH110X_WHITE);
    display.print(TIS);    
    display.display();
    while (! digitalRead(BUTTON_C))   //wait for button depress to prevent cycling
    {
      __asm__("nop\n\t");
    }
  }  //END BUTTON_C
}
2 Likes

Nice work on getting it running:) It’s hard to say - there’s a lot of big libraries included.

I had a quick look, the most noteworthy point is that the RTC is on an I2C interface and it’s writing register values to the RTC when you perform those alarm commands. If there’s an interrupt in there somewhere for writing to the SD card, that could be messing with the I2C communication to the clock, and hence the interference. It’s just a guess though.

1 Like