#ifndef _HELPER_H
#define _HELPER_H
// Return the minimum of two values a and b
#define minimum(a,b) (((a) < (b)) ? (a) : (b))
void SetFgBg(int fg, int bg) {
tft.setBackColor(bg);
tft.setColor(fg);
}
void ClearScreen() {
tft.clrScr();
}
// *************************** BASIC I/O SYSTEM *****************************************
void BiosMenu(uint8_t v) {
tft.clrScr();
SetFgBg(DKBLUE, BLACK);
tft.setColor(DKBLUE);
tft.drawRect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
tft.fillRect(0, 0, SCREEN_WIDTH - 1, 15);
SetFgBg(WHITE, DKBLUE);
tft.setFont(SmallFont);
tft.print("ETMS - CapSoft Ltd. MiUAIG BIOS (c) 2020 - 2021", CENTER, 2);
switch (v) {
case 0:
tft.setColor(RED);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, RED);
tft.print("Main Information", CENTER, 305);
break;
case 1:
tft.setColor(PINK);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, PINK);
tft.print("Touchscreen Calibration", CENTER, 305);
break;
case 2:
tft.setColor(DKBLUE);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, DKBLUE);
tft.print("Sensor Information", CENTER, 305);
break;
case 3:
tft.setColor(RED);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, RED);
tft.print("Drive Information", CENTER, 305);
break;
case 4:
tft.setColor(RED);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, RED);
tft.print("Data Logs", CENTER, 305);
break;
case 5:
tft.setColor(DKBLUE);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, DKBLUE);
tft.print("Graph Data", CENTER, 305);
break;
case 6:
tft.setColor(BLUE);
tft.fillRect(0, 302, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
SetFgBg(WHITE, BLUE);
tft.print("2 CH SCOPE", CENTER, 305);
break;
default:
break;
}
}
//====================================================================================
/*
******************** Menu System V1.1 ***********************************
*/
void MenuSystem(uint16_t msc , uint16_t msr, uint8_t level) {
uint8_t vo = 5;
uint8_t bw = 80;
uint8_t bh = 20;
tft.setColor(BLACK);
switch (level)
{
case 0:
for (int i = 0; i < 9; i++) {
tft.setColor(BLUE);
tft.fillRoundRect(msc, msr, msc + bw, msr + bh);
SetFgBg(YELLOW, BLUE);
tft.print(MainMenuText[i], msc + 10, msr + vo);
msr = msr + bh + 10;
}
break;
case 1:
for (int i = 0; i < 9; i++) {
tft.setColor(BLUE);
tft.fillRoundRect(msc, msr, msc + bw, msr + bh);
tft.setBackColor(BLUE);
tft.setColor(YELLOW);
tft.print(AuxMenuText[i], msc + 10, msr + vo);
msr = msr + bh + 10;
}
break;
default:
break;
}
}
/*
* ********************************* Show all data on one page.....
*/
void ShowAll() {
BiosMenu(2);
SetFgBg(BLUE, BLACK);
tft.drawRect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1);
/* Get a new sensor event */
sensors_event_t event;
mag.getEvent(&event);
float heading = atan2(event.magnetic.y, event.magnetic.x);
float declinationAngle = 0.22;
heading += declinationAngle;
if (heading < 0)
heading += 2 * PI;
if (heading > 2 * PI)
heading -= 2 * PI;
headingDegrees = heading * 180 / M_PI; // Convert radians to degrees for readability.
tft.print("Current Heading: ", 100, 20);
tft.printNumF(headingDegrees, 0 , 240, 20);
tft.print("degrees", 290, 20);
if (CCS811_READY) {
//compensating the CCS811 with humidity and temperature readings from the HDC1080
myCCS811.setEnvironmentalData(myHDC1080.readHumidity(), myHDC1080.readTemperature());
myCCS811.readAlgorithmResults();
tft.print("Temp=", 20, 40);
tft.printNumF(myHDC1080.readTemperature(), 2, 65, 40);
tft.print("C", 130, 40);
tft.print("Humidity=", 180, 40);
tft.printNumI(myHDC1080.readHumidity(), 255, 40);
tft.print("%", 275, 40);
tft.print("Baro=", 320, 40);
tft.printNumF(myBME280.readFloatPressure() * 0.00750062, 2, 365, 40);
tft.print(" hPa", 420, 40);
tft.print("Alt.=", 20, 60);
tft.printNumF(myBME280.readFloatAltitudeMeters(), 2, 65, 60);
tft.print("m", 140, 60);
tft.print("CO2=", 180, 60);
tft.printNumF(myCCS811.getCO2(), 2, 220, 60);
tft.print("ppm", 280, 60);
tft.print("TVOC=", 320, 60);
tft.printNumF(myCCS811.getTVOC(), 3, 365, 60);
tft.print("ppb", 420, 60);
}
if (SI1145_READY) {
tft.print("Vis:", 20, 80);
tft.printNumI(light_data.readVisible(), 60, 80);
tft.print("UV Index:", 180, 80);
tft.printNumF(light_data.readUV() / 100, 3, 255, 80);
tft.print("Ir:", 320, 80);
tft.printNumI(light_data.readIR(), 350, 80);
}
sensors_event_t a, g, temp;
myGyro.getEvent(&a, &g, &temp);
/* Print out the values */
tft.print("Acceleration X:", 20, 100);
tft.printNumF(a.acceleration.x, 3, 150, 100);
tft.print(", Y:", 190, 100);
tft.printNumF(a.acceleration.y, 3, 240, 100);
tft.print(", Z:", 300, 100);
tft.printNumF(a.acceleration.z, 3, 340, 100);
tft.print("m/s^2", 400, 100);
tft.print("Rotation X:", 20, 120);
tft.printNumF(g.gyro.x, 3, 150, 120);
tft.print(", Y:", 190, 120);
tft.printNumF(g.gyro.y, 3, 240, 120);
tft.print(", Z:", 300, 120);
tft.printNumF(g.gyro.z, 3, 340, 120);
tft.print(" rad/s", 400, 120);
tft.print("IMU IC Temp: ", 20, 140);
tft.printNumF(temp.temperature, 2, 130, 140);
tft.print("deg C", 175, 140);
tft.print("Analog CH0:", 20, 160); tft.printNumI(analogRead(0), 110, 160); tft.print("mV", 150, 160);
tft.print("Analog CH1:", 180, 160); tft.printNumI(analogRead(1), 270, 160); tft.print("mV", 310, 160);
tft.print("Analog CH2:", 340, 160); tft.printNumI(analogRead(2), 430, 160); tft.print("mV", 460, 160);
tft.print("Analog CH3:", 20, 180); tft.printNumI(analogRead(3), 110, 180); tft.print("mV", 150, 160);
tft.print("Analog CH4:", 180, 180); tft.printNumI(analogRead(4), 270, 180); tft.print("mV", 310, 160);
tft.print("Analog CH5:", 340, 180); tft.printNumI(analogRead(5), 430, 180); tft.print("mV", 460, 160);
delay(4000);
}
/*
* ************************** DISPLAY *******************************************************
*/
void InitDisplay() {
tft.InitLCD(0);
delay(30);
BiosMenu(0);
SetFgBg(RED, BLACK);
tft.print("ST7796S TFT controller initialized OK", CENTER, 40);
tft.print("XPT2046 Touch sort of OK?", CENTER, 60);
}
/*
* *************** TOUCH *********************************************************************
*/
void InitMyTouch() {
myTouch.begin();
//myTouch.calibrate(cal);
}
/*
xpos & ypos are screen coordinates!
*/
void DrawCalTarget(int xpos, int ypos) {
SetFgBg(RED, BLACK);
tft.drawCircle (xpos, ypos, 6);
tft.drawLine(xpos - 5, ypos, xpos + 5, ypos);
tft.drawLine(xpos, ypos - 5, xpos, ypos + 5);
}
void ParseTouchData(int x, int y) {
SetFgBg(GREEN, BLACK);
float xpos, ypos;
tft.print( "Touch Raw Data:", 130, 20);
tft.print( "X= ", 255, 20);
xpos = (((float)x / 4096) * SCREEN_WIDTH);
ypos = (((float)y / 4096 ) * SCREEN_HEIGHT);
tft.printNumI(xpos , 275, 20);
tft.print( "Y= ", 315, 20 );
tft.printNumI(ypos , 335, 20);
DrawCalTarget(xpos, ypos);
delay(100);
}
/*
******************* ScanI2CBus is implemented - 10/02/2020 *****************************************
*/
void ScanI2CBus() {
byte error, address;
int nDevices;
Wire.begin();
Wire.setClock(50000);
tft.setFont(SmallFont);
tft.print("I2C Bus Scan:", 20, 260);
tft.print("Scanning...", 180, 260);
int row = 100;
for (address = 1; address < 127; address++ )
{
/*
The i2c_scanner uses the return value of
the Write.endTransmisstion to see if
a device did acknowledge to the address.
*/
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
tft.print("I2C device at address > ", 30, row);
String str = String(address, HEX);
tft.print("0x" + str, 235, row);
//tft.printNumI(address, 240, row);
if (address == 61) {
tft.print("OLED Display2", 280, row);
}
if (address == 0x40) {
tft.print("HDC1080 Humidity", 280, row);
HDC1080_AVAIL = true;
}
if (address == 0x51) {
tft.print("24C32 EEPROM", 280, row);
EEPROM_AVAIL = true;
}
if (address == 0x57) {
tft.print("MAX30102 Oxiometer", 280, row);
MAX30102_AVAIL = true;
}
if (address == 0x5A) {
tft.print("CCS811 Air Quality", 280, row);
CCS811_AVAIL = true;
}
if (address == 0x60) {
tft.print("Si1145 Light Quality", 280, row);
SI1145_AVAIL = true;
}
if (address == 0x76) {
tft.print("BME280 Atmospherics", 280, row);
BME280_AVAIL = true;
}
if (address == 0x68) {
tft.print("DS3231 RTC", 280, row);
DS3231_AVAIL = true;
}
if (address == 0x69) {
tft.print("MPU6050 Gyro/Accel", 280, row);
MPU6050_AVAIL = true;
}
if (address == 0x1E) {
tft.print("HMC5883 Compass", 280, row);
HMC5883_AVAIL = true;
}
row = row + 12;
nDevices++;
delay(500);
}
else if (error == 4)
{
tft.print("Unknown error at address >", 20, 260);
tft.printNumI(address, 220, 260);
}
}
if (nDevices == 0)
{
tft.print("No I2C devices found ", 260, 260);
}
else
{
tft.print("Done.... ", 180, 260);
}
delay(2000);
}
/*
Initialize any i2c device that was found by scan - hence RUN Scan First!
*/
void InitI2CDevices() {
// for all the found devices an attempt to start devices and if started _READY will be true
if (DS3231_AVAIL) {
DS3231_READY = true;
}
if (BME280_AVAIL) {
myBME280.settings.commInterface = I2C_MODE;
myBME280.settings.I2CAddress = 0x76;
myBME280.settings.runMode = 3; //Normal mode
myBME280.settings.tStandby = 0;
myBME280.settings.filter = 4;
myBME280.settings.tempOverSample = 5;
myBME280.settings.pressOverSample = 5;
myBME280.settings.humidOverSample = 5;
myBME280.begin();
}
if (SI1145_AVAIL) {
light_data.begin(SI1145_ADDR);
SI1145_READY = true;
}
if (CCS811_AVAIL) {
myCCS811.begin();
CCS811_READY = true;
}
if (HDC1080_AVAIL) {
myHDC1080.begin(HDC1080_ADDR);
HDC1080_READY = true;
}
if (MLX90614_AVAIL) {
mlx.begin();
MLX90614_READY = true;
}
if (MPU6050_AVAIL) {
// init gyro myGyro
myGyro.begin(0x69);
myGyro.setAccelerometerRange(MPU6050_RANGE_8_G);
myGyro.setGyroRange(MPU6050_RANGE_500_DEG);
myGyro.setFilterBandwidth(MPU6050_BAND_21_HZ);
MPU6050_READY = true;
}
if (HMC5883_AVAIL) {
// init compass mag
mag.begin();
}
if (MAX30102_AVAIL) {
// init oximeter
particleSensor.begin(Wire, I2C_SPEED_FAST); //Use default I2C port, 400kHz speed
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
}
}
/*
*********************** COMPASS *************************************************
*/
void ShowCompassDetails(void) {
ClearScreen();
sensor_t sensor;
mag.getSensor(&sensor);
tft.setFont(SmallFont);
tft.setColor(BLUE);
tft.print("Sensor:", 100, 120); tft.print((sensor.name), 200, 120);
tft.print("Driver Ver:", 100, 140); tft.printNumI((sensor.version), 200, 140);
tft.print("Unique ID:", 100, 160); tft.printNumI((sensor.sensor_id), 200, 160);
}
/*
this plot function checks for the boundaries of the field of view, ie., the tft dimensional limits.
if the values of x and y are outside of the limits the plot is ignored.
*/
void PlotXY(int x, int y) {
if ((480 < x >= 0 ) & (320 < y >= 0)) {
tft.drawPixel(x, y);
}
}
/*
Plot a sine wave
*/
void DemoPlot() {
SetFgBg(YELLOW, BLACK);
int yoffset = 160;
float dtr = 3.141592 / 180;
float yval = 0;
int xval = 0;
for (int xpos = 45; xpos < 460; xpos += 1) {
yval = sin(dtr * xval);
yval = (yval * 100)+yoffset;
PlotXY(xpos, yval);
Serial.println(yval);
xval += 1;
}
}
/*
Main Graph plot...
*/
void ShowGraph(int Gtype) {
tft.clrScr();
//draw grid as defined by Gtype
BiosMenu(5);
int ScaleXMax = 60;
tft.setColor(GREEN);
tft.drawLine(40, 20, 40, 280);
tft.drawLine(40, 280, 460, 280);
for (int ypos = 20; ypos < 280; ypos += 20) {
tft.drawLine(35, ypos, 55, ypos);
for (int xi = 45; xi < 460; xi += 20) {
tft.drawPixel(xi, ypos);
}
SetFgBg(WHITE, BLACK);
tft.printNumI(ScaleXMax, 1, ypos - 5);
tft.setColor(GREEN);
ScaleXMax -= 10;
}
for (int xpos = 45; xpos < 460; xpos += 20) {
tft.drawLine(xpos, 275, xpos, 285);
}
}
/*
RTC
*/
void ShowClock() {
if (DS3231_READY) {
tft.clrScr();
int xpos = 10;
int ypos = 40;
DateTime now = Clock.now();
tft.print("Current Date:", xpos, ypos);
xpos += 110;
tft.printNumI(now.year(), xpos, ypos);
xpos += 50;
tft.print("/", xpos, ypos);
xpos += 8;
tft.printNumI(now.month(), xpos, ypos);
xpos += 14;
tft.print("/", xpos, ypos);
xpos += 8;
tft.printNumI(now.day(), xpos, ypos);
xpos += 14;
tft.print("(", xpos, ypos);
xpos += 24;
tft.print(daysOfTheWeek[now.dayOfTheWeek()], xpos, ypos);
xpos += 100;
tft.print(")", xpos, ypos);
xpos = 10;
ypos += 20;
tft.print("Current Time:", xpos, ypos);
xpos += 110;
tft.printNumI(now.hour(), xpos, ypos);
xpos += 14;
tft.print(":", xpos, ypos); xpos += 8;
tft.printNumI(now.minute(), xpos, ypos); xpos += 14;
tft.print(":", xpos, ypos); xpos += 8;
tft.printNumI(now.second(), xpos, ypos);
}
}
void SetClock(int MM, int DD, int YY, int hh, int mm, int ss) {
Clock.adjust(DateTime(YY, MM, DD, hh, mm, ss));
DateTime now = Clock.now();
}
/*
* ******************* IR sensor ******************************
*/
void ReadIRTemp() {
Wire.setClock(100000);
OTC = mlx.readObjectTempC();
OTF = mlx.readObjectTempF();
ATC = mlx.readAmbientTempC();
ATF = mlx.readAmbientTempF();
Wire.setClock(400000);
}
/*
****************** Oxi ***************************************
*/
void ScanOximeter() {
long irValue = particleSensor.getIR(); //Read IR value to know if there's a finger on the sensor or not
if (irValue > 7000) {
// tft.drawBitmap(5, 5,24 ,21,SmallHeart,1); //Draw the first bmp picture (little heart)
}
}
// Return the minimum of two values a and b
#define minimum(a,b) (((a) < (b)) ? (a) : (b))
//====================================================================================
// Decode and render onto the TFT screen
//====================================================================================
void renderJPEG(int xpos, int ypos) {
// retrieve infomration about the image
uint16_t *pImg;
uint16_t mcu_w = JpegDec.MCUWidth;
uint16_t mcu_h = JpegDec.MCUHeight;
uint16_t max_x = JpegDec.width;
uint16_t max_y = JpegDec.height;
// Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
// Typically these MCUs are 16x16 pixel blocks
// Determine the width and height of the right and bottom edge image blocks
uint16_t min_w = minimum(mcu_w, max_x % mcu_w);
uint16_t min_h = minimum(mcu_h, max_y % mcu_h);
// save the current image block size
uint16_t win_w = mcu_w;
uint16_t win_h = mcu_h;
// record the current time so we can measure how long it takes to draw an image
//uint32_t drawTime = millis();
// save the coordinate of the right and bottom edges to assist image cropping
// to the screen size
max_x += xpos;
max_y += ypos;
// read each MCU block until there are no more
while ( JpegDec.read()) {
// save a pointer to the image block
pImg = JpegDec.pImage;
// calculate where the image block should be drawn on the screen
int mcu_x = JpegDec.MCUx * mcu_w + xpos;
int mcu_y = JpegDec.MCUy * mcu_h + ypos;
// check if the image block size needs to be changed for the right and bottom edges
if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
else win_w = min_w;
if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
else win_h = min_h;
// calculate how many pixels must be drawn
uint16_t mcu_pixels = win_w * win_h;
// draw image MCU block only if it will fit on the screen
if (( mcu_x + win_w ) <= tft.getDisplayXSize() && ( mcu_y + win_h ) <= tft.getDisplayYSize())
{
// Now set a MCU bounding window on the TFT to push pixels into (x, y, x + width - 1, y + height - 1)
digitalWrite(TFT_CS, LOW); // Set chip select low so we can take control of display
tft.setXY(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1);
// Write all MCU pixels to the TFT window
while (mcu_pixels--) {
// Push each pixel to the TFT MCU area
uint8_t col_h = (*pImg) >> 8; // High byte
uint8_t col_l = (*pImg) & 0xFF; // Low byte
pImg++; // Increment pointer
tft.LCD_Write_DATA(col_h, col_l); // Send a pixel colour to window
}
digitalWrite(TFT_CS, HIGH); // Set chip select high to release contol
}
// Stop drawing blocks if the bottom of the screen has been reached,
// the abort function will close the file
else if ( (mcu_y + win_h) >= tft.getDisplayYSize()) JpegDec.abort();
}
}
//====================================================================================
// Open a Jpeg image file and displays it at the given coordinates.
//====================================================================================
void jpegDraw(const char* filename, int x, int y) {
File jpegFile;
// Try to open requested file on SD card
if (!SD.open(filename, O_READ)) {
//tft.print("Jpeg file not found on SD card.");
return;
}
tft.print("Decoding image : ", 10, 10);
tft.print(filename, 160, 10);
//tft.println('\'');
delay(1000);
// initialise the decoder, check compatibility and gain access to image information
boolean decoded = JpegDec.decodeSdFile(filename);
if (decoded) {
// render the image onto the screen at given coordinates
renderJPEG(x, y);
}
else {
tft.print("Jpeg file format not supported.", 10, 10);
}
}
//====================================================================================
void SaveCalToSD(String CalDataString, int len) {
if (SDCARD_READY) {
// if the sd card is ready then save calibration values to touch.cal
File dataFile = SD.open("touch.cal", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
tft.print("saving calibration", 10, 312);
// dataFile.write(CalDataString,len);
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
tft.print("error opening touch.cal", 10, 312);
}
}
}
void GetCalFromSD() {
if (SDCARD_READY) {
tft.print("getting calibration", 10, 312);
// 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("touch.cal");
// if the file is available, read from it:
if (dataFile) {
while (dataFile.available()) {
// String CalDataString = (dataFile.read());
}
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
tft.print("error opening touch.cal", 10, 312);
}
}
}
/*
Show all jpeg images on sd card
*/
void ShowAllJpg() {
File dir = SD.open("/");
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
tft.clrScr();
jpegDraw( entry.name(), 0, 0 );
entry.close();
delay(5000);
}
}
/*
***************** SD CARD FILE OPERATIONS *************************************************
*/
void InitMySDCard() {
pinMode(48, OUTPUT);
digitalWrite(48, HIGH);
pinMode(44, INPUT);
pinMode(53, OUTPUT);
digitalWrite(53, HIGH);
SD.begin(48);
}
void StopSDCard() {
SD.end();
}
void printDirectory(File dir, int numTabs) {
// Begin at the start of the directory
dir.rewindDirectory();
uint8_t ypos = 80;
while (true) {
File entry = dir.openNextFile();
ypos = ypos + 12;
if (! entry) {
// no more files
break;
}
// print the 8.3 name to LCD
tft.setColor(YELLOW);
tft.print(entry.name(), 40, ypos);
// Recurse for directories, otherwise print the file size
if (entry.isDirectory()) {
String ename = entry.name();
tft.print("/", ename.length() + 65, ypos);
ypos = ypos + 12;
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
tft.setColor(RED);
tft.printNumI(entry.size(), 180, ypos);
}
entry.close();
}
delay(2000);
}
/*
Mount drive if exists
*/
void CheckSDCard() {
BiosMenu(3);
SetFgBg(WHITE, BLACK);
tft.print("Looking for SD card...", 10, 15);
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!sdcard.init(SPI_HALF_SPEED, chipSelect)) {
tft.print("No SD card found!", 260, 15);
SDCARD_READY = false;
delay(2000);
return;
} else {
SDCARD_READY = true;
tft.print("A card is present. ", 10, 17);
}
// print the type of card
tft.print("Card type: ", 10, 30);
switch (sdcard.type()) {
case SD_CARD_TYPE_SD1:
tft.print("SD1", 95, 30);
break;
case SD_CARD_TYPE_SD2:
tft.print("SD2", 95, 30);
break;
case SD_CARD_TYPE_SDHC:
tft.print("SDHC", 95, 30);
break;
default:
tft.print("Unknown", 95, 30);
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(sdcard)) {
tft.print("Could not find a FAT16/FAT32 partition.", 20, 80);
tft.print("Make sure you've formatted the card", 20, 92);
tft.print("Power down, and check your SD Card!", 20, 104);
tft.print("Continuing without the SD card will result", 20, 116);
tft.print("in lost logs, no saved data. Any screen calibration", 20, 128);
tft.print("data will not be available. Are you sure?", 20, 140);
delay(5000);
return;
}
// display the type and size of the first FAT-type volume
uint32_t volumesize;
tft.print("Volume type is FAT", 145, 30);
tft.printNumI(volume.fatType(), 300, 30);
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
//volumesize *= 512; // SD card blocks are always 512 bytes
volumesize /= 2048;
//volumesize /= 1024;
tft.print("Volume size (Mbytes): ", 10, 50);
tft.printNumI(volumesize, 180, 50);
tft.print("Files were found on the card (name and size in bytes): ", 10, 72);
root = SD.open("/");
printDirectory(root, 0);
}
void PutEEPROM(String dataString) {
}
void GetEEPROM() {
}
void LogToSD(String dataString) {
// 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();
}
// if the file isn't open, pop up an error:
else {
tft.print("error opening datalog.txt", 10, 312);
}
}
void DumpLog() {
if (SDCARD_READY) {
tft.print("card ready!", 10, 312);
// 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");
// if the file is available, write to it:
if (dataFile) {
while (dataFile.available()) {
Serial.write(dataFile.read());
}
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
tft.print("error opening datalog.txt", 10, 312);
}
}
}
#endif
Comments