Skip to content

Instantly share code, notes, and snippets.

@jaytaph
Created June 29, 2016 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jaytaph/15aa92c4e2e8c6a1c5398f97322e2430 to your computer and use it in GitHub Desktop.
Save jaytaph/15aa92c4e2e8c6a1c5398f97322e2430 to your computer and use it in GitHub Desktop.
#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