Created
October 20, 2013 02:18
-
-
Save lpereira/7064088 to your computer and use it in GitHub Desktop.
Arduino 7-segment display driver
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace { | |
const char segment_pin[7] = { | |
[0] = 0, | |
[1] = 0, | |
[2] = 0, | |
[3] = 0, | |
[4] = 0, | |
[5] = 0, | |
[6] = 0, | |
}; | |
constexpr int hassomething(char c) { | |
if (c == ' ') | |
return 0; | |
return 1; | |
} | |
constexpr unsigned char SegmentToFontData(const char *drawing) { | |
/* | |
* This function calculates which segments will light up according to a | |
* diagram of a 7-segment display: | |
* | |
* +------------ 5 | |
* | +--------- 0 | |
* | v | |
* | _ | |
* +>|_| <------ 1 (6 is the middle segment) | |
* +>|_| <------ 2 | |
* | ^ | |
* | +--------- 3 | |
* +------------ 4 | |
*/ | |
unsigned char data = 0; | |
data = hassomething(drawing[1]); | |
data |= 1<<(1 * hassomething(drawing[5])); | |
data |= 1<<(2 * hassomething(drawing[8])); | |
data |= 1<<(3 * hassomething(drawing[7])); | |
data |= 1<<(4 * hassomething(drawing[6])); | |
data |= 1<<(5 * hassomething(drawing[3])); | |
data |= 1<<(6 * hassomething(drawing[4])); | |
return data; | |
} | |
const char font[] = { | |
[0] = SegmentToFontData( | |
" _ " | |
"| |" | |
"|_|"), | |
[1] = SegmentToFontData( | |
" " | |
" |" | |
" |"), | |
[2] = SegmentToFontData( | |
" _ " | |
" _|" | |
"|_ "), | |
[3] = SegmentToFontData( | |
" _ " | |
" _|" | |
" _|"), | |
[4] = SegmentToFontData( | |
" " | |
"|_|" | |
" |"), | |
[5] = SegmentToFontData( | |
" _ " | |
"|_ " | |
" _|"), | |
[6] = SegmentToFontData( | |
" _ " | |
"|_ " | |
"|_|"), | |
[7] = SegmentToFontData( | |
" _ " | |
" |" | |
" |"), | |
[8] = SegmentToFontData( | |
" _ " | |
"|_|" | |
"|_|"), | |
[9] = SegmentToFontData( | |
" _ " | |
"|_|" | |
" _|"), | |
}; | |
}; | |
class DisplayDigit { | |
private: | |
int anode_pin_; | |
public: | |
DisplayDigit(int anode_pin) : anode_pin_(anode_pin) {} | |
void Deactivate(); | |
void DisplayNumber(int number); | |
}; | |
void DisplayDigit::Deactivate() { | |
digitalWrite(anode_pin_, LOW); | |
} | |
void DisplayDigit::DisplayNumber(int number) { | |
for (int segment = 0; segment < 7; segment++) | |
digitalWrite(segment_pin[segment], font[number] & 1<<segment); | |
digitalWrite(anode_pin_, HIGH); | |
} | |
class Display { | |
private: | |
DisplayDigit *digits_; | |
int n_digits_; | |
int number_; | |
public: | |
~Display(); | |
void Init(int n_digits); | |
void DisplayNumber(int number); | |
void Loop(); | |
}; | |
void Display::Init(int n_digits) { | |
n_digits_ = n_digits; | |
digits_ = new DisplayDigit[n_digits]; | |
} | |
Display::~Display() { | |
delete[] digits_; | |
} | |
void Display::DisplayNumber(int number) { | |
number_ = number; | |
} | |
void Display::Loop() { | |
int number, digit; | |
for (number = number_, digit = n_digits_; | |
number && digit; number /= 10, digit--) { | |
if (digit != n_digits_) | |
digits_[digit + 1]->Deactivate(); | |
digits_[digit]->DisplayNumber(number % 10); | |
} | |
for (; digit; digit--) | |
digits_[digit]->Deactivate(); | |
} | |
Display d; | |
void setup() { | |
d.Init(7); | |
d.DisplayNumber(42); | |
} | |
void loop() { | |
d.Loop(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment