Created
June 29, 2016 11:47
-
-
Save jaytaph/15aa92c4e2e8c6a1c5398f97322e2430 to your computer and use it in GitHub Desktop.
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
#include <Wire.h> | |
#define NEXTCMD 128 // Issue when there will be more commands after this one | |
#define LASTCMD 0 // Issue when when this is the last command before ending transmission | |
/* Constants and default settings for the PCF */ | |
// MODE SET | |
#define MODESET 64 | |
#define MODE_NORMAL 0 | |
#define MODE_POWERSAVING 16 | |
#define DISPLAY_DISABLED 0 | |
#define DISPLAY_ENABLED 8 | |
#define BIAS_THIRD 0 | |
#define BIAS_HALF 4 | |
#define DRIVE_STATIC 1 | |
#define DRIVE_2 2 | |
#define DRIVE_3 3 | |
#define DRIVE_4 0 | |
byte set_modeset = MODESET | MODE_POWERSAVING | DISPLAY_ENABLED | BIAS_THIRD | DRIVE_4; // default init mode | |
//BLINK | |
#define BLINK 112 | |
#define BLINKING_NORMAL 0 | |
#define BLINKING_ALTERNATION 4 | |
#define BLINK_FREQUENCY_OFF 0 | |
#define BLINK_FREQUENCY2 1 | |
#define BLINK_FREQUENCY1 2 | |
#define BLINK_FREQUENCY05 3 | |
byte set_blink = BLINK | BLINKING_ALTERNATION | BLINK_FREQUENCY_OFF; // Whatever you do, do not blink. | |
//LOADDATAPOINTER | |
#define LOADDATAPOINTER 0 | |
byte set_datapointer = LOADDATAPOINTER | 0; | |
//BANK SELECT | |
#define BANKSELECT 120 | |
#define BANKSELECT_O1_RAM0 0 | |
#define BANKSELECT_O1_RAM2 2 | |
#define BANKSELECT_O2_RAM0 0 | |
#define BANKSELECT_O2_RAM2 1 | |
byte set_bankselect = BANKSELECT | BANKSELECT_O1_RAM0 | BANKSELECT_O2_RAM0; | |
#define DEVICE_SELECT 96 | |
byte set_deviceselect = DEVICE_SELECT; | |
#define PCF8576 B111000 // This is the address of the PCF on the i2c bus | |
// Matrix which hold the LCD data (8 segments * 2 bytes per segment means only the first 16 bytes are used) | |
unsigned char matrix[20]; | |
/* Text to LCD segment mapping. You can add your own symbols, but make sure the index and font arrays match up */ | |
const char index[] = "_ -:ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
const unsigned char font[] = { | |
B00000000, B00000001, // underscore | |
B00000000, B00000000, // space | |
B00000100, B00100000, // dash | |
B00000001, B10000000, // : | |
B11100100, B00100110, // A | |
B11100001, B10100001, // B | |
B10000000, B00000111, // C | |
B11100001, B10000001, // D | |
B10000100, B00000111, // E | |
B10000100, B00000110, // F | |
B10100000, B00100111, // G | |
B01100100, B00100110, // H | |
B00000001, B10000000, // I | |
B01100000, B00000011, // J | |
B00000100, B01010110, // K | |
B00000000, B00000111, // L | |
B01101000, B01000110, // M | |
B01101000, B00010110, // N | |
B11100000, B00000111, // O | |
B11000100, B00100110, // P | |
B11100000, B00010111, // Q | |
B11000100, B00110110, // R | |
B10100100, B00100101, // S | |
B10000001, B10000000, // T | |
B01100000, B00000111, // U | |
B00000010, B01000110, // V | |
B01100010, B00010110, // W | |
B00001010, B01010000, // X | |
B00001001, B01000000, // Y | |
B10000010, B01000001, // Z | |
B11101000, B00010111, // 0 | |
B01100000, B00000000, // 1 | |
B11000100, B00100011, // 2 | |
B11100000, B00100001, // 3 | |
B01100100, B00100100, // 4 | |
B10000100, B00010101, // 5 | |
B10100100, B00100111, // 6 | |
B11100000, B00000000, // 7 | |
B11100100, B00100111, // 8 | |
B11100100, B00100101, // 9 | |
}; | |
/* Physically send out the given data */ | |
void sendToLcd(byte *data) { | |
Wire.beginTransmission(PCF8576); | |
Wire.write(NEXTCMD | set_deviceselect); // I think this is needed, as internally the data can overflow and the PCF will automatically select the next device. | |
Wire.write(LASTCMD | set_datapointer | 0); // This will always set everything at once, starting from the beginning | |
Wire.write(matrix, 20); // Store all 20 bytes | |
Wire.endTransmission(); | |
} | |
/* Writes the first 8 characters of the string to the matrix */ | |
void writeToLcd(const char *text) { | |
// Clear whole matrix first | |
memset(matrix, 0, 20); | |
for (int idx=0; idx!=strlen(text); idx++) { | |
if (idx > 7) break; | |
char *c = strchr(index, (int)toupper(text[idx])); | |
int pos; | |
if (c == NULL) { | |
pos = 0; // Char not found, use underscore space instead | |
} else { | |
pos = c - index; | |
} | |
matrix[(7-idx) * 2] = font[(pos * 2) + 1]; // font bytes are in HI-LO but matrix must be LO-HI | |
matrix[((7-idx) * 2) + 1] = font[(pos * 2)]; | |
} | |
sendToLcd(matrix); | |
} | |
/* Creates a countdown clock. Uses delays instead of interrupts though */ | |
void countdown(int seconds) { | |
char buf[9]; | |
while (seconds >= 0) { | |
snprintf(buf, 8, " %02d:%02d", seconds / 60, seconds % 60); | |
writeToLcd(buf); | |
delay(500); | |
snprintf(buf, 8, " %02d %02d", seconds / 60, seconds % 60); | |
writeToLcd(buf); | |
delay(500); | |
seconds--; | |
} | |
} | |
/* Scrolls a text over the LCD */ | |
void scroll(const char *text, int speed) { | |
for (int i=0; i<=strlen(text)-7; i++) { | |
writeToLcd(text+i); | |
delay(speed); | |
} | |
} | |
void setup(){ | |
Serial.begin(9600); | |
Serial.println("Init start"); | |
Wire.begin(); | |
delay(1000); // Give some time to boot | |
// Init | |
Wire.beginTransmission(PCF8576); | |
Wire.write(NEXTCMD | set_modeset); | |
Wire.write(NEXTCMD | set_deviceselect); | |
Wire.write(NEXTCMD | set_blink); | |
Wire.write(LASTCMD | set_datapointer); | |
Wire.write(matrix, 20); | |
Wire.endTransmission(); | |
Serial.println("Init completed"); | |
} | |
void loop(){ | |
writeToLcd("JAYTAPH"); | |
delay(500); | |
scroll(" oh hai there This is really fun ", 200); | |
delay(500); | |
countdown(10); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment