From 38be4163c0d7999d1876b6fc4c3324d5aa4c34f6 Mon Sep 17 00:00:00 2001 From: Scott Allen Date: Mon, 22 Sep 2014 19:16:34 -0400 Subject: [PATCH] Replaced sprintf calls with dedicated code Using sprintf generates a large amount of code. By replacing the sprintf calls with dedicated code, program size is reduced when widgets are used. Also: - Added a getValLen method for widgets which returns the print length for the current value, similar to the existing getMaxValLen. - The value for widgets is now initialised to the minimum value, instead of 0, because 0 could be outside the specified range. - Added getValLen and getMaxValLen keywords. - The MicroViewWidgetDemo example sketch was modified to use the new getValLen method, plus a few other small changes. --- MicroView.cpp | 100 +++++++++++++----- MicroView.h | 4 + .../MicroViewWidgetDemo.ino | 7 +- keywords.txt | 2 + 4 files changed, 81 insertions(+), 32 deletions(-) diff --git a/MicroView.cpp b/MicroView.cpp index 7873510..cffada8 100644 --- a/MicroView.cpp +++ b/MicroView.cpp @@ -1362,11 +1362,13 @@ int MicroView::readSerial(void) The MicroViewWidget class is the parent class for child widget like MicroViewSlider and MicroViewGauge. */ MicroViewWidget::MicroViewWidget(uint8_t newx, uint8_t newy, int16_t min, int16_t max) { - setX(newx); - setY(newy); - value=0; - setMinValue(min); - setMaxValue(max); + x=newx; + y=newy; + value=min; + valLen=getInt16PrintLen(value); + minValue=min; + maxValue=max; + setMaxValLen(); } /** \brief Get widget x position. */ @@ -1403,37 +1405,44 @@ int16_t MicroViewWidget::getValue() { return value; } The minimum value of the widget is set to the variable passed in. */ -void MicroViewWidget::setMinValue(int16_t min) { minValue=min; } +void MicroViewWidget::setMinValue(int16_t min) { + minValue = min; + setMaxValLen(); +} /** \brief Set maximum value. The maximum value of the widget is set to the variable passed in. */ -void MicroViewWidget::setMaxValue(int16_t max) { maxValue=max; } - -/** \brief Get the maximum possible print lenth of the value - - Return the maximum number of characters that would be printed using printf("%d", value) for the current value range. -*/ -uint8_t MicroViewWidget::getMaxValLen() { - uint8_t minLen, maxLen; - - maxLen = getInt16PrintLen(maxValue); - minLen = getInt16PrintLen(minValue); - return maxLen >= minLen ? maxLen : minLen; +void MicroViewWidget::setMaxValue(int16_t max) { + maxValue = max; + setMaxValLen(); } +/** \brief Get the maximum possible print length of the value + + Return the maximum number of characters that would be printed using uView.print(value) for the current value range. +*/ +uint8_t MicroViewWidget::getMaxValLen() { return maxValLen; } + /** \brief Set current value. The current value of the widget is set to the variable passed in. */ -void MicroViewWidget::setValue(int16_t val) { - if ((val<=maxValue) && (val>=minValue)){ - value=val; +void MicroViewWidget::setValue(int16_t val) { + if ((val<=maxValue) && (val>=minValue)) { + value = val; + valLen = getInt16PrintLen(val); this->draw(); } } +/** \brief Get the print length of the value + + Return the number of characters that would be printed using uView.print(value) for the current value. +*/ +uint8_t MicroViewWidget::getValLen() { return valLen; } + /** \brief MicroView Widget reDraw routine. Redraws the widget. @@ -1449,12 +1458,22 @@ void MicroViewWidget::reDraw() { The value is right justified with leading spaces, within a field the length of the maximum posible for the widget's value range. */ void MicroViewWidget::drawNumValue(int16_t value) { - char strBuffer[7]; - char formatStr[] = "%1d"; - formatStr[1] = '0' + getMaxValLen(); // Set the field width for the value range - sprintf(strBuffer, formatStr, value); - uView.print(strBuffer); + for (uint8_t i = maxValLen - getInt16PrintLen(value); i > 0; i--) { + uView.print(" "); + } + uView.print(value); +} + +/* Set the maximum number of characters that would be printed + using uView.print(value) for the current value range. +*/ +void MicroViewWidget::setMaxValLen() { + uint8_t minLen, maxLen; + + maxLen = getInt16PrintLen(maxValue); + minLen = getInt16PrintLen(minValue); + maxValLen = maxLen >= minLen ? maxLen : minLen; } // ------------------------------------------------------------------------------------- @@ -1844,11 +1863,34 @@ MicroView uView; /** \brief Get the number of characters for a 16 bit signed value. - Return the number of characters that would be printed using printf("%d", x) for x being a signed 16 bit integer. + Return the number of characters that would be printed using uView.print(x) for x being a signed 16 bit integer. */ uint8_t getInt16PrintLen(int16_t val) { - char sbuf[7]; + int16_t i; + uint8_t count; - return sprintf(sbuf, "%d", val); + if (val >= 10000) { + return 5; + } + + if (val <= -10000) { + return 6; + } + + if (val >= 0) { + count = 1; + } + else { + count = 2; + val = abs(val); + } + + i = 10; + while (val >= i) { + count++; + i *= 10; + } + + return count; } diff --git a/MicroView.h b/MicroView.h index a784e09..4d9b58d 100644 --- a/MicroView.h +++ b/MicroView.h @@ -243,6 +243,7 @@ public: void setMinValue(int16_t min); void setMaxValue(int16_t max); void setValue(int16_t val); + uint8_t getValLen(); uint8_t getMaxValLen(); /** \brief Draw widget value overridden by child class. */ virtual void draw(){}; @@ -252,11 +253,14 @@ public: void drawNumValue(int16_t value); virtual ~MicroViewWidget(){}; private: + void setMaxValLen(); uint8_t x; uint8_t y; int16_t maxValue; int16_t minValue; int16_t value; + uint8_t valLen; + uint8_t maxValLen; }; class MicroViewSlider: public MicroViewWidget{ diff --git a/examples/MicroViewWidgetDemo/MicroViewWidgetDemo.ino b/examples/MicroViewWidgetDemo/MicroViewWidgetDemo.ino index d172ad5..1eb5b78 100644 --- a/examples/MicroViewWidgetDemo/MicroViewWidgetDemo.ino +++ b/examples/MicroViewWidgetDemo/MicroViewWidgetDemo.ino @@ -208,7 +208,7 @@ void loop() { /* ==================== Demo 13 ==================== Gauge style 1, with no numeric value. - Value manually displayed beneath, as a letter. + Value manually displayed as a letter. Range 1 to 26 (A to Z). ================================================ */ demoNumber(13); @@ -246,15 +246,15 @@ void customSlider0(int16_t val) { // Update function for Demo 9 void customSlider1(int16_t val) { + widget1->setValue(val); uint8_t offsetY = widget1->getY() - 10; uint8_t offsetX = widget1->getX() + 14; uView.setCursor(offsetX, offsetY); uView.print(" "); // erase the previous value in case it's longer // calculate the offset to centre the value - offsetX += ((widget1->getMaxValLen() - getInt16PrintLen(val)) * 3); + offsetX += ((widget1->getMaxValLen() - widget1->getValLen()) * 3); uView.setCursor(offsetX, offsetY); uView.print(val); - widget1->setValue(val); } // Update function for Demo 10 @@ -324,6 +324,7 @@ void spin(int16_t lowVal, int16_t highVal, int16_t stepSize, unsigned long stepDelay, void (*drawFunction)(int16_t val)) { drawFunction(lowVal); uView.display(); + prevVal = lowVal; delay(1500); for (int16_t i = lowVal + stepSize; i <= highVal; i += stepSize) { diff --git a/keywords.txt b/keywords.txt index 455e1b1..e94d608 100644 --- a/keywords.txt +++ b/keywords.txt @@ -63,6 +63,8 @@ getMaxValue KEYWORD2 setMaxValue KEYWORD2 setMinValue KEYWORD2 setValue KEYWORD2 +getValLen KEYWORD2 +getMaxValLen KEYWORD2 draw KEYWORD2 reDraw KEYWORD2 drawFace KEYWORD2