#define BLANK_IDX 36 // Must match with 'digitCodeMap'
#define DASH_IDX 37
#define PERIOD_IDX 38
#define ASTERISK_IDX 39
#define UNDERSCORE_IDX 40
uint32_t powersOf10[] = {
1, // 10^0
10,
100,
1000,
10000,
100000,
1000000,
10000000//,
//100000000,
//1000000000
}; // 10^9
uint32_t powersOf16[] = {
0x1, // 16^0
0x10,
0x100,
0x1000,
0x10000,
0x100000//,
//0x1000000,
//0x10000000
}; // 16^7
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
};
#define COMMON_CATHODE 0
#define COMMON_ANODE 1
#define N_TRANSISTORS 2
#define P_TRANSISTORS 3
#ifndef MAXNUMDIGITS
#define MAXNUMDIGITS 8 // Can be increased, but the max number is 2^31
#endif
int digitNum;
long *powersOfBase;
long maxNum;
long minNum;
long factor;
uint8_t digits[MAXNUMDIGITS];
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
const uint8_t * const numeralCodes = digitCodeMap;
const uint8_t * const alphaCodes = digitCodeMap + 10;
uint8_t strIdx = 0; // Current position within str[]
uint32_t us;
byte hardwareConfig = COMMON_CATHODE;
byte digitPinsUSE[] = {6, 5, 4};
byte segmentPinsUSE[] = {13, 12, 11, 10, 9, 8, 7, 3};
float VOLTt = 12.9;
//long VOLT = VOLTt*100;
int dec;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(0b00111111);
//pinMode(2,OUTPUT); //dp
/*
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
*/
begin(hardwareConfig, 3, digitPinsUSE, segmentPinsUSE, 0, 0, 0, 0);
}
bool valA1 = 1, valB1 = 1;
int time1 = 990;
void loop() {
valB1 = (millis()/500)%2;
if(valA1 == 0 && valB1 == 1){
//time1++;
}
valA1 = valB1;
if (VOLTt < 9.99) {
dec = 2;
}
if (VOLTt > 9.99) {
dec = 1;
}
//VOLTt *=100;
//setNumberF(VOLTt, dec, 0);
//setNewNum(time1, 2, 0);
//stringToChar(String(12.3, 1));
setNumberF(12.3, 1, 0);//setChars("12.3");
refreshDisplay();
delay(2);
}
void stringToChar(const String& inputString) {
// Allocate memory for the char array (including null terminator)
char* charArray = new char[inputString.length() + 1];
char* cResult;
// Copy the string content to the char array
inputString.toCharArray(charArray, inputString.length() + 1);
cResult = charArray;
setChars(cResult);
delete[] charArray;
}
void begin(uint8_t hardwareConfig, uint8_t numDigitsIn, uint8_t digitPinsIn[],
uint8_t segmentPinsIn[], bool resOnSegmentsIn,
bool updateWithDelaysIn, bool leadingZerosIn, bool disableDecPoint) {
for(int i; i < 3; i++){pinMode(digitPinsIn[i], OUTPUT);}
for(int i; i < 8; i++){pinMode(segmentPinsIn[i], OUTPUT);}
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];
}
blank(); // Initialise the display
}
void 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 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 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 digitOff(uint8_t digitNum) {
for (uint8_t segmentNum = 0 ; segmentNum < numSegments ; segmentNum++) {
digitalWrite(segmentPins[segmentNum], segmentOffVal);
}
digitalWrite(digitPins[digitNum], digitOffVal);
}
void blank(void) {
for (uint8_t digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digitCodes[digitNum] = digitCodeMap[BLANK_IDX];
}
segmentOff(0);
digitOff(0);
}
void setChars(const char str[]) {
for(uint8_t digit = 0; digit < numDigits; digit++) {
digitCodes[digit] = 0;
}
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++;
}
}
}
void refreshDisplay() {
if (!updateWithDelays) {
us = millis() * 1000;
// 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);
}
}
}
}
void setNewNum(long numToShow, int8_t decPlaces, uint8_t hex) {
//digits[MAXNUMDIGITS];
findDigits(numToShow, decPlaces, hex, digits);
setDigitCodes(digits, decPlaces);
}
void findDigits(long numToShow, uint8_t decPlaces, uint8_t *hex, uint8_t digits[]) {
/*if (powersOfBase == hex) {
powersOfBase = powersOf16;
} else {
powersOfBase = powersOf10;
}*/
powersOfBase = (hex == 16) ? powersOf16 : powersOf10;
maxNum = powersOfBase[numDigits] - 1;
minNum = -(powersOfBase[numDigits - 1] - 1);
// If the number is out of range, just display dashes
if (numToShow > maxNum || numToShow < minNum) {
for (digitNum = 0 ; digitNum < numDigits ; digitNum++) {
digits[digitNum] = DASH_IDX;
}
}
else {
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++) {
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;
}
}
}
}
}
void setDigitCodes(const uint8_t digits[], uint8_t decPlaces) {
// Set the digitCode for each digit in the display
for (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];
}
}
}
}
void 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);
}
/*
const int digitPins[] = {4, 5, 6}; // Pins for controlling digits
const int segmentPins[] = {13, 12, 11, 10, 9, 8, 7, 3}; // Pins for controlling segments
void setup() {
for (int i = 0; i < 3; i++) {
pinMode(digitPins[i], OUTPUT);
}
for (int i = 0; i < 8; i++) {
pinMode(segmentPins[i], OUTPUT);
}
}
void loop() {
sevsegShowString("12.3");
}
void sevsegShowString(const char* str) {
// Display each character in the string
for (int i = 0; i < 3; i++) {
char c = str[i];
// Display the character
displayChar(c, i);
// Delay to control the character on-time
delay(5);
}
}
void displayChar(char c, int digit) {
// Define patterns for characters '0'-'9' and '.'
byte charPatterns[] = {
B11111100, // 0
B01100000, // 1
B11011010, // 2
B11110010, // 3
B01100110, // 4
B10110110, // 5
B10111110, // 6
B11100000, // 7
B11111110, // 8
B11110110, // 9
B00000001 // . (decimal point)
};
// Turn off all digits
for (int i = 0; i < 3; i++) {
digitalWrite(digitPins[i], HIGH);
}
// Activate the selected digit
digitalWrite(digitPins[digit], LOW);
// Set segment values based on the character pattern
for (int segment = 0; segment < 8; segment++) {
bool segmentState = bitRead(charPatterns[getIndex(c)], segment);
digitalWrite(segmentPins[segment], segmentState);
}
}
int getIndex(char c) {
// Map characters to their corresponding index in the charPatterns array
if (c >= '0' && c <= '9') {
return c - '0';
} else if (c == '.') {
return 10; // Decimal point
} else {
return 0; // Default to '0' for unknown characters
}
}
*/