Testing OK

This commit is contained in:
2022-06-18 15:10:35 -05:00
parent 5580b6fda8
commit 2eeedbe232
182 changed files with 39598 additions and 904 deletions

View File

@ -0,0 +1,78 @@
#include <Wire.h>
#include <LiquidCrystal.h>
#define CONTRAST_PIN 9
#define BACKLIGHT_PIN 7
#define CONTRAST 110
LiquidCrystal lcd(12, 11, 5, 4, 3, 2, BACKLIGH_PIN, POSITIVE );
// Creat a set of new characters
byte smiley[8] = {
0b00000,
0b00000,
0b01010,
0b00000,
0b00000,
0b10001,
0b01110,
0b00000
};
byte armsUp[8] = {
0b00100,
0b01010,
0b00100,
0b10101,
0b01110,
0b00100,
0b00100,
0b01010
};
byte frownie[8] = {
0b00000,
0b00000,
0b01010,
0b00000,
0b00000,
0b00000,
0b01110,
0b10001
};
void setup()
{
Serial.begin ( 57600 );
// Switch on the backlight and LCD contrast levels
pinMode(CONTRAST_PIN, OUTPUT);
analogWrite ( CONTRAST_PIN, CONTRAST );
//lcd.setBacklightPin ( BACKLIGHT_PIN, POSITIVE );
//lcd.setBacklight ( HIGH );
lcd.backlight();
lcd.begin(16,2); // initialize the lcd
lcd.createChar (0, smiley); // load character to the LCD
lcd.createChar (1, armsUp); // load character to the LCD
lcd.createChar (2, frownie); // load character to the LCD
lcd.home (); // go home
lcd.print("Hello, ARDUINO ");
lcd.setCursor ( 0, 1 ); // go to the next line
lcd.print (" FORUM - fm ");
}
void loop()
{
// Do a little animation by writing to the same location
lcd.setCursor ( 14, 1 );
lcd.print (char(2));
delay (200);
lcd.setCursor ( 14, 1 );
lcd.print ( char(0));
delay (200);
}

View File

@ -0,0 +1,36 @@
#include <Wire.h>
#include <LiquidCrystal_SR.h>
LiquidCrystal_SR lcd(8,7,TWO_WIRE);
// | |
// | \-- Clock Pin
// \---- Data/Enable Pin
// Creat a set of new characters
byte armsUp[8] = {0b00100,0b01010,0b00100,0b10101,0b01110,0b00100,0b00100,0b01010};
byte armsDown[8] = {0b00100,0b01010,0b00100,0b00100,0b01110,0b10101,0b00100,0b01010};
void setup(){
lcd.begin(16,2); // initialize the lcd
lcd.createChar (0, armsUp); // load character to the LCD
lcd.createChar (1, armsDown); // load character to the LCD
lcd.home (); // go home
lcd.print("LiquidCrystal_SR");
}
void loop(){
// Do a little animation
for(int i = 0; i <= 15; i++) showHappyGuy(i);
for(int i = 15; i >= 0; i--) showHappyGuy(i);
}
void showHappyGuy(int pos){
lcd.setCursor ( pos, 1 ); // go to position
lcd.print(char(random(0,2))); // show one of the two custom characters
delay(150); // wait so it can be seen
lcd.setCursor ( pos, 1 ); // go to position again
lcd.print(" "); // delete character
}

View File

@ -0,0 +1,61 @@
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 13
LiquidCrystal_I2C lcd(0x38); // Set the LCD I2C address
//LiquidCrystal_I2C lcd(0x38, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address
// Creat a set of new characters
const uint8_t charBitmap[][8] = {
{ 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
{ 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
{ 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
{ 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
{ 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
{ 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
{ 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
};
void setup()
{
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
// Switch on the backlight
pinMode ( BACKLIGHT_PIN, OUTPUT );
digitalWrite ( BACKLIGHT_PIN, HIGH );
lcd.begin(16,2); // initialize the lcd
for ( int i = 0; i < charBitmapSize; i++ )
{
lcd.createChar ( i, (uint8_t *)charBitmap[i] );
}
lcd.home (); // go home
lcd.print("Hello, ARDUINO ");
lcd.setCursor ( 0, 1 ); // go to the next line
lcd.print (" FORUM - fm ");
delay ( 1000 );
}
void loop()
{
lcd.home ();
// Do a little animation by writing to the same location
for ( int i = 0; i < 2; i++ )
{
for ( int j = 0; j < 16; j++ )
{
lcd.print (char(random(7)));
}
lcd.setCursor ( 0, 1 );
}
delay (200);
}

View File

@ -0,0 +1,274 @@
static char dummyvar; // dummy declaration for STUPID IDE!!!!
/*----------------------------------------------------------------------------
* vi:ts=4
*
* LCDiSpeed - LCD Interface Speed
*
* Created by Bill Perry 2012-03-16
* Copyright 2012 - Under creative commons license 3.0:
* Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
* license page: http://creativecommons.org/licenses/by-nc-sa/3.0/
*
* Sketch to measure and report the speed of the interface to the LCD and
* speed of updating the LCD.
*
* 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
* 2012.03.15 bperrybap - Original creation
*
* @author Bill Perry - bperrybap@opensource.billsworld.billandterrie.com
*----------------------------------------------------------------------------
/*
* Define your LCD size
*/
#define LCD_COLS 16
#define LCD_ROWS 2
/*
* Pick your interface.
*/
//#define LCDIF_4BIT
//#define LCDIF_I2C
//#define LCDIF_SR2W
//#define LCDIF_SR_2W // SR in 2 wire mode
//#define LCDIF_SR_3W // SR in 3 wire mode
#define LCDIF_SR3W
//#define LCDIF_SR1W
/*
* Options
*/
#define FPS_iter 1 // number of iterations to repeat each "frame" within the test
// (current frame test is 10 full display frames, 1 for each digits 0-9)
// FPS_iter like 100 will allow the frames to be seen
// Note: the only reason other than visual to make this larger than 1
// might be to compensate for Async serial buffering should a serial interface be tested
// even with 1 iteration, 340 bytes are written for a 16x2 display
// bytes written = FPS_iter * ((LCD_ROWS * LCD_COLS) + LCD_ROWS) * 10
#define iLCD // turn on code to calculate speed of "independent" sized display
#define iLCD_ROWS 2 // independent FPS row size
#define iLCD_COLS 16 // independent FPS col size
#define DELAY_TIME 3500 // delay time to see information on lcd
#if defined(LCDIF_4BIT)
// Include the Liquid Crystal library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
// lcd(RS, E, d4, d5, d6, d7, bl, polarity)
#ifdef BACKLIGHT_ON
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7, 10, POSITIVE); // new constructor with backlight support
#else
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7); // old style constructor w/o backlight (to test old library)
#endif
#elif defined(LCDIF_I2C)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x38); // Set the LCD I2C address
#elif defined(LCDIF_SR3W)
#include <LiquidCrystal_SR3W.h>
// d,clk,strb, en,rw,rs,d4,d5,d6,d7,bl,blpol
//LiquidCrystal_SR3W lcd (2, 3, 4, 6, 7, 1, 2, 3, 4, 5, 0, POSITIVE);
LiquidCrystal_SR3W lcd(3, 2, 4);
#elif defined(LCDIF_SR2W)
#include <LiquidCrystal_SR2W.h>
// d, clk, (blPolarity optional, defaults to POSITIVE)
LiquidCrystal_SR2W lcd (2, 3);
#elif defined(LCDIF_SR1W)
#include <LiquidCrystal_SR1W.h>
LiquidCrystal_SR1W lcd (2);
#elif defined(LCDIF_SR_2W)
#include <LiquidCrystal_SR.h>
// d, clk
LiquidCrystal_SR lcd (2, 3);
#elif defined(LCDIF_SR_3W)
#include <LiquidCrystal_SR.h>
// d,clk,strb
LiquidCrystal_SR lcd (2, 3, 4);
#endif
void setup()
{
// set up the LCD's number of columns and rows:
lcd.begin(LCD_COLS, LCD_ROWS);
#ifdef BACKLIGHT_ON
lcd.backlight(); // make sure backlight is on with new library
#endif
}
void loop()
{
unsigned long etime;
char buf[8];
lcd.clear();
/*
* Time an FPS test
*/
etime = timeFPS(FPS_iter, LCD_COLS, LCD_ROWS);
/*
* show the average single byte xfer time during the FPS test
*/
showByteXfer(etime);
/*
* show FPS rate and Frame update time for this display
*/
sprintf(buf, "%dx%d", LCD_COLS, LCD_ROWS);
showFPS(etime, buf);
#ifdef iLCD
/*
* 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.
*/
etime = etime *iLCD_ROWS * iLCD_COLS / LCD_ROWS / LCD_COLS;
/*
* show independent FPS rate & Frame update time
*/
sprintf(buf, "%dx%d", iLCD_COLS, iLCD_ROWS);
showFPS(etime, buf);
#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/ByteXfer calcuations 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
* The 10.0 is for the 10 frames done per iteration
* one for each digit 0-9
*/
fps = (10.0 * FPS_iter) * 1000000.0/(etime);
lcd.clear();
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("Ftime: ");
lcd.print((etime)/10.0/FPS_iter/1000);
lcd.print("ms");
delay(DELAY_TIME);
}
void showByteXfer(unsigned long etime)
{
lcd.clear();
lcd.print("ByteXfer: ");
/*
* Calculate average byte xfer time from time of FPS test
* This takes into consideration the set cursor position commands 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.
*/
lcd.print((int) (etime / (FPS_iter * (10.0 * (LCD_COLS * LCD_ROWS + LCD_ROWS)))+0.5));
lcd.print("uS");
delay(DELAY_TIME);
}

View File

@ -0,0 +1,20 @@
16Mhz AVR
Interface ByteXfer 16x2FPS Ftime
----------------------------------------------
4BIT 338uS 86.92 11.51ms (orignal Liquid Crystal)
4BIT 98uS 298.58 3.35ms
SR2W 76uS 388.62 2.57ms
SR_2W 72uS 406.90 2.46ms
SR_3W 61uS 480.03 2.08ms
SR3W 102uS 287.92 3.47ms
80Mhz Pic32 (ChipKit Uno32)
Interface ByteXfer 16x2FPS Ftime
----------------------------------------------
4BIT 232uS 126.73 7.89ms (orignal mpide Liquid Crystal)
4BIT 57uS 517.41 1.93ms
SR2W 53uS 557.35 1.79ms
SR_2W 53uS 554.66 1.80ms
SR_3W 50uS 591.40 1.69ms
SR3W 56uS 524.91 1.91ms

View File

@ -0,0 +1,37 @@
/*
* Displays text sent over the serial port (e.g. from the Serial Monitor) on
* an attached LCD.
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define BACKLIGHT_PIN 13
LiquidCrystal_I2C lcd(0x38); // set the LCD address to 0x38
void setup()
{
pinMode ( BACKLIGHT_PIN, OUTPUT );
lcd.begin (16,2);
digitalWrite ( BACKLIGHT_PIN, HIGH );
Serial.begin(57600);
}
void loop()
{
// when characters arrive over the serial port...
if (Serial.available())
{
// wait a bit for the entire message to arrive
delay(100);
// clear the screen
lcd.clear();
// read all the available characters
while (Serial.available() > 0)
{
// display each character to the LCD
lcd.write(Serial.read());
}
}
}

View File

@ -0,0 +1,246 @@
// ---------------------------------------------------------------------------
// Created by Francisco Malpartida on 1/1/12.
// Copyright 2011 - Under creative commons license:
// Attribution-NonCommercial-ShareAlike CC BY-NC-SA
//
// This software is furnished "as is", without technical support, and with no
// warranty, express or implied, as to its usefulness for any purpose.
//
// Thread Safe: No
// Extendable: Yes
//
// @file i2CLCDextraIO.pde
// Temperature logging to demonstrate the I2CLCDextraIO library.
//
// @brief This application is a demostration file for the I2CLCDextraIO library
// that reads a temperature from the internal ATMEGA328p temperature sensor
// and displays it on the LCD. The application also demonstrates some of the
// methods of the library, such as loading custom characters to the LCD,
// moving around the LCD, and writing to it.
//
// @author F. Malpartida
// ---------------------------------------------------------------------------
#include <Wire.h>
#include <LCD.h>
#define _LCD_I2C_
#ifdef _LCD_I2C_
#include <LiquidCrystal_I2C.h>
#endif
#ifdef _LCD_4BIT_
#include <LiquidCrystal.h>
#endif
/*!
@defined CHAR_WIDTH
@abstract Character witdth of the display, expressed in pixeles per character.
*/
#define CHAR_WIDTH 5
/*!
@defined BACKLIGHT_PIN
@abstract LCD backlight pin definition.
@discussion AVR pin used for the backlight illumintation of the LCD.
*/
#define BACKLIGHT_PIN 7
/*!
@defined TEMP_CAL_OFFSET
@abstract Temperature calibration offset.
@discussion This is the offset value that has to be modified to get a
correct temperature reading from the internal temperature sensor
of your AVR.
*/
#define TEMP_CAL_OFFSET 334
/*!
@defined FILTER_ALP
@abstract Low pass filter alpha value
@discussion This value defines how much does the current reading, influences
the over all value. The smaller, the less influence the current
reading has over the overall result.
*/
#define FILTER_ALP 0.1
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;
#ifdef _LCD_I2C_
LiquidCrystal_I2C lcd(0x38); // set the LCD address to 0x20 for a 16 chars and 2 line display
#endif
#ifdef _LCD_4BIT_
LiquidCrystal lcd(12, 11, 5, 4, 3, 2, BACKLIGHT_PIN, POSITIVE);
#endif
const int CONTRAST_PIN = 9;
const int CONTRAST = 65;
LCD *myLCD = &lcd;
static double tempFilter;
/*!
@const charBitmap
@abstract Define Character bitmap for the bargraph.
@discussion Defines a character bitmap to represent a bargraph on a text
display. The bitmap goes from a blank character to full black.
*/
const uint8_t charBitmap[][8] = {
{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
{ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0 },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0 },
{ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x0 },
{ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0 },
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0 },
{ 0xe, 0x11, 0x11, 0x11, 0xe, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0x0, 0, 0, 0}
};
/*!
@function
@abstract Return available RAM memory
@discussion This routine returns the ammount of RAM memory available after
initialising the C runtime.
@param
@result Free RAM available.
*/
static int freeMemory()
{
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
/*!
@function
@abstract Returns AVR328p internal temperature
@discussion Configures the ADC MUX for the temperature ADC channel and
waits for conversion and returns the value of the ADC module
@result The internal temperature reading - in degrees C
*/
static int readTemperature()
{
ADMUX = 0xC8; // activate interal temperature sensor,
// using 1.1V ref. voltage
ADCSRA |= _BV(ADSC); // start the conversion
while (bit_is_set(ADCSRA, ADSC)); // ADSC is cleared when the conversion
// finishes
// combine bytes & correct for temperature offset (approximate)
return ( (ADCL | (ADCH << 8)) - TEMP_CAL_OFFSET);
}
/*!
@function
@abstract Braws a bargraph onto the display representing the value passed.
@discussion Draws a bargraph on the specified row using barLength characters.
@param value[in] Value to represent in the bargraph
@param row[in] Row of the LCD where to display the bargraph. Range (0, 1)
for this display.
@param barlength[in] Length of the bar, expressed in display characters.
@param start[in] Start bar character
@param end [in] End bar character
@result None
*/
static void drawBars ( int value, uint8_t row, uint8_t barLength, char start,
char end )
{
int numBars;
// Set initial titles on the display
myLCD->setCursor (0, row);
myLCD->print (start);
// Calculate the size of the bar
value = map ( value, -30, 50, 0, ( barLength ) * CHAR_WIDTH );
numBars = value / CHAR_WIDTH;
// Limit the size of the bargraph to barLength
if ( numBars > barLength )
{
numBars = barLength;
}
myLCD->setCursor ( 1, row );
// Draw the bars
while ( numBars-- )
{
myLCD->print ( char( 5 ) );
}
// Draw the fractions
numBars = value % CHAR_WIDTH;
myLCD->print ( char(numBars) );
myLCD->setCursor (barLength + 1, row);
myLCD->print (end);
}
void setup ()
{
int i;
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
Serial.begin ( 57600 );
analogReference ( INTERNAL );
#ifdef _LCD_4BIT_
pinMode(CONTRAST_PIN, OUTPUT);
lcd.backlight();
digitalWrite(BACKLIGHT_PIN, HIGH);
analogWrite (CONTRAST_PIN, CONTRAST);
#else
pinMode ( BACKLIGHT_PIN, OUTPUT );
digitalWrite(BACKLIGHT_PIN, HIGH);
#endif
myLCD->begin ( 16, 2 );
// Load custom character set into CGRAM
for ( i = 0; i < charBitmapSize; i++ )
{
myLCD->createChar ( i, (uint8_t *)charBitmap[i] );
}
Serial.println ( freeMemory () );
myLCD->clear ();
myLCD->print ("Temp:");
tempFilter = readTemperature (); // Initialise the temperature Filter
}
void loop ()
{
int temp;
temp = readTemperature();
tempFilter = ( FILTER_ALP * temp) + (( 1.0 - FILTER_ALP ) * tempFilter);
myLCD->setCursor ( 8, 0 );
myLCD->print (" ");
myLCD->setCursor ( 8, 0 );
myLCD->print ( tempFilter, 1 );
myLCD->setCursor ( 12, 0 );
myLCD->print ( "\x07" );
myLCD->print ("C");
drawBars ( tempFilter, 1, 14, '-', '+' );
delay (200);
}

View File

@ -0,0 +1,332 @@
// ---------------------------------------------------------------------------
// Created by Francisco Malpartida on 1/1/12.
// Copyright 2011 - Under creative commons license:
// Attribution-NonCommercial-ShareAlike CC BY-NC-SA
//
// This software is furnished "as is", without technical support, and with no
// warranty, express or implied, as to its usefulness for any purpose.
//
// Thread Safe: No
// Extendable: Yes
//
// @file i2CLCDextraIO_tempLeonardo.ino
// Temperature logging to demonstrate the I2CLCDextraIO library.
//
// @brief This application is a demostration file for the I2CLCDextraIO library
// that reads a temperature from the internal ATMEGA32U4 temperature sensor
// and displays it on the LCD. The application also demonstrates some of the
// methods of the library, such as loading custom characters to the LCD,
// moving around the LCD, and writing to it.
//
// @author F. Malpartida
// ---------------------------------------------------------------------------
#include <Arduino.h>
#include <Wire.h>
#include <LCD.h>
#define _LCD_SR3W_
#ifdef _LCD_I2C_
#include <LiquidCrystal_I2C.h>
#endif
#ifdef _LCD_4BIT_
#include <LiquidCrystal.h>
#endif
#ifdef _LCD_SR_
#include <LiquidCrystal_SR.h>
#endif
#ifdef _LCD_SR3W_
#include <LiquidCrystal_SR3W.h>
#endif
/*!
@defined CHAR_WIDTH
@abstract Character witdth of the display, expressed in pixeles per character.
*/
#define CHAR_WIDTH 5
/*!
@defined BACKLIGHT_PIN
@abstract LCD backlight pin definition.
@discussion AVR pin used for the backlight illumintation of the LCD.
*/
#define BACKLIGHT_PIN 12
/*!
@defined STATUS_PIN
@abstract Status LED indicator.
@discussion Activity LED blinking indicating that the system is up.
*/
#define STATUS_PIN 13
/*!
@defined LOOP_DELAY
@abstract Main loop delay.
@discussion Main loop delay executing temperature readings and LCD updates.
*/
#define LOOP_DELAY 300
/*!
@defined TEMP_CAL_OFFSET
@abstract Temperature calibration offset.
@discussion This is the offset value that has to be modified to get a
correct temperature reading from the internal temperature sensor
of your AVR.
*/
#define TEMP_CAL_OFFSET 282
/*!
@defined FILTER_ALP
@abstract Low pass filter alpha value
@discussion This value defines how much does the current reading, influences
the over all value. The smaller, the less influence the current
reading has over the overall result.
*/
#define FILTER_ALP 0.1
/*!
@defined MIN_TEMP
@abstract Minimum temperature range for bargraph
*/
#define MIN_TEMP -10
/*!
@defined MAX_TEMP
@abstract Maximum temperature range for bargraph
*/
#define MAX_TEMP 50
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;
// Initialise LCD module
// -----------------------------------------------------------------------------
#ifdef _LCD_I2C_
LiquidCrystal_I2C lcd(0x38);
#endif
#ifdef _LCD_4BIT_
LiquidCrystal lcd(12, 11, 5, 4, 3, 2, BACKLIGHT_PIN, POSITIVE);
const int CONTRAST_PIN = 9;
const int CONTRAST = 65;
#endif
#ifdef _LCD_SR_
LiquidCrystal_SR lcd(3,2,TWO_WIRE);
// | |
// | \-- Clock Pin
// \---- Data/Enable Pin
#endif
#ifdef _LCD_SR3W_
LiquidCrystal_SR3W lcd(3, 2, 4);
// | |
// | \-- Clock Pin
// \---- Data/Enable Pin
#endif
// LCD reference variable
LCD *myLCD = &lcd;
// Temperature filter variable
static double tempFilter;
/*!
@const charBitmap
@abstract Define Character bitmap for the bargraph.
@discussion Defines a character bitmap to represent a bargraph on a text
display. The bitmap goes from a blank character to full black.
*/
const uint8_t charBitmap[][8] = {
{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
{ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0 },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0 },
{ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x0 },
{ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0 },
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0 },
{ 0xe, 0x11, 0x11, 0x11, 0xe, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0x0, 0, 0, 0}
};
/*!
@function
@abstract Return available RAM memory
@discussion This routine returns the ammount of RAM memory available after
initialising the C runtime.
@param
@result Free RAM available.
*/
static int freeMemory()
{
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
/*!
@function
@abstract Returns AVR328p internal temperature
@discussion Configures the ADC MUX for the temperature ADC channel and
waits for conversion and returns the value of the ADC module
@result The internal temperature reading - in degrees C
*/
static int readTemperature()
{
ADMUX = 0xC7; // activate interal temperature sensor,
// using 2.56V ref. voltage
ADCSRB |= _BV(MUX5);
ADCSRA |= _BV(ADSC); // start the conversion
while (bit_is_set(ADCSRA, ADSC)); // ADSC is cleared when the conversion
// finishes
// combine bytes & correct for temperature offset (approximate)
return ( (ADCL | (ADCH << 8)) - TEMP_CAL_OFFSET);
}
/*!
@function
@abstract Braws a bargraph onto the display representing the value passed.
@discussion Draws a bargraph on the specified row using barLength characters.
@param value[in] Value to represent in the bargraph
@param row[in] Row of the LCD where to display the bargraph. Range (0, 1)
for this display.
@param barlength[in] Length of the bar, expressed in display characters.
@param start[in] Start bar character
@param end [in] End bar character
@result None
*/
static void drawBars ( int value, uint8_t row, uint8_t barLength, char start,
char end )
{
int numBars;
// Set initial titles on the display
myLCD->setCursor (0, row);
myLCD->print (start);
// Calculate the size of the bar
value = map ( value, MIN_TEMP, MAX_TEMP, 0, ( barLength ) * CHAR_WIDTH );
numBars = value / CHAR_WIDTH;
// Limit the size of the bargraph to barLength
if ( numBars > barLength )
{
numBars = barLength;
}
myLCD->setCursor ( 1, row );
// Draw the bars
while ( numBars-- )
{
myLCD->print ( char( 5 ) );
}
// Draw the fractions
numBars = value % CHAR_WIDTH;
myLCD->print ( char(numBars) );
myLCD->setCursor (barLength + 1, row);
myLCD->print (end);
}
/*!
@function
@abstract Initialise the HW
@discussion Initialise the HW used within this application: UART, LCD & IOs
@param
@result
*/
static void initHW ( void )
{
int i;
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
Serial.begin ( 57600 );
// Hardware initialise
// ------------------------------------
//ADCSRA |= (1 << ADEN); // Initialise ADC block (no need done by env)
// Initialise LCD HW: backlight and LCD
// -------------------------------------
#ifdef _LCD_4BIT_
pinMode(CONTRAST_PIN, OUTPUT);
analogWrite (CONTRAST_PIN, CONTRAST);
#endif
#ifdef _LCD_I2C_
pinMode ( BACKLIGHT_PIN, OUTPUT );
digitalWrite (BACKLIGHT_PIN, HIGH);
#endif
pinMode ( STATUS_PIN, OUTPUT );
myLCD->begin ( 20, 2 );
// Load custom character set into CGRAM
// --------------------------------------------------------------------
for ( i = 0; i < charBitmapSize; i++ )
{
myLCD->createChar ( i, (uint8_t *)charBitmap[i] );
}
}
void setup ()
{
initHW();
Serial.println ( freeMemory () );
myLCD->clear ();
myLCD->print ( F("Free Mem: "));
myLCD->print ( freeMemory () );
delay ( 2000 );
myLCD->clear ();
myLCD->print (F("Temp:"));
myLCD->setCursor ( 8, 0 );
tempFilter = 0;
myLCD->print ( readTemperature() );
}
void loop ()
{
int temp;
static byte status = 1;
status ^= 1;
digitalWrite ( STATUS_PIN, status);
temp = readTemperature();
tempFilter = ( FILTER_ALP * temp) + (( 1.0 - FILTER_ALP ) * tempFilter);
// Display the information to the LCD
myLCD->setCursor ( 8, 0 );
myLCD->print (" ");
myLCD->setCursor ( 8, 0 );
myLCD->print ( tempFilter, 1 );
myLCD->setCursor ( 12, 0 );
myLCD->print ( "\x07" );
myLCD->print ("C");
drawBars ( tempFilter, 1, 14, '-', '+' );
delay (LOOP_DELAY);
}

View File

@ -0,0 +1,480 @@
// Created by Francisco Malpartida on 20/08/11.
// Copyright 2011 - Under creative commons license 3.0:
// Attribution-ShareAlike CC BY-SA
//
// This software is furnished "as is", without technical support, and with no
// warranty, express or implied, as to its usefulness for any purpose.
//
// Thread Safe: No
// Extendable: Yes
//
// @file performanceLCD.h
// This sketch implements a simple benchmark for the New LiquidCrystal library.
//
// @brief
// This sketch provides a simple benchmark for the New LiquidCrystal library. It
// enables to test the varios classes provided by the library giving a performance
// reference.
//
// This library is only compatible with Arduino's SDK version 1.0
//
// @version API 1.0.0
//
// @author F. Malpartida - fmalpartida@gmail.com
// Contribution by flo - Florian@Fida.biz - for benchmarking SR
// ---------------------------------------------------------------------------
#include <Wire.h>
#define _LCD_I2C_
#ifdef _LCD_I2C_
#include <LiquidCrystal_I2C.h>
#endif
#ifdef _LCD_4BIT_
#include <LiquidCrystal.h>
#endif
#ifdef _LCD_SR_
#include <LiquidCrystal_SR.h>
#endif
#ifdef _LCD_SR3W_
#include <LiquidCrystal_SR3W.h>
#endif
#ifdef _LCD_SR1_
#include <LiquidCrystal_SR1.h>
#endif
// C runtime variables
// -------------------
#ifdef __AVR__
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;
#endif
// Constants and definitions
// -------------------------
// Definitions for compatibility with Arduino SDK prior to version 1.0
#ifndef F
#define F(str) str
#endif
/*!
@defined NUM_BENCHMARKS
@abstract Number of benchmarks in the project.
*/
#define NUM_BENCHMARKS 4
/*!
@defined ITERATIONS
@abstract Number of benchmarks iterations to perform.
*/
#define ITERATIONS 10
/*!
@defined LCD_ROWS
@abstract LCD rows
@discussion Defines the number of rows that the LCD has, normal LCD ranges are (1, 2, 4).
*/
#define LCD_ROWS 2
/*!
@defined LCD_COLUMNS
@abstract LCD available columns
@discussion Defines the number of colums that the LCD has, normal LCD ranges are (8, 16, 20).
*/
#define LCD_COLUMNS 16
/*!
@const Pin constant definitions
@abstract Define several constants required to manage the LCD backlight and contrast
*/
#ifdef _LCD_I2C_
const int BACKLIGHT_PIN = 12;
const int CONTRAST_PIN = 0; // none
const int CONTRAST = 0; // none
#endif
#ifdef _LCD_4BIT_
const int CONTRAST_PIN = 9;
const int BACKLIGHT_PIN = 7;
const int CONTRAST = 120;
#endif
#ifdef _LCD_SR_
const int CONTRAST_PIN = 0; // not connected
const int BACKLIGHT_PIN = 0; // none
const int CONTRAST = 0;
#endif
#ifdef _LCD_SR1_
const int CONTRAST_PIN = 0; // not connected
const int BACKLIGHT_PIN = 0; // none
const int CONTRAST = 0;
#endif
#ifdef _LCD_SR3W_
const int CONTRAST_PIN = 0; // none
const int BACKLIGHT_PIN = 5;
const int CONTRAST = 0;
#endif
/*!
@const charBitmap
@abstract Define Character bitmap for the bargraph.
@discussion Defines a character bitmap to represent a bargraph on a text
display. The bitmap goes from a blank character to full black.
*/
const uint8_t charBitmap[][8] = {
{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
{ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0 },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0 },
{ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x0 },
{ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x0 },
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0 }
};
/*!
@typedef t_benchmarkOp
@abstract Function pointer associated to each benchmark.
*/
typedef long (*t_benchmarkOp)( uint8_t );
/*!
@typedef t_timeBenchMarks
@abstract Structure to store results of the execution time of the benchmark.
@field benchmark: function pointer of the benchmark to be executed.
*/
typedef struct
{
t_benchmarkOp benchmark; /**< Function pointer associated to the benchmark */
long benchTime; /**< execution time for benchmark 1 in useconds */
uint16_t numWrites; /**< Number of write cycles of the benchmark */
} t_benchMarks;
// Main LCD objects
// ----------------
#ifdef _LCD_I2C_
LiquidCrystal_I2C lcd(0x38); // set the LCD address to 0x20 for a 16 chars and 2 line display
#endif
#ifdef _LCD_4BIT_
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#endif
#ifdef _LCD_SR_
LiquidCrystal_SR lcd(8,7,TWO_WIRE);
#endif
#ifdef _LCD_SR1_
LiquidCrystal_SR1 lcd(2);
#endif
#ifdef _LCD_SR3W_
LiquidCrystal_SR3W lcd(3, 2, 4);
#endif
// benchMarks definitions
// ----------------------
extern long benchmark1 ( uint8_t );
extern long benchmark2 ( uint8_t );
extern long benchmark3 ( uint8_t );
extern long benchmark4 ( uint8_t );
//! @brief benchmark structure that will be initialised and
static t_benchMarks myBenchMarks[NUM_BENCHMARKS] =
{
{ benchmark1, 0, (LCD_ROWS * LCD_COLUMNS) + 2 },
{ benchmark2, 0, LCD_ROWS * LCD_COLUMNS * 6 * 2 },
{ benchmark3, 0, 40 + 2 },
{ benchmark4, 0, 40 + 2 }
};
// Static methods
// --------------
/*!
@function freeMemory
@abstract Return available RAM memory
@discussion This routine returns the ammount of RAM memory available after
initialising the C runtime.
@param
@return Free RAM available, -1 for non AVR microcontrollers
*/
static int freeMemory ( void )
{
#ifdef __AVR__
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
#else
return -1;
#endif
}
/*!
@function LCDSetup
@abstract Initialise LCD associated pins and initialise the LCD object
with its geometry.
@discussion Initialise the LCD object and make it ready for operation by
setting up the LCD geometry, i.e. LCD character size. Initialise
and configure all associated control pins such as backlight and
contras pin if necessary.
@param[in] charBitmapSize: contrasts pin associated to the contrast (should be an
analog pin). 0 if contrast pin is not required.
@param[in] backlight: backlight pin associated to the LCD backlight.
@param[in] cols: number of LCD columns normal values (1, 2, 4)
@param[in] rows: number of LCD rows normal values (8, 16, 20)
*/
static void LCDSetup ( uint8_t contrasPin, uint8_t backlight, uint8_t cols, uint8_t rows )
{
// If our setup uses a PWM to control the backlight, configure it
// --------------------------------------------------------------
if ( contrasPin != 0 )
{
pinMode ( contrasPin, OUTPUT );
analogWrite ( contrasPin, CONTRAST );
}
// Setup backlight pin
if ( backlight != 0 ){
pinMode(backlight, OUTPUT);
digitalWrite(backlight, HIGH);
}
lcd.begin ( cols, rows );
lcd.clear ( );
}
/*!
@function LCDLoadCharacters
@abstract Loads onto the LCD the character set for the benchmark.
@discussion Loads onto the LCD the character set that will be used throughout
the benchmark.
@param[in] charBitmapSize: number of characters to load to the LCD.
*/
static void LCDLoadCharacters ( int numChars )
{
// Load custom character set into CGRAM
for ( int i = 0; i < numChars; i++ )
{
lcd.createChar ( i, (uint8_t *)charBitmap[i] );
}
}
// Benchmarks
// ----------
/*!
@function benchmark1
@abstract writes to the LCD a full set of characters loaded on the LCD
memory.
@discussion Writes to all the positions of the LCD a fixed pattern from
memory. For every line it writes, it positions the cursor.
The number of writen LCD accesses is: LCD_ROW * LCD_COLUMS + 2.
It returns the cumulative time used by all the iterations.
@param[in] iterations: number of iterations the benchmark is executed before
returning the time taken by all iterations.
@return The time take to execute iterations number of benchmarks.
*/
long benchmark1 ( uint8_t iterations )
{
unsigned long time, totalTime = 0;
int i, j;
while ( iterations > 0 )
{
// Clear the LCD
lcd.clear ( );
time = micros ();
for ( i = 0; i < LCD_ROWS; i++ )
{
lcd.setCursor ( 0, i );
for ( j = 0; j < LCD_COLUMNS; j++ )
{
lcd.print (char(5));
}
}
totalTime += ( micros() - time );
delay ( 200 ); // it doesn't keep up with the LCD refresh rate.
iterations--;
}
return ( totalTime );
}
/*!
@function benchmark2
@abstract writes to the LCD a full set of characters loaded on the LCD
memory one line pixel at the time
@discussion Writes to all the positions of the LCD a fixed pattern from
memory each patern take 6 write operations to the LCD. For every
character it writes it sets the cursor possition.
The number of writen LCD accesses is: LCD_ROW * LCD_COLUMS * 6.
It returns the cumulative time used by all the iterations.
@param[in] iterations: number of iterations the benchmark is executed before
returning the time taken by all iterations.
@return The time take to execute iterations number of benchmarks.
*/
long benchmark2 ( uint8_t iterations )
{
unsigned long time, totalTime = 0;
int i, j, k;
while ( iterations > 0 )
{
// Clear the LCD
lcd.clear ( );
time = micros ();
for ( i = 0; i < LCD_ROWS; i++ )
{
for ( j = 0; j < LCD_COLUMNS; j++ )
{
for ( k = 0; k <= 5; k++ )
{
lcd.setCursor ( j, i );
lcd.print (char(k));
}
}
}
totalTime += ( micros() - time );
iterations--;
}
return ( totalTime );
}
/*!
@function benchmark3
@abstract writes to the LCD a full set of characters from memory.
@discussion Writes to all the positions of the LCD a fixed pattern from
RAM. For every line it writes, it positions the cursor.
The number of writen LCD accesses is: LCD_ROW * LCD_COLUMS + 2.
It returns the cumulative time used by all the iterations.
@param[in] iterations: number of iterations the benchmark is executed before
returning the time taken by all iterations.
@return The time take to execute iterations number of benchmarks.
*/
long benchmark3 ( uint8_t iterations )
{
unsigned long time, totalTime = 0;
int i;
while ( iterations > 0 )
{
// Clear the LCD
lcd.clear ( );
time = micros ();
for ( i = 0; i < LCD_ROWS; i++ )
{
lcd.setCursor ( 0, i );
lcd.print ( "####################" );
}
totalTime += ( micros() - time );
delay ( 200 ); // it doesn't keep up with the LCD refresh rate.
iterations--;
}
return ( totalTime );
}
/*!
@function benchmark4
@abstract writes to the LCD a full set of characters from memory.
@discussion Writes to all the positions of the LCD a fixed pattern from
flash. For every line it writes, it positions the cursor.
The number of writen LCD accesses is: LCD_ROW * LCD_COLUMS + 2.
It returns the cumulative time used by all the iterations.
@param[in] iterations: number of iterations the benchmark is executed before
returning the time taken by all iterations.
@return The time take to execute iterations number of benchmarks.
*/
long benchmark4 ( uint8_t iterations )
{
unsigned long time, totalTime = 0;
int i;
while ( iterations > 0 )
{
// Clear the LCD
lcd.clear ( );
time = micros ();
for ( i = 0; i < LCD_ROWS; i++ )
{
lcd.setCursor ( 0, i );
lcd.print ( F("####################") );
}
totalTime += ( micros() - time );
delay ( 200 ); // it doesn't keep up with the LCD refresh rate.
iterations--;
}
return ( totalTime );
}
// Main system setup
// -----------------
void setup ()
{
Serial.begin ( 57600 );
#ifdef __AVR__
Serial.print ( F("Free mem: ") );
Serial.println ( freeMemory () );
#endif
// Initialise the LCD
LCDSetup ( CONTRAST_PIN, BACKLIGHT_PIN, LCD_COLUMNS, LCD_ROWS );
LCDLoadCharacters ( (sizeof(charBitmap ) / sizeof (charBitmap[0])) );
}
// Main system loop
// ----------------
void loop ()
{
int i;
lcd.setCursor ( 0, 0 );
lcd.clear ( );
// Run benchmark
for ( i = 0; i < NUM_BENCHMARKS; i++ )
{
myBenchMarks[i].benchTime =
(myBenchMarks[i].benchmark (ITERATIONS))/ITERATIONS;
Serial.println (i);
}
float fAllWrites=0.0;
for ( i = 0; i < NUM_BENCHMARKS; i++ )
{
Serial.print ( F("benchmark") );
Serial.print ( i );
Serial.print ( F(": ") );
Serial.print ( myBenchMarks[i].benchTime );
Serial.print ( F(" us - ") );
Serial.print ( F(" write: ") );
Serial.print ( myBenchMarks[i].benchTime / (float)myBenchMarks[i].numWrites );
Serial.println ( F(" us") );
fAllWrites += myBenchMarks[i].benchTime / (float)myBenchMarks[i].numWrites;
}
Serial.print( F("avg. write: ") );
Serial.println( fAllWrites / (float)NUM_BENCHMARKS );
}