Fixed data corruption issue due to incorrect PROGMEM usage
Added switchable shift register order Added potentiometer-controlled delay for demonstration purposes
This commit is contained in:
parent
2e1cb6e054
commit
4c16260e55
|
@ -4,26 +4,36 @@ SegmentDisplay* display;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
pinMode(A3, INPUT);
|
||||||
|
|
||||||
display = new SegmentDisplay();
|
display = new SegmentDisplay();
|
||||||
//display->setClockSpeed(4000000UL);
|
//display->setClockSpeed(4000000UL);
|
||||||
display->setDigits(2);
|
display->setClockPin(12);
|
||||||
|
display->setDataPin(11);
|
||||||
|
display->setLatchPin(10);
|
||||||
|
display->setDigits(6);
|
||||||
display->begin();
|
display->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long currentTime;
|
||||||
unsigned long lastCounterTime = 0;
|
unsigned long lastCounterTime = 0;
|
||||||
uint32_t counter = 0;
|
uint32_t counter = 0;
|
||||||
|
uint32_t delayValue;
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
unsigned long currentTime = millis();
|
currentTime = millis();
|
||||||
|
|
||||||
if (currentTime - lastCounterTime > 1000UL)
|
if (currentTime - lastCounterTime > 100UL)
|
||||||
{
|
{
|
||||||
counter++;
|
counter++;
|
||||||
if (counter > 99)
|
if (counter > 999999)
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
lastCounterTime = currentTime;
|
lastCounterTime = currentTime;
|
||||||
|
|
||||||
|
delayValue = ((uint32_t)analogRead(A3) * 100);
|
||||||
|
display->setDigitDelayMicroseconds(delayValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
display->writeNumber(counter);
|
display->writeNumber(counter);
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
#include "SegmentDisplayConfig.h"
|
||||||
#include "SegmentDisplay.h"
|
#include "SegmentDisplay.h"
|
||||||
|
|
||||||
|
|
||||||
void SegmentDisplay::begin()
|
void SegmentDisplay::begin()
|
||||||
{
|
{
|
||||||
#if !defined(SDSupportSPI)
|
|
||||||
pinMode(latchPin, OUTPUT);
|
pinMode(latchPin, OUTPUT);
|
||||||
|
|
||||||
|
#if !defined(SDUseSPI)
|
||||||
pinMode(clockPin, OUTPUT);
|
pinMode(clockPin, OUTPUT);
|
||||||
pinMode(dataPin, OUTPUT);
|
pinMode(dataPin, OUTPUT);
|
||||||
|
|
||||||
|
@ -12,11 +14,13 @@ void SegmentDisplay::begin()
|
||||||
digitalWrite(dataPin, LOW);
|
digitalWrite(dataPin, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
writeDisplay(0, 0);
|
||||||
|
|
||||||
digitalWrite(latchPin, HIGH);
|
digitalWrite(latchPin, HIGH);
|
||||||
digitalWrite(latchPin, LOW);
|
digitalWrite(latchPin, LOW);
|
||||||
digitalWrite(latchPin, HIGH);
|
digitalWrite(latchPin, HIGH);
|
||||||
|
|
||||||
#if defined(SDSupportSPI)
|
#if defined(SDUseSPI)
|
||||||
SPI.begin();
|
SPI.begin();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -24,7 +28,7 @@ void SegmentDisplay::begin()
|
||||||
|
|
||||||
void SegmentDisplay::end()
|
void SegmentDisplay::end()
|
||||||
{
|
{
|
||||||
#if defined(SDSupportSPI)
|
#if defined(SDUseSPI)
|
||||||
SPI.end();
|
SPI.end();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -64,15 +68,15 @@ void SegmentDisplay::writeText(char* value)
|
||||||
|
|
||||||
// Lowercase
|
// Lowercase
|
||||||
if (charValue >= ASCIILowercaseA && charValue <= ASCIILowercaseZ)
|
if (charValue >= ASCIILowercaseA && charValue <= ASCIILowercaseZ)
|
||||||
writeDisplay(SDCharacterSegments[charValue - ASCIILowercaseA], digitMask);
|
writeDisplay(pgm_read_byte_near(SDCharacterSegments + (charValue - ASCIILowercaseA)), digitMask);
|
||||||
|
|
||||||
// Uppercase
|
// Uppercase
|
||||||
else if (charValue >= ASCIIUppercaseA && charValue <= ASCIIUppercaseZ)
|
else if (charValue >= ASCIIUppercaseA && charValue <= ASCIIUppercaseZ)
|
||||||
writeDisplay(SDCharacterSegments[charValue - ASCIIUppercaseA], digitMask);
|
writeDisplay(pgm_read_byte_near(SDCharacterSegments + (charValue - ASCIIUppercaseA)), digitMask);
|
||||||
|
|
||||||
// Numbers
|
// Numbers
|
||||||
else if (charValue >= ASCIIZero && charValue <= ASCIINine)
|
else if (charValue >= ASCIIZero && charValue <= ASCIINine)
|
||||||
writeDisplay(SDNumberSegments[charValue - ASCIIZero], digitMask);
|
writeDisplay(pgm_read_byte_near(SDNumberSegments + (charValue - ASCIIZero)), digitMask);
|
||||||
|
|
||||||
// Space / unknown
|
// Space / unknown
|
||||||
else
|
else
|
||||||
|
@ -95,29 +99,43 @@ void SegmentDisplay::writeText(char* value)
|
||||||
|
|
||||||
inline void SegmentDisplay::writeDigit(byte value, byte digitMask)
|
inline void SegmentDisplay::writeDigit(byte value, byte digitMask)
|
||||||
{
|
{
|
||||||
writeDisplay(SDNumberSegments[value], digitMask);
|
writeDisplay(pgm_read_byte_near(SDNumberSegments + value), digitMask);
|
||||||
delayMicroseconds(digitDelayMicroseconds);
|
|
||||||
|
if (digitDelayMicroseconds > 1000)
|
||||||
|
delay(digitDelayMicroseconds / 1000);
|
||||||
|
else
|
||||||
|
delayMicroseconds(digitDelayMicroseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(SDSupportSPI)
|
#if defined(SDUseSPI)
|
||||||
|
|
||||||
inline void SegmentDisplay::writeDisplay(byte characterMask, byte digitMask)
|
inline void SegmentDisplay::writeDisplay(byte segmentMask, byte digitMask)
|
||||||
{
|
{
|
||||||
SPI.beginTransaction(SPISettings(clockSpeed, MSBFIRST, SPI_MODE0));
|
SPI.beginTransaction(SPISettings(clockSpeed, MSBFIRST, SPI_MODE0));
|
||||||
SPI.transfer(characterMask);
|
#if defined(SDPushSegmentsFirst)
|
||||||
|
SPI.transfer(segmentMask);
|
||||||
SPI.transfer(digitMask);
|
SPI.transfer(digitMask);
|
||||||
|
#else
|
||||||
|
SPI.transfer(digitMask);
|
||||||
|
SPI.transfer(segmentMask);
|
||||||
|
#endif
|
||||||
SPI.endTransaction();
|
SPI.endTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
inline void SegmentDisplay::writeDisplay(byte characterMask, byte digitMask)
|
inline void SegmentDisplay::writeDisplay(byte segmentMask, byte digitMask)
|
||||||
{
|
{
|
||||||
digitalWrite(latchPin, LOW);
|
digitalWrite(latchPin, LOW);
|
||||||
|
|
||||||
shiftOut(dataPin, clockPin, MSBFIRST, characterMask);
|
#if defined(SDPushSegmentsFirst)
|
||||||
|
shiftOut(dataPin, clockPin, MSBFIRST, segmentMask);
|
||||||
shiftOut(dataPin, clockPin, MSBFIRST, digitMask);
|
shiftOut(dataPin, clockPin, MSBFIRST, digitMask);
|
||||||
|
#else
|
||||||
|
shiftOut(dataPin, clockPin, MSBFIRST, digitMask);
|
||||||
|
shiftOut(dataPin, clockPin, MSBFIRST, segmentMask);
|
||||||
|
#endif
|
||||||
|
|
||||||
digitalWrite(latchPin, HIGH);
|
digitalWrite(latchPin, HIGH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,27 @@
|
||||||
#ifndef SegmentDisplay_h
|
#ifndef SegmentDisplay_h
|
||||||
#define SegmentDisplay_h
|
#define SegmentDisplay_h
|
||||||
|
|
||||||
|
#include "SegmentDisplayConfig.h"
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#if defined(SDUseSPI)
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "SegmentDisplayChars.h"
|
#include "SegmentDisplayChars.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drives up to 8 digits using two 8-bit shift registers.
|
* Drives up to 8 digits using two 8-bit shift registers.
|
||||||
*
|
*
|
||||||
* Pushes out the segment bits first and the display selection
|
* Least significant bit ends up at output pin 0 of the shift register,
|
||||||
* second: connect the display select register first and chain the
|
* which correlates to Segment A (as defined in SegmentDisplayChars.h).
|
||||||
* segment register to it's output.
|
* The last digit is also assumed to be at output pin 0 of the chained
|
||||||
|
* shift register.
|
||||||
*
|
*
|
||||||
* Least significant bit ends up at pin 0, which correlates to
|
* The order in which the shift registers are chained is determined by
|
||||||
* (as defined in SegmentDisplayChars.h):
|
* (un)defining SDPushSegmentsFirst.
|
||||||
* - Last digit
|
|
||||||
* - Segment A
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
// Comment to use shiftOut. Set clockPin and dataPin instead.
|
|
||||||
//#define SDSupportSPI
|
|
||||||
|
|
||||||
|
|
||||||
class SegmentDisplay
|
class SegmentDisplay
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -41,12 +40,12 @@ class SegmentDisplay
|
||||||
uint32_t getDigitDelayMicroseconds() { return digitDelayMicroseconds; }
|
uint32_t getDigitDelayMicroseconds() { return digitDelayMicroseconds; }
|
||||||
void setDigitDelayMicroseconds(uint32_t value) { digitDelayMicroseconds = value; }
|
void setDigitDelayMicroseconds(uint32_t value) { digitDelayMicroseconds = value; }
|
||||||
|
|
||||||
#if defined(SDSupportSPI)
|
#if defined(SDUseSPI)
|
||||||
uint32_t getClockSpeed() { return clockSpeed; }
|
uint32_t getClockSpeed() { return clockSpeed; }
|
||||||
void setClockSpeed(uint32_t value) { clockSpeed = value; }
|
void setClockSpeed(uint32_t value) { clockSpeed = value; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SDSupportSPI)
|
#if !defined(SDUseSPI)
|
||||||
uint32_t getClockPin() { return clockPin; }
|
uint32_t getClockPin() { return clockPin; }
|
||||||
void setClockPin(uint32_t value) { clockPin = value; }
|
void setClockPin(uint32_t value) { clockPin = value; }
|
||||||
|
|
||||||
|
@ -63,11 +62,11 @@ class SegmentDisplay
|
||||||
uint32_t digitDelayMicroseconds = 1000;
|
uint32_t digitDelayMicroseconds = 1000;
|
||||||
uint32_t latchPin = SS;
|
uint32_t latchPin = SS;
|
||||||
|
|
||||||
#if defined(SDSupportSPI)
|
#if defined(SDUseSPI)
|
||||||
uint32_t clockSpeed = 20000000;
|
uint32_t clockSpeed = 20000000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SDSupportSPI)
|
#if !defined(SDUseSPI)
|
||||||
uint32_t clockPin = SCK;
|
uint32_t clockPin = SCK;
|
||||||
uint32_t dataPin = MOSI;
|
uint32_t dataPin = MOSI;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef SegmentDisplayConfig_h
|
||||||
|
#define SegmentDisplayConfig_h
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable SPI support
|
||||||
|
*
|
||||||
|
* If not defined, shiftOut will be used. Use setClockPin and
|
||||||
|
* setDataPin instead to change the defaults.
|
||||||
|
*
|
||||||
|
* When using SPI, use setClockSpeed to match your target.
|
||||||
|
**/
|
||||||
|
//#define SDUseSPI
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shift register chaining order
|
||||||
|
*
|
||||||
|
* If defined, the segment mask is pushed out first followed
|
||||||
|
* by the digit mask. In other words, connect D1, D2, etc to
|
||||||
|
* the first shift register and A, B, etc to the second.
|
||||||
|
*
|
||||||
|
* If not defined, the order is reversed.
|
||||||
|
**/
|
||||||
|
//#define SDPushSegmentsFirst
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
Top view
|
||||||
|
|
||||||
D1 A F D2 D3 B
|
D1 A F D2 D3 B
|
||||||
__|__|__|__|__|__|__
|
__|__|__|__|__|__|__
|
||||||
| |
|
| |
|
||||||
|
@ -11,6 +13,22 @@
|
||||||
E D DP C G
|
E D DP C G
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Bottom view
|
||||||
|
|
||||||
|
B D3 D2 F A D1
|
||||||
|
__|__|__|__|__|__|__
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|_____ __ __ __ __ __|
|
||||||
|
| | | | |
|
||||||
|
G C DP D E
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Pin Assignment
|
Pin Assignment
|
||||||
|
|
||||||
1 E Bottom Left
|
1 E Bottom Left
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
O1 O2 O3 O4 O5 O6 O7 O8 GND
|
||||||
|
__|____|____|____|____|____|____|____|____|__
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|\ |
|
||||||
|
|/ |
|
||||||
|
| |
|
||||||
|
|__ ____ ____ ____ ____ ____ ____ ____ ____ __|
|
||||||
|
| | | | | | | | |
|
||||||
|
I1 I2 I3 I4 I5 I6 I7 I8 VCC
|
||||||
|
|
||||||
|
|
||||||
|
Pin Assignment
|
||||||
|
|
||||||
|
1 I1
|
||||||
|
2 I2
|
||||||
|
3 I3
|
||||||
|
4 I4
|
||||||
|
5 I5
|
||||||
|
6 I6
|
||||||
|
7 I7
|
||||||
|
8 I8
|
||||||
|
9 VCC
|
||||||
|
10 GND Ground
|
||||||
|
11 O8
|
||||||
|
12 O7
|
||||||
|
13 O6
|
||||||
|
14 O5
|
||||||
|
15 O4
|
||||||
|
16 O3
|
||||||
|
17 O2
|
||||||
|
18 O1
|
Loading…
Reference in New Issue