You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
665 lines
17 KiB
C++
665 lines
17 KiB
C++
#include <TFT_FastPin.h>
|
|
#include <TFT_ILI9341.h>
|
|
#include <User_Setup.h>
|
|
|
|
#include "SPI.h"
|
|
#include "Adafruit_GFX.h"
|
|
//#include "./PDQ_ILI9341_config.h"
|
|
//#include "PDQ_GFX.h"
|
|
//#include "PDQ_ILI9341.h"
|
|
#include "SD.h"
|
|
#include <Fonts/FreeSerif12pt7b.h> // include fancy serif font
|
|
#include <Fonts/FreeSans12pt7b.h>
|
|
// For the Adafruit shield, these are the default.
|
|
#define TFT_DC 48
|
|
#define TFT_CS 49
|
|
|
|
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
|
|
TFT_ILI9341 tft;
|
|
extern "C" char __data_start[]; // start of SRAM data
|
|
extern "C" char _end[]; // end of SRAM data (used to check amount of SRAM this program's variables use)
|
|
extern "C" char __data_load_end[]; // end of FLASH (used to check amount of Flash this program's code and data uses)
|
|
|
|
|
|
#include <TouchScreen.h>
|
|
#include <avr/power.h>
|
|
#include <avr/sleep.h>
|
|
#include <avr/wdt.h>
|
|
#include "Adafruit_seesaw.h"
|
|
|
|
Adafruit_seesaw soil1;
|
|
Adafruit_seesaw soil2;
|
|
Adafruit_seesaw soil3;
|
|
Adafruit_seesaw soil4;
|
|
|
|
word pin00 = 0;
|
|
word pin01 = 1;
|
|
word pin02 = 2;
|
|
word pin03 = 3;
|
|
word pin04 = 4;
|
|
word pin05 = 5;
|
|
word pin06 = 6;
|
|
word pin07 = 7;
|
|
word pin08 = 8;
|
|
word pin09 = 9;
|
|
word pin10 = 10;
|
|
word pin11 = 11;
|
|
word pin12 = 12;
|
|
word led = 13;
|
|
word pin14 = 14;
|
|
word pin15 = 15;
|
|
word pin16 = 16;
|
|
word pin17 = 17;
|
|
word pin18 = 18;
|
|
word SD_CS = 19;
|
|
word pin20 = 20;
|
|
word pin21 = 21;
|
|
word pin22 = 22;
|
|
word pin23 = 23;
|
|
word pin24 = 24;
|
|
word pin25 = 25;
|
|
word pin26 = 26;
|
|
word pin27 = 27;
|
|
word pin28 = 28;
|
|
word pin29 = 29;
|
|
//word pin30 = 30;
|
|
//word pin31 = 31;
|
|
word pin32 = 32;
|
|
word pin33 = 33;
|
|
word pin34 = 34;
|
|
word pin35 = 35;
|
|
word pin36 = 36;
|
|
word pin37 = 37;
|
|
word pin38 = 38;
|
|
word pin39 = 39;
|
|
word pin40 = 40;
|
|
word pin41 = 41;
|
|
word pin42 = 42;
|
|
word pin43 = 43;
|
|
word pin44 = 44;
|
|
word pin45 = 45;
|
|
word pin46 = 46;
|
|
word pin47 = 47;
|
|
word pin48 = 48;
|
|
word pin49 = 49;
|
|
word pin50 = 50;
|
|
word pin51 = 51;
|
|
word pin52 = 52;
|
|
word pin53 = 53;
|
|
//word LCD_RD = A0;
|
|
//word LCD_WR = A1;
|
|
//word LCD_CD = A2;
|
|
//word LCD_CS = A3;
|
|
word pinA4 = A4;
|
|
word pinA5 = A5;
|
|
word pinA6 = A6;
|
|
word pinA7 = A7;
|
|
word pinA8 = A8;
|
|
word pinA9 = A9;
|
|
word pinA10 = A10;
|
|
word pinA11 = A11;
|
|
word pinA12 = A12;
|
|
word pinA13 = A13;
|
|
word pinA14 = A14;
|
|
word pinA15 = A15;
|
|
|
|
|
|
#define BLACK 0x0000
|
|
#define BLUE 0x001F
|
|
#define RED 0xF800
|
|
#define GREEN 0x07E0
|
|
#define CYAN 0x07FF
|
|
#define MAGENTA 0xF81F
|
|
#define YELLOW 0xFFE0
|
|
#define WHITE 0xFFFF
|
|
|
|
#define YP A4
|
|
#define XM A5
|
|
#define YM 30
|
|
#define XP 31
|
|
|
|
#define TS_MINX 100
|
|
#define TS_MINY 150
|
|
#define TS_MAXX 900
|
|
#define TS_MAXY 900
|
|
|
|
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 333);
|
|
|
|
|
|
String outtext = "";
|
|
String oldtext = "";
|
|
boolean fastboot = false;
|
|
boolean debug = true;
|
|
|
|
boolean ps3 = false;
|
|
boolean upd;
|
|
boolean s1, s2, s3, s4;
|
|
String outtext2 = "";
|
|
int linecount = 0;
|
|
|
|
void setup(void) {
|
|
Serial.begin(9600);
|
|
//tft.reset();
|
|
#if defined(ILI9341_RST_PIN) // reset like Adafruit does
|
|
FastPin<ILI9341_RST_PIN>::setOutput();
|
|
FastPin<ILI9341_RST_PIN>::hi();
|
|
FastPin<ILI9341_RST_PIN>::lo();
|
|
delay(1);
|
|
FastPin<ILI9341_RST_PIN>::hi();
|
|
#endif
|
|
tft.begin();
|
|
//tft.reset();
|
|
tft.setRotation(1);
|
|
boolean didDraw = true;
|
|
|
|
if(!fastboot) {
|
|
//if (SD.begin(SD_CS)) {
|
|
//tft.fillScreen(ILI9341_WHITE);
|
|
//bmpDraw("gbs.bmp", 0, 0);
|
|
//delay(4000);
|
|
//} else {
|
|
didDraw = false;
|
|
// }
|
|
tft.fillScreen(ILI9341_WHITE);
|
|
//yield();
|
|
//tft.fillRect(0, 0, 320, 23, ILI9341_BLACK);
|
|
|
|
}
|
|
clearLog();
|
|
printFastCText("Booting GreenhouseOS...");
|
|
printFastCText("");
|
|
printFastCText("");
|
|
delay(250);
|
|
if(!didDraw) {
|
|
printFastCText("[FAILED] SD Card not detected!");
|
|
}
|
|
printFastCText("[ OK ] Enabling powersaving features... "); // 53 characters wide example
|
|
enablePS(3);
|
|
upd = true;
|
|
|
|
if (!soil1.begin(0x36)) {
|
|
printFastCText("[ INFO ] Soil sensor 1 unplugged.");
|
|
s1 = false;
|
|
} else {
|
|
String out = "[ OK ] Soil sensor 1 connected. Version: ";
|
|
out += (soil1.getVersion(), HEX);
|
|
printFastCText(out);
|
|
s1 = true;
|
|
}
|
|
if (!soil2.begin(0x37)) {
|
|
printFastCText("[ INFO ] Soil sensor 2 unplugged.");
|
|
s2 = false;
|
|
} else {
|
|
String out = "[ OK ] Soil sensor 2 connected. Version: ";
|
|
out += (soil2.getVersion(), HEX);
|
|
printFastCText(out);
|
|
s2 = true;
|
|
}
|
|
if (!soil3.begin(0x38)) {
|
|
printFastCText("[ INFO ] Soil sensor 3 unplugged.");
|
|
s3 = false;
|
|
} else {
|
|
String out = "[ OK ] Soil sensor 3 connected. Version: ";
|
|
out += (soil3.getVersion(), HEX);
|
|
printFastCText(out);
|
|
s3 = true;
|
|
}
|
|
if (!soil4.begin(0x39)) {
|
|
printFastCText("[ INFO ] Soil sensor 4 unplugged.");
|
|
s4 = false;
|
|
} else {
|
|
String out = "[ OK ] Soil sensor 4 connected. Version: ";
|
|
out += (soil4.getVersion(), HEX);
|
|
printFastCText(out);
|
|
s4 = true;
|
|
}
|
|
getMoisture();
|
|
}
|
|
|
|
void loop(void) {
|
|
if (ps3) {
|
|
ADCSRA = 0;
|
|
}
|
|
if(Serial.available() > 0) {
|
|
String txtin = "Serial: " + Serial.readString();
|
|
int x = 0;
|
|
while(txtin.length() > 53) {
|
|
printFastCText(txtin.substring(0, 53));
|
|
txtin = txtin.substring(53);
|
|
}
|
|
printFastCText(txtin.substring(0, txtin.length() - 1));
|
|
|
|
}
|
|
unsigned long mil = millis();
|
|
/*String tmp = "[";
|
|
if(mil / 1000 < 10) {
|
|
tmp += " ";
|
|
}
|
|
else if(mil / 1000 < 100) {
|
|
tmp += " ";
|
|
}
|
|
else if(mil / 1000 < 1000) {
|
|
tmp += " ";
|
|
}
|
|
else if(mil / 1000 < 10000) {
|
|
tmp += " ";
|
|
}
|
|
else if(mil / 1000 < 100000) {
|
|
tmp += " ";
|
|
}
|
|
else if(mil / 1000 < 1000000) {
|
|
tmp += " ";
|
|
}
|
|
tmp += mil / 1000;
|
|
tmp += ".";
|
|
|
|
if(mil % 1000 < 10) {
|
|
tmp += "00";
|
|
}
|
|
else if(mil % 1000 < 100) {
|
|
tmp += "0";
|
|
}
|
|
tmp += mil % 1000;
|
|
tmp += "]";*/
|
|
//printConsoleText(tmp);
|
|
//tft.scrollTo(320);
|
|
if(mil % 60000 < 3000) {
|
|
getMoisture();
|
|
delay(500);
|
|
//tft.scrollTo(480);
|
|
//tft.setAddrWindow(320, 0, 320, 240);
|
|
}
|
|
|
|
// change upd to true if screen update needed
|
|
if(!debug && upd) {
|
|
tft.fillScreen(ILI9341_BLACK);
|
|
yield();
|
|
tft.fillRect(0, 0, 320, 20, ILI9341_WHITE);
|
|
tft.setCursor(2, 2);
|
|
tft.setTextSize(2);
|
|
tft.setTextColor(ILI9341_BLACK);
|
|
tft.print("Water Level: ");
|
|
|
|
|
|
upd = false;
|
|
}
|
|
|
|
}
|
|
|
|
#define BUFFPIXEL 80
|
|
/*
|
|
void bmpDraw(char *filename, int16_t x, int16_t y) {
|
|
|
|
File bmpFile;
|
|
int bmpWidth, bmpHeight; // W+H in pixels
|
|
uint8_t bmpDepth; // Bit depth (currently must be 24)
|
|
uint32_t bmpImageoffset; // Start of image data in file
|
|
uint32_t rowSize; // Not always = bmpWidth; may have padding
|
|
uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel)
|
|
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
|
|
boolean goodBmp = false; // Set to true on valid header parse
|
|
boolean flip = true; // BMP is stored bottom-to-top
|
|
int w, h, row, col, x2, y2, bx1, by1;
|
|
uint8_t r, g, b;
|
|
uint32_t pos = 0, startTime = millis();
|
|
|
|
if((x >= tft.width()) || (y >= tft.height())) return;
|
|
|
|
Serial.println();
|
|
Serial.print(F("Loading image '"));
|
|
Serial.print(filename);
|
|
Serial.println('\'');
|
|
|
|
// Open requested file on SD card
|
|
if ((bmpFile = SD.open(filename)) == NULL) {
|
|
Serial.print(F("File not found"));
|
|
return;
|
|
}
|
|
|
|
// Parse BMP header
|
|
if(read16(bmpFile) == 0x4D42) { // BMP signature
|
|
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
|
|
(void)read32(bmpFile); // Read & ignore creator bytes
|
|
bmpImageoffset = read32(bmpFile); // Start of image data
|
|
Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC);
|
|
// Read DIB header
|
|
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
|
|
bmpWidth = read32(bmpFile);
|
|
bmpHeight = read32(bmpFile);
|
|
if(read16(bmpFile) == 1) { // # planes -- must be '1'
|
|
bmpDepth = read16(bmpFile); // bits per pixel
|
|
Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
|
|
if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed
|
|
|
|
goodBmp = true; // Supported BMP format -- proceed!
|
|
Serial.print(F("Image size: "));
|
|
Serial.print(bmpWidth);
|
|
Serial.print('x');
|
|
Serial.println(bmpHeight);
|
|
|
|
// BMP rows are padded (if needed) to 4-byte boundary
|
|
rowSize = (bmpWidth * 3 + 3) & ~3;
|
|
|
|
// If bmpHeight is negative, image is in top-down order.
|
|
// This is not canon but has been observed in the wild.
|
|
if(bmpHeight < 0) {
|
|
bmpHeight = -bmpHeight;
|
|
flip = false;
|
|
}
|
|
|
|
// Crop area to be loaded
|
|
x2 = x + bmpWidth - 1; // Lower-right corner
|
|
y2 = y + bmpHeight - 1;
|
|
if((x2 >= 0) && (y2 >= 0)) { // On screen?
|
|
w = bmpWidth; // Width/height of section to load/display
|
|
h = bmpHeight;
|
|
bx1 = by1 = 0; // UL coordinate in BMP file
|
|
if(x < 0) { // Clip left
|
|
bx1 = -x;
|
|
x = 0;
|
|
w = x2 + 1;
|
|
}
|
|
if(y < 0) { // Clip top
|
|
by1 = -y;
|
|
y = 0;
|
|
h = y2 + 1;
|
|
}
|
|
if(x2 >= tft.width()) w = tft.width() - x; // Clip right
|
|
if(y2 >= tft.height()) h = tft.height() - y; // Clip bottom
|
|
|
|
// Set TFT address window to clipped image bounds
|
|
tft.startWrite(); // Requires start/end transaction now
|
|
tft.setAddrWindow(x, y, w, h);
|
|
|
|
for (row=0; row<h; row++) { // For each scanline...
|
|
|
|
// Seek to start of scan line. It might seem labor-
|
|
// intensive to be doing this on every line, but this
|
|
// method covers a lot of gritty details like cropping
|
|
// and scanline padding. Also, the seek only takes
|
|
// place if the file position actually needs to change
|
|
// (avoids a lot of cluster math in SD library).
|
|
if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
|
|
pos = bmpImageoffset + (bmpHeight - 1 - (row + by1)) * rowSize;
|
|
else // Bitmap is stored top-to-bottom
|
|
pos = bmpImageoffset + (row + by1) * rowSize;
|
|
pos += bx1 * 3; // Factor in starting column (bx1)
|
|
if(bmpFile.position() != pos) { // Need seek?
|
|
tft.endWrite(); // End TFT transaction
|
|
bmpFile.seek(pos);
|
|
buffidx = sizeof(sdbuffer); // Force buffer reload
|
|
tft.startWrite(); // Start new TFT transaction
|
|
}
|
|
for (col=0; col<w; col++) { // For each pixel...
|
|
// Time to read more pixel data?
|
|
if (buffidx >= sizeof(sdbuffer)) { // Indeed
|
|
tft.endWrite(); // End TFT transaction
|
|
bmpFile.read(sdbuffer, sizeof(sdbuffer));
|
|
buffidx = 0; // Set index to beginning
|
|
tft.startWrite(); // Start new TFT transaction
|
|
}
|
|
// Convert pixel from BMP to TFT format, push to display
|
|
b = sdbuffer[buffidx++];
|
|
g = sdbuffer[buffidx++];
|
|
r = sdbuffer[buffidx++];
|
|
tft.writePixel(tft.color565(r,g,b));
|
|
} // end pixel
|
|
} // end scanline
|
|
tft.endWrite(); // End last TFT transaction
|
|
} // end onscreen
|
|
Serial.print(F("Loaded in "));
|
|
Serial.print(millis() - startTime);
|
|
Serial.println(" ms");
|
|
} // end goodBmp
|
|
}
|
|
}
|
|
|
|
bmpFile.close();
|
|
if(!goodBmp) Serial.println(F("BMP format not recognized."));
|
|
}
|
|
*/
|
|
uint16_t read16(File &f) {
|
|
uint16_t result;
|
|
((uint8_t *)&result)[0] = f.read(); // LSB
|
|
((uint8_t *)&result)[1] = f.read(); // MSB
|
|
return result;
|
|
}
|
|
|
|
uint32_t read32(File &f) {
|
|
uint32_t result;
|
|
((uint8_t *)&result)[0] = f.read(); // LSB
|
|
((uint8_t *)&result)[1] = f.read();
|
|
((uint8_t *)&result)[2] = f.read();
|
|
((uint8_t *)&result)[3] = f.read(); // MSB
|
|
return result;
|
|
}
|
|
|
|
ISR (WDT_vect)
|
|
{
|
|
wdt_disable(); // disable watchdog
|
|
} // end of WDT_vect
|
|
|
|
void getMoisture() {
|
|
if (s1) {
|
|
float t1 = soil1.getTemp();
|
|
int sm1 = map(soil1.touchRead(0), 0, 1023, 0, 100);
|
|
if(sm1 > 6000 && t1 < 1) {
|
|
s1 = false;
|
|
printFastCText("[ INFO ] Soil sensor 1 unplugged.");
|
|
} else {
|
|
printS1(t1, sm1);
|
|
}
|
|
} else if (!s1) {
|
|
if (soil1.begin(0x36)) {
|
|
clearLog();
|
|
s1 = true;
|
|
printFastCText("[ INFO ] Soil sensor 1 connected.");
|
|
float t1 = soil1.getTemp();
|
|
int sm1 = map(soil1.touchRead(0), 0, 1023, 0, 100);
|
|
printS1(t1, sm1);
|
|
}
|
|
}
|
|
|
|
if (s2) {
|
|
float t2 = soil2.getTemp();
|
|
int sm2 = map(soil2.touchRead(0), 0, 1023, 0, 100);
|
|
if(sm2 > 6000 && t2 < 1) {
|
|
s2 = false;
|
|
printFastCText("[ INFO ] Soil sensor 2 unplugged.");
|
|
} else {
|
|
printS2(t2, sm2);
|
|
}
|
|
} else if (!s2) {
|
|
if (soil2.begin(0x37)) {
|
|
clearLog();
|
|
s2 = true;
|
|
printFastCText("[ INFO ] Soil sensor 2 connected.");
|
|
float t2 = soil2.getTemp();
|
|
int sm2 = map(soil2.touchRead(0), 0, 1023, 0, 100);
|
|
printS2(t2, sm2);
|
|
}
|
|
}
|
|
|
|
if (s3) {
|
|
float t3 = soil3.getTemp();
|
|
int sm3 = map(soil3.touchRead(0), 0, 1023, 0, 100);
|
|
if(sm3 > 6000 && t3 < 1) {
|
|
s3 = false;
|
|
printFastCText("[ INFO ] Soil sensor 3 unplugged.");
|
|
} else {
|
|
printS3(t3, sm3);
|
|
}
|
|
} else if (!s3) {
|
|
if (soil3.begin(0x38)) {
|
|
clearLog();
|
|
s3 = true;
|
|
printFastCText("[ INFO ] Soil sensor 3 connected.");
|
|
float t3 = soil3.getTemp();
|
|
int sm3 = map(soil3.touchRead(0), 0, 1023, 0, 100);
|
|
printS3(t3, sm3);
|
|
}
|
|
}
|
|
|
|
if (s4) {
|
|
float t4 = soil4.getTemp();
|
|
int sm4 = map(soil4.touchRead(0), 0, 1023, 0, 100);
|
|
if(sm4 > 6000 && t4 < 1) {
|
|
s4 = false;
|
|
printFastCText("[ INFO ] Soil sensor 4 unplugged.");
|
|
} else {
|
|
printS4(t4, sm4);
|
|
}
|
|
} else if (!s4) {
|
|
if (soil4.begin(0x39)) {
|
|
clearLog();
|
|
s4 = true;
|
|
printFastCText("[ INFO ] Soil sensor 4 connected.");
|
|
float t4 = soil4.getTemp();
|
|
int sm4 = map(soil4.touchRead(0), 0, 1023, 0, 100);
|
|
printS4(t4, sm4);
|
|
}
|
|
}
|
|
}
|
|
|
|
void printS1(float t, int sm) {
|
|
String out = "[ OK ] Soil sensor 1 temperature: ";
|
|
out += t;
|
|
out += " C, ";
|
|
out += (t * 9.0 / 5.0 + 32);
|
|
out += " F";
|
|
printFastCText(out);
|
|
out = "";
|
|
out += "[ OK ] Soil sensor 1 moisture: ";
|
|
out += sm;
|
|
out += "%";
|
|
printFastCText(out);
|
|
}
|
|
|
|
void printS2(float t, int sm) {
|
|
String out = "[ OK ] Soil sensor 2 temperature: ";
|
|
out += t;
|
|
out += " C, ";
|
|
out += (t * 9.0 / 5.0 + 32);
|
|
out += " F";
|
|
printFastCText(out);
|
|
out = "";
|
|
out += "[ OK ] Soil sensor 2 moisture: ";
|
|
out += sm;
|
|
out += "%";
|
|
printFastCText(out);
|
|
}
|
|
|
|
void printS3(float t, int sm) {
|
|
String out = "[ OK ] Soil sensor 3 temperature: ";
|
|
out += t;
|
|
out += " C, ";
|
|
out += (t * 9.0 / 5.0 + 32);
|
|
out += " F";
|
|
printFastCText(out);
|
|
out = "";
|
|
out += "[ OK ] Soil sensor 3 moisture: ";
|
|
out += sm;
|
|
out += "%";
|
|
printFastCText(out);
|
|
}
|
|
|
|
void printS4(float t, int sm) {
|
|
String out = "[ OK ] Soil sensor 4 temperature: ";
|
|
out += t;
|
|
out += " C, ";
|
|
out += (t * 9.0 / 5.0 + 32);
|
|
out += " F";
|
|
printFastCText(out);
|
|
out = "";
|
|
out += "[ OK ] Soil sensor 4 moisture: ";
|
|
out += sm;
|
|
out += "%";
|
|
printFastCText(out);
|
|
}
|
|
|
|
|
|
void enablePS(int level) {
|
|
if (level > 0) {
|
|
for(int x = 0; x <= 19; x++) {
|
|
if(x != 8) {
|
|
pinMode(x, OUTPUT);
|
|
digitalWrite(x, LOW);
|
|
}
|
|
}
|
|
for(int x = 32; x <= 53; x++) {
|
|
pinMode(x, OUTPUT);
|
|
digitalWrite(x, LOW);
|
|
}
|
|
printFastCText("[ OK ] Enabled Level 1 powersaving.");
|
|
} else {
|
|
printFastCText("[FAILED] Powersaving: Argument must be > 0.");
|
|
}
|
|
if(level > 1) {
|
|
Serial.end();
|
|
power_adc_disable();
|
|
//power_spi_disable(); // needed for screen
|
|
power_usart0_disable();
|
|
power_usart1_disable();
|
|
power_usart2_disable();
|
|
power_timer1_disable();
|
|
power_timer2_disable();
|
|
power_timer3_disable();
|
|
power_timer4_disable();
|
|
power_timer5_disable();
|
|
//power_twi_disable(); // twi needed for soil sensors / i2c
|
|
printFastCText("[ OK ] Enabled Level 2 powersaving.");
|
|
}
|
|
if(level > 2) {
|
|
// disable ADC
|
|
ADCSRA = 0;
|
|
//power_all_disable();
|
|
ps3 = true;
|
|
|
|
printFastCText("[ OK ] Enabled Level 3 powersaving.");
|
|
printFastCText("[ INFO ] All powersaving features enabled.");
|
|
}
|
|
}
|
|
|
|
void clearLog() {
|
|
outtext = "";
|
|
outtext2 = "";
|
|
linecount = 0;
|
|
tft.fillScreen(ILI9341_BLACK);
|
|
}
|
|
|
|
void printFastCText(String text) { // NOTE: text MUST be under 53 characters long! (this is how the code runs faster)
|
|
linecount ++;
|
|
if (linecount > 30) {
|
|
outtext2 = outtext2.substring(53);
|
|
//scrollAddress(8);
|
|
}
|
|
if (text.length() < 53) {
|
|
outtext2 += text;
|
|
for (int x = text.length(); x < 53; x++) {
|
|
outtext2 += " ";
|
|
}
|
|
} else {
|
|
outtext2 += text;
|
|
}
|
|
if (debug) {
|
|
//tft.setCursor(0, 0);
|
|
//tft.fillScreen(BLACK);
|
|
tft.setCursor(0, 0);
|
|
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
|
|
tft.setTextSize(1);
|
|
//int cursory = linecount * 8;
|
|
//for (int x = linecount - 1; x >= 0; x--) {
|
|
//tft.setCursor(0, cursory - 8);
|
|
//tft.fillRect(0, cursory - 8, 320, 8, BLACK);
|
|
//tft.fillScreen(ILI9341_BLACK);
|
|
tft.print(outtext2);
|
|
//cursory -= 8;
|
|
//}
|
|
}
|
|
}
|
|
void scrollAddress(uint16_t vsp) {
|
|
tft.writecommand(ILI9341_VSCRSADD); // Vertical scrolling pointer
|
|
tft.writedata(vsp>>8);
|
|
tft.writedata(vsp);
|
|
}
|