Mark van Renswoude
4c16260e55
Added switchable shift register order Added potentiometer-controlled delay for demonstration purposes
144 lines
2.9 KiB
C++
144 lines
2.9 KiB
C++
#include "SegmentDisplayConfig.h"
|
|
#include "SegmentDisplay.h"
|
|
|
|
|
|
void SegmentDisplay::begin()
|
|
{
|
|
pinMode(latchPin, OUTPUT);
|
|
|
|
#if !defined(SDUseSPI)
|
|
pinMode(clockPin, OUTPUT);
|
|
pinMode(dataPin, OUTPUT);
|
|
|
|
digitalWrite(clockPin, LOW);
|
|
digitalWrite(dataPin, LOW);
|
|
#endif
|
|
|
|
writeDisplay(0, 0);
|
|
|
|
digitalWrite(latchPin, HIGH);
|
|
digitalWrite(latchPin, LOW);
|
|
digitalWrite(latchPin, HIGH);
|
|
|
|
#if defined(SDUseSPI)
|
|
SPI.begin();
|
|
#endif
|
|
}
|
|
|
|
|
|
void SegmentDisplay::end()
|
|
{
|
|
#if defined(SDUseSPI)
|
|
SPI.end();
|
|
#endif
|
|
}
|
|
|
|
|
|
void SegmentDisplay::writeNumber(uint32_t value)
|
|
{
|
|
byte digitMask = 1;
|
|
|
|
for (byte digit = digits; digit > 0; digit--)
|
|
{
|
|
writeDigit((byte)(value % 10), digitMask);
|
|
|
|
value /= 10;
|
|
digitMask <<= 1;
|
|
}
|
|
}
|
|
|
|
|
|
#define ASCIIZero 48
|
|
#define ASCIINine 57
|
|
#define ASCIIUppercaseA 65
|
|
#define ASCIIUppercaseZ 90
|
|
#define ASCIILowercaseA 97
|
|
#define ASCIILowercaseZ 122
|
|
|
|
|
|
void SegmentDisplay::writeText(char* value)
|
|
{
|
|
byte digitMask = 1;
|
|
byte digit = digits;
|
|
byte charValue;
|
|
|
|
while (digit > 0 && value != '\0')
|
|
{
|
|
charValue = *value;
|
|
|
|
// Lowercase
|
|
if (charValue >= ASCIILowercaseA && charValue <= ASCIILowercaseZ)
|
|
writeDisplay(pgm_read_byte_near(SDCharacterSegments + (charValue - ASCIILowercaseA)), digitMask);
|
|
|
|
// Uppercase
|
|
else if (charValue >= ASCIIUppercaseA && charValue <= ASCIIUppercaseZ)
|
|
writeDisplay(pgm_read_byte_near(SDCharacterSegments + (charValue - ASCIIUppercaseA)), digitMask);
|
|
|
|
// Numbers
|
|
else if (charValue >= ASCIIZero && charValue <= ASCIINine)
|
|
writeDisplay(pgm_read_byte_near(SDNumberSegments + (charValue - ASCIIZero)), digitMask);
|
|
|
|
// Space / unknown
|
|
else
|
|
writeDisplay(0, digitMask);
|
|
|
|
digit--;
|
|
digitMask <<= 1;
|
|
value++;
|
|
}
|
|
|
|
while (digit > 0)
|
|
{
|
|
writeDisplay(0, digitMask);
|
|
|
|
digit--;
|
|
digitMask <<= 1;
|
|
}
|
|
}
|
|
|
|
|
|
inline void SegmentDisplay::writeDigit(byte value, byte digitMask)
|
|
{
|
|
writeDisplay(pgm_read_byte_near(SDNumberSegments + value), digitMask);
|
|
|
|
if (digitDelayMicroseconds > 1000)
|
|
delay(digitDelayMicroseconds / 1000);
|
|
else
|
|
delayMicroseconds(digitDelayMicroseconds);
|
|
}
|
|
|
|
|
|
#if defined(SDUseSPI)
|
|
|
|
inline void SegmentDisplay::writeDisplay(byte segmentMask, byte digitMask)
|
|
{
|
|
SPI.beginTransaction(SPISettings(clockSpeed, MSBFIRST, SPI_MODE0));
|
|
#if defined(SDPushSegmentsFirst)
|
|
SPI.transfer(segmentMask);
|
|
SPI.transfer(digitMask);
|
|
#else
|
|
SPI.transfer(digitMask);
|
|
SPI.transfer(segmentMask);
|
|
#endif
|
|
SPI.endTransaction();
|
|
}
|
|
|
|
#else
|
|
|
|
inline void SegmentDisplay::writeDisplay(byte segmentMask, byte digitMask)
|
|
{
|
|
digitalWrite(latchPin, LOW);
|
|
|
|
#if defined(SDPushSegmentsFirst)
|
|
shiftOut(dataPin, clockPin, MSBFIRST, segmentMask);
|
|
shiftOut(dataPin, clockPin, MSBFIRST, digitMask);
|
|
#else
|
|
shiftOut(dataPin, clockPin, MSBFIRST, digitMask);
|
|
shiftOut(dataPin, clockPin, MSBFIRST, segmentMask);
|
|
#endif
|
|
|
|
digitalWrite(latchPin, HIGH);
|
|
}
|
|
|
|
#endif
|