Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LCD Display: Display Energy formatted to significant figures instead of decimal digits. #341

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 80 additions & 17 deletions src/lcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ void LcdTask::displayInfoLine(LcdInfoLine line, unsigned long &nextUpdate)
{
case LcdInfoLine::EnergySession:
// Energy 1,018Wh
displayScaledNumberValue(1, "Energy", _evse->getSessionEnergy(), 1, "Wh");
displayScaledNumberValue(1, "Energy", _evse->getSessionEnergy(), "Wh");
_updateInfoLine = false;
break;

Expand Down Expand Up @@ -619,30 +619,77 @@ void LcdTask::displayInfoLine(LcdInfoLine line, unsigned long &nextUpdate)
}
}

void LcdTask::displayScaledNumberValue(int line, const char *name, double value, int precision, const char *unit)
{
static const char *mod[] = {
"",
"k",
"m",
"g",
"t",
"p"
};

int index = 0;
while (value > 1000 && index < ARRAY_ITEMS(mod))
// Adjust the value down until its in the range 0-1000,
// and return the SI prefix for the scaled number.
const char *LcdTask::ScaleNumberSI(double *value) {
{
value /= 1000;
index++;
static const char *mod[] = {
"",
"k",
"m",
"g",
"t",
"p"
Comment on lines +629 to +632
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened another PR before seeing this one to correct the capitalization of these units - might be worth updating it here since you're moving these around? #344

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of multiple changes per PR but #344 will conflict with this PR and visa-versa so ok if @rbsexton wants to add the unit update

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one has been laying around! I'd forgotten all about it. I'll update this so that it can get pulled.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I'm pretty sure that the merge of PR#344 made mine unmergable. I'm going to start over and I'll fix the rounding error while I'm at it.

};

int index = 0;
while (*value > 1000 && index < ARRAY_ITEMS(mod))
{
*value /= 1000;
index++;
}

return(mod[index]);
}
}

// Format a number to a specif number of signficant figures.
// Requires a a number that that has already been adjusted for SI notation.
//
// Arguments: buffer, buffer length,
// value in question, number of significant figures.
// returns a pointer to the formatted buffer.
char *LcdTask::formatDoubleSigFigures(char *buffer, int buflen, double value, int figures)
{

// There is no way to get less than three.
int integer_figures;
if ( value >= 100.0 ) integer_figures = 3;
else if ( value >= 10.0 ) integer_figures = 2;
else if ( value >= 1.0 ) integer_figures = 1;
else integer_figures = 0;

int precision = figures - integer_figures;

snprintf(buffer, buflen, "%.*f", precision, value);
return(buffer);
}


// Display a scaled number with a specific number of digits after the decimal point.
void LcdTask::displayScaledNumberValue(int line, const char *name, double value, int precision, const char *unit)
{

char newUnit[20];
sprintf(newUnit, "%s%s", mod[index], unit);
sprintf(newUnit, "%s%s", ScaleNumberSI(&value), unit);

displayNumberValue(line, name, value, precision, newUnit);
}

// Display a scaled number and adjust output such that the user gets some number
// of significant figures eg, for 4: 1.00598kWh appears as 1.005 rather than 1.0
// Overloaded on displayScaledNumberValue
Comment on lines +680 to +681
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this example highlights a flaw with the implementation. 1.00598kWh should be rounded up to 1.006kWh

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. printf() doesn't round. I'll add that.

void LcdTask::displayScaledNumberValue(int line, const char *name, double value, const char *unit)
{

char newUnit[20];
sprintf(newUnit, "%s%s", ScaleNumberSI(&value), unit);

displayNumberValueSigFigures(line, name, value, 4, newUnit);
}

// Display a numeric value preceded by the quantity name, scaled for SI notation,
// and with a specific number of digits after the decimal point.
void LcdTask::displayNumberValue(int line, const char *name, double value, int precision, const char *unit)
{
char number[20];
Expand All @@ -651,6 +698,22 @@ void LcdTask::displayNumberValue(int line, const char *name, double value, int p
displayNameValue(line, name, number);
}


// Display a numeric value that has already been SI adjusted,
// adjusted to a specifed number of significant figures, and appended with units
void LcdTask::displayNumberValueSigFigures(int line, const char *name, double value, int figures, const char *unit)
{

char number[20];

formatDoubleSigFigures(number, sizeof(number), value, figures);

char with_unit[20];
sprintf(with_unit,"%s%s",number,unit);

displayNameValue(line, name, with_unit);
}

void LcdTask::displayInfoEventTime(const char *name, Scheduler::EventInstance &event)
{
char temp[20];
Expand Down
4 changes: 4 additions & 0 deletions src/lcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ class LcdTask : public MicroTasks::Task
void displayStateLine(uint8_t EvseState, unsigned long &nextUpdate);
void displayInfoLine(LcdInfoLine info, unsigned long &nextUpdate);
void displayNumberValue(int line, const char *name, double value, int precision, const char *unit);
void displayNumberValueSigFigures(int line, const char *name, double value, int figures, const char *unit);
const char *ScaleNumberSI(double *value);
char *formatDoubleSigFigures(char *buffer, int buflen, double value, int figures);
void displayScaledNumberValue(int line, const char *name, double value, int precision, const char *unit);
void displayScaledNumberValue(int line, const char *name, double value, const char *unit);
void displayInfoEventTime(const char *name, Scheduler::EventInstance &event);
void displayNameValue(int line, const char *name, const char *value);
void displayStopWatchTime(const char *name, uint32_t time);
Expand Down