84#define SEGMENT_BLANK 0b00000000
85#define SEGMENT_MINUS 0b00000001
86#define SEGMENT_DOT 0b10000000
95 _numDigits = constrain(numDigits, 1, 8);
109 pinMode(_dinPin, OUTPUT);
110 pinMode(_clkPin, OUTPUT);
111 pinMode(_csPin, OUTPUT);
113 digitalWrite(_csPin, HIGH);
114 digitalWrite(_clkPin, LOW);
115 digitalWrite(_dinPin, LOW);
144 _alignment = alignment;
152 _brightness = constrain(level, 0, 15);
161 for (uint8_t i = 0; i < _numDigits; i++) {
176 long num = atol(text);
177 displayNumberInternal(num,
false);
180 displayTextInternal(text);
185 displayNumberInternal((
long)number,
false);
189 displayNumberInternal(number,
false);
193 displayFloatInternal((
float)number, decimals);
197 if (position >= _numDigits)
return;
199 uint8_t physPos = getPhysicalPosition(position);
203 uint8_t data = constrain(value, 0, 9);
204 if (dp) data |= 0x80;
208 uint8_t segments = (value <= 9) ? digitToSegments(value) :
SEGMENT_BLANK;
215 if (position >= _numDigits)
return;
217 uint8_t physPos = getPhysicalPosition(position);
221 if (character >=
'0' && character <=
'9') {
222 uint8_t data = character -
'0';
223 if (dp) data |= 0x80;
225 }
else if (character ==
'-') {
232 uint8_t segments = charToSegments(character);
242 if (_numDigits < 4)
return;
244 hours = constrain(hours, 0, 99);
245 minutes = constrain(minutes, 0, 59);
251 startPos = (_numDigits - 4) / 2;
253 startPos = _numDigits - 4;
256 displayAt(startPos + 0, (uint8_t)(hours / 10));
257 displayAt(startPos + 1, (uint8_t)(hours % 10),
true);
258 displayAt(startPos + 2, (uint8_t)(minutes / 10));
259 displayAt(startPos + 3, (uint8_t)(minutes % 10));
263 if (_numDigits < 6)
return;
265 hours = constrain(hours, 0, 99);
266 minutes = constrain(minutes, 0, 59);
267 seconds = constrain(seconds, 0, 59);
273 startPos = (_numDigits - 6) / 2;
275 startPos = _numDigits - 6;
278 displayAt(startPos + 0, (uint8_t)(hours / 10));
279 displayAt(startPos + 1, (uint8_t)(hours % 10),
true);
280 displayAt(startPos + 2, (uint8_t)(minutes / 10));
281 displayAt(startPos + 3, (uint8_t)(minutes % 10),
true);
282 displayAt(startPos + 4, (uint8_t)(seconds / 10));
283 displayAt(startPos + 5, (uint8_t)(seconds % 10));
291 for (
int i = _numDigits - 1; i >= 0; i--) {
292 uint8_t digit = value & 0xF;
293 uint8_t physPos = getPhysicalPosition(i);
302 if (value == 0 && i > 0) {
304 for (
int j = i - 1; j >= 0; j--) {
305 uint8_t pos = getPhysicalPosition(j);
314 if (_numDigits < 8)
return;
316 for (
int i = 0; i < 8; i++) {
317 uint8_t bit = (value >> (7 - i)) & 1;
326 for (uint8_t i = 0; i < times; i++) {
335 uint8_t oldBrightness = _brightness;
336 for (uint8_t b = 0; b <= 15; b++) {
344 uint8_t oldBrightness = _brightness;
345 for (
int b = _brightness; b >= 0; b--) {
353 int len = strlen(text);
355 for (
int offset = _numDigits - 1; offset >= -len; offset--) {
358 for (
int i = 0; i < len; i++) {
359 int pos = offset + i;
360 if (pos >= 0 && pos < _numDigits) {
371 sprintf(buffer,
"%ld", number);
376 for (uint8_t i = 0; i < _numDigits; i++) {
382 for (
int i = _numDigits - 1; i >= 0; i--) {
390 if (from > to)
return;
392 for (
long i = from; i <= to; i++) {
399 if (from < to)
return;
401 for (
long i = from; i >= to; i--) {
411 if (position >= _numDigits)
return;
412 uint8_t physPos = getPhysicalPosition(position);
417 if (position >= _numDigits)
return;
418 uint8_t physPos = getPhysicalPosition(position);
419 uint8_t data = value;
420 if (dp) data |= 0x80;
427void MAX7219::sendCommand(uint8_t address, uint8_t data) {
428 digitalWrite(_csPin, LOW);
429 delayMicroseconds(1);
432 delayMicroseconds(1);
433 digitalWrite(_csPin, HIGH);
434 delayMicroseconds(1);
437void MAX7219::sendByte(uint8_t data) {
438 for (
int i = 7; i >= 0; i--) {
439 sendBit((data >> i) & 0x01);
443void MAX7219::sendBit(uint8_t bit) {
444 digitalWrite(_dinPin, bit ? HIGH : LOW);
445 delayMicroseconds(1);
446 digitalWrite(_clkPin, HIGH);
447 delayMicroseconds(1);
448 digitalWrite(_clkPin, LOW);
451uint8_t MAX7219::getPhysicalPosition(uint8_t logicalPosition) {
453 return _numDigits - 1 - logicalPosition;
455 return logicalPosition;
458 return _numDigits - 1 - logicalPosition;
462uint8_t MAX7219::charToSegments(
char c) {
463 if (c >=
'0' && c <=
'9') {
465 }
else if (c >=
'A' && c <=
'Z') {
467 }
else if (c >=
'a' && c <=
'z') {
469 }
else if (c ==
'-') {
471 }
else if (c ==
' ') {
477uint8_t MAX7219::digitToSegments(uint8_t digit) {
484void MAX7219::displayNumberInternal(
long number,
bool leadingZeros) {
485 bool negative = number < 0;
486 if (negative) number = -number;
493 uint8_t numDigits = 0;
499 while (number > 0 && numDigits < 8) {
500 digits[numDigits++] = number % 10;
507 bool hasShownDigit =
false;
516 startPos = (_numDigits - numDigits) / 2;
523 for (
int i = numDigits - 1; i >= 0; i--) {
530 pos = startPos + (numDigits - 1 - i);
533 pos = numDigits - 1 - i;
536 if (!leadingZeros && !hasShownDigit && digits[i] == 0 && i > 0) {
538 uint8_t physPos = getPhysicalPosition(pos);
546 hasShownDigit =
true;
552 if (negative && hasShownDigit) {
558 leftmostPos = (startPos > 0) ? startPos - 1 : 0;
560 leftmostPos = _numDigits - 1;
562 if (leftmostPos != lastPos && leftmostPos < _numDigits) {
568void MAX7219::displayFloatInternal(
double number, uint8_t decimals) {
569 if (decimals >= _numDigits) decimals = _numDigits - 1;
575 for (uint8_t i = 0; i < decimals; i++) multiplier *= 10;
577 long intValue = (long)(number * multiplier);
578 bool negative = intValue < 0;
579 if (negative) intValue = -intValue;
583 uint8_t numDigits = 0;
589 while (intValue > 0 && numDigits < 8) {
590 digits[numDigits++] = intValue % 10;
597 bool hasShownDigit =
false;
604 startPos = (_numDigits - numDigits) / 2;
609 for (
int i = numDigits - 1; i >= 0; i--) {
614 pos = startPos + (numDigits - 1 - i);
616 pos = numDigits - 1 - i;
618 bool showDP = (numDigits - 1 - i == decimals);
620 hasShownDigit =
true;
625 if (negative && hasShownDigit) {
631 leftmostPos = (startPos > 0) ? startPos - 1 : 0;
633 leftmostPos = _numDigits - 1;
635 if (leftmostPos != lastPos && leftmostPos < _numDigits) {
641void MAX7219::displayTextInternal(
const char* text) {
642 int len = strlen(text);
643 int textStartIdx = 0;
644 int logicalStartPos = 0;
650 if (len <= _numDigits) {
655 for (
int i = 0; i < len && i < _numDigits; i++) {
660 textStartIdx = len - _numDigits;
661 for (
int i = 0; i < _numDigits; i++) {
662 displayAt(_numDigits - 1 - i, text[textStartIdx + i]);
667 if (len <= _numDigits) {
668 logicalStartPos = (_numDigits - len) / 2;
670 for (
int i = 0; i < len && i < _numDigits; i++) {
671 displayAt(logicalStartPos + i, text[textStartIdx + i]);
676 textStartIdx = len - _numDigits;
677 for (
int i = 0; i < _numDigits; i++) {
678 displayAt(logicalStartPos + i, text[textStartIdx + i]);
685 for (
int i = 0; i < _numDigits && (textStartIdx + i) < len; i++) {
686 displayAt(logicalStartPos + i, text[textStartIdx + i]);
const uint8_t SEGMENT_DIGITS[10]
const uint8_t SEGMENT_HEX[6]
const uint8_t SEGMENT_LETTERS[26]
#define MAX7219_REG_INTENSITY
#define MAX7219_ALIGN_CENTER
#define MAX7219_REG_SCANLIMIT
#define MAX7219_ALIGN_LEFT
#define MAX7219_REG_DECODE
#define MAX7219_REG_SHUTDOWN
#define MAX7219_MODE_DECODE
#define MAX7219_ALIGN_RIGHT
#define MAX7219_REG_DISPLAYTEST
#define MAX7219_REG_DIGIT0
#define MAX7219_MODE_NO_DECODE
void displayHex(uint32_t value)
Display value in hexadecimal format.
void chase(uint16_t delayMs=100)
Chase animation (digit-by-digit)
void clear()
Clear all digits.
void setPower(bool on)
Turn display on or off.
void setSegments(uint8_t position, uint8_t segments)
Set raw segment pattern at position.
void begin()
Initialize the display with default mode.
void blink(uint8_t times=3, uint16_t delayMs=500)
Blink the display.
void fadeIn(uint16_t delayMs=50)
Fade in animation.
void setBrightness(uint8_t level)
Set display brightness.
uint8_t getMode()
Get current mode.
uint8_t getAlignment()
Get current alignment.
void scroll(const char *text, uint16_t delayMs=200)
Scroll text across display.
void setMode(uint8_t mode)
Set decode mode.
void setRawDigit(uint8_t position, uint8_t value, bool dp=false)
Set raw digit value at position.
void displayAt(uint8_t position, uint8_t value, bool dp=false)
Display value at specific position.
void display(const char *text)
Display text string.
void fadeOut(uint16_t delayMs=50)
Fade out animation.
void displayBinary(uint8_t value)
Display value in binary format.
void countDown(long from, long to, uint16_t delayMs=100)
Count down animation.
void countUp(long from, long to, uint16_t delayMs=100)
Count up animation.
MAX7219(uint8_t dinPin, uint8_t clkPin, uint8_t csPin, uint8_t numDigits=8)
Constructor for MAX7219 display.
void setAlignment(uint8_t alignment)
Set text alignment.
void displayTime(uint8_t hours, uint8_t minutes)
Display time in HH:MM format.