#ifndef MAXDIGITS
#define MAXDIGITS 8
#endif
#ifndef MARET_SevenSegment_h
#define MARET_SevenSegment_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#define CC 0 // Common Cathode
#define CA 1 // Common Anode
#define NPN 2
#define PNP 3
#define NP_CC 1
#define NP_CA 00
class MARET_SevenSegment {
public:
MARET_SevenSegment(uint8_t hardwareConfig, uint8_t numDigits, const uint8_t digitPins[], const uint8_t segmentPins[], bool resOn = false, bool updateWDelay = false, bool leadZero = false, bool disDecPoint = false);
void refreshDisplay();
void begin();
void setBrightness(int16_t brightness);
void setNumber(int32_t num, int8_t decPlace = -1, bool hex = false);
void setNumberFloat(float num, int8_t decPlace = -1, bool hex = false);
void setSegments(const uint8_t segs[]);
void getSegments(uint8_t segs[]);
void setSegmentsDigit(const uint8_t digitNum, const uint8_t segs);
void setChars(const char str[]);
void blank(void);
private:
void setNewNum(int32_t num, int8_t decPlace, bool hex = false);
void findDigits(int32_t num, int8_t decPlace, bool hex, uint8_t digits[]);
void setDigitCodes(const uint8_t nums[], int8_t decPlace);
void segmentOn(uint8_t segmentNum);
void segmentOff(uint8_t segmentNum);
void digitOn(uint8_t digitNum);
void digitOff(uint8_t digitNum);
uint8_t _hardwareConfig;
uint8_t digitOnVal, digitOffVal, segmentOnVal, segmentOffVal;
bool _resOn, _updateWDelay, _leadZero;
uint8_t _digitPins[MAXDIGITS];
uint8_t _segmentPins[8];
uint8_t _numDigits;
uint8_t _numSegments;
uint8_t prevUpdateIdx;
uint8_t digitCodes[MAXDIGITS];
uint32_t prevUpdateTime;
uint16_t ledOnTime;
uint16_t waitOffTime;
bool waitOffActive;
};
#endif
#define BLANK_IDX 36
#define DASH_IDX 37
#define PERIOD_IDX 38
#define ASTERISK_IDX 39
#define UNDERSCORE_IDX 40
static const int32_t powersOf10[] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
};
static const int32_t powersOf16[] = {
0x1,
0x10,
0x100,
0x1000,
0x10000,
0x100000,
0x1000000,
0x10000000
};
static const uint8_t digitCodeMap[] = {
// GFEDCBA Segments 7-segment map:
0b00111111, // 0 "0" AAA
0b00000110, // 1 "1" F B
0b01011011, // 2 "2" F B
0b01001111, // 3 "3" GGG
0b01100110, // 4 "4" E C
0b01101101, // 5 "5" E C
0b01111101, // 6 "6" DDD
0b00000111, // 7 "7"
0b01111111, // 8 "8"
0b01101111, // 9 "9"
0b01110111, // 65 'A'
0b01111100, // 66 'b'
0b00111001, // 67 'C'
0b01011110, // 68 'd'
0b01111001, // 69 'E'
0b01110001, // 70 'F'
0b00111101, // 71 'G'
0b01110110, // 72 'H'
0b00110000, // 73 'I'
0b00001110, // 74 'J'
0b01110110, // 75 'K' Same as 'H'
0b00111000, // 76 'L'
0b00000000, // 77 'M' NO DISPLAY
0b01010100, // 78 'n'
0b00111111, // 79 'O'
0b01110011, // 80 'P'
0b01100111, // 81 'q'
0b01010000, // 82 'r'
0b01101101, // 83 'S'
0b01111000, // 84 't'
0b00111110, // 85 'U'
0b00111110, // 86 'V' Same as 'U'
0b00000000, // 87 'W' NO DISPLAY
0b01110110, // 88 'X' Same as 'H'
0b01101110, // 89 'y'
0b01011011, // 90 'Z' Same as '2'
0b00000000, // 32 ' ' BLANK
0b01000000, // 45 '-' DASH
0b10000000, // 46 '.' PERIOD
0b01100011, // 42 '*' DEGREE ..
0b00001000, // 95 '_' UNDERSCORE
};
const uint8_t * const numeralCodes = digitCodeMap;
const uint8_t * const alphaCodes = digitCodeMap + 10;
MARET_SevenSegment::MARET_SevenSegment(uint8_t hardwareConfig, uint8_t numDigits, const uint8_t digitPins[], const uint8_t segmentPins[], bool resOn, bool updateWDelay, bool leadZero, bool disDecPoint) {
_hardwareConfig = hardwareConfig;
_numDigits = numDigits;
_numSegments = disDecPoint ? 7 : 8;
_resOn = resOn;
_updateWDelay = updateWDelay;
_leadZero = leadZero;
ledOnTime = 2000;
waitOffTime = 0;
waitOffActive = false;
prevUpdateIdx = 0;
prevUpdateTime = 0;
for (uint8_t segmentNum = 0; segmentNum < _numSegments; segmentNum++) _segmentPins[segmentNum] = segmentPins[segmentNum];
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) _digitPins[digitNum] = digitPins[digitNum];
}
void MARET_SevenSegment::begin() {
if (_numDigits > MAXDIGITS) _numDigits = MAXDIGITS;
switch (_hardwareConfig) {
case 0: // Common Cathode
digitOnVal = LOW;
segmentOnVal = HIGH;
break;
case 1: // Common Anode
digitOnVal = HIGH;
segmentOnVal = LOW;
break;
case 2: // With active-high, low-side switches (most commonly N-type FETs)
digitOnVal = HIGH;
segmentOnVal = HIGH;
break;
case 3: // With active low, high side switches (most commonly P-type FETs)
digitOnVal = LOW;
segmentOnVal = LOW;
break;
}
if (digitOnVal == HIGH) digitOffVal = LOW;
else digitOffVal = HIGH;
if (segmentOnVal == HIGH) segmentOffVal = LOW;
else segmentOffVal = HIGH;
for (uint8_t digit = 0; digit < _numDigits; digit++) {
pinMode(_digitPins[digit], OUTPUT);
digitalWrite(_digitPins[digit], digitOffVal);
}
for (uint8_t segmentNum = 0; segmentNum < _numSegments; segmentNum++) {
pinMode(_segmentPins[segmentNum], OUTPUT);
digitalWrite(_segmentPins[segmentNum], segmentOffVal);
}
blank();
}
void MARET_SevenSegment::refreshDisplay() {
if (!_updateWDelay) {
uint32_t us = micros();
if (waitOffActive) {
if ((us - prevUpdateTime) < waitOffTime) return;
} else {
if ((us - prevUpdateTime) < ledOnTime) return;
}
prevUpdateTime = us;
if (!_resOn) {
if (waitOffActive) waitOffActive = false;
else {
segmentOff(prevUpdateIdx);
if(waitOffTime) {
waitOffActive = true;
return;
}
}
prevUpdateIdx++;
if (prevUpdateIdx >= _numSegments) prevUpdateIdx = 0;
segmentOn(prevUpdateIdx);
} else {
if (waitOffActive) waitOffActive = false;
else {
digitOff(prevUpdateIdx);
if (waitOffTime) {
waitOffActive = true;
return;
}
}
prevUpdateIdx++;
if (prevUpdateIdx >= _numDigits) prevUpdateIdx = 0;
digitOn(prevUpdateIdx);
}
} else {
if (!_resOn) {
for (uint8_t segmentNum = 0; segmentNum < _numSegments; segmentNum++) {
segmentOn(segmentNum);
delayMicroseconds(ledOnTime);
segmentOff(segmentNum);
if (waitOffTime) delayMicroseconds(waitOffTime);
}
} else {
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) {
digitOn(digitNum);
delayMicroseconds(ledOnTime);
digitOff(digitNum);
if (waitOffTime) delayMicroseconds(waitOffTime);
}
}
}
}
void MARET_SevenSegment::segmentOn(uint8_t segmentNum) {
digitalWrite(_segmentPins[segmentNum], segmentOnVal);
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) {
if (digitCodes[digitNum] & (1 << segmentNum)) digitalWrite(_digitPins[digitNum], digitOnVal);
}
}
void MARET_SevenSegment::segmentOff(uint8_t segmentNum) {
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) digitalWrite(_digitPins[digitNum], digitOffVal);
digitalWrite(_segmentPins[segmentNum], segmentOffVal);
}
void MARET_SevenSegment::digitOn(uint8_t digitNum) {
digitalWrite(_digitPins[digitNum], digitOnVal);
for (uint8_t segmentNum = 0; segmentNum < _numSegments; segmentNum++) {
if (digitCodes[digitNum] & (1 << segmentNum)) digitalWrite(_segmentPins[segmentNum], segmentOnVal);
}
}
void MARET_SevenSegment::digitOff(uint8_t digitNum) {
for (uint8_t segmentNum = 0; segmentNum < _numSegments; segmentNum++) digitalWrite(_segmentPins[segmentNum], segmentOffVal);
digitalWrite(_digitPins[digitNum], digitOffVal);
}
void MARET_SevenSegment::setBrightness(int16_t brightness) {
brightness = constrain(brightness, -200, 200);
if (brightness > 0) {
ledOnTime = map(brightness, 0, 100, 1, 2000);
waitOffTime = 0;
waitOffActive = false;
} else {
ledOnTime = 0;
waitOffTime = map(brightness, 0, -100, 1, 2000);
}
}
void MARET_SevenSegment::setNumber(int32_t num, int8_t decPlace, bool hex) { setNewNum(num, decPlace, hex); }
void MARET_SevenSegment::setNumberFloat(float num, int8_t decPlace, bool hex) {
if (decPlace < 0) {
String numStr = String(num);
int point = numStr.indexOf('.');
decPlace = map(point, 0, _numDigits, _numDigits, 0);
}
int8_t decPlacePos = constrain(decPlace, 0, MAXDIGITS);
if (hex) num = num * powersOf16[decPlacePos];
else num = num * powersOf10[decPlacePos];
num += (num >= 0.f) ? 0.5f : -0.5f;
setNewNum((int32_t)num, (int8_t)decPlace, hex);
}
void MARET_SevenSegment::setNewNum(int32_t num, int8_t decPlace, bool hex) {
uint8_t digits[MAXDIGITS];
findDigits(num, decPlace, hex, digits);
setDigitCodes(digits, decPlace);
}
// Bit-segment mapping: 0bHGFEDCBA
// Visual mapping:
// AAAA 0000
// F B 5 1
// F B 5 1
// GGGG 6666
// E C 4 2
// E C 4 2 (Segment H is often called
// DDDD H 3333 7 DP, for Decimal Point)
void MARET_SevenSegment::setSegments(const uint8_t segs[]) { for (uint8_t digit = 0; digit < _numDigits; digit++) digitCodes[digit] = segs[digit]; }
void MARET_SevenSegment::setSegmentsDigit(const uint8_t digitNum, const uint8_t segs) { if (digitNum < _numDigits) digitCodes[digitNum] = segs; }
void MARET_SevenSegment::getSegments(uint8_t segs[]) { for (uint8_t digit = 0; digit < _numDigits; digit++) segs[digit] = digitCodes[digit]; }
void MARET_SevenSegment::setChars(const char str[]) {
for (uint8_t digit = 0; digit < _numDigits; digit++) digitCodes[digit] = 0;
uint8_t strIdx = 0;
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) {
char ch = str[strIdx];
if (ch == '\0') break;
if (ch >= '0' && ch <= '9') digitCodes[digitNum] = numeralCodes[ch - '0'];
else if (ch >= 'A' && ch <= 'Z') digitCodes[digitNum] = alphaCodes[ch - 'A'];
else if (ch >= 'a' && ch <= 'z') digitCodes[digitNum] = alphaCodes[ch - 'a'];
else if (ch == ' ') digitCodes[digitNum] = digitCodeMap[BLANK_IDX];
else if (ch == '.') digitCodes[digitNum] = digitCodeMap[PERIOD_IDX];
else if (ch == '*') digitCodes[digitNum] = digitCodeMap[ASTERISK_IDX];
else if (ch == '_') digitCodes[digitNum] = digitCodeMap[UNDERSCORE_IDX];
else digitCodes[digitNum] = digitCodeMap[DASH_IDX];
strIdx++;
if (str[strIdx] == '.') {
digitCodes[digitNum] |= digitCodeMap[PERIOD_IDX];
strIdx++;
}
}
}
void MARET_SevenSegment::blank(void) {
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) digitCodes[digitNum] = digitCodeMap[BLANK_IDX];
segmentOff(0);
digitOff(0);
}
void MARET_SevenSegment::findDigits(int32_t num, int8_t decPlace, bool hex, uint8_t digits[]) {
const int32_t * powersOfBase = hex ? powersOf16 : powersOf10;
const int32_t maxNum = powersOfBase[_numDigits] - 1;
const int32_t minNum = -(powersOfBase[_numDigits - 1] - 1);
if (num > maxNum || num < minNum) for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) digits[digitNum] = DASH_IDX;
else {
uint8_t digitNum = 0;
if (num < 0) {
digits[0] = DASH_IDX;
digitNum = 1;
num = -num;
}
for (; digitNum < _numDigits; digitNum++) {
int32_t factor = powersOfBase[_numDigits - 1 - digitNum];
digits[digitNum] = num / factor;
num -= digits[digitNum] * factor;
}
if (decPlace < 0) decPlace = 0;
if (!_leadZero) {
for (digitNum = 0; digitNum < (_numDigits - 1 - decPlace); digitNum++) {
if (digits[digitNum] == 0) digits[digitNum] = BLANK_IDX;
else if (digits[digitNum] <= 9) {
break;
}
}
}
}
}
void MARET_SevenSegment::setDigitCodes(const uint8_t digits[], int8_t decPlace) {
for (uint8_t digitNum = 0; digitNum < _numDigits; digitNum++) {
digitCodes[digitNum] = digitCodeMap[digits[digitNum]];
if (decPlace >= 0) if (digitNum == _numDigits - 1 - decPlace) digitCodes[digitNum] |= digitCodeMap[PERIOD_IDX];
}
}
#ifndef MARET_Button_h
#define MARET_Button_h
#include "Arduino.h"
extern "C" {
typedef void (*callbackFunction)(void);
typedef void (*parameterizedCallbackFunction)(void *);
}
class MARET_Button {
public:
MARET_Button();
MARET_Button(const int pin, const boolean activeLow = true, const bool pullupActive = true);
void setDebounceTicks(const int ticks);
void setClickTicks(const int ticks);
void setPressTicks(const int ticks);
void attachClick(callbackFunction newFunction);
void attachClick(parameterizedCallbackFunction newFunction, void *parameter);
void attachDoubleClick(callbackFunction newFunction);
void attachDoubleClick(parameterizedCallbackFunction newFunction, void *parameter);
void attachMultiClick(callbackFunction newFunction);
void attachMultiClick(parameterizedCallbackFunction newFunction, void *parameter);
void attachLongPressStart(callbackFunction newFunction);
void attachLongPressStart(parameterizedCallbackFunction newFuntion, void *parameter);
void attachDuringLongPress(callbackFunction newFunction);
void attachDuringLongPress(parameterizedCallbackFunction newFuntion, void *parameter);
void attachLongPressStop(callbackFunction newFunction);
void attachLongPressStop(parameterizedCallbackFunction newFunction, void *parameter);
void tick(void);
void tick(bool level);
void reset(void);
int getNumberClicks(void);
bool isIdle() const { return _state == OCS_INIT; }
bool isLongPressed() const { return _state == OCS_PRESS; };
private:
int _pin;
unsigned int _debounceTicks = 50;
unsigned int _clickTicks = 400;
unsigned int _pressTicks = 800;
int _buttonPressed;
callbackFunction _clickFunc = NULL;
parameterizedCallbackFunction _paramClickFunc = NULL;
void *_clickFuncParam = NULL;
callbackFunction _doubleClickFunc = NULL;
parameterizedCallbackFunction _paramDoubleClickFunc = NULL;
void *_doubleClickFuncParam = NULL;
callbackFunction _multiClickFunc = NULL;
parameterizedCallbackFunction _paramMultiClickFunc = NULL;
void *_multiClickFuncParam = NULL;
callbackFunction _longPressStartFunc = NULL;
parameterizedCallbackFunction _paramLongPressStartFunc = NULL;
void *_longPressStartFuncParam = NULL;
callbackFunction _duringLongPressFunc = NULL;
parameterizedCallbackFunction _paramDuringLongPressFunc = NULL;
void *_duringLongPressFuncParam = NULL;
callbackFunction _longPressStopFunc = NULL;
parameterizedCallbackFunction _paramLongPressStopFunc = NULL;
void *_longPressStopFuncParam = NULL;
enum stateMachine_t : int {
OCS_INIT = 0,
OCS_DOWN = 1,
OCS_UP = 2,
OCS_COUNT = 3,
OCS_PRESS = 6,
OCS_PRESSEND = 7,
UNKNOWN = 99
};
void _newState(stateMachine_t nextState);
stateMachine_t _state = OCS_INIT;
stateMachine_t _lastState = OCS_INIT;
unsigned long _startTime;
int _nClicks;
int _maxClicks = 1;
};
#endif
MARET_Button::MARET_Button() { _pin = -1; }
MARET_Button::MARET_Button(const int pin, const boolean activeLow, const bool pullupActive) {
_pin = pin;
if (activeLow) _buttonPressed = LOW;
else _buttonPressed = HIGH;
if (pullupActive) pinMode(pin, INPUT_PULLUP);
else pinMode(pin, INPUT);
}
void MARET_Button::setDebounceTicks(const int ticks) { _debounceTicks = ticks; }
void MARET_Button::setClickTicks(const int ticks) { _clickTicks = ticks; }
void MARET_Button::setPressTicks(const int ticks) { _pressTicks = ticks; }
void MARET_Button::attachClick(callbackFunction newFunction) { _clickFunc = newFunction; }
void MARET_Button::attachClick(parameterizedCallbackFunction newFunction, void *parameter) {
_paramClickFunc = newFunction;
_clickFuncParam = parameter;
}
void MARET_Button::attachDoubleClick(callbackFunction newFunction) {
_doubleClickFunc = newFunction;
_maxClicks = max(_maxClicks, 2);
}
void MARET_Button::attachDoubleClick(parameterizedCallbackFunction newFunction, void *parameter) {
_paramDoubleClickFunc = newFunction;
_doubleClickFuncParam = parameter;
_maxClicks = max(_maxClicks, 2);
}
void MARET_Button::attachMultiClick(callbackFunction newFunction) {
_multiClickFunc = newFunction;
_maxClicks = max(_maxClicks, 100);
}
void MARET_Button::attachMultiClick(parameterizedCallbackFunction newFunction, void *parameter) {
_paramMultiClickFunc = newFunction;
_multiClickFuncParam = parameter;
_maxClicks = max(_maxClicks, 100);
}
void MARET_Button::attachLongPressStart(callbackFunction newFunction) { _longPressStartFunc = newFunction; }
void MARET_Button::attachLongPressStart(parameterizedCallbackFunction newFunction, void *parameter ) {
_paramLongPressStartFunc = newFunction;
_longPressStartFuncParam = parameter;
}
void MARET_Button::attachDuringLongPress(callbackFunction newFunction) { _duringLongPressFunc = newFunction; }
void MARET_Button::attachDuringLongPress(parameterizedCallbackFunction newFunction, void *parameter) {
_paramDuringLongPressFunc = newFunction;
_duringLongPressFuncParam = parameter;
}
void MARET_Button::attachLongPressStop(callbackFunction newFunction) { _longPressStopFunc = newFunction; }
void MARET_Button::attachLongPressStop(parameterizedCallbackFunction newFunction, void *parameter) {
_paramLongPressStopFunc = newFunction;
_longPressStopFuncParam = parameter;
}
void MARET_Button::reset(void) {
_state = MARET_Button::OCS_INIT;
_lastState = MARET_Button::OCS_INIT;
_nClicks = 0;
_startTime = 0;
}
int MARET_Button::getNumberClicks(void) { return _nClicks; }
void MARET_Button::tick(void) { if (_pin >= 0) tick(digitalRead(_pin) == _buttonPressed); };
void MARET_Button::_newState(stateMachine_t nextState) {
_lastState = _state;
_state = nextState;
}
void MARET_Button::tick(bool activeLevel) {
unsigned long now = millis();
unsigned long waitTime = (now - _startTime);
switch (_state) {
case MARET_Button::OCS_INIT:
if (activeLevel) {
_newState(MARET_Button::OCS_DOWN);
_startTime = now;
_nClicks = 0;
}
break;
case MARET_Button::OCS_DOWN:
if ((!activeLevel) && (waitTime < _debounceTicks)) _newState(_lastState);
else if (!activeLevel) {
_newState(MARET_Button::OCS_UP);
_startTime = now;
} else if ((activeLevel) && (waitTime > _pressTicks)) {
if (_longPressStartFunc) _longPressStartFunc();
if (_paramLongPressStartFunc) _paramLongPressStartFunc(_longPressStartFuncParam);
_newState(MARET_Button::OCS_PRESS);
}
break;
case MARET_Button::OCS_UP:
if ((activeLevel) && (waitTime < _debounceTicks)) _newState(_lastState);
else if (waitTime >= _debounceTicks) {
_nClicks++;
_newState(MARET_Button::OCS_COUNT);
}
break;
case MARET_Button::OCS_COUNT:
if (activeLevel) {
_newState(MARET_Button::OCS_DOWN);
_startTime = now;
} else if ((waitTime > _clickTicks) || (_nClicks == _maxClicks)) {
if (_nClicks == 1) {
if (_clickFunc) _clickFunc();
if (_paramClickFunc) _paramClickFunc(_clickFuncParam);
} else if (_nClicks == 2) {
if (_doubleClickFunc) _doubleClickFunc();
if (_paramDoubleClickFunc) _paramDoubleClickFunc(_doubleClickFuncParam);
} else {
if (_multiClickFunc) _multiClickFunc();
if (_paramMultiClickFunc) _paramMultiClickFunc(_multiClickFuncParam);
}
reset();
}
break;
case MARET_Button::OCS_PRESS:
if (!activeLevel) {
_newState(MARET_Button::OCS_PRESSEND);
_startTime = now;
} else {
if (_duringLongPressFunc) _duringLongPressFunc();
if (_paramDuringLongPressFunc) _paramDuringLongPressFunc(_duringLongPressFuncParam);
}
break;
case MARET_Button::OCS_PRESSEND:
if ((activeLevel) && (waitTime < _debounceTicks)) _newState(_lastState);
else if (waitTime >= _debounceTicks) {
if (_longPressStopFunc) _longPressStopFunc();
if (_paramLongPressStopFunc) _paramLongPressStopFunc(_longPressStopFuncParam);
reset();
}
break;
default:
_newState(MARET_Button::OCS_INIT);
break;
}
}
#define DIG1 0
#define DIG2 1
#define DIG3 5
#define A 6
#define B 7
#define C 8
#define D 9
#define E 10
#define F 11
#define G 12
#define P 13
byte NumDigits = 3;
byte DigitPins[] = { DIG1, DIG2, DIG3 };
byte SegmentPins[] = { A, B, C, D, E, F, G, P };
bool ResistorsOnSegments = false;
byte HardwareConfig = CA;
bool UpdateWithDelays = false;
bool LeadingZeros = false;
bool DisableDecimalPoint = false;
MARET_Button UP(A0, true);
MARET_Button DOWN(A1, true);
MARET_SevenSegment display(HardwareConfig, NumDigits, DigitPins, SegmentPins, ResistorsOnSegments, UpdateWithDelays, LeadingZeros, DisableDecimalPoint);
int value = 0;
void upClicked() {
if (value >= 500) value = 500;
else value++;
}
void downClicked() {
if (value <= 0) value = 0;
else value--;
}
void upLongPress() {
if (value >= 500) value = 500;
else value++;
delay(10);
}
void downLongPress() {
if (value <= 0) value = 0;
else value--;
delay(10);
}
void setup() {
pinMode(A2, OUTPUT);
digitalWrite(A2, HIGH);
display.begin();
display.setBrightness(90);
UP.attachClick(upClicked);
DOWN.attachClick(downClicked);
UP.attachDuringLongPress(upLongPress);
DOWN.attachDuringLongPress(downLongPress);
}
void loop() {
UP.tick();
DOWN.tick();
display.setNumber(value);
//double a = 15.56;
//display.setNumberFloat(a);
//display.setChars("12.5");
display.refreshDisplay();
}