721 lines
17 KiB
C++
721 lines
17 KiB
C++
static const int dummyvar = 0; // dummy declaration for older broken IDEs!!!!
|
|
// vi:ts=4
|
|
// ----------------------------------------------------------------------------
|
|
// LCDLibTest - LCD library Test sketch
|
|
// Copyright 2012-2020 Bill perry
|
|
// ---------------------------------------------------------------------------
|
|
//
|
|
// LCDlibTest is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation version 3 of the License.
|
|
//
|
|
// LCDlibTest is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with LCDLibTest. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
// ---------------------------------------------------------------------------
|
|
//
|
|
// Sketch to measure and report the speed of the interface to the LCD and
|
|
// speed of updating the LCD as well as test some of the library extensions
|
|
// for hardware control like backlight control.
|
|
//
|
|
// It runs a Frames/Sec (FPS) test which writes a "frame" of each digit 0-9 to
|
|
// the display.
|
|
// A "frame" is a full display of characters.
|
|
// It is created by positioning the cursor to the begining of each row
|
|
// and then writing a character to every position on the row, until the
|
|
// entire display is filled.
|
|
// The FPS test does a frame of 9's then 8's, .... down to 0's
|
|
// On fast interfaces it will not normally be seen.
|
|
//
|
|
// The sketch will then calculate & report transfer speeds and
|
|
// LCD update rates to the LCD display.
|
|
//
|
|
// Reported Information:
|
|
// - Single byte transfer speed (ByteXfer)
|
|
// This is the time it takes for a single character to be sent from
|
|
// the sketch to the LCD display.
|
|
//
|
|
// - Frame/Sec (FPS)
|
|
// This is the number of times the full display can be updated
|
|
// in one second.
|
|
//
|
|
// - Frame Time (Ftime)
|
|
// This is the amount of time it takes to update the full LCD display.
|
|
//
|
|
//
|
|
// The sketch will also report "independent" FPS and Ftime values.
|
|
// These are timing values that are independent of the size of the LCD under test.
|
|
// Currently they represent the timing for a 16x2 LCD
|
|
// The value of always having numbers for a 16x2 display
|
|
// is that these numbers can be compared to each other since they are
|
|
// independent of the size of the actual LCD display that is running the test.
|
|
//
|
|
// All times & rates are measured and calculeted from what a sketch "sees"
|
|
// using the LiquidCrystal API.
|
|
// It includes any/all s/w overhead including the time to go through the
|
|
// Arduino Print class and LCD library.
|
|
// The actual low level hardware times are obviously lower.
|
|
//
|
|
// History
|
|
// 2018.03.23 bperrybap - bumped default instruction time to 38us
|
|
// 2012.04.01 bperrybap - Original creation
|
|
//
|
|
// @author Bill Perry - bperrybap@opensource.billsworld.billandterrie.com
|
|
// ---------------------------------------------------------------------------
|
|
|
|
#ifndef HD44780_LCDOBJECT
|
|
|
|
#error "Special purpose sketch: Use i/o class example wrapper sketch instead."
|
|
|
|
/*
|
|
* If not using a hd44780 library i/o class example wrapper sketch,
|
|
* you must modify the sketch to include any needed header files for the
|
|
* intended library and define the lcd object.
|
|
*
|
|
* Add your includes and constructor.
|
|
* The lcd object must be named "lcd"
|
|
* and comment out the #error message.
|
|
*/
|
|
|
|
#endif
|
|
|
|
// ============================================================================
|
|
// user configurable options below this point
|
|
// ============================================================================
|
|
|
|
|
|
/*
|
|
* Define your LCD size
|
|
* 16x2 will work ok on larger displays but if you want the frame rate
|
|
* for the full LCD geometry, define that here
|
|
* Note: if these can be overridden by defines in a wrapper sketch.
|
|
*/
|
|
#ifndef LCD_COLS
|
|
#define LCD_COLS 16
|
|
#endif
|
|
|
|
#ifndef LCD_ROWS
|
|
#define LCD_ROWS 2
|
|
#endif
|
|
|
|
// if you have a slow display uncomment these defines
|
|
// to override the default execution times.
|
|
// CHEXECTIME is the execution time for clear and home commands
|
|
// INSEXECTIME is the execution time for everything else; cmd/data
|
|
// times are in Us
|
|
// NOTE: if using, you must enable both
|
|
// Although each display can have seperate times, these values will be used
|
|
// on all displays.
|
|
|
|
//#define LCD_CHEXECTIME 2000
|
|
//#define LCD_INSEXECTIME 38
|
|
|
|
|
|
/*
|
|
* LCDlibTest Options (normally shouldn not need to change these)
|
|
*/
|
|
|
|
|
|
//#define SINGLEWAVE // different "wave" style
|
|
#define SLOWERWAVE // slow down wave speed
|
|
#define DELAY_TIME 3500
|
|
#define DEBUGPRINT // turn on serial debug messages
|
|
|
|
#define TIMEBYTE // turn on code that times a byte transfer
|
|
#define TIMEFPS // turn on code that calculates FPS
|
|
#define FPS_iter 5 // number of iterations to repeat each frame
|
|
// FPS_iter larger than about 1 allows the test to be seen
|
|
#define iLCD_ROWS 2 // independent FPS row size
|
|
#define iLCD_COLS 16 // independent FPS col size
|
|
|
|
#define TRACKTIME // turn on code that displays elapsed time
|
|
#define STATUSBARS // turn on status bars on left & right
|
|
|
|
// ============================================================================
|
|
// End of user configurable options
|
|
// ============================================================================
|
|
|
|
|
|
// Turn on extra stuff for certain libraries
|
|
//
|
|
|
|
#if defined(hd44780_h) || defined(LiquidCrystal_I2C_h) || (defined(_LCD_H_) && defined(FOUR_BITS) && defined(BACKLIGHT_ON))
|
|
#define ONOFFCMDS // If on() and off() commands exist
|
|
#define SETBACKLIGHTCMD // if setbacklight() exists
|
|
#define BACKLIGHTCMDS // if backlight()/noBacklight() exist
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Data format is for each custom character is 8 bytes
|
|
// Pixels within the bytes is as follows:
|
|
// lowest byte is at top, MSB of byte is on right
|
|
// only lower 5 bits of each byte is used.
|
|
|
|
|
|
// Data for a set of new characters for a bargraph
|
|
// start with 1 underbar and add additional bars until full 5x8 block
|
|
|
|
const uint8_t charBitmap[][8] = {
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f}, // char 0
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f}, // char 1
|
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f}, // char 2
|
|
{0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f}, // char 3
|
|
{0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}, // char 4
|
|
{0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}, // char 5
|
|
{0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}, // char 6
|
|
{0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f}, // char 7
|
|
};
|
|
/*
|
|
* prototypes
|
|
*/
|
|
|
|
char animchar(int col, int iter);
|
|
void showFPS(unsigned long etime, const char *type);
|
|
unsigned long timeFPS(uint8_t iter, uint8_t cols, uint8_t rows);
|
|
void showByteXfer(Print &dev, unsigned long FPStime);
|
|
void fatalError(int ecode);
|
|
|
|
void setup()
|
|
{
|
|
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
|
|
unsigned long etime;
|
|
|
|
|
|
#ifdef DEBUGPRINT
|
|
Serial.begin(9600);
|
|
#if (ARDUINO > 101)
|
|
do
|
|
{
|
|
// wait on serial port to be ready but timout out after 3 seconds
|
|
// this is for sytems that use virtual serial over USB.
|
|
if(millis() > 3000) // millis starts at 0 after reset
|
|
break;
|
|
delay(10); // easy way to allow some cores to call yield()
|
|
} while(!Serial);
|
|
#endif
|
|
#endif
|
|
|
|
// set up the LCD's number of columns and rows:
|
|
// with hd44780 library,
|
|
// set execution times & check for initializatin failure
|
|
#if defined(hd44780_h)
|
|
|
|
// set custom exectution times if configured
|
|
#if defined(LCD_CHEXECTIME) && defined(LCD_INSEXECTIME)
|
|
lcd.setExecTimes(LCD_CHEXECTIME, LCD_INSEXECTIME);
|
|
#endif
|
|
|
|
|
|
if(lcd.begin(LCD_COLS, LCD_ROWS))
|
|
{
|
|
// begin() failed so blink the onboard LED if possible
|
|
fatalError(1); // this never returns
|
|
}
|
|
|
|
// NOTE: Can't check initalization status on other libraries
|
|
// NOTE: fm's LiquidCrystal_I2C class and other LiquidCrystal_I2C
|
|
// classes define LiquidCrystal_I2C_h, but they don't initialize the
|
|
// the same way. We check for I2CIO use when checking for
|
|
// LiquidCrystal_I2C use to see which "LiquidCrystal_I2C" is
|
|
// is being used since fm's uses begin() while all the others use init()
|
|
//
|
|
#elif defined(LiquidCrystal_I2C_h) && !defined(_I2CIO_H_)
|
|
lcd.init();
|
|
#else
|
|
lcd.begin(LCD_COLS, LCD_ROWS);
|
|
#endif
|
|
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("LCD initialized");
|
|
#endif
|
|
|
|
#ifdef WIRECLOCK
|
|
#if (ARDUINO >= 157) && !defined(MPIDE)
|
|
Wire.setClock(WIRECLOCK); // set i2c clock bit rate, if asked
|
|
#else
|
|
#error attempting to use Wire.setClock on IDE that does not support it
|
|
#endif
|
|
#endif
|
|
|
|
// create the custom bargraph characters
|
|
for ( int i = 0; i < charBitmapSize; i++ )
|
|
{
|
|
lcd.createChar ( i, (uint8_t *)charBitmap[i] );
|
|
}
|
|
|
|
// must do something like set cursor postion after defining chars
|
|
// on most libraries (not hd44780)
|
|
// to reset address back to display ram
|
|
lcd.setCursor(0,0);
|
|
|
|
|
|
#if defined(TIMEBYTE) || defined(TIMEFPS)
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Byte timing test");
|
|
#endif
|
|
delay(10); // delay to ensure no previous commands still pending
|
|
etime = timeFPS(FPS_iter, LCD_COLS, LCD_ROWS);
|
|
lcd.clear();
|
|
#endif
|
|
|
|
#ifdef TIMEBYTE
|
|
// show the average single byte xfer time during the FPS test
|
|
showByteXfer(lcd, etime);
|
|
#ifdef DEBUGPRINT
|
|
showByteXfer(Serial, etime);
|
|
Serial.println();
|
|
#endif
|
|
delay(DELAY_TIME); // show it for a while
|
|
lcd.clear();
|
|
#endif
|
|
|
|
#ifdef TIMEFPS
|
|
// calculate Frame update time and FPS rate for this display
|
|
showFPS(etime, " ");
|
|
|
|
/*
|
|
* If the size of the display is not size of the "standad"
|
|
* display, calculate Independent FPS and Frame update time
|
|
* (rate & time for a "standard" display - default of 16x2)
|
|
* This is simply a matter of scaling the time based on the
|
|
* ratio of the display sizes.
|
|
*/
|
|
|
|
if((iLCD_COLS != LCD_COLS) || (iLCD_ROWS != LCD_ROWS))
|
|
{
|
|
etime = etime *iLCD_ROWS * iLCD_COLS / LCD_ROWS / LCD_COLS;
|
|
|
|
/*
|
|
* show independent FPS rate & Frame update time
|
|
*/
|
|
showFPS(etime, "i");
|
|
}
|
|
|
|
|
|
lcd.clear();
|
|
#endif
|
|
|
|
|
|
#ifdef SETBACKLIGHTCMD
|
|
|
|
// If using hd44780 library check to see if controlling backlight is possible
|
|
#if defined(hd44780_h)
|
|
|
|
// try to turn on the backlight
|
|
// if it fails then backlight control isn't possible
|
|
if(lcd.setBacklight(-1))
|
|
{
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("LCD API 1.0 setBacklight() not supported");
|
|
#endif
|
|
goto skip_dimmingBL;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Dimming Backlight");
|
|
#endif
|
|
|
|
// Print a message to the LCD.
|
|
lcd.print(" Dimming BL");
|
|
|
|
// soft blink the backlight 3 times by ramping down then back up
|
|
// Hardware that does not support dimming will see the backlight as full on
|
|
// during this test.
|
|
for(int times = 0; times < 3; times++)
|
|
{
|
|
for(int x = 1; x < 16; x++)
|
|
{
|
|
lcd.setBacklight(256-x * 16);
|
|
delay(45);
|
|
}
|
|
for(int x = 1; x < 16; x++)
|
|
{
|
|
lcd.setBacklight(x * 16);
|
|
delay(45);
|
|
}
|
|
}
|
|
#else
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("No LCD API 1.0 setBacklight() function");
|
|
#endif
|
|
#endif // SETBACKLIGHTCMD
|
|
|
|
skip_dimmingBL:
|
|
|
|
// Need cursor functions here
|
|
// ul cusor
|
|
// blk cursor
|
|
// ul cursor blink
|
|
// blk cursor blink
|
|
// cursorLeft()
|
|
// cursofRight()
|
|
lcd.clear();
|
|
lcd.print("cursor");
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("cursor");
|
|
#endif
|
|
lcd.cursor();
|
|
delay(DELAY_TIME); // show it for a while
|
|
|
|
lcd.clear();
|
|
lcd.print("Cursor Blink");
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Cursor Blink");
|
|
#endif
|
|
lcd.cursor();
|
|
lcd.blink();
|
|
delay(DELAY_TIME); // show it for a while
|
|
lcd.noCursor();
|
|
delay(DELAY_TIME); // show it for a while
|
|
lcd.noBlink();
|
|
|
|
|
|
#ifdef BACKLIGHTCMDS
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Blinking Backlight");
|
|
#endif
|
|
// If using hd44780 library check to see if controlling backlight is possible
|
|
#if defined(hd44780_h)
|
|
|
|
// try to turn on the backlight
|
|
// if it fails then backlight control isn't possible
|
|
if(lcd.setBacklight(-1))
|
|
{
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("LCD API 1.0 backlight()/noBacklight() not supported");
|
|
#endif
|
|
goto skip_blinkBL;
|
|
}
|
|
|
|
#endif
|
|
|
|
lcd.home();
|
|
lcd.print(" Blinking BL");
|
|
for(int x = 1; x < 5; x++)
|
|
{
|
|
delay(500);
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Backlight OFF");
|
|
#endif
|
|
lcd.noBacklight(); // turns off backlight but leaves pixels on
|
|
delay(500);
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Backlight On");
|
|
#endif
|
|
lcd.backlight();
|
|
}
|
|
#else
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("No LCD API 1.0 backlight()/noBacklight() functions");
|
|
#endif
|
|
#endif // BACKLIGHTCMDS
|
|
|
|
skip_blinkBL:
|
|
|
|
lcd.home();
|
|
lcd.print(" Pixels on/off");
|
|
for(int x = 1; x < 5; x++)
|
|
{
|
|
delay(500);
|
|
lcd.noDisplay(); // turns off display pixels, not backlight
|
|
delay(500);
|
|
lcd.display(); // turns on display pixels
|
|
}
|
|
|
|
#ifdef later
|
|
#ifdef ONOFFCMDS
|
|
lcd.home();
|
|
lcd.print(" On/Off Test ");
|
|
for(int x = 1; x < 5; x++)
|
|
{
|
|
delay(500);
|
|
lcd.off(); // turns off both display pixels and backlight
|
|
delay(500);
|
|
lcd.on(); // turns on both display pixels and backlight
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
lcd.clear();
|
|
lcd.print(" Scroll Right ");
|
|
delay(700);
|
|
for(int x = 0; x < LCD_COLS/2; x++)
|
|
{
|
|
delay(300);
|
|
lcd.scrollDisplayRight();
|
|
}
|
|
lcd.clear();
|
|
lcd.print(" Scroll Left ");
|
|
delay(700);
|
|
for(int x = 0; x < LCD_COLS/2; x++)
|
|
{
|
|
delay(300);
|
|
lcd.scrollDisplayLeft();
|
|
}
|
|
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("setup() done");
|
|
#endif
|
|
|
|
lcd.clear();
|
|
#ifndef TRACKTIME
|
|
lcd.print(" Animations");
|
|
#ifdef DEBUGPRINT
|
|
Serial.println("Animations");
|
|
#endif
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifdef TRACKTIME
|
|
void PrintTime(Print &dev, uint8_t hr, uint8_t min, uint8_t sec)
|
|
{
|
|
// print time in HH:MM:SS format
|
|
// Print class does not support fixed width formatting
|
|
// so insert a zero if number smaller than 10
|
|
if(hr < 10)
|
|
dev.write('0');
|
|
dev.print((int)hr);
|
|
dev.write(':');
|
|
if(min < 10)
|
|
dev.write('0');
|
|
dev.print((int)min);
|
|
dev.write(':');
|
|
if(sec < 10)
|
|
dev.write('0');
|
|
dev.print((int)sec);
|
|
}
|
|
#endif
|
|
|
|
|
|
void loop()
|
|
{
|
|
static int loopcount = 0;
|
|
#ifdef TRACKTIME
|
|
static unsigned long lastsecs;
|
|
unsigned long secs;
|
|
|
|
secs = millis() / 1000;
|
|
if(secs != lastsecs)
|
|
{
|
|
uint8_t hr;
|
|
int min;
|
|
uint8_t sec;
|
|
|
|
lastsecs = secs;
|
|
min = secs / 60;
|
|
|
|
hr = min / 60;
|
|
|
|
min = min % 60;
|
|
|
|
sec = secs % 60;
|
|
|
|
lcd.setCursor(4,0);
|
|
PrintTime(lcd, hr, (uint8_t)min, sec);
|
|
#ifdef DEBUGPRINT
|
|
PrintTime(Serial, hr, (uint8_t)min, sec);
|
|
Serial.println();
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef STATUSBARS
|
|
/*
|
|
* Update Status "bars"
|
|
* 2 up/down bars out of phase with each other.
|
|
*/
|
|
|
|
lcd.setCursor(0,0);
|
|
lcd.write(animchar(0, loopcount/16));
|
|
lcd.write(animchar(7, loopcount/16));
|
|
|
|
lcd.setCursor(LCD_COLS -2,0);
|
|
lcd.write(animchar(7, loopcount/16));
|
|
lcd.write(animchar(0, loopcount/16));
|
|
#endif
|
|
|
|
if(LCD_ROWS > 1)
|
|
{
|
|
/*
|
|
* Draw Wave
|
|
*/
|
|
lcd.setCursor(0, 1);
|
|
for ( int c = 0; c < LCD_COLS; c++ )
|
|
{
|
|
lcd.write(animchar(c, loopcount));
|
|
}
|
|
}
|
|
#ifdef SLOWERWAVE
|
|
delay(35);
|
|
#endif
|
|
|
|
loopcount++;
|
|
|
|
}
|
|
|
|
#if defined(SINGLEWAVE)
|
|
char animchar(int col, int iter)
|
|
{
|
|
int c;
|
|
|
|
if(col > 7)
|
|
{
|
|
col = (char)( (15 -col) & 7);
|
|
}
|
|
|
|
#if 1
|
|
if((iter % 64) > 31)
|
|
{
|
|
if((iter % 32) > 15)
|
|
{
|
|
c = (col + 7 -(iter & 0xf)); // fall down from the edge
|
|
}
|
|
else
|
|
{
|
|
c = 7 - col -7 + (iter & 0xf); // rise up from the edge
|
|
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if((iter % 32) > 15)
|
|
{
|
|
c = (7 - col + 7 -(iter & 0xf)); // fall down from the middle
|
|
}
|
|
else
|
|
{
|
|
c = col -7 + (iter & 0xf); // rise up from the middle
|
|
|
|
}
|
|
}
|
|
|
|
|
|
if(c > 7)
|
|
c = 7;
|
|
|
|
if(c < 0)
|
|
c = 0;
|
|
|
|
return(char(c));
|
|
}
|
|
#else
|
|
char animchar(int col, int iter)
|
|
{
|
|
int c;
|
|
col &= 0xf;
|
|
|
|
if(col > 7)
|
|
{
|
|
col = (char)( (15 -col) & 7);
|
|
}
|
|
|
|
c = (col + (iter & 0xf)) & 0xf;
|
|
|
|
if(c > 7)
|
|
{
|
|
c = 15 - c;
|
|
}
|
|
return((char) c);
|
|
}
|
|
#endif
|
|
|
|
unsigned long timeFPS(uint8_t iter, uint8_t cols, uint8_t rows)
|
|
{
|
|
char c;
|
|
unsigned long stime, etime;
|
|
|
|
stime = micros();
|
|
for(c = '9'; c >= '0'; c--) // do not change this unless you change the FPS calcuation as well
|
|
{
|
|
for(uint8_t i = 0; i < iter; i++)
|
|
{
|
|
for(uint8_t row = 0; row < rows; row++)
|
|
{
|
|
lcd.setCursor(0, row);
|
|
for(uint8_t col = 0; col< cols;col++)
|
|
{
|
|
lcd.write(c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
etime = micros();
|
|
return((etime-stime));
|
|
}
|
|
void showFPS(unsigned long etime, const char *type)
|
|
{
|
|
float fps;
|
|
|
|
|
|
/*
|
|
* calculate Frame update time and FPS rate
|
|
*/
|
|
|
|
fps = (10.0 * FPS_iter) * 1000000.0/(etime);
|
|
|
|
|
|
lcd.clear();
|
|
lcd.print(" ");
|
|
lcd.print(type);
|
|
lcd.print("FPS: ");
|
|
lcd.print(fps);
|
|
|
|
if(LCD_ROWS > 1)
|
|
{
|
|
lcd.setCursor(0,1);
|
|
}
|
|
else
|
|
{
|
|
delay(DELAY_TIME);
|
|
lcd.clear();
|
|
}
|
|
lcd.print(type);
|
|
lcd.print("Ftime: ");
|
|
lcd.print((etime)/10.0/FPS_iter/1000);
|
|
lcd.print("ms");
|
|
|
|
delay(DELAY_TIME);
|
|
}
|
|
void showByteXfer(Print &dev, unsigned long FPStime)
|
|
{
|
|
dev.print("ByteXfer:");
|
|
|
|
/*
|
|
* Calculate average byte xfer time from time of FPS test
|
|
* This takes into consideration the set cursor position commands
|
|
* (1 per row) which are single byte commands and take the same amount of
|
|
* time as a data byte write.
|
|
* The final result is rounded up to an integer.
|
|
*/
|
|
dev.print((int) (FPStime / (FPS_iter * (10.0 * (LCD_COLS * LCD_ROWS + LCD_ROWS)))+0.5));
|
|
dev.print("uS");
|
|
}
|
|
|
|
// fatalError() - loop & blink and error code
|
|
void fatalError(int ecode)
|
|
{
|
|
#if defined(hd44780_h)
|
|
// if using hd44780 library use built in fatalError()
|
|
hd44780::fatalError(ecode);
|
|
#else
|
|
if(ecode){} // dummy if statement to remove warning about not using ecode
|
|
while(1)
|
|
{
|
|
delay(1); // delay to prevent WDT on some cores
|
|
}
|
|
#endif
|
|
}
|