// SevSeg.h
#ifndef MAXNUMDIGITS
#define MAXNUMDIGITS 8 // Can be increased, but the max number is 2^31
#endif
#ifndef SevSeg_h
#define SevSeg_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
// Use defines to link the hardware configurations to the correct numbers
#define COMMON_CATHODE 0
#define COMMON_ANODE 1
#define N_TRANSISTORS 2
#define P_TRANSISTORS 3
#define NP_COMMON_CATHODE 1
#define NP_COMMON_ANODE 0
class SevSeg
{
public:
SevSeg();
void refreshDisplay();
void begin(uint8_t hardwareConfig, uint8_t numDigitsIn, const uint8_t digitPinsIn[],
const uint8_t segmentPinsIn[], bool resOnSegmentsIn=0,
bool updateWithDelaysIn=0, bool leadingZerosIn=0,
bool disableDecPoint=0);
// void setBrightness(int16_t brightnessIn); // A number from 0..100
void setNumber(int32_t numToShow, int8_t decPlaces=-1, bool hex=0);
void setNumberF(float numToShow, int8_t decPlaces=-1, bool hex=0);
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);
uint8_t getNumDigits() { return numDigits; }
// private:
void setNewNum(int32_t numToShow, int8_t decPlaces, bool hex=0);
void findDigits(int32_t numToShow, int8_t decPlaces, bool hex, uint8_t digits[]);
void setDigitCodes(const uint8_t nums[], int8_t decPlaces);
void segmentOn(uint8_t segmentNum);
void segmentOff(uint8_t segmentNum);
void digitOn(uint8_t digitNum);
void digitOff(uint8_t digitNum);
uint8_t digitOnVal,digitOffVal,segmentOnVal,segmentOffVal;
bool resOnSegments, updateWithDelays, leadingZeros;
uint8_t digitPins[MAXNUMDIGITS];
uint8_t segmentPins[8];
uint8_t numDigits;
uint8_t numSegments;
uint8_t prevUpdateIdx; // The previously updated segment or digit
uint8_t digitCodes[MAXNUMDIGITS]; // The active setting of each segment of each digit
uint32_t prevUpdateTime; // The time (millis()) when the display was last updated
uint16_t ledOnTime; // The time (us) to wait with LEDs on
uint16_t waitOffTime; // The time (us) to wait with LEDs off
bool waitOffActive; // Whether the program is waiting with LEDs off
};
#endif //SevSeg_h
/// END ///
// SevSeg.cpp
// #include "SevSeg.h"
#define BLANK_IDX 36 // Must match with 'digitCodeMap'
#define DASH_IDX 37
#define PERIOD_IDX 38
#define ASTERISK_IDX 39
#define UNDERSCORE_IDX 40
static const int32_t powersOf10[] = {
1, // 10^0
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
}; // 10^9
static const int32_t powersOf16[] = {
0x1, // 16^0
0x10,
0x100,
0x1000,
0x10000,
0x100000,
0x1000000,
0x10000000
}; // 16^7
// digitCodeMap indicate which segments must be illuminated to display
// each number.
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
};
// Constant pointers to constant data
const uint8_t * const numeralCodes = digitCodeMap;
const uint8_t * const alphaCodes = digitCodeMap + 10;
// SevSeg Constructor
/******************************************************************************/
SevSeg::SevSeg() {
// Initial value
ledOnTime = 2000; // Corresponds to a brightness of 100
waitOffTime = 0;
waitOffActive = false;
numDigits = 0;
prevUpdateIdx = 0;
prevUpdateTime = 0;
resOnSegments = 0;
updateWithDelays = 0;
}
// begin
void SevSeg::begin(uint8_t hardwareConfig, uint8_t numDigitsIn, const uint8_t digitPinsIn[],
const uint8_t segmentPinsIn[], bool resOnSegmentsIn,
bool updateWithDelaysIn, bool leadingZerosIn, bool disableDecPoint) {
resOnSegments = resOnSegmentsIn;
updateWithDelays = updateWithDelaysIn;
leadingZeros = leadingZerosIn;
numDigits = numDigitsIn;
numSegments = disableDecPoint ? 7 : 8; // Ternary 'if' statement
//Limit the max number of digits to prevent overflowing
if (numDigits > MAXNUMDIGITS) numDigits = MAXNUMDIGITS;
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;
}
// define the Off-Values depending on the On-Values
if (digitOnVal == HIGH){
digitOffVal = LOW;
} else {
digitOffVal = HIGH;
}
// define the Off-Values depending on the On-Values
if (segmentOnVal == HIGH){
segmentOffVal = LOW;
} else {
segmentOffVal = HIGH;
}
// Save the input pin numbers to library variables
for (uint8_t segmentNum = 0 ; segmentNum < numSegments ; segmentNum++) {
segmentPins[segmentNum] = segmentPinsIn[segmentNum];
}
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digitPins[digitNum] = digitPinsIn[digitNum];
}
// Set the pins as outputs, and turn them off
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(); // Initialise the display
}
// refreshDisplay
// Turns on the segments specified in 'digitCodes[]'
// There are 4 versions of this function, with the choice depending on the
// location of the current-limiting resistors, and whether or not you wish to
// use 'update delays' (the standard method until 2017).
// For resistors on *digits* we will cycle through all 8 segments (7 + period),
// turning on the *digits* as appropriate for a given segment, before moving on
// to the next segment.
// For resistors on *segments* we will cycle through all __ # of digits,
// turning on the *segments* as appropriate for a given digit, before moving on
// to the next digit.
// If using update delays, refreshDisplay has a delay between each digit/segment
// as it cycles through. It exits with all LEDs off.
// If not using updateDelays, refreshDisplay exits with a single digit/segment
// on. It will move to the next digit/segment after being called again (if
// enough time has passed).
void SevSeg::refreshDisplay() {
if (!updateWithDelays) {
uint32_t us = micros();
// Exit if it's not time for the next display change
if (waitOffActive) {
if ((us - prevUpdateTime) < waitOffTime) return;
}
else {
if ((us - prevUpdateTime) < ledOnTime) return;
}
prevUpdateTime = us;
if (!resOnSegments) {
// RESISTORS ON DIGITS, UPDATE WITHOUT DELAYS
if (waitOffActive) {
waitOffActive = false;
}
else {
// Turn all lights off for the previous segment
segmentOff(prevUpdateIdx);
if (waitOffTime) {
// Wait a delay with all lights off
waitOffActive = true;
return;
}
}
prevUpdateIdx++;
if (prevUpdateIdx >= numSegments) prevUpdateIdx = 0;
// Illuminate the required digits for the new segment
segmentOn(prevUpdateIdx);
}
else {
// RESISTORS ON SEGMENTS, UPDATE WITHOUT DELAYS
if (waitOffActive) {
waitOffActive = false;
}
else {
// Turn all lights off for the previous digit
digitOff(prevUpdateIdx);
if (waitOffTime) {
// Wait a delay with all lights off
waitOffActive = true;
return;
}
}
prevUpdateIdx++;
if (prevUpdateIdx >= numDigits) prevUpdateIdx = 0;
// Illuminate the required segments for the new digit
digitOn(prevUpdateIdx);
}
}
else {
if (!resOnSegments) {
// RESISTORS ON DIGITS, UPDATE WITH DELAYS
for (uint8_t segmentNum = 0 ; segmentNum < numSegments ; segmentNum++) {
// Illuminate the required digits for this segment
segmentOn(segmentNum);
// Wait with lights on (to increase brightness)
delayMicroseconds(ledOnTime);
// Turn all lights off
segmentOff(segmentNum);
// Wait with all lights off if required
if (waitOffTime) delayMicroseconds(waitOffTime);
}
}
else {
// RESISTORS ON SEGMENTS, UPDATE WITH DELAYS
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
// Illuminate the required segments for this digit
digitOn(digitNum);
// Wait with lights on (to increase brightness)
delayMicroseconds(ledOnTime);
// Turn all lights off
digitOff(digitNum);
// Wait with all lights off if required
if (waitOffTime) delayMicroseconds(waitOffTime);
}
}
}
}
// segmentOn
// Turns a segment on, as well as all corresponding digit pins
// (according to digitCodes[])
void SevSeg::segmentOn(uint8_t segmentNum) {
digitalWrite(segmentPins[segmentNum], segmentOnVal);
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
if (digitCodes[digitNum] & (1 << segmentNum)) { // Check a single bit
digitalWrite(digitPins[digitNum], digitOnVal);
}
}
}
// segmentOff
// Turns a segment off, as well as all digit pins
void SevSeg::segmentOff(uint8_t segmentNum) {
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digitalWrite(digitPins[digitNum], digitOffVal);
}
digitalWrite(segmentPins[segmentNum], segmentOffVal);
}
// digitOn
// Turns a digit on, as well as all corresponding segment pins
// (according to digitCodes[])
void SevSeg::digitOn(uint8_t digitNum) {
digitalWrite(digitPins[digitNum], digitOnVal);
for (uint8_t segmentNum = 0 ; segmentNum < numSegments ; segmentNum++) {
if (digitCodes[digitNum] & (1 << segmentNum)) { // Check a single bit
digitalWrite(segmentPins[segmentNum], segmentOnVal);
}
}
}
// digitOff
// Turns a digit off, as well as all segment pins
void SevSeg::digitOff(uint8_t digitNum) {
for (uint8_t segmentNum = 0 ; segmentNum < numSegments ; segmentNum++) {
digitalWrite(segmentPins[segmentNum], segmentOffVal);
}
digitalWrite(digitPins[digitNum], digitOffVal);
}
// setNumber
// Receives an integer and passes it to 'setNewNum'.
void SevSeg::setNumber(int32_t numToShow, int8_t decPlaces, bool hex) { //int32_t
setNewNum(numToShow, decPlaces, hex);
}
// setNumberF
// Receives a float, prepares it, and passes it to 'setNewNum'.
void SevSeg::setNumberF(float numToShow, int8_t decPlaces, bool hex) { //float
int8_t decPlacesPos = constrain(decPlaces, 0, MAXNUMDIGITS);
if (hex) {
numToShow = numToShow * powersOf16[decPlacesPos];
}
else {
numToShow = numToShow * powersOf10[decPlacesPos];
}
// Modify the number so that it is rounded to an integer correctly
numToShow += (numToShow >= 0.f) ? 0.5f : -0.5f;
setNewNum((int32_t)numToShow, (int8_t)decPlaces, hex);
}
// setNewNum
// Changes the number that will be displayed.
void SevSeg::setNewNum(int32_t numToShow, int8_t decPlaces, bool hex) {
uint8_t digits[MAXNUMDIGITS];
findDigits(numToShow, decPlaces, hex, digits);
setDigitCodes(digits, decPlaces);
}
// setSegments
// Sets the 'digitCodes' that are required to display the desired segments.
// Using this function, one can display any arbitrary set of segments (like
// letters, symbols or animated cursors). See setDigitCodes() for common
// numeric examples.
//
// 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 SevSeg::setSegments(const uint8_t segs[]) {
for (uint8_t digit = 0; digit < numDigits; digit++) {
digitCodes[digit] = segs[digit];
}
}
// setSegmentsDigit
// Like setSegments above, but only manipulates the segments for one digit
// digitNum is 0-indexed.
void SevSeg::setSegmentsDigit(const uint8_t digitNum, const uint8_t segs) {
if (digitNum < numDigits) {
digitCodes[digitNum] = segs;
}
}
// getSegments
// Gets the 'digitCodes' of currently displayed segments.
// Using this function, one can get the current set of segments (placed
// elsewhere) and manipulate them to obtain effects, for example blink of
// only some digits.
// See setSegments() for bit-segment mapping
//
void SevSeg::getSegments(uint8_t segs[]) {
for (uint8_t digit = 0; digit < numDigits; digit++) {
segs[digit] = digitCodes[digit];
}
}
// setChars
// Displays the string on the display, as best as possible.
// Only alphanumeric characters plus '-' and ' ' are supported
// void SevSeg::setChars(const char str[]) {
// for (uint8_t digit = 0; digit < numDigits; digit++) {
// digitCodes[digit] = 0;
// }
// uint8_t strIdx = 0; // Current position within str[]
// for (uint8_t digitNum = 0; digitNum < numDigits; digitNum++) {
// char ch = str[strIdx];
// if (ch == '\0') break; // NULL string terminator
// if (ch >= '0' && ch <= '9') { // Numerical
// 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 {
// // Every unknown character is shown as a dash
// digitCodes[digitNum] = digitCodeMap[DASH_IDX];
// }
// strIdx++;
// // Peek at next character. If it's a period, add it to this digit
// if (str[strIdx] == '.') {
// digitCodes[digitNum] |= digitCodeMap[PERIOD_IDX];
// strIdx++;
// }
// }
// }
// blank
// void SevSeg::blank(void) {
// for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
// digitCodes[digitNum] = digitCodeMap[BLANK_IDX];
// }
// segmentOff(0);
// digitOff(0);
// }
// findDigits
// Decides what each digit will display.
// Enforces the upper and lower limits on the number to be displayed.
// digits[] is an output
void SevSeg::findDigits(int32_t numToShow, int8_t decPlaces, 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 the number is out of range, just display dashes
if (numToShow > maxNum || numToShow < minNum) {
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digits[digitNum] = DASH_IDX;
}
}
else {
uint8_t digitNum = 0;
// Convert all number to positive values
if (numToShow < 0) {
digits[0] = DASH_IDX;
digitNum = 1; // Skip the first iteration
numToShow = -numToShow;
}
// Find all digits for base's representation, starting with the most
// significant digit
for ( ; digitNum < numDigits ; digitNum++) {
int32_t factor = powersOfBase[numDigits - 1 - digitNum];
digits[digitNum] = numToShow / factor;
numToShow -= digits[digitNum] * factor;
}
// Find unnnecessary leading zeros and set them to BLANK
if (decPlaces < 0) decPlaces = 0;
if (!leadingZeros) {
for (digitNum = 0 ; digitNum < (numDigits - 1 - decPlaces) ; digitNum++) {
if (digits[digitNum] == 0) {
digits[digitNum] = BLANK_IDX;
}
// Exit once the first non-zero number is encountered
else if (digits[digitNum] <= 9) {
break;
}
}
}
}
}
// setDigitCodes
// Sets the 'digitCodes' that are required to display the input numbers
void SevSeg::setDigitCodes(const uint8_t digits[], int8_t decPlaces) {
// Set the digitCode for each digit in the display
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digitCodes[digitNum] = digitCodeMap[digits[digitNum]];
// Set the decimal point segment
if (decPlaces >= 0) {
if (digitNum == numDigits - 1 - decPlaces) {
digitCodes[digitNum] |= digitCodeMap[PERIOD_IDX];
}
}
}
}
/// END ///
// main lib consume code:
SevSeg sevseg; // Instantiate a seven-segment controller object
uint8_t digitCodes[MAXNUMDIGITS]; // The active setting of each segment of each digit
byte numDigits = 4;
// ESP32 pins connected to segment display's digit pins 1,2,3,4
byte digitPins[] = {23, 13, 14, 12}; // Pins connected to the digits
// ESP32 pins connected to segment display's pins a,b,c,d,e,f,g,dp
byte segmentPins[] = {15, 2, 4, 16, 17, 5, 18, 19}; // Pins connected to the segments
void setup() {
Serial.begin(115200);
bool resistorsOnSegments = false; // "false" means resistors are on digit pins
byte hardwareConfig = COMMON_ANODE; // See README.md for options
bool updateWithDelays = false; // Default 'false' is recommended
bool leadingZeros = false; // Set to 'true' if you'd like to keep the leading zeros
bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist on your display
// Initialize the seven-segment display
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
// sevseg.setBrightness(90); // Set the brightness level (0-100)
}
void loop() {
static unsigned long timer = millis();
static int deciSeconds = 0;
// Check if 400 milliseconds have passed
if (millis() - timer >= 400) {
timer += 400;
// deciSeconds++; // 0.0 -> 0.1 -> 0.2
// deciSeconds += 10; // 0.0 -> 1.0 -> 2.0 -> ... -> 10.0
if (deciSeconds == 10000) { // Reset to 0 after counting 1000 seconds
deciSeconds = 0;
}
// Display the number with 1 decimal place
// sevseg.setNumber(deciSeconds, 1); // xx0.1
// myCustomSetNumberF(9.20, 1, 0); // xx9.2
// myCustomSetNumberF(9.20, 2, 0); // x9.20
myCustomSetNumberF(11.20, 2, 0); // 11.20
// Display the number with 2 decimal place
// sevseg.setNumber(deciSeconds, 2); // x0.01
}
// Refresh the display (must be called repeatedly)
sevseg.refreshDisplay();
}
// setDigitCodes
// Sets the 'digitCodes' that are required to display the input numbers
void myCustomSetDigitCodes(const uint8_t digits[], int8_t decPlaces) {
// Set the digitCode for each digit in the display
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digitCodes[digitNum] = digitCodeMap[digits[digitNum]];
// Set the decimal point segment
if (decPlaces >= 0) {
if (digitNum == numDigits - 1 - decPlaces) {
digitCodes[digitNum] |= digitCodeMap[PERIOD_IDX];
}
}
}
}
// setNewNum
// Changes the number that will be displayed.
void myCustomSetNewNum(int32_t numToShow, int8_t decPlaces, bool hex) {
uint8_t digits[MAXNUMDIGITS];
sevseg.findDigits(numToShow, decPlaces, hex, digits);
// myCustomSetDigitCodes(digits, decPlaces); // not work
// debug
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
Serial.printf("%d ", digitCodeMap[digits[digitNum]]);
} // 6 6 91 63
Serial.printf("digits: %d, decPlaces: %d\n", digits, decPlaces); // digits: 1073422852, decPlaces: 2
sevseg.setDigitCodes(digits, decPlaces); // worked
}
void myCustomSetNumberF(float numToShow, int8_t decPlaces, bool hex) { //float
int8_t decPlacesPos = constrain(decPlaces, 0, MAXNUMDIGITS);
if (hex) {
numToShow = numToShow * powersOf16[decPlacesPos];
}
else {
numToShow = numToShow * powersOf10[decPlacesPos];
}
// Modify the number so that it is rounded to an integer correctly
numToShow += (numToShow >= 0.f) ? 0.5f : -0.5f;
myCustomSetNewNum((int32_t)numToShow, (int8_t)decPlaces, hex);
}
/*
#include "SevSeg.h"
SevSeg sevseg; // Instantiate a seven-segment controller object
void setup() {
byte numDigits = 4;
// ESP32 pins connected to segment display's digit pins 1,2,3,4
byte digitPins[] = {23, 13, 14, 12}; // Pins connected to the digits
// ESP32 pins connected to segment display's pins a,b,c,d,e,f,g,dp
byte segmentPins[] = {15, 2, 4, 16, 17, 5, 18, 19}; // Pins connected to the segments
bool resistorsOnSegments = false; // "false" means resistors are on digit pins
byte hardwareConfig = COMMON_ANODE; // See README.md for options
bool updateWithDelays = false; // Default 'false' is recommended
bool leadingZeros = false; // Set to 'true' if you'd like to keep the leading zeros
bool disableDecPoint = false; // Use 'true' if your decimal point doesn't exist on your display
// Initialize the seven-segment display
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
// sevseg.setBrightness(90); // Set the brightness level (0-100)
}
void loop() {
static unsigned long timer = millis();
static int deciSeconds = 0;
// Check if 400 milliseconds have passed
if (millis() - timer >= 400) {
timer += 400;
deciSeconds++;
if (deciSeconds == 10000) { // Reset to 0 after counting 1000 seconds
deciSeconds = 0;
}
// Display the number with 1 decimal place
sevseg.setNumber(deciSeconds, 1);
}
// Refresh the display (must be called repeatedly)
sevseg.refreshDisplay();
}
*/
/*
// Define pins for the ESP32, avoiding GPIO21 and GPIO22
int a = 15; // GPIO15 for segment 'a'
int b = 2; // GPIO2 for segment 'b'
int c = 4; // GPIO4 for segment 'c'
int d = 16; // GPIO16 for segment 'd'
int e = 17; // GPIO17 for segment 'e'
int f = 5; // GPIO5 for segment 'f'
int g = 18; // GPIO18 for segment 'g'
int dp = 19; // GPIO19 for decimal point 'dp'
int d1 = 23; // GPIO23 for digit 1
int d2 = 13; // GPIO13 for digit 2
int d3 = 14; // GPIO14 for digit 3
int d4 = 12; // GPIO12 for digit 4
int seg[] = {a, b, c, d, e, f, g, dp}; // segment pins
// Character data for the 7-segment display
byte chars[12][9] {
{'0',0,0,0,0,0,0,1,1}, // 0
{'1',1,0,0,1,1,1,1,1}, // 1
{'2',0,0,1,0,0,1,0,1}, // 2
{'3',0,0,0,0,1,1,0,1}, // 3
{'4',1,0,0,1,1,0,0,1}, // 4
{'5',0,1,0,0,1,0,0,1}, // 5
{'6',0,1,0,0,0,0,0,1}, // 6
{'7',0,0,0,1,1,1,1,1}, // 7
{'8',0,0,0,0,0,0,0,1}, // 8
{'9',0,0,0,0,1,0,0,1}, // 9
{'h',1,1,0,1,0,0,0,1}, // h
{'t',1,1,1,0,0,0,0,1}, // t
};
// byte chars[12][9] {
// {'0',0,0,0,0,0,0,1,1},//0
// {'1',1,0,0,1,1,1,1,1},//1
// {'2',0,0,1,0,0,1,0,1},//2
// {'3',0,0,0,0,1,1,0,1},//3
// {'4',1,0,0,1,1,0,0,1},//4
// {'5',0,1,0,0,1,0,0,1},//5
// {'6',0,1,0,0,0,0,0,1},//6
// {'7',0,0,0,1,1,1,1,1},//7
// {'8',0,0,0,0,0,0,0,1},//8
// {'9',0,0,0,0,1,0,0,1},//9
// {'h',1,1,0,1,0,0,0,1},//h
// {'t',1,1,1,0,0,0,0,1},//t
// };
void setup()
{
// Set all segment pins to output
for (int i = 0; i < 8; i++)
{
pinMode(seg[i], OUTPUT);
}
// Set all digit select pins to output
pinMode(d1, OUTPUT);
pinMode(d2, OUTPUT);
pinMode(d3, OUTPUT);
pinMode(d4, OUTPUT);
// Clear the display initially
clearDisplay();
// twoDigits();
oneDigit();
}
void clearDisplay()
{
// Deactivate all digits
digitalWrite(d1, HIGH);
digitalWrite(d2, HIGH);
digitalWrite(d3, HIGH);
digitalWrite(d4, HIGH);
// Turn off all segments
for (int i = 0; i < 8; i++)
{
digitalWrite(seg[i], HIGH); // Common anode: HIGH turns the segment off
}
}
void oneDigit()
{
// Select the first digit (d1)
digitalWrite(d1, LOW);
// Display each character from chars array
for (int i = 0; i < 2; i++) // int i = 0; i < 12; i++
{
// j=5 mean is the middle horizontal stroke of the tube.
for (int j = 0; j < 8; j++) // j = 0; j < 8; j++ (j<7 is still working)
{
digitalWrite(seg[j], chars[i][j+1]); // Set segments according to chars array
}
delay(500); // Wait for 500 ms
}
// Deselect the first digit
digitalWrite(d1, HIGH);
}
void twoDigits()
{
// Display the first digit (d1)
digitalWrite(d1, LOW);
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 8; j++)
{
digitalWrite(seg[j], chars[i][j+1]);
}
delay(500);
}
// Deselect the first digit
digitalWrite(d1, HIGH);
// Display the second digit (d2)
digitalWrite(d2, LOW);
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 8; j++)
{
digitalWrite(seg[j], chars[i][j+1]);
}
delay(500);
}
// Deselect the second digit
digitalWrite(d2, HIGH);
}
void displayNumber(float number) {
// Break down the number into digits
int intPart = (int)number; // Get integer part (e.g., 8 from 8.567)
int firstDigit = intPart / 10; // Get tens place
int secondDigit = intPart % 10; // Get ones place
int thirdDigit = (int)(number * 10) % 10; // First decimal place
int fourthDigit = (int)(number * 100) % 10; // Second decimal place
// Clear display before showing a new number
clearDisplay();
// Handle first digit only if it's 2 digits (e.g., 10 or greater)
if (firstDigit > 0) {
digitalWrite(d1, LOW); // Activate the first digit
displayDigit(firstDigit); // Display first digit
digitalWrite(d1, HIGH); // Deactivate the first digit
}
// Display second digit (always visible)
digitalWrite(d2, LOW); // Activate the second digit
displayDigit(secondDigit); // Display second digit
digitalWrite(dp, LOW); // Light the decimal point after the second digit
delay(5); // Short delay to prevent flicker
digitalWrite(dp, HIGH); // Turn off decimal point after lighting it
digitalWrite(d2, HIGH); // Deactivate the second digit
// Display third digit (first decimal place)
digitalWrite(d3, LOW); // Activate the third digit
displayDigit(thirdDigit); // Display third digit
digitalWrite(d3, HIGH); // Deactivate the third digit
// Display fourth digit (second decimal place)
digitalWrite(d4, LOW); // Activate the fourth digit
displayDigit(fourthDigit); // Display fourth digit
digitalWrite(d4, HIGH); // Deactivate the fourth digit
}
// Function to map segments for each digit
void displayDigit(int digit) {
for (int j = 0; j < 8; j++) {
digitalWrite(seg[j], chars[digit][j+1]); // Display the character segment-by-segment
}
}
// void loop() {
// float number = 4.567; // Example number to display
// clearDisplay();
// displayNumber(number); // Call the function to display the number
// delay(1000);
// }
void loop()
{
// oneDigit();
// delay(500);
// Display two digits
// twoDigits();
}
*/
// // Define ESP32 GPIO pins for segments and digits
// int a = 15; // GPIO15 for segment 'a'
// int b = 2; // GPIO2 for segment 'b'
// int c = 4; // GPIO4 for segment 'c'
// int d = 16; // GPIO16 for segment 'd'
// int e = 17; // GPIO17 for segment 'e'
// int f = 5; // GPIO5 for segment 'f'
// int g = 18; // GPIO18 for segment 'g'
// int dp = 19; // GPIO19 for decimal point 'dp'
// int d1 = 23; // GPIO23 for digit 1
// int d2 = 13; // GPIO13 for digit 2
// int d3 = 14; // GPIO14 for digit 3
// int d4 = 12; // GPIO12 for digit 4
// int seg[] = {a, b, c, d, e, f, g, dp}; // segment pins
// // Segment data for digits 0-9 (common anode configuration, LOW to light up segment)
// byte chars[10][8] = {
// {0, 0, 0, 0, 0, 0, 1, 1}, // 0
// {1, 0, 0, 1, 1, 1, 1, 1}, // 1
// {0, 0, 1, 0, 0, 1, 0, 1}, // 2
// {0, 0, 0, 0, 1, 1, 0, 1}, // 3
// {1, 0, 0, 1, 1, 0, 0, 1}, // 4
// {0, 1, 0, 0, 1, 0, 0, 1}, // 5
// {0, 1, 0, 0, 0, 0, 0, 1}, // 6
// {0, 0, 0, 1, 1, 1, 1, 1}, // 7
// {0, 0, 0, 0, 0, 0, 0, 1}, // 8
// {0, 0, 0, 0, 1, 0, 0, 1}, // 9
// };
// // Function to clear all segments
// void clearDisplay() {
// for (int i = 0; i < 8; i++) {
// digitalWrite(seg[i], HIGH); // turn off all segments (common anode)
// }
// }
// // Function to display a single digit on a specified digit position
// void displayDigit(int digit, int pos) {
// clearDisplay(); // Clear display before lighting up new digit
// // Activate the corresponding digit (d1, d2, d3, d4)
// digitalWrite(d1, pos == 1 ? LOW : HIGH);
// digitalWrite(d2, pos == 2 ? LOW : HIGH);
// digitalWrite(d3, pos == 3 ? LOW : HIGH);
// digitalWrite(d4, pos == 4 ? LOW : HIGH);
// // Light up the segments for the specified digit
// for (int i = 0; i < 8; i++) {
// digitalWrite(seg[i], chars[digit][i]);
// }
// delay(5); // Short delay to let the digit be visible
// }
// void setup() {
// // Set segment pins as output
// for (int i = 0; i < 8; i++) {
// pinMode(seg[i], OUTPUT);
// digitalWrite(seg[i], HIGH); // Initialize to off state
// }
// // Set digit control pins as output
// pinMode(d1, OUTPUT);
// pinMode(d2, OUTPUT);
// pinMode(d3, OUTPUT);
// pinMode(d4, OUTPUT);
// // Initialize digits to off
// digitalWrite(d1, HIGH);
// digitalWrite(d2, HIGH);
// digitalWrite(d3, HIGH);
// digitalWrite(d4, HIGH);
// }
// void loop() {
// // Continuously display '1234'
// // displayDigit(1, 1); // Display '1' on the first digit
// displayDigit(2, 2); // Display '2' on the second digit
// // displayDigit(3, 3); // Display '3' on the third digit
// // displayDigit(4, 4); // Display '4' on the fourth digit
// }
// #define duration 5000
// #define A 15
// #define B 2
// #define C 4
// #define D 16
// #define E 17
// #define F 5
// #define G 18
// #define DP 19
// #define disp1 23
// #define disp2 13
// #define disp3 14
// #define disp4 12
// // int a = 15; // GPIO15 for segment 'a'
// // int b = 2; // GPIO2 for segment 'b'
// // int c = 4; // GPIO4 for segment 'c'
// // int d = 16; // GPIO16 for segment 'd'
// // int e = 17; // GPIO17 for segment 'e'
// // int f = 5; // GPIO5 for segment 'f'
// // int g = 18; // GPIO18 for segment 'g'
// // int dp = 19; // GPIO19 for decimal point 'dp'
// // int d1 = 23; // GPIO23 for digit 1
// // int d2 = 13; // GPIO13 for digit 2
// // int d3 = 14; // GPIO14 for digit 3
// // int d4 = 12; // GPIO12 for digit 4
// #define numbersegments { \
// {1,1,1,1,1,1,0,0},\
// {0,1,1,0,0,0,0,0},\
// {1,1,0,1,1,0,1,0},\
// {1,1,1,1,0,0,1,0},\
// {0,1,1,0,0,1,1,0},\
// {1,0,1,1,0,1,1,0},\
// {1,0,1,1,1,1,1,0},\
// {1,1,1,0,0,0,0,0},\
// {1,1,1,1,1,1,1,0},\
// {1,1,1,0,0,1,1,0},\
// }
// byte numbers[10][8] = numbersegments;
// const int segments[8] = {A, B, C, D, E, F, G, DP};
// void setup()
// {
// pinMode(A, OUTPUT);
// pinMode(B, OUTPUT);
// pinMode(C, OUTPUT);
// pinMode(D, OUTPUT);
// pinMode(E, OUTPUT);
// pinMode(F, OUTPUT);
// pinMode(G, OUTPUT);
// pinMode(DP, OUTPUT);
// pinMode(disp1, OUTPUT);
// pinMode(disp2, OUTPUT);
// pinMode(disp3, OUTPUT);
// pinMode(disp4, OUTPUT);
// digitalWrite(A, LOW);
// digitalWrite(B, LOW);
// digitalWrite(C, LOW);
// digitalWrite(D, LOW);
// digitalWrite(E, LOW);
// digitalWrite(F, LOW);
// digitalWrite(G, LOW);
// digitalWrite(DP, LOW);
// digitalWrite(disp1, LOW);
// digitalWrite(disp2, LOW);
// digitalWrite(disp3, LOW);
// digitalWrite(disp4, LOW);
// }
// void loop()
// {
// for (int digit4=0; digit4<10; digit4++)
// {
// for (int digit3=0; digit3<10; digit3++)
// {
// for (int digit2=0; digit2<10; digit2++)
// {
// for (int digit1=0; digit1<10; digit1++)
// {
// for (int t=0; t<30; t++)
// {
// setsegments(digit1, disp1, duration);
// setsegments(digit2, disp2, duration);
// setsegments(digit3, disp3, duration);
// setsegments(digit4, disp4, duration);
// }
// }
// }
// }
// }
// }
// void setsegments(int number, int digit, int ontime)
// {
// for (int seg=0; seg<8; seg++)
// {
// if(numbers[number][seg]==1)
// {
// digitalWrite(segments[seg], HIGH);
// }
// else
// {
// digitalWrite(segments[seg], LOW);
// }
// }
// digitalWrite(digit, HIGH);
// delayMicroseconds(ontime);
// digitalWrite(digit, LOW);
// }