From 0d043853266539e962ea37d61c5de985c0bae76e Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Fri, 25 Jul 2014 19:23:31 +0800 Subject: [PATCH 01/45] Changed structure to meet new standard. --- .../sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Arduino/{Sample/sketch_HT1632_sample_code/sketch_HT1632_sample_code.pde => HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino} (99%) diff --git a/Arduino/Sample/sketch_HT1632_sample_code/sketch_HT1632_sample_code.pde b/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino similarity index 99% rename from Arduino/Sample/sketch_HT1632_sample_code/sketch_HT1632_sample_code.pde rename to Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino index c4fd53d..d24aaba 100644 --- a/Arduino/Sample/sketch_HT1632_sample_code/sketch_HT1632_sample_code.pde +++ b/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino @@ -7,7 +7,7 @@ int wd; void setup () { Serial.begin(9600); - HT1632.begin(12, 13, 10, 9); +c /* From 2be0d2500dc7d928a367aec84facdd90442da238 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Fri, 25 Jul 2014 22:01:21 +0800 Subject: [PATCH 02/45] Made the pixelsInAByte abstract. --- .../sketch_HT1632_sample_code.ino | 11 +++++------ ...image_drawing_utility.html => image_drawing.html} | 12 +++++++----- 2 files changed, 12 insertions(+), 11 deletions(-) rename Utilities/{Image drawing/LED_image_drawing_utility.html => image_drawing.html} (95%) diff --git a/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino b/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino index d24aaba..73e8d20 100644 --- a/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino +++ b/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino @@ -7,8 +7,7 @@ int wd; void setup () { Serial.begin(9600); -c - + HT1632.begin(12, 10, 9); /* // Multiple screen control @@ -25,7 +24,7 @@ c HT1632.render(); //*/ - /* + //* // Buffer swap transition example. // Fill board buffer with one image HT1632.drawTarget(BUFFER_BOARD(1)); @@ -56,10 +55,10 @@ void loop () { // Font rendering example - // HT1632.transition(TRANSITION_BUFFER_SWAP); - // HT1632.render(); + HT1632.transition(TRANSITION_BUFFER_SWAP); + HT1632.render(); - //* + /* HT1632.drawTarget(BUFFER_BOARD(1)); HT1632.clear(); HT1632.drawText("Hello, how are you?", 2*OUT_SIZE - i, 2, FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH); diff --git a/Utilities/Image drawing/LED_image_drawing_utility.html b/Utilities/image_drawing.html similarity index 95% rename from Utilities/Image drawing/LED_image_drawing_utility.html rename to Utilities/image_drawing.html index 8ae9d86..37c4b05 100644 --- a/Utilities/Image drawing/LED_image_drawing_utility.html +++ b/Utilities/image_drawing.html @@ -37,6 +37,8 @@ var height; var renderCircle = false; +var pixelsInAByte = 4; + function initialize(){ updateCanvasSize(); updateUseCircle(); @@ -60,9 +62,9 @@ function textUpdate() { val = ""; for(var i=0; i=0; --k) + for(var k=pixelsInAByte - 1; k>=0; --k) val += (map[i][j+k]?"1":"0") ; val += ", "; } @@ -86,13 +88,13 @@ var i = 0; // Current array element. for(var x = 0; x < width; ++x) - for(var y = 0; y < height; y += 4) { + for(var y = 0; y < height; y += pixelsInAByte) { var currData = trim(src[i++]).replace("0b", "").split(""); currData.reverse(); // After reversing, [0] is the element with the lowest y-value. - for(var k = 0; (k < 4) && (y + k < height); ++k) + for(var k = 0; (k < pixelsInAByte) && (y + k < height); ++k) map[x][y+k] = (currData[k] == "0"?false:true); } - + canvasRender(); } From 7be3183bf75f2c9b5763b0f7a61b1146a5545494 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 26 Jul 2014 00:03:36 +0800 Subject: [PATCH 03/45] Changed all images and fonts to the 8-pixels-per-byte scheme. --- .../examples/HT1632_Buffer/HT1632_Buffer.ino | 38 +++++ Arduino/HT1632/font_5x4.h | 160 +++++++++--------- Arduino/HT1632/images.h | 19 ++- Utilities/font_conv.html | 71 ++++++++ Utilities/image_drawing.html | 25 +-- 5 files changed, 210 insertions(+), 103 deletions(-) create mode 100644 Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino create mode 100644 Utilities/font_conv.html diff --git a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino new file mode 100644 index 0000000..e7725d1 --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino @@ -0,0 +1,38 @@ +#include +#include +#include + +int i = 0; +int wd; + +void setup () { + HT1632.begin(12, 10, 9); + + // Buffer swap transition example. + // Fill board buffer with one image + HT1632.drawTarget(BUFFER_BOARD(1)); + HT1632.drawImage(IMG_SPEAKER_A, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 0); + HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 1); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 1); + + // Fill secondary buffer with another image + HT1632.drawTarget(BUFFER_SECONDARY); + HT1632.drawImage(IMG_SPEAKER_B, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 1); + HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 1); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 0); + + HT1632.drawTarget(BUFFER_BOARD(1)); + + HT1632.render(); +} + +void loop () { + HT1632.transition(TRANSITION_BUFFER_SWAP); + HT1632.render(); + + delay(200); +} diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index b04020f..d4fc4e8 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -1,96 +1,90 @@ /* * 5-high FONT FOR RENDERING TO THE LED SCREEN. * Includes kerning support + + * 8 pixels-per-byte, variable width. * Gaurav Manek, 2011 */ #define FONT_5X4_HEIGHT 5 - -#define FONT_5X4_STEP_GLYPH 10 // Number of bytes per glyph -char FONT_5X4 [] = { - 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // SPACE - 0b0111, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ! - 0b0011, 0b0000, 0b0000, 0b0000, 0b0011, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // " - 0b1010, 0b0000, 0b1111, 0b0001, 0b1010, 0b0000, 0b1111, 0b0001, 0b1010, 0b0000, // # - 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // $ - 0b0011, 0b0001, 0b1011, 0b0000, 0b0100, 0b0000, 0b1010, 0b0001, 0b1001, 0b0001, // % - 0b1010, 0b0000, 0b0101, 0b0001, 0b1001, 0b0001, 0b1010, 0b0001, 0b0000, 0b0000, // & - 0b0011, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ' - - 0b1110, 0b0000, 0b0001, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ( - 0b0001, 0b0001, 0b1110, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ) - 0b0101, 0b0000, 0b0010, 0b0000, 0b0101, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // * - 0b0100, 0b0000, 0b0100, 0b0000, 0b1111, 0b0001, 0b0100, 0b0000, 0b0100, 0b0000, // + - 0b0000, 0b0001, 0b1000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // , - 0b0100, 0b0000, 0b0100, 0b0000, 0b0100, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // - - 0b0000, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // . - 0b0000, 0b0001, 0b1100, 0b0000, 0b0110, 0b0000, 0b0001, 0b0000, 0b0000, 0b0000, // / - - 0b1110, 0b0000, 0b0001, 0b0001, 0b1110, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // 0 - 0b0010, 0b0001, 0b1111, 0b0001, 0b0000, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // 1 - 0b0010, 0b0001, 0b1001, 0b0001, 0b0101, 0b0001, 0b0010, 0b0001, 0b0000, 0b0000, // 2 - 0b0101, 0b0001, 0b0101, 0b0001, 0b1010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // 3 - 0b1100, 0b0000, 0b1010, 0b0000, 0b1111, 0b0001, 0b1000, 0b0000, 0b0000, 0b0000, // 4 - 0b0111, 0b0001, 0b0101, 0b0001, 0b1101, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // 5 - 0b1110, 0b0000, 0b0101, 0b0001, 0b0101, 0b0001, 0b1000, 0b0000, 0b0000, 0b0000, // 6 - 0b0001, 0b0000, 0b1101, 0b0001, 0b0101, 0b0000, 0b0011, 0b0000, 0b0000, 0b0000, // 7 - - 0b1010, 0b0000, 0b0101, 0b0001, 0b0101, 0b0001, 0b1010, 0b0000, 0b0000, 0b0000, // 8 - 0b0010, 0b0000, 0b0101, 0b0000, 0b0101, 0b0001, 0b1110, 0b0000, 0b0000, 0b0000, // 9 - 0b1010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // : - 0b0000, 0b0001, 0b1010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ; - 0b0100, 0b0000, 0b1010, 0b0000, 0b0001, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // < - 0b1010, 0b0000, 0b1010, 0b0000, 0b1010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // = - 0b0001, 0b0001, 0b1010, 0b0000, 0b0100, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // > - 0b0010, 0b0000, 0b0001, 0b0000, 0b1001, 0b0001, 0b0110, 0b0000, 0b0000, 0b0000, // ? - - 0b1110, 0b0000, 0b0001, 0b0000, 0b1101, 0b0000, 0b0101, 0b0001, 0b1111, 0b0000, // @ - 0b1110, 0b0001, 0b0101, 0b0000, 0b0101, 0b0000, 0b1110, 0b0001, 0b0000, 0b0000, // A - 0b1111, 0b0001, 0b0101, 0b0001, 0b1010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // B - 0b1110, 0b0000, 0b0001, 0b0001, 0b0001, 0b0001, 0b1010, 0b0000, 0b0000, 0b0000, // C - 0b1111, 0b0001, 0b0001, 0b0001, 0b1110, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // D - 0b1111, 0b0001, 0b0101, 0b0001, 0b0001, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // E - 0b1111, 0b0001, 0b0101, 0b0000, 0b0101, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // F - 0b1110, 0b0000, 0b0001, 0b0001, 0b1001, 0b0001, 0b1010, 0b0000, 0b0000, 0b0000, // G - - 0b1111, 0b0001, 0b0100, 0b0000, 0b0100, 0b0000, 0b1111, 0b0001, 0b0000, 0b0000, // H - 0b0001, 0b0001, 0b1111, 0b0001, 0b0001, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // I - 0b1001, 0b0000, 0b0001, 0b0001, 0b1111, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // J - 0b1111, 0b0001, 0b0100, 0b0000, 0b1010, 0b0000, 0b0001, 0b0001, 0b0000, 0b0000, // K - 0b1111, 0b0001, 0b0000, 0b0001, 0b0000, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // L - 0b1111, 0b0001, 0b0010, 0b0000, 0b0100, 0b0000, 0b0010, 0b0000, 0b1111, 0b0001, // M - 0b1111, 0b0001, 0b0010, 0b0000, 0b0100, 0b0000, 0b1000, 0b0000, 0b1111, 0b0001, // N - 0b1110, 0b0000, 0b0001, 0b0001, 0b0001, 0b0001, 0b1110, 0b0000, 0b0000, 0b0000, // O - - 0b1111, 0b0001, 0b0101, 0b0000, 0b0010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // P - 0b1110, 0b0000, 0b0001, 0b0001, 0b0001, 0b0001, 0b1001, 0b0000, 0b0110, 0b0001, // Q - 0b1111, 0b0001, 0b0101, 0b0000, 0b1010, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // R - 0b0010, 0b0001, 0b0101, 0b0001, 0b0101, 0b0001, 0b1001, 0b0000, 0b0000, 0b0000, // S - 0b0001, 0b0000, 0b1111, 0b0001, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // T - 0b1111, 0b0000, 0b0000, 0b0001, 0b0000, 0b0001, 0b1111, 0b0000, 0b0000, 0b0000, // U - 0b0011, 0b0000, 0b1100, 0b0000, 0b0000, 0b0001, 0b1100, 0b0000, 0b0011, 0b0000, // V - 0b1111, 0b0000, 0b0000, 0b0001, 0b1100, 0b0000, 0b0000, 0b0001, 0b1111, 0b0000, // W - - 0b1011, 0b0001, 0b0100, 0b0000, 0b1011, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, // X - 0b0011, 0b0000, 0b1100, 0b0001, 0b0011, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // Y - 0b1001, 0b0001, 0b0101, 0b0001, 0b0101, 0b0001, 0b0011, 0b0001, 0b0000, 0b0000, // Z - 0b1111, 0b0001, 0b0001, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // [ - 0b0001, 0b0000, 0b0110, 0b0000, 0b1100, 0b0000, 0b0000, 0b0001, 0b0000, 0b0000, // backslash - 0b0001, 0b0001, 0b1111, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ] - 0b0010, 0b0000, 0b0001, 0b0000, 0b0010, 0b0000, 0b0000, 0b0000, 0b0000, 0b0000, // ^ - 0b0000, 0b0001, 0b0000, 0b0001, 0b0000, 0b0001, 0b0000, 0b0000, 0b0000, 0b0000 // _ +uint8_t FONT_5X4 [] = { + 0b00000000, // SPACE + 0b00010111, // ! + 0b00000011, 0b00000000, 0b00000011, // " + 0b00001010, 0b00011111, 0b00001010, 0b00011111, 0b00001010, // # + 0b00000000, 0b00000000, 0b00000000, 0b00000000, // $ + 0b00010011, 0b00001011, 0b00000100, 0b00011010, 0b00011001, // % + 0b00001010, 0b00010101, 0b00011001, 0b00011010, // & + 0b00000011, // ' + 0b00001110, 0b00010001, // ( + 0b00010001, 0b00001110, // ) + 0b00000101, 0b00000010, 0b00000101, // * + 0b00000100, 0b00000100, 0b00011111, 0b00000100, 0b00000100, // + + 0b00010000, 0b00001000, // , + 0b00000100, 0b00000100, 0b00000100, // - + 0b00010000, // . + 0b00010000, 0b00001100, 0b00000110, 0b00000001, // / + 0b00001110, 0b00010001, 0b00001110, // 0 + 0b00010010, 0b00011111, 0b00010000, // 1 + 0b00010010, 0b00011001, 0b00010101, 0b00010010, // 2 + 0b00010101, 0b00010101, 0b00001010, // 3 + 0b00001100, 0b00001010, 0b00011111, 0b00001000, // 4 + 0b00010111, 0b00010101, 0b00001101, // 5 + 0b00001110, 0b00010101, 0b00010101, 0b00001000, // 6 + 0b00000001, 0b00011101, 0b00000101, 0b00000011, // 7 + 0b00001010, 0b00010101, 0b00010101, 0b00001010, // 8 + 0b00000010, 0b00000101, 0b00010101, 0b00001110, // 9 + 0b00001010, // : + 0b00010000, 0b00001010, // ; + 0b00000100, 0b00001010, 0b00010001, // < + 0b00001010, 0b00001010, 0b00001010, // = + 0b00010001, 0b00001010, 0b00000100, // > + 0b00000010, 0b00000001, 0b00011001, 0b00000110, // ? + 0b00001110, 0b00000001, 0b00001101, 0b00010101, 0b00001111, // @ + 0b00011110, 0b00000101, 0b00000101, 0b00011110, // A + 0b00011111, 0b00010101, 0b00001010, // B + 0b00001110, 0b00010001, 0b00010001, 0b00001010, // C + 0b00011111, 0b00010001, 0b00001110, // D + 0b00011111, 0b00010101, 0b00010001, // E + 0b00011111, 0b00000101, 0b00000101, // F + 0b00001110, 0b00010001, 0b00011001, 0b00001010, // G + 0b00011111, 0b00000100, 0b00000100, 0b00011111, // H + 0b00010001, 0b00011111, 0b00010001, // I + 0b00001001, 0b00010001, 0b00001111, // J + 0b00011111, 0b00000100, 0b00001010, 0b00010001, // K + 0b00011111, 0b00010000, 0b00010000, // L + 0b00011111, 0b00000010, 0b00000100, 0b00000010, 0b00011111, // M + 0b00011111, 0b00000010, 0b00000100, 0b00001000, 0b00011111, // N + 0b00001110, 0b00010001, 0b00010001, 0b00001110, // O + 0b00011111, 0b00000101, 0b00000010, // P + 0b00001110, 0b00010001, 0b00010001, 0b00001001, 0b00010110, // Q + 0b00011111, 0b00000101, 0b00011010, // R + 0b00010010, 0b00010101, 0b00010101, 0b00001001, // S + 0b00000001, 0b00011111, 0b00000001, // T + 0b00001111, 0b00010000, 0b00010000, 0b00001111, // U + 0b00000011, 0b00001100, 0b00010000, 0b00001100, 0b00000011, // V + 0b00001111, 0b00010000, 0b00001100, 0b00010000, 0b00001111, // W + 0b00011011, 0b00000100, 0b00011011, // X + 0b00000011, 0b00011100, 0b00000011, // Y + 0b00011001, 0b00010101, 0b00010101, 0b00010011, // Z + 0b00011111, 0b00010001, // [ + 0b00000001, 0b00000110, 0b00001100, 0b00010000, // BACKSLASH + 0b00010001, 0b00011111, // ] + 0b00000010, 0b00000001, 0b00000010, // ^ + 0b00010000, 0b00010000, 0b00010000 // _ }; -char FONT_5X4_WIDTH [] = { - 1, 1, 3, 5, 4, 5, 4, 1, - 2, 2, 3, 5, 2, 3, 1, 4, - 3, 3, 4, 3, 4, 3, 4, 4, - 4, 4, 1, 2, 3, 3, 3, 4, - 5, 4, 3, 4, 3, 3, 3, 4, - 4, 3, 3, 4, 3, 5, 5, 4, - 3, 5, 3, 4, 3, 4, 5, 5, - 3, 3, 4, 2, 4, 2, 3, 3 +// If your number goes above 255, change this to int. +uint8_t FONT_5X4_END [] = { + 1, 2, 5, 10, 14, 19, 23, 24, + 26, 28, 31, 36, 38, 41, 42, 46, + 49, 52, 56, 59, 63, 66, 70, 74, + 78, 82, 83, 85, 88, 91, 94, 98, + 103, 107, 110, 114, 117, 120, 123, 127, + 131, 134, 137, 141, 144, 149, 154, 158, + 161, 166, 169, 173, 176, 180, 185, 190, + 193, 196, 200, 202, 206, 208, 211, 214 }; diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index 7b4535b..0e1c244 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -1,34 +1,35 @@ /* * SIMPLE IMAGES FOR RENDERING TO THE LED SCREEN. - * Gaurav Manek, 2011 + * 8 pixels-per-byte + * Gaurav Manek, 2014 */ -char IMG_MAIL [] = {0b1111, 0b1111, 0b0011, 0b1000, 0b0101, 0b1000, 0b1001, 0b1000, 0b0001, 0b1001, 0b0001, 0b1010, 0b0001, 0b1010, 0b0001, 0b1001, 0b1001, 0b1000, 0b0101, 0b1000, 0b0011, 0b1000, 0b1111, 0b1111}; +char IMG_MAIL [] = {0b11111111, 0b10000011, 0b10000101, 0b10001001, 0b10010001, 0b10100001, 0b10100001, 0b10010001}; #define IMG_MAIL_WIDTH 12 #define IMG_MAIL_HEIGHT 8 -char IMG_FB [] = {0b1100, 0b1111, 0b0010, 0b0000, 0b0001, 0b0000, 0b0001, 0b0000, 0b0001, 0b0010, 0b0001, 0b1111, 0b1001, 0b0010, 0b1001, 0b0000}; +char IMG_FB [] = {0b11111100, 0b00000010, 0b00100001, 0b11111001, 0b00100101, 0b00000101, 0b00000001, 0b00000001}; #define IMG_FB_WIDTH 8 #define IMG_FB_HEIGHT 8 -char IMG_PHONE [] = {0b0000, 0b0100, 0b0000, 0b1110, 0b1111, 0b0111, 0b0011, 0b0000, 0b0011, 0b0000, 0b0011, 0b0010, 0b0011, 0b0111, 0b1111, 0b0011}; +char IMG_PHONE [] = {0b00111100, 0b01111110, 0b11100111, 0b11000011}; #define IMG_PHONE_WIDTH 8 #define IMG_PHONE_HEIGHT 8 -char IMG_MUSIC [] = {0b0000, 0b0100, 0b0000, 0b1110, 0b1111, 0b0111, 0b0011, 0b0000, 0b0011, 0b0000, 0b0011, 0b0010, 0b0011, 0b0111, 0b1111, 0b0011}; +char IMG_MUSIC [] = {0b01000000, 0b11100000, 0b01111111, 0b00000011, 0b00000011, 0b00100011, 0b01110011, 0b00111111}; #define IMG_MUSIC_WIDTH 8 #define IMG_MUSIC_HEIGHT 8 -char IMG_MUSICNOTE [] = {0b0000, 0b0010, 0b0000, 0b0111, 0b1111, 0b0011, 0b0010, 0b0000}; +char IMG_MUSICNOTE [] = {0b00100000, 0b01110000, 0b00111111, 0b00000010}; #define IMG_MUSICNOTE_WIDTH 4 #define IMG_MUSICNOTE_HEIGHT 7 -char IMG_HEART [] = {0b1110, 0b0000, 0b1111, 0b0001, 0b1111, 0b0011, 0b1111, 0b0111, 0b1110, 0b1111, 0b1111, 0b0111, 0b1111, 0b0011, 0b1111, 0b0001, 0b1110, 0b0000}; +char IMG_HEART [] = {0b00001110, 0b00011111, 0b00111111, 0b01111111, 0b11111110, 0b01111111, 0b00111111, 0b00011111, 0b00001110}; #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 -char IMG_SPEAKER_A [] = {0b1000, 0b0001, 0b1000, 0b0001, 0b1100, 0b0011, 0b0010, 0b0100, 0b0101, 0b1010, 0b1000, 0b0001}; -char IMG_SPEAKER_B [] = {0b1000, 0b0001, 0b1000, 0b0001, 0b1100, 0b0011, 0b0010, 0b0100, 0b1101, 0b1011, 0b0000, 0b0000}; +char IMG_SPEAKER_A [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; +char IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; #define IMG_SPEAKER_WIDTH 6 #define IMG_SPEAKER_HEIGHT 8 diff --git a/Utilities/font_conv.html b/Utilities/font_conv.html new file mode 100644 index 0000000..a482adf --- /dev/null +++ b/Utilities/font_conv.html @@ -0,0 +1,71 @@ + + +LED Screen Paint + + + + + +

+
+
diff --git a/Utilities/image_drawing.html b/Utilities/image_drawing.html
index 37c4b05..774e9c1 100644
--- a/Utilities/image_drawing.html
+++ b/Utilities/image_drawing.html
@@ -56,16 +56,15 @@
 	map[cellX][cellY] = !map[cellX][cellY];
 	
 	canvasRender();
-	textUpdate();
 }
 
 function textUpdate() {
 	val = ""; 
 	for(var i=0; i=0; --k)
-				val += (map[i][j+k]?"1":"0") ;
+				val += (map[i][j+k]?"1":"0");
 			val += ", ";
 		}
 	}
@@ -75,15 +74,9 @@
 }
 
 function loadImage() {
-	if(!updateCanvasSize()) {
-		alert("Image not loaded!");
-		return;
-	}
-	
 	// Load the image.
 	var src = $('binary_out').value.split(",");
-	var eleCountHeight = Math.ceil(height/4);
-	
+	var eleCountHeight = Math.ceil(height/pixelsInAByte);
 	
 	var i = 0; // Current array element.
 	
@@ -165,6 +158,8 @@
 		cx.lineTo(canvasNode.width, i);
 	}
 	cx.stroke();
+
+	textUpdate();
 }
 
 function $(e){
@@ -180,6 +175,14 @@
 	canvasRender();
 }
 
+function updatePxPerByte() {
+	var v = $("pxInByte").value * 1;
+	if(v > 0 && v <= 8){
+		pixelsInAByte = v;
+		canvasRender();
+	}
+}
+
 window.addEventListener("load", initialize, false);
 
 
@@ -187,7 +190,7 @@
 
 

-Width: Height: Use Circle

+Width: Height: Pixels per Byte: Use Circle

From 59b02eacfb751f028af5345bf2de6debb16f1c4c Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sun, 27 Jul 2014 22:53:53 +0800 Subject: [PATCH 04/45] Changed image engine support. --- Arduino/HT1632/HT1632.cpp | 714 ++++++++++++++++++++------------------ Arduino/HT1632/HT1632.h | 12 +- 2 files changed, 375 insertions(+), 351 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 9208b71..de483bb 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -1,9 +1,9 @@ #include "HT1632.h" #if (ARDUINO >= 100) - #include + #include #else - #include + #include #endif /* @@ -13,64 +13,66 @@ */ void HT1632Class::drawText(const char text [], int x, int y, const char font [], const char font_width [], char font_height, int font_glyph_step, char gutter_space) { - int curr_x = x; - char i = 0; - char currchar; - - // Check if string is within y-bounds - if(y + font_height < 0 || y >= COM_SIZE) - return; - - while(true){ - if(text[i] == '\0') - return; - - currchar = text[i] - 32; - if(currchar >= 65 && currchar <= 90) // If character is lower-case, automatically make it upper-case - currchar -= 32; // Make this character uppercase. - if(currchar < 0 || currchar >= 64) { // If out of bounds, skip - ++i; - continue; // Skip this character. - } - // Check to see if character is not too far right. - if(curr_x >= OUT_SIZE) - break; // Stop rendering - all other characters are no longer within the screen - - // Check to see if character is not too far left. - if(curr_x + font_width[currchar] + gutter_space >= 0){ - drawImage(font, font_width[currchar], font_height, curr_x, y, currchar*font_glyph_step); - - // Draw the gutter space - for(char j = 0; j < gutter_space; ++j) - drawImage(font, 1, font_height, curr_x + font_width[currchar] + j, y, 0); - - } - - curr_x += font_width[currchar] + gutter_space; - ++i; - } + int curr_x = x; + char i = 0; + char currchar; + + // Check if string is within y-bounds + if(y + font_height < 0 || y >= COM_SIZE) + return; + + while(true){ + if(text[i] == '\0') + return; + + currchar = text[i] - 32; + if(currchar >= 65 && currchar <= 90) // If character is lower-case, automatically make it upper-case + currchar -= 32; // Make this character uppercase. + + if(currchar < 0 || currchar >= 64) { // If out of bounds, skip + ++i; + continue; // Skip this character. + } + + // Check to see if character is not too far right. + if(curr_x >= OUT_SIZE) + break; // Stop rendering - all other characters are no longer within the screen + + // Check to see if character is not too far left. + if(curr_x + font_width[currchar] + gutter_space >= 0){ + drawImage(font, font_width[currchar], font_height, curr_x, y, currchar*font_glyph_step); + + // Draw the gutter space + for(char j = 0; j < gutter_space; ++j) + drawImage(font, 1, font_height, curr_x + font_width[currchar] + j, y, 0); + + } + + curr_x += font_width[currchar] + gutter_space; + ++i; + } } // Gives you the width, in columns, of a particular string. int HT1632Class::getTextWidth(const char text [], const char font_width [], char font_height, char gutter_space) { - int wd = 0; - char i = 0; - char currchar; - - while(true){ - if(text[i] == '\0') - return wd - gutter_space; - - currchar = text[i] - 32; - if(currchar >= 65 && currchar <= 90) // If character is lower-case, automatically make it upper-case - currchar -= 32; // Make this character uppercase. - if(currchar < 0 || currchar >= 64) { // If out of bounds, skip - ++i; - continue; // Skip this character. - } - wd += font_width[currchar] + gutter_space; - ++i; - } + int wd = 0; + char i = 0; + char currchar; + + while(true){ + if(text[i] == '\0') + return wd - gutter_space; + + currchar = text[i] - 32; + if(currchar >= 65 && currchar <= 90) // If character is lower-case, automatically make it upper-case + currchar -= 32; // Make this character uppercase. + if(currchar < 0 || currchar >= 64) { // If out of bounds, skip + ++i; + continue; // Skip this character. + } + wd += font_width[currchar] + gutter_space; + ++i; + } } /* @@ -80,278 +82,300 @@ int HT1632Class::getTextWidth(const char text [], const char font_width [], char */ void HT1632Class::begin(int pinCS1, int pinWR, int pinDATA) { - _numActivePins = 1; - _pinCS[0] = pinCS1; - initialize(pinWR, pinDATA); + _numActivePins = 1; + _pinCS[0] = pinCS1; + initialize(pinWR, pinDATA); } void HT1632Class::begin(int pinCS1, int pinCS2, int pinWR, int pinDATA) { - _numActivePins = 2; - _pinCS[0] = pinCS1; - _pinCS[1] = pinCS2; - initialize(pinWR, pinDATA); + _numActivePins = 2; + _pinCS[0] = pinCS1; + _pinCS[1] = pinCS2; + initialize(pinWR, pinDATA); } void HT1632Class::begin(int pinCS1, int pinCS2, int pinCS3, int pinWR, int pinDATA) { - _numActivePins = 3; - _pinCS[0] = pinCS1; - _pinCS[1] = pinCS2; - _pinCS[2] = pinCS3; - initialize(pinWR, pinDATA); + _numActivePins = 3; + _pinCS[0] = pinCS1; + _pinCS[1] = pinCS2; + _pinCS[2] = pinCS3; + initialize(pinWR, pinDATA); } void HT1632Class::begin(int pinCS1, int pinCS2, int pinCS3, int pinCS4, int pinWR, int pinDATA) { - _numActivePins = 4; - _pinCS[0] = pinCS1; - _pinCS[1] = pinCS2; - _pinCS[2] = pinCS3; - _pinCS[3] = pinCS4; - initialize(pinWR, pinDATA); + _numActivePins = 4; + _pinCS[0] = pinCS1; + _pinCS[1] = pinCS2; + _pinCS[2] = pinCS3; + _pinCS[3] = pinCS4; + initialize(pinWR, pinDATA); } void HT1632Class::initialize(int pinWR, int pinDATA) { - _pinWR = pinWR; - _pinDATA = pinDATA; - - for(int i=0; i<_numActivePins; ++i){ - pinMode(_pinCS[i], OUTPUT); - // Allocate new memory for mem - mem[i] = (char *)malloc(ADDR_SPACE_SIZE); - drawTarget(i); - clear(); // Clean out mem - } - pinMode(_pinWR, OUTPUT); - pinMode(_pinDATA, OUTPUT); - - select(); - - mem[4] = (char *)malloc(ADDR_SPACE_SIZE); - // Each 8-bit mem array element stores data in the 4 least significant bits, - // and meta-data in the 4 most significant bits. Use bitmasking to read/write - // the meta-data. - drawTarget(4); - clear(); - // Clean out memory - int i=0; - - - // Send configuration to chip: - // This configuration is from the HT1632 datasheet, with one modification: - // The RC_MASTER_MODE command is not sent to the master. Since acting as - // the RC Master is the default behaviour, this is not needed. Sending - // this command causes problems in HT1632C (note the C at the end) chips. - - // Send Master commands - - select(0b1111); // Assume that board 1 is the master. - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - - writeCommand(HT1632_CMD_SYSDIS); // Turn off system oscillator - // N-MOS or P-MOS open drain output and 8 or 16 common option + _pinWR = pinWR; + _pinDATA = pinDATA; + + for(int i=0; i<_numActivePins; ++i){ + pinMode(_pinCS[i], OUTPUT); + // Allocate new memory for mem + mem[i] = (char *)malloc(ADDR_SPACE_SIZE); + drawTarget(i); + clear(); // Clean out mem + } + pinMode(_pinWR, OUTPUT); + pinMode(_pinDATA, OUTPUT); + + select(); + + mem[4] = (char *)malloc(ADDR_SPACE_SIZE); + // Each 8-bit mem array element stores data in the 4 least significant bits, + // and meta-data in the 4 most significant bits. Use bitmasking to read/write + // the meta-data. + drawTarget(4); + clear(); + // Clean out memory + int i=0; + + + // Send configuration to chip: + // This configuration is from the HT1632 datasheet, with one modification: + // The RC_MASTER_MODE command is not sent to the master. Since acting as + // the RC Master is the default behaviour, this is not needed. Sending + // this command causes problems in HT1632C (note the C at the end) chips. + + // Send Master commands + + select(0b1111); // Assume that board 1 is the master. + writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode + + writeCommand(HT1632_CMD_SYSDIS); // Turn off system oscillator + // N-MOS or P-MOS open drain output and 8 or 16 common option #if USE_NMOS == 1 && COM_SIZE == 8 - writeCommand(HT1632_CMD_COMS00); + writeCommand(HT1632_CMD_COMS00); #elif USE_NMOS == 1 && COM_SIZE == 16 - writeCommand(HT1632_CMD_COMS01); + writeCommand(HT1632_CMD_COMS01); #elif USE_NMOS == 0 && COM_SIZE == 8 - writeCommand(HT1632_CMD_COMS10); + writeCommand(HT1632_CMD_COMS10); #elif USE_NMOS == 0 && COM_SIZE == 16 - writeCommand(HT1632_CMD_COMS11); + writeCommand(HT1632_CMD_COMS11); #else #error Invalid USE_NMOS or COM_SIZE values! Change the values in HT1632.h. #endif - - if(false && _numActivePins > 1){ - select(0b0001); // - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - writeCommand(HT1632_CMD_RCCLK); // Switch system to MASTER mode - select(0b1110); // All other boards are slaves - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - - writeCommand(HT1632_CMD_MSTMD); // Switch system to SLAVE mode. - // The use of the MSTMD command to switch to slave is explained here: - // http://forums.parallax.com/showthread.php?117423-Electronics-I-O-%28outputs-to-common-anode-RGB-LED-matrix%29-question/page4 - - - select(0b1111); - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - } - - writeCommand(HT1632_CMD_SYSEN); //Turn on system - writeCommand(HT1632_CMD_LEDON); // Turn on LED duty cycle generator - writeCommand(HT1632_CMD_PWM(16)); // PWM 16/16 duty - - select(); - - - for(int i=0; i<_numActivePins; ++i) { - drawTarget(i); - _globalNeedsRewriting[i] = true; - clear(); - // Perform the initial rendering - render(); - } - // Set drawTarget to default board. - drawTarget(0); + + if(false && _numActivePins > 1){ + select(0b0001); // + writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode + writeCommand(HT1632_CMD_RCCLK); // Switch system to MASTER mode + select(0b1110); // All other boards are slaves + writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode + + writeCommand(HT1632_CMD_MSTMD); // Switch system to SLAVE mode. + // The use of the MSTMD command to switch to slave is explained here: + // http://forums.parallax.com/showthread.php?117423-Electronics-I-O-%28outputs-to-common-anode-RGB-LED-matrix%29-question/page4 + + + select(0b1111); + writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode + } + + writeCommand(HT1632_CMD_SYSEN); //Turn on system + writeCommand(HT1632_CMD_LEDON); // Turn on LED duty cycle generator + writeCommand(HT1632_CMD_PWM(16)); // PWM 16/16 duty + + select(); + + + for(int i=0; i<_numActivePins; ++i) { + drawTarget(i); + _globalNeedsRewriting[i] = true; + clear(); + // Perform the initial rendering + render(); + } + // Set drawTarget to default board. + drawTarget(0); } -void HT1632Class::drawTarget(char targetBuffer) { - if(targetBuffer == 0x04 || (targetBuffer >= 0 && targetBuffer < _numActivePins)) - _tgtBuffer = targetBuffer; +void HT1632Class::drawTarget(uint8_t targetBuffer) { + if(targetBuffer == 0x04 || (targetBuffer >= 0 && targetBuffer < _numActivePins)) + _tgtBuffer = targetBuffer; } -void HT1632Class::drawImage(const char * img, char width, char height, char x, char y, int offset){ - char length = width*height/4; - char mask; - - // Sanity checks - if(y + height < 0 || x + width < 0 || y > COM_SIZE || x > OUT_SIZE) - return; - // After looking at the rest of this function, you may need one. - - // Copying Engine. - // You are not expected to understand this. - for(char i=0; i= OUT_SIZE) // Skip this column if it is out of range. - continue; - for(char j=0; j < (carryover_valid ? (height+4):height) ; j+=4) { - char loc_y = j + y; - if(loc_y <= -4 || loc_y >= COM_SIZE) // Skip this row if it is out of range. - continue; - // Direct copying possible when render is on boundaries. - // The bit manipulation here is designed to copy from img only the relevant sections. - - // This mask is only not used when emptying the cache (for copying to non-4-bit aligned spaces) - - //if(j= 4)?0b00001111:(0b00001111 >> (4-(height-j))) & 0b00001111; // Mask bottom - - if(loc_y % 4 == 0) { - mask = (height-loc_y >= 4)?0b00001111:(0b00001111 >> (4-(height-j))) & 0b00001111; - mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] = (mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] & (~mask) & 0b00001111) | (img[(int)ceil((float)height/4.0f)*i + j/4 + offset] & mask) | MASK_NEEDS_REWRITING; - } else { - // If carryover_valid is NOT true, then this is the first set to be copied. - // If loc_y > 0, preserve the contents of the pixels above, copy to mem, and then copy remaining - // data to the carry over buffer. If y loc_y < 0, just copy data to carry over buffer. - // It is expected that this section is only reached when j == 0. - // COPY START - if(!carryover_valid) { - if(loc_y > 0) { - mask = (height-loc_y >= 4)?0b00001111:(0b00001111 >> (4-(height-j))) & 0b00001111; // Mask bottom - mask = (0b00001111 << carryover_num) & mask; // Mask top - mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] = (mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] & (~mask) & 0b00001111) | ((img[(int)ceil((float)height/4.0f)*i + j/4 + offset] << carryover_num) & mask) | MASK_NEEDS_REWRITING; - } - carryover_valid = true; - } else { - // COPY END - if(j >= height) { - // Its writing one line past the end. - // Use this line to get rid of the final carry-over. - mask = (0b00001111 >> (4 - carryover_num)) & 0b00001111; // Mask bottom - mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] = (mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] & (~mask) & 0b00001111) | (carryover_y >> (4 - carryover_num) & mask) | MASK_NEEDS_REWRITING; - // COPY MIDDLE - } else { - // There is data in the carry-over buffer. Copy that data and the values from the current cell into mem. - // The inclusion of a carryover_num term is to account for the presence of the carryover data when calculating the bottom clipping. - mask = (height-loc_y >= 4)?0b00001111:(0b00001111 >> (4-(height+carryover_num-j))) & 0b00001111; // Mask bottom - mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] = (mem[_tgtBuffer][GET_ADDR_FROM_X_Y(loc_x,loc_y)] & (~mask) & 0b00001111) | ((img[(int)ceil((float)height/4.0f)*i + j/4 + offset] << carryover_num) & mask) | (carryover_y >> (4 - carryover_num) & mask) | MASK_NEEDS_REWRITING; - } - } - carryover_y = img[(int)ceil((float)height/4.0f)*i + j/4 + offset]; - } - } - } +#IF PIXELS_PER_BYTE != 8 + #ERROR "The current drawImage implementation requires PIXELS_PER_BYTE == 8" +#ENDIF + +void HT1632Class::drawImage(const uint8_t * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { + uint8_t bytesPerColumn = height/PIXELS_PER_BYTE; + // Equivalent to taking Math.ceil(), without working with floats + if (bytesPerColumn * PIXELS_PER_BYTE < height) + bytesPerColumn++; + + // Sanity checks + if(y + height < 0 || x + width < 0 || y > COM_SIZE || x > OUT_SIZE) + return; + // After looking at the rest of this function, you may need one. + + // Copying Engine. + + // Current off + int8_t dst_x = x; + int8_t src_x = 0; + // Repeat until each column has been copied. + while (src_x < width) { + if(dst_x < 0) { + // Skip this column if it is too far to the left. + offset += bytesPerColumn; + src_x++; + dst_x++; + continue; + } else if (dst_x >= OUT_SIZE) { + // End the copy if it is too far to the right. + break; + } + + int8_t src_y = 0; + int8_t dst_y = y; + while (src_y < height) { + if (dst_y < 0) { + // Skip pixels if the starting point to too far up. + src_y -= dst_y; + dst_y = 0; + continue; + } else if (dst_y >= COM_SIZE) { + // End copying this column if it is too far down + break; + } + + // The use of bitmasking here assumes that PIXELS_PER_BYTE == 8 + + // Find out how many we can copy in the next step: + // as a minimum of the number of bits in the current byte of source + // and destination. + uint8_t copyInNextStep = 8 - max((src_y & 0b111), (dst_y & 0b111)); + + // Limit this by the height of the image: + copyInNextStep = min(copyInNextStep, (height - src_y)); + + // Prepare the bitmask with the number of bits that need to be copied. + uint8_t dst_copyMask = (0b1 << copyInNextStep) - 1; + + // Shift the bitmasks to the correct position. + dst_copyMask <<= (8 - (dst_y & 0b111) - copyInNextStep); + + // Shift the data to the bits of highest significance + uint8_t copyData = img[img_offset + ] << (src_y & 0b111); + // Shift data to match the destination place value. + copyData = copyData >> (dst_y & 0b111); + + // Perform the copy + mem[_tgtBuffer][GET_ADDR_FROM_X_Y(dst_x, dst_y)] = // Put in destination + (mem[_tgtBuffer][GET_ADDR_FROM_X_Y(dst_x, dst_y)] & ~dst_copyMask) | // All bits not in the mask from destination + (copyData & dst_copyMask); // All bits in the mask from source + + src_y += copyInNextStep; + dst_y += copyInNextStep; + /* Copy bytes without alignment: + * 0 8 16 + * To: |-------|-------| + * From: |-------|-------| + * -3 5 13 + * A B C D E + * + */ + + } + + src_x++; + dst_x++; + } } void HT1632Class::clear(){ - for(char i=0; i < ADDR_SPACE_SIZE; ++i) - mem[_tgtBuffer][i] = 0x00 | MASK_NEEDS_REWRITING; // Needs to be redrawn + for(char i=0; i < ADDR_SPACE_SIZE; ++i) + mem[_tgtBuffer][i] = 0x00 | MASK_NEEDS_REWRITING; // Needs to be redrawn } // Draw the contents of map to screen, for memory addresses that have the needsRedrawing flag void HT1632Class::render() { - if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) - return; - - char selectionmask = 0b0001 << _tgtBuffer; - - bool isOpen = false; // Automatically compact sequential writes. - for(int i=0; i= _numActivePins || _tgtBuffer < 0) + return; + + char selectionmask = 0b0001 << _tgtBuffer; + + bool isOpen = false; // Automatically compact sequential writes. + for(int i=0; i= _numActivePins || _tgtBuffer < 0) - return; - - switch(mode) { - case TRANSITION_BUFFER_SWAP: - { - char * tmp = mem[_tgtBuffer]; - mem[_tgtBuffer] = mem[BUFFER_SECONDARY]; - mem[BUFFER_SECONDARY] = tmp; - _globalNeedsRewriting[_tgtBuffer] = true; - } - break; - case TRANSITION_NONE: - for(char i=0; i < ADDR_SPACE_SIZE; ++i) - mem[_tgtBuffer][i] = mem[BUFFER_SECONDARY][i]; // Needs to be redrawn - _globalNeedsRewriting[_tgtBuffer] = true; - break; - case TRANSITION_FADE: - time /= 32; - for(int i = 15; i > 0; --i) { - setBrightness(i); - delay(time); - } - clear(); - render(); - delay(time); - transition(TRANSITION_BUFFER_SWAP); - render(); - delay(time); - for(int i = 2; i <= 16; ++i) { - setBrightness(i); - delay(time); - } - break; - } - + if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) + return; + + switch(mode) { + case TRANSITION_BUFFER_SWAP: + { + char * tmp = mem[_tgtBuffer]; + mem[_tgtBuffer] = mem[BUFFER_SECONDARY]; + mem[BUFFER_SECONDARY] = tmp; + _globalNeedsRewriting[_tgtBuffer] = true; + } + break; + case TRANSITION_NONE: + for(char i=0; i < ADDR_SPACE_SIZE; ++i) + mem[_tgtBuffer][i] = mem[BUFFER_SECONDARY][i]; // Needs to be redrawn + _globalNeedsRewriting[_tgtBuffer] = true; + break; + case TRANSITION_FADE: + time /= 32; + for(int i = 15; i > 0; --i) { + setBrightness(i); + delay(time); + } + clear(); + render(); + delay(time); + transition(TRANSITION_BUFFER_SWAP); + render(); + delay(time); + for(int i = 2; i <= 16; ++i) { + setBrightness(i); + delay(time); + } + break; + } + } @@ -361,65 +385,65 @@ void HT1632Class::transition(char mode, int time){ */ void HT1632Class::writeCommand(char data) { - writeData(data, HT1632_CMD_LEN); - writeSingleBit(); + writeData(data, HT1632_CMD_LEN); + writeSingleBit(); } // Integer write to display. Used to write commands/addresses. // PRECONDITION: WR is LOW void HT1632Class::writeData(char data, char len) { - for(int j=len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ - // Set the DATA pin to the correct state - digitalWrite(_pinDATA, ((data & t) == 0)?LOW:HIGH); - NOP(); // Delay - // Raise the WR momentarily to allow the device to capture the data - digitalWrite(_pinWR, HIGH); - NOP(); // Delay - // Lower it again, in preparation for the next cycle. - digitalWrite(_pinWR, LOW); - } + for(int j=len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ + // Set the DATA pin to the correct state + digitalWrite(_pinDATA, ((data & t) == 0)?LOW:HIGH); + NOP(); // Delay + // Raise the WR momentarily to allow the device to capture the data + digitalWrite(_pinWR, HIGH); + NOP(); // Delay + // Lower it again, in preparation for the next cycle. + digitalWrite(_pinWR, LOW); + } } // REVERSED Integer write to display. Used to write cell values. // PRECONDITION: WR is LOW void HT1632Class::writeDataRev(char data, char len) { - for(int j=0; j>= 1; - } + for(int j=0; j>= 1; + } } // Write single bit to display, used as padding between commands. // PRECONDITION: WR is LOW void HT1632Class::writeSingleBit() { - // Set the DATA pin to the correct state - digitalWrite(_pinDATA, LOW); - NOP(); // Delay - // Raise the WR momentarily to allow the device to capture the data - digitalWrite(_pinWR, HIGH); - NOP(); // Delay - // Lower it again, in preparation for the next cycle. - digitalWrite(_pinWR, LOW); + // Set the DATA pin to the correct state + digitalWrite(_pinDATA, LOW); + NOP(); // Delay + // Raise the WR momentarily to allow the device to capture the data + digitalWrite(_pinWR, HIGH); + NOP(); // Delay + // Lower it again, in preparation for the next cycle. + digitalWrite(_pinWR, LOW); } // Choose a chip. This function sets the correct CS line to LOW, and the rest to HIGH // Call the function with no arguments to deselect all chips. // Call the function with a bitmask (0b4321) to select specific chips. 0b1111 selects all. void HT1632Class::select(char mask) { - for(int i=0, t=1; i<_numActivePins; ++i, t <<= 1){ - digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); - /*Serial.write(48+_pinCS[i]); - Serial.write((t & mask)?"LOW":"HIGH"); - Serial.write('\n'); - */} - //Serial.write('\n'); + for(int i=0, t=1; i<_numActivePins; ++i, t <<= 1){ + digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); + /*Serial.write(48+_pinCS[i]); + Serial.write((t & mask)?"LOW":"HIGH"); + Serial.write('\n'); + */} + //Serial.write('\n'); } void HT1632Class::select() { - for(int i=0; i<_numActivePins; ++i) - digitalWrite(_pinCS[i], HIGH); + for(int i=0; i<_numActivePins; ++i) + digitalWrite(_pinCS[i], HIGH); } /* @@ -428,21 +452,21 @@ void HT1632Class::select() { */ void HT1632Class::recursiveWriteUInt (int inp) { - if(inp <= 0) return; - int rd = inp % 10; - recursiveWriteUInt(inp/10); - Serial.write(48+rd); + if(inp <= 0) return; + int rd = inp % 10; + recursiveWriteUInt(inp/10); + Serial.write(48+rd); } void HT1632Class::writeInt (int inp) { - if(inp == 0) - Serial.write('0'); - else - if (inp < 0){ - Serial.write('-'); - recursiveWriteUInt(-inp); - } else - recursiveWriteUInt(inp); + if(inp == 0) + Serial.write('0'); + else + if (inp < 0){ + Serial.write('-'); + recursiveWriteUInt(-inp); + } else + recursiveWriteUInt(inp); } HT1632Class HT1632; diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 5ae2935..4f4cc61 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -21,6 +21,11 @@ #define OUT_SIZE 32 // COM_SIZE MUST be either 8 or 16. +// Pixels in a single byte of the internal image representation: +#define PIXELS_PER_BYTE 8 +// Pixels per word of the HT1632 image representation. +#define PIXELS_PER_WORD 4 + // Target buffer // Each board has a "render" buffer, and all boards share one "secondary" buffer. All calls to // render() draw the contents of the render buffer of the currently selected board to the board @@ -58,18 +63,13 @@ // try changing the value. // NOTE: THIS HARDCODES THE DIMENSIONS OF THE 3208! CHANGE! -#define GET_ADDR_FROM_X_Y(_x,_y) ((_x)*2+(_y)/4) +#define GET_ADDR_FROM_X_Y(_x,_y) ((_x)*((COM_SIZE)/(PIXELS_PER_BYTE))+(_y)/(PIXELS_PER_BYTE)) /* * END USER OPTIONS * Don't edit anything below unless you know what you are doing! */ -// Meta-data masks -#define MASK_NEEDS_REWRITING 0b00010000 - -// Round up to multiple of 4 function - // NO-OP Definition #define NOP(); __asm__("nop\n\t"); // The HT1632 requires at least 50 ns between the change in data and the rising From fad0a67e3573ab0752c4aa884f2b5cf0bfe6e46e Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sun, 27 Jul 2014 23:58:42 +0800 Subject: [PATCH 05/45] More updates on types. --- Arduino/HT1632/HT1632.cpp | 176 ++++++++---------- Arduino/HT1632/HT1632.h | 53 +++--- .../examples/HT1632_Buffer/HT1632_Buffer.ino | 2 +- Arduino/HT1632/font_5x4.h | 2 +- Arduino/HT1632/images.h | 16 +- 5 files changed, 112 insertions(+), 137 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index de483bb..b18300d 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -1,17 +1,12 @@ #include "HT1632.h" -#if (ARDUINO >= 100) - #include -#else - #include -#endif - /* * HIGH LEVEL FUNCTIONS * Functions that perform advanced tasks using lower-level * functions go here: */ +/* void HT1632Class::drawText(const char text [], int x, int y, const char font [], const char font_width [], char font_height, int font_glyph_step, char gutter_space) { int curr_x = x; char i = 0; @@ -74,6 +69,7 @@ int HT1632Class::getTextWidth(const char text [], const char font_width [], char ++i; } } +*/ /* * MID LEVEL FUNCTIONS @@ -81,25 +77,25 @@ int HT1632Class::getTextWidth(const char text [], const char font_width [], char * and perform the rendering go here: */ -void HT1632Class::begin(int pinCS1, int pinWR, int pinDATA) { +void HT1632Class::begin(uint8_t pinCS1, uint8_t pinWR, uint8_t pinDATA) { _numActivePins = 1; _pinCS[0] = pinCS1; initialize(pinWR, pinDATA); } -void HT1632Class::begin(int pinCS1, int pinCS2, int pinWR, int pinDATA) { +void HT1632Class::begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinWR, uint8_t pinDATA) { _numActivePins = 2; _pinCS[0] = pinCS1; _pinCS[1] = pinCS2; initialize(pinWR, pinDATA); } -void HT1632Class::begin(int pinCS1, int pinCS2, int pinCS3, int pinWR, int pinDATA) { +void HT1632Class::begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinWR, uint8_t pinDATA) { _numActivePins = 3; _pinCS[0] = pinCS1; _pinCS[1] = pinCS2; _pinCS[2] = pinCS3; initialize(pinWR, pinDATA); } -void HT1632Class::begin(int pinCS1, int pinCS2, int pinCS3, int pinCS4, int pinWR, int pinDATA) { +void HT1632Class::begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinCS4, uint8_t pinWR, uint8_t pinDATA) { _numActivePins = 4; _pinCS[0] = pinCS1; _pinCS[1] = pinCS2; @@ -108,30 +104,30 @@ void HT1632Class::begin(int pinCS1, int pinCS2, int pinCS3, int pinCS4, int pi initialize(pinWR, pinDATA); } -void HT1632Class::initialize(int pinWR, int pinDATA) { +void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { _pinWR = pinWR; _pinDATA = pinDATA; - for(int i=0; i<_numActivePins; ++i){ - pinMode(_pinCS[i], OUTPUT); - // Allocate new memory for mem - mem[i] = (char *)malloc(ADDR_SPACE_SIZE); - drawTarget(i); - clear(); // Clean out mem + for(uint8_t i=0; i<_numActivePins; ++i){ + pinMode(_pinCS[i], OUTPUT); + // Allocate new memory for mem + mem[i] = (byte *)malloc(ADDR_SPACE_SIZE); + drawTarget(i); + clear(); // Clean out mem } pinMode(_pinWR, OUTPUT); pinMode(_pinDATA, OUTPUT); select(); - mem[4] = (char *)malloc(ADDR_SPACE_SIZE); + mem[4] = (byte *)malloc(ADDR_SPACE_SIZE); // Each 8-bit mem array element stores data in the 4 least significant bits, // and meta-data in the 4 most significant bits. Use bitmasking to read/write // the meta-data. drawTarget(4); clear(); // Clean out memory - int i=0; + uint8_t i=0; // Send configuration to chip: @@ -183,11 +179,10 @@ void HT1632Class::initialize(int pinWR, int pinDATA) { for(int i=0; i<_numActivePins; ++i) { - drawTarget(i); - _globalNeedsRewriting[i] = true; - clear(); - // Perform the initial rendering - render(); + drawTarget(i); + clear(); + // Perform the initial rendering + render(); } // Set drawTarget to default board. drawTarget(0); @@ -198,11 +193,11 @@ void HT1632Class::drawTarget(uint8_t targetBuffer) { _tgtBuffer = targetBuffer; } -#IF PIXELS_PER_BYTE != 8 - #ERROR "The current drawImage implementation requires PIXELS_PER_BYTE == 8" -#ENDIF +#if PIXELS_PER_BYTE != 8 + #error "The current drawImage implementation requires PIXELS_PER_BYTE == 8" +#endif -void HT1632Class::drawImage(const uint8_t * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { +void HT1632Class::drawImage(const byte * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { uint8_t bytesPerColumn = height/PIXELS_PER_BYTE; // Equivalent to taking Math.ceil(), without working with floats if (bytesPerColumn * PIXELS_PER_BYTE < height) @@ -222,7 +217,6 @@ void HT1632Class::drawImage(const uint8_t * img, uint8_t width, uint8_t height, while (src_x < width) { if(dst_x < 0) { // Skip this column if it is too far to the left. - offset += bytesPerColumn; src_x++; dst_x++; continue; @@ -261,7 +255,7 @@ void HT1632Class::drawImage(const uint8_t * img, uint8_t width, uint8_t height, dst_copyMask <<= (8 - (dst_y & 0b111) - copyInNextStep); // Shift the data to the bits of highest significance - uint8_t copyData = img[img_offset + ] << (src_y & 0b111); + uint8_t copyData = img[img_offset + (bytesPerColumn * src_x) + (src_y >> 3)] << (src_y & 0b111); // Shift data to match the destination place value. copyData = copyData >> (dst_y & 0b111); @@ -272,15 +266,6 @@ void HT1632Class::drawImage(const uint8_t * img, uint8_t width, uint8_t height, src_y += copyInNextStep; dst_y += copyInNextStep; - /* Copy bytes without alignment: - * 0 8 16 - * To: |-------|-------| - * From: |-------|-------| - * -3 5 13 - * A B C D E - * - */ - } src_x++; @@ -290,37 +275,27 @@ void HT1632Class::drawImage(const uint8_t * img, uint8_t width, uint8_t height, void HT1632Class::clear(){ for(char i=0; i < ADDR_SPACE_SIZE; ++i) - mem[_tgtBuffer][i] = 0x00 | MASK_NEEDS_REWRITING; // Needs to be redrawn + mem[_tgtBuffer][i] = 0x00; // Needs to be redrawn } // Draw the contents of map to screen, for memory addresses that have the needsRedrawing flag void HT1632Class::render() { - if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) - return; - - char selectionmask = 0b0001 << _tgtBuffer; + if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) { + return; + } - bool isOpen = false; // Automatically compact sequential writes. - for(int i=0; i> HT1632_WORD_LEN], HT1632_WORD_LEN); // Write the data in reverse. + writeDataRev(mem[_tgtBuffer][i], HT1632_WORD_LEN); // Write the data in reverse. + // TODO: Write two bytes to memory. } - _globalNeedsRewriting[_tgtBuffer] = false; + + select(); // Close the stream at the end } // Set the brightness to an integer level between 1 and 16 (inclusive). @@ -339,29 +314,27 @@ void HT1632Class::setBrightness(char brightness, char selectionmask) { select(); } -void HT1632Class::transition(char mode, int time){ +void HT1632Class::transition(uint8_t mode, int time){ if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) return; switch(mode) { case TRANSITION_BUFFER_SWAP: { - char * tmp = mem[_tgtBuffer]; - mem[_tgtBuffer] = mem[BUFFER_SECONDARY]; - mem[BUFFER_SECONDARY] = tmp; - _globalNeedsRewriting[_tgtBuffer] = true; + byte * tmp = mem[_tgtBuffer]; + mem[_tgtBuffer] = mem[BUFFER_SECONDARY]; + mem[BUFFER_SECONDARY] = tmp; } break; case TRANSITION_NONE: for(char i=0; i < ADDR_SPACE_SIZE; ++i) - mem[_tgtBuffer][i] = mem[BUFFER_SECONDARY][i]; // Needs to be redrawn - _globalNeedsRewriting[_tgtBuffer] = true; + mem[_tgtBuffer][i] = mem[BUFFER_SECONDARY][i]; // Needs to be redrawn break; case TRANSITION_FADE: time /= 32; for(int i = 15; i > 0; --i) { - setBrightness(i); - delay(time); + setBrightness(i); + delay(time); } clear(); render(); @@ -370,8 +343,8 @@ void HT1632Class::transition(char mode, int time){ render(); delay(time); for(int i = 2; i <= 16; ++i) { - setBrightness(i); - delay(time); + setBrightness(i); + delay(time); } break; } @@ -390,31 +363,31 @@ void HT1632Class::writeCommand(char data) { } // Integer write to display. Used to write commands/addresses. // PRECONDITION: WR is LOW -void HT1632Class::writeData(char data, char len) { - for(int j=len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ - // Set the DATA pin to the correct state - digitalWrite(_pinDATA, ((data & t) == 0)?LOW:HIGH); - NOP(); // Delay - // Raise the WR momentarily to allow the device to capture the data - digitalWrite(_pinWR, HIGH); - NOP(); // Delay - // Lower it again, in preparation for the next cycle. - digitalWrite(_pinWR, LOW); +void HT1632Class::writeData(byte data, uint8_t len) { + for(uint8_t j=len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ + // Set the DATA pin to the correct state + digitalWrite(_pinDATA, ((data & t) == 0)?LOW:HIGH); + NOP(); // Delay + // Raise the WR momentarily to allow the device to capture the data + digitalWrite(_pinWR, HIGH); + NOP(); // Delay + // Lower it again, in preparation for the next cycle. + digitalWrite(_pinWR, LOW); } } // REVERSED Integer write to display. Used to write cell values. // PRECONDITION: WR is LOW -void HT1632Class::writeDataRev(char data, char len) { - for(int j=0; j>= 1; +void HT1632Class::writeDataRev(byte data, uint8_t len) { + for(uint8_t j = 0; j < len; ++j){ + // Set the DATA pin to the correct state + digitalWrite(_pinDATA, data & 1); + NOP(); // Delay + // Raise the WR momentarily to allow the device to capture the data + digitalWrite(_pinWR, HIGH); + NOP(); // Delay + // Lower it again, in preparation for the next cycle. + digitalWrite(_pinWR, LOW); + data >>= 1; } } // Write single bit to display, used as padding between commands. @@ -434,16 +407,13 @@ void HT1632Class::writeSingleBit() { // Call the function with a bitmask (0b4321) to select specific chips. 0b1111 selects all. void HT1632Class::select(char mask) { for(int i=0, t=1; i<_numActivePins; ++i, t <<= 1){ - digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); - /*Serial.write(48+_pinCS[i]); - Serial.write((t & mask)?"LOW":"HIGH"); - Serial.write('\n'); - */} - //Serial.write('\n'); + digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); + } } void HT1632Class::select() { - for(int i=0; i<_numActivePins; ++i) - digitalWrite(_pinCS[i], HIGH); + for(int i=0; i<_numActivePins; ++i) { + digitalWrite(_pinCS[i], HIGH); + } } /* diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 4f4cc61..909b43d 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -2,7 +2,7 @@ HT1632.h - Library for communicating with the popular HT1632/HT1632C LED controllers. This library provides higher-level access (including text drawing) for these chips. Currently, the library supports writing - to a single chip at a time, and has been tested with a single + to a single chip at a time, and has been tested with two Sure Electronics 3208 5mm red board. Created by Gaurav Manek, April 8, 2011. @@ -11,6 +11,14 @@ #ifndef HT1632_h #define HT1632_h +#include + +// Custom typedefs +typedef unsigned char uint8_t; +typedef unsigned char byte; +// typedef char int8_t; + + /* * USER OPTIONS * Change these options @@ -23,8 +31,6 @@ // Pixels in a single byte of the internal image representation: #define PIXELS_PER_BYTE 8 -// Pixels per word of the HT1632 image representation. -#define PIXELS_PER_WORD 4 // Target buffer // Each board has a "render" buffer, and all boards share one "secondary" buffer. All calls to @@ -55,7 +61,7 @@ // Address space size (number of 4-bit words in HT1632 memory) // Exactly equal to the number of 4-bit address spaces available. -#define ADDR_SPACE_SIZE (COM_SIZE*OUT_SIZE/4) +#define ADDR_SPACE_SIZE (COM_SIZE * OUT_SIZE / PIXELS_PER_BYTE) // Use N-MOS (if 1) or P-MOS (if 0): #define USE_NMOS 1 @@ -108,18 +114,17 @@ class HT1632Class { private: - char _pinCS [4]; - char _numActivePins; - char _pinWR; - char _pinDATA; - char _tgtBuffer; - char _globalNeedsRewriting [4]; - char * mem [5]; + uint8_t _pinCS [4]; + uint8_t _numActivePins; + uint8_t _pinWR; + uint8_t _pinDATA; + uint8_t _tgtBuffer; + byte * mem [5]; void writeCommand(char); - void writeData(char, char); - void writeDataRev(char, char); + void writeData(byte, uint8_t); + void writeDataRev(byte, uint8_t); void writeSingleBit(); - void initialize(int, int); + void initialize(uint8_t, uint8_t); void select(); void select(char mask); @@ -128,18 +133,18 @@ class HT1632Class void recursiveWriteUInt(int); public: - void begin(int pinCS1, int pinWR, int pinDATA); - void begin(int pinCS1, int pinCS2, int pinWR, int pinDATA); - void begin(int pinCS1, int pinCS2, int pinCS3, int pinWR, int pinDATA); - void begin(int pinCS1, int pinCS2, int pinCS3, int pinCS4, int pinWR, int pinDATA); - void sendCommand(char command); - void drawTarget(char targetBuffer); + void begin(uint8_t pinCS1, uint8_t pinWR, uint8_t pinDATA); + void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinWR, uint8_t pinDATA); + void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinWR, uint8_t pinDATA); + void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinCS4, uint8_t pinWR, uint8_t pinDATA); + void sendCommand(uint8_t command); + void drawTarget(uint8_t targetBuffer); void render(); - void transition(char mode, int time = 1000); // Time is in miliseconds. + void transition(uint8_t mode, int time = 1000); // Time is in milliseconds. void clear(); - void drawImage(const char * img, char width, char height, char x, char y, int offset = 0); - void drawText(const char [], int x, int y, const char font [], const char font_width [], char font_height, int font_glyph_step, char gutter_space = 1); - int getTextWidth(const char [], const char font_width [], char font_height, char gutter_space = 1); + void drawImage(const uint8_t * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int offset = 0); +// void drawText(const char [], int x, int y, const char font [], const char font_width [], char font_height, int font_glyph_step, char gutter_space = 1); +// int getTextWidth(const char [], const char font_width [], char font_height, char gutter_space = 1); void setBrightness(char brightness, char selectionmask = 0b00010000); }; diff --git a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino index e7725d1..6add1b1 100644 --- a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino +++ b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino @@ -1,5 +1,5 @@ -#include #include +#include #include int i = 0; diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index d4fc4e8..89b1719 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -9,7 +9,7 @@ #define FONT_5X4_HEIGHT 5 // Number of bytes per glyph -uint8_t FONT_5X4 [] = { +byte FONT_5X4 [] = { 0b00000000, // SPACE 0b00010111, // ! 0b00000011, 0b00000000, 0b00000011, // " diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index 0e1c244..41c0d43 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -4,32 +4,32 @@ * Gaurav Manek, 2014 */ -char IMG_MAIL [] = {0b11111111, 0b10000011, 0b10000101, 0b10001001, 0b10010001, 0b10100001, 0b10100001, 0b10010001}; +byte IMG_MAIL [] = {0b11111111, 0b10000011, 0b10000101, 0b10001001, 0b10010001, 0b10100001, 0b10100001, 0b10010001}; #define IMG_MAIL_WIDTH 12 #define IMG_MAIL_HEIGHT 8 -char IMG_FB [] = {0b11111100, 0b00000010, 0b00100001, 0b11111001, 0b00100101, 0b00000101, 0b00000001, 0b00000001}; +byte IMG_FB [] = {0b11111100, 0b00000010, 0b00100001, 0b11111001, 0b00100101, 0b00000101, 0b00000001, 0b00000001}; #define IMG_FB_WIDTH 8 #define IMG_FB_HEIGHT 8 -char IMG_PHONE [] = {0b00111100, 0b01111110, 0b11100111, 0b11000011}; +byte IMG_PHONE [] = {0b00111100, 0b01111110, 0b11100111, 0b11000011}; #define IMG_PHONE_WIDTH 8 #define IMG_PHONE_HEIGHT 8 -char IMG_MUSIC [] = {0b01000000, 0b11100000, 0b01111111, 0b00000011, 0b00000011, 0b00100011, 0b01110011, 0b00111111}; +byte IMG_MUSIC [] = {0b01000000, 0b11100000, 0b01111111, 0b00000011, 0b00000011, 0b00100011, 0b01110011, 0b00111111}; #define IMG_MUSIC_WIDTH 8 #define IMG_MUSIC_HEIGHT 8 -char IMG_MUSICNOTE [] = {0b00100000, 0b01110000, 0b00111111, 0b00000010}; +byte IMG_MUSICNOTE [] = {0b00100000, 0b01110000, 0b00111111, 0b00000010}; #define IMG_MUSICNOTE_WIDTH 4 #define IMG_MUSICNOTE_HEIGHT 7 -char IMG_HEART [] = {0b00001110, 0b00011111, 0b00111111, 0b01111111, 0b11111110, 0b01111111, 0b00111111, 0b00011111, 0b00001110}; +byte IMG_HEART [] = {0b00001110, 0b00011111, 0b00111111, 0b01111111, 0b11111110, 0b01111111, 0b00111111, 0b00011111, 0b00001110}; #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 -char IMG_SPEAKER_A [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; -char IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; +byte IMG_SPEAKER_A [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; +byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; #define IMG_SPEAKER_WIDTH 6 #define IMG_SPEAKER_HEIGHT 8 From 58643a0cca6e9e337dda77331906d72f47e2d2db Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 01:22:00 +0800 Subject: [PATCH 06/45] Fixed image pixel order problem. --- Arduino/HT1632/HT1632.cpp | 61 ++++----- Arduino/HT1632/HT1632.h | 5 +- .../examples/HT1632_Buffer/HT1632_Buffer.ino | 2 + Arduino/HT1632/font_5x4.h | 126 +++++++++--------- Arduino/HT1632/images.h | 16 +-- Utilities/font_conv.html | 2 +- Utilities/image_drawing.html | 39 +++++- 7 files changed, 136 insertions(+), 115 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index b18300d..3b70190 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -115,21 +115,16 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { drawTarget(i); clear(); // Clean out mem } + pinMode(_pinWR, OUTPUT); pinMode(_pinDATA, OUTPUT); select(); mem[4] = (byte *)malloc(ADDR_SPACE_SIZE); - // Each 8-bit mem array element stores data in the 4 least significant bits, - // and meta-data in the 4 most significant bits. Use bitmasking to read/write - // the meta-data. drawTarget(4); clear(); - // Clean out memory - uint8_t i=0; - - + // Send configuration to chip: // This configuration is from the HT1632 datasheet, with one modification: // The RC_MASTER_MODE command is not sent to the master. Since acting as @@ -154,31 +149,16 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { #else #error Invalid USE_NMOS or COM_SIZE values! Change the values in HT1632.h. #endif - - if(false && _numActivePins > 1){ - select(0b0001); // - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - writeCommand(HT1632_CMD_RCCLK); // Switch system to MASTER mode - select(0b1110); // All other boards are slaves - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - - writeCommand(HT1632_CMD_MSTMD); // Switch system to SLAVE mode. - // The use of the MSTMD command to switch to slave is explained here: - // http://forums.parallax.com/showthread.php?117423-Electronics-I-O-%28outputs-to-common-anode-RGB-LED-matrix%29-question/page4 - - - select(0b1111); - writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode - } writeCommand(HT1632_CMD_SYSEN); //Turn on system writeCommand(HT1632_CMD_LEDON); // Turn on LED duty cycle generator writeCommand(HT1632_CMD_PWM(16)); // PWM 16/16 duty select(); - - for(int i=0; i<_numActivePins; ++i) { + Serial.write("End initialize"); + + for(uint8_t i = 0; i < _numActivePins; ++i) { drawTarget(i); clear(); // Perform the initial rendering @@ -257,7 +237,7 @@ void HT1632Class::drawImage(const byte * img, uint8_t width, uint8_t height, int // Shift the data to the bits of highest significance uint8_t copyData = img[img_offset + (bytesPerColumn * src_x) + (src_y >> 3)] << (src_y & 0b111); // Shift data to match the destination place value. - copyData = copyData >> (dst_y & 0b111); + copyData >>= (dst_y & 0b111); // Perform the copy mem[_tgtBuffer][GET_ADDR_FROM_X_Y(dst_x, dst_y)] = // Put in destination @@ -285,14 +265,14 @@ void HT1632Class::render() { } select(0b0001 << _tgtBuffer); // Selecting the chip + + writeData(HT1632_ID_WR, HT1632_ID_LEN); + writeData(0, HT1632_ADDR_LEN); // Selecting the memory address for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { - writeData(HT1632_ID_WR, HT1632_ID_LEN); - writeData(i, HT1632_ADDR_LEN); // Selecting the memory address // Write the higher bits before the the lower bits. - writeDataRev(mem[_tgtBuffer][i >> HT1632_WORD_LEN], HT1632_WORD_LEN); // Write the data in reverse. - writeDataRev(mem[_tgtBuffer][i], HT1632_WORD_LEN); // Write the data in reverse. - // TODO: Write two bytes to memory. + writeData(mem[_tgtBuffer][i] >> HT1632_WORD_LEN, HT1632_WORD_LEN); // Write the data in reverse. + writeData(mem[_tgtBuffer][i], HT1632_WORD_LEN); // Write the data in reverse. } select(); // Close the stream at the end @@ -364,7 +344,7 @@ void HT1632Class::writeCommand(char data) { // Integer write to display. Used to write commands/addresses. // PRECONDITION: WR is LOW void HT1632Class::writeData(byte data, uint8_t len) { - for(uint8_t j=len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ + for(int j = len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ // Set the DATA pin to the correct state digitalWrite(_pinDATA, ((data & t) == 0)?LOW:HIGH); NOP(); // Delay @@ -420,7 +400,7 @@ void HT1632Class::select() { * HELPER FUNCTIONS * "Would you like some fries with that?" */ - +/* void HT1632Class::recursiveWriteUInt (int inp) { if(inp <= 0) return; int rd = inp % 10; @@ -429,15 +409,28 @@ void HT1632Class::recursiveWriteUInt (int inp) { } void HT1632Class::writeInt (int inp) { + Serial.write("@ "); if(inp == 0) Serial.write('0'); else if (inp < 0){ Serial.write('-'); recursiveWriteUInt(-inp); - } else + } else { recursiveWriteUInt(inp); + } + Serial.write('\n'); } +void HT1632Class::writeByte (byte inp) { + uint8_t a = 0b1 << 7; + while (a) { + Serial.write((a & inp)?'1':'0'); + a >>= 1; + } + Serial.write("\n"); +} +*/ + HT1632Class HT1632; diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 909b43d..206d3b4 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -129,8 +129,9 @@ class HT1632Class void select(char mask); // Debugging functions, write to Serial. - void writeInt(int); - void recursiveWriteUInt(int); +// void writeInt(int); +// void recursiveWriteUInt(int); +// void writeByte(byte b); public: void begin(uint8_t pinCS1, uint8_t pinWR, uint8_t pinDATA); diff --git a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino index 6add1b1..d62efd3 100644 --- a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino +++ b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino @@ -6,6 +6,8 @@ int i = 0; int wd; void setup () { + Serial.begin(9600); + Serial.write("Started!"); HT1632.begin(12, 10, 9); // Buffer swap transition example. diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index 89b1719..17e5bc3 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -10,70 +10,70 @@ // Number of bytes per glyph byte FONT_5X4 [] = { - 0b00000000, // SPACE - 0b00010111, // ! - 0b00000011, 0b00000000, 0b00000011, // " - 0b00001010, 0b00011111, 0b00001010, 0b00011111, 0b00001010, // # + 0b00000000, // + 0b11101000, // ! + 0b11000000, 0b00000000, 0b11000000, // " + 0b01010000, 0b11111000, 0b01010000, 0b11111000, 0b01010000, // # 0b00000000, 0b00000000, 0b00000000, 0b00000000, // $ - 0b00010011, 0b00001011, 0b00000100, 0b00011010, 0b00011001, // % - 0b00001010, 0b00010101, 0b00011001, 0b00011010, // & - 0b00000011, // ' - 0b00001110, 0b00010001, // ( - 0b00010001, 0b00001110, // ) - 0b00000101, 0b00000010, 0b00000101, // * - 0b00000100, 0b00000100, 0b00011111, 0b00000100, 0b00000100, // + - 0b00010000, 0b00001000, // , - 0b00000100, 0b00000100, 0b00000100, // - - 0b00010000, // . - 0b00010000, 0b00001100, 0b00000110, 0b00000001, // / - 0b00001110, 0b00010001, 0b00001110, // 0 - 0b00010010, 0b00011111, 0b00010000, // 1 - 0b00010010, 0b00011001, 0b00010101, 0b00010010, // 2 - 0b00010101, 0b00010101, 0b00001010, // 3 - 0b00001100, 0b00001010, 0b00011111, 0b00001000, // 4 - 0b00010111, 0b00010101, 0b00001101, // 5 - 0b00001110, 0b00010101, 0b00010101, 0b00001000, // 6 - 0b00000001, 0b00011101, 0b00000101, 0b00000011, // 7 - 0b00001010, 0b00010101, 0b00010101, 0b00001010, // 8 - 0b00000010, 0b00000101, 0b00010101, 0b00001110, // 9 - 0b00001010, // : - 0b00010000, 0b00001010, // ; - 0b00000100, 0b00001010, 0b00010001, // < - 0b00001010, 0b00001010, 0b00001010, // = - 0b00010001, 0b00001010, 0b00000100, // > - 0b00000010, 0b00000001, 0b00011001, 0b00000110, // ? - 0b00001110, 0b00000001, 0b00001101, 0b00010101, 0b00001111, // @ - 0b00011110, 0b00000101, 0b00000101, 0b00011110, // A - 0b00011111, 0b00010101, 0b00001010, // B - 0b00001110, 0b00010001, 0b00010001, 0b00001010, // C - 0b00011111, 0b00010001, 0b00001110, // D - 0b00011111, 0b00010101, 0b00010001, // E - 0b00011111, 0b00000101, 0b00000101, // F - 0b00001110, 0b00010001, 0b00011001, 0b00001010, // G - 0b00011111, 0b00000100, 0b00000100, 0b00011111, // H - 0b00010001, 0b00011111, 0b00010001, // I - 0b00001001, 0b00010001, 0b00001111, // J - 0b00011111, 0b00000100, 0b00001010, 0b00010001, // K - 0b00011111, 0b00010000, 0b00010000, // L - 0b00011111, 0b00000010, 0b00000100, 0b00000010, 0b00011111, // M - 0b00011111, 0b00000010, 0b00000100, 0b00001000, 0b00011111, // N - 0b00001110, 0b00010001, 0b00010001, 0b00001110, // O - 0b00011111, 0b00000101, 0b00000010, // P - 0b00001110, 0b00010001, 0b00010001, 0b00001001, 0b00010110, // Q - 0b00011111, 0b00000101, 0b00011010, // R - 0b00010010, 0b00010101, 0b00010101, 0b00001001, // S - 0b00000001, 0b00011111, 0b00000001, // T - 0b00001111, 0b00010000, 0b00010000, 0b00001111, // U - 0b00000011, 0b00001100, 0b00010000, 0b00001100, 0b00000011, // V - 0b00001111, 0b00010000, 0b00001100, 0b00010000, 0b00001111, // W - 0b00011011, 0b00000100, 0b00011011, // X - 0b00000011, 0b00011100, 0b00000011, // Y - 0b00011001, 0b00010101, 0b00010101, 0b00010011, // Z - 0b00011111, 0b00010001, // [ - 0b00000001, 0b00000110, 0b00001100, 0b00010000, // BACKSLASH - 0b00010001, 0b00011111, // ] - 0b00000010, 0b00000001, 0b00000010, // ^ - 0b00010000, 0b00010000, 0b00010000 // _ + 0b11001000, 0b11010000, 0b00100000, 0b01011000, 0b10011000, // % + 0b01010000, 0b10101000, 0b10011000, 0b01011000, // & + 0b11000000, // ' + 0b01110000, 0b10001000, // ( + 0b10001000, 0b01110000, // ) + 0b10100000, 0b01000000, 0b10100000, // * + 0b00100000, 0b00100000, 0b11111000, 0b00100000, 0b00100000, // + + 0b00001000, 0b00010000, // , + 0b00100000, 0b00100000, 0b00100000, // - + 0b00001000, // . + 0b00001000, 0b00110000, 0b01100000, 0b10000000, // / + 0b01110000, 0b10001000, 0b01110000, // 0 + 0b01001000, 0b11111000, 0b00001000, // 1 + 0b01001000, 0b10011000, 0b10101000, 0b01001000, // 2 + 0b10101000, 0b10101000, 0b01010000, // 3 + 0b00110000, 0b01010000, 0b11111000, 0b00010000, // 4 + 0b11101000, 0b10101000, 0b10110000, // 5 + 0b01110000, 0b10101000, 0b10101000, 0b00010000, // 6 + 0b10000000, 0b10111000, 0b10100000, 0b11000000, // 7 + 0b01010000, 0b10101000, 0b10101000, 0b01010000, // 8 + 0b01000000, 0b10100000, 0b10101000, 0b01110000, // 9 + 0b01010000, // : + 0b00001000, 0b01010000, // ; + 0b00100000, 0b01010000, 0b10001000, // < + 0b01010000, 0b01010000, 0b01010000, // = + 0b10001000, 0b01010000, 0b00100000, // > + 0b01000000, 0b10000000, 0b10011000, 0b01100000, // ? + 0b01110000, 0b10000000, 0b10110000, 0b10101000, 0b11110000, // @ + 0b01111000, 0b10100000, 0b10100000, 0b01111000, // A + 0b11111000, 0b10101000, 0b01010000, // B + 0b01110000, 0b10001000, 0b10001000, 0b01010000, // C + 0b11111000, 0b10001000, 0b01110000, // D + 0b11111000, 0b10101000, 0b10001000, // E + 0b11111000, 0b10100000, 0b10100000, // F + 0b01110000, 0b10001000, 0b10011000, 0b01010000, // G + 0b11111000, 0b00100000, 0b00100000, 0b11111000, // H + 0b10001000, 0b11111000, 0b10001000, // I + 0b10010000, 0b10001000, 0b11110000, // J + 0b11111000, 0b00100000, 0b01010000, 0b10001000, // K + 0b11111000, 0b00001000, 0b00001000, // L + 0b11111000, 0b01000000, 0b00100000, 0b01000000, 0b11111000, // M + 0b11111000, 0b01000000, 0b00100000, 0b00010000, 0b11111000, // N + 0b01110000, 0b10001000, 0b10001000, 0b01110000, // O + 0b11111000, 0b10100000, 0b01000000, // P + 0b01110000, 0b10001000, 0b10001000, 0b10010000, 0b01101000, // Q + 0b11111000, 0b10100000, 0b01011000, // R + 0b01001000, 0b10101000, 0b10101000, 0b10010000, // S + 0b10000000, 0b11111000, 0b10000000, // T + 0b11110000, 0b00001000, 0b00001000, 0b11110000, // U + 0b11000000, 0b00110000, 0b00001000, 0b00110000, 0b11000000, // V + 0b11110000, 0b00001000, 0b00110000, 0b00001000, 0b11110000, // W + 0b11011000, 0b00100000, 0b11011000, // X + 0b11000000, 0b00111000, 0b11000000, // Y + 0b10011000, 0b10101000, 0b10101000, 0b11001000, // Z + 0b11111000, 0b10001000, // [ + 0b10000000, 0b01100000, 0b00110000, 0b00001000, // \ + 0b10001000, 0b11111000, // ] + 0b01000000, 0b10000000, 0b01000000, // ^ + 0b00001000, 0b00001000, 0b00001000, // _ }; // If your number goes above 255, change this to int. diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index 41c0d43..39559d1 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -4,27 +4,23 @@ * Gaurav Manek, 2014 */ -byte IMG_MAIL [] = {0b11111111, 0b10000011, 0b10000101, 0b10001001, 0b10010001, 0b10100001, 0b10100001, 0b10010001}; -#define IMG_MAIL_WIDTH 12 +byte IMG_MAIL [] = {0b11111111, 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10000101, 0b10000101, 0b10001001}; +#define IMG_MAIL_WIDTH 8 #define IMG_MAIL_HEIGHT 8 -byte IMG_FB [] = {0b11111100, 0b00000010, 0b00100001, 0b11111001, 0b00100101, 0b00000101, 0b00000001, 0b00000001}; +byte IMG_FB [] = {0b00111111, 0b01000000, 0b10000100, 0b10011111, 0b10100100, 0b10100000, 0b10000000, 0b10000000}; #define IMG_FB_WIDTH 8 #define IMG_FB_HEIGHT 8 -byte IMG_PHONE [] = {0b00111100, 0b01111110, 0b11100111, 0b11000011}; -#define IMG_PHONE_WIDTH 8 -#define IMG_PHONE_HEIGHT 8 - -byte IMG_MUSIC [] = {0b01000000, 0b11100000, 0b01111111, 0b00000011, 0b00000011, 0b00100011, 0b01110011, 0b00111111}; +byte IMG_MUSIC [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100}; #define IMG_MUSIC_WIDTH 8 #define IMG_MUSIC_HEIGHT 8 -byte IMG_MUSICNOTE [] = {0b00100000, 0b01110000, 0b00111111, 0b00000010}; +byte IMG_MUSICNOTE [] = {0b00000100, 0b00001110, 0b11111100, 0b01000000}; #define IMG_MUSICNOTE_WIDTH 4 #define IMG_MUSICNOTE_HEIGHT 7 -byte IMG_HEART [] = {0b00001110, 0b00011111, 0b00111111, 0b01111111, 0b11111110, 0b01111111, 0b00111111, 0b00011111, 0b00001110}; +byte IMG_HEART [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100}; #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 diff --git a/Utilities/font_conv.html b/Utilities/font_conv.html index a482adf..74036cb 100644 --- a/Utilities/font_conv.html +++ b/Utilities/font_conv.html @@ -32,7 +32,7 @@ for(var i = 0; i < 64; ++i){ sb = i * FONT_5X4_STEP; for(j = 0; j < FONT_5X4_WIDTH[i]; ++j) { - rv += "0b" + src[sb + 2*j + 1] + "" + src[sb + 2*j] + ", "; + rv += "0b" + (src[sb + 2*j + 1] + "" + src[sb + 2*j]).split("").reverse().join("") + ", "; } rv += " // " + String.fromCharCode(32 + i); rv += "\n"; diff --git a/Utilities/image_drawing.html b/Utilities/image_drawing.html index 774e9c1..3a250b0 100644 --- a/Utilities/image_drawing.html +++ b/Utilities/image_drawing.html @@ -37,7 +37,8 @@ var height; var renderCircle = false; -var pixelsInAByte = 4; +var pixelsInAByte = 8; +var reversePixelOrder = false; function initialize(){ updateCanvasSize(); @@ -63,8 +64,13 @@ for(var i=0; i=0; --k) - val += (map[i][j+k]?"1":"0"); + if (reversePixelOrder) { + for(var k=pixelsInAByte - 1; k>=0; --k) + val += (map[i][j+k]?"1":"0"); + } else { + for(var k=0; k < pixelsInAByte; ++k) + val += (map[i][j+k]?"1":"0"); + } val += ", "; } } @@ -83,7 +89,9 @@ for(var x = 0; x < width; ++x) for(var y = 0; y < height; y += pixelsInAByte) { var currData = trim(src[i++]).replace("0b", "").split(""); - currData.reverse(); // After reversing, [0] is the element with the lowest y-value. + if (reversePixelOrder) { + currData.reverse(); // After reversing, [0] is the element with the lowest y-value. + } for(var k = 0; (k < pixelsInAByte) && (y + k < height); ++k) map[x][y+k] = (currData[k] == "0"?false:true); } @@ -183,14 +191,35 @@ } } +function updateReversePixel() { + reversePixelOrder = $("chkRevPx").checked; + canvasRender(); +} + window.addEventListener("load", initialize, false); + +function settings(ver) { + if (ver == 1) { + pixelsInAByte = 4; + reversePixelOrder = true; + } else { + pixelsInAByte = 8; + reversePixelOrder = false; + } + $("chkRevPx").checked = reversePixelOrder; + $("pxInByte").value = pixelsInAByte; + canvasRender(); +} +

-Width: Height: Pixels per Byte: Use Circle

+Width: Height: Use Circle
+Pixels per Byte: Reverse Pixel Order
+
From 02887ffb6cba2db134164979259e8d911ce41e43 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 02:22:55 +0800 Subject: [PATCH 07/45] Font rendering complete! --- Arduino/HT1632/HT1632.cpp | 114 ++++++------------ Arduino/HT1632/HT1632.h | 11 +- .../examples/HT1632_Buffer/HT1632_Buffer.ino | 2 - .../examples/HT1632_Text/HT1632_Text.ino | 25 ++++ Arduino/HT1632/font_5x4.h | 2 +- 5 files changed, 70 insertions(+), 84 deletions(-) create mode 100644 Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 3b70190..e72b6cf 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -6,8 +6,7 @@ * functions go here: */ -/* -void HT1632Class::drawText(const char text [], int x, int y, const char font [], const char font_width [], char font_height, int font_glyph_step, char gutter_space) { +void HT1632Class::drawText(const char text [], int x, int y, byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space) { int curr_x = x; char i = 0; char currchar; @@ -34,42 +33,62 @@ void HT1632Class::drawText(const char text [], int x, int y, const char font [], break; // Stop rendering - all other characters are no longer within the screen // Check to see if character is not too far left. - if(curr_x + font_width[currchar] + gutter_space >= 0){ - drawImage(font, font_width[currchar], font_height, curr_x, y, currchar*font_glyph_step); + int chr_width = getCharWidth(font_end, currchar); + if(curr_x + chr_width + gutter_space >= 0){ + drawImage(font, chr_width, font_height, curr_x, y, getCharOffset(font_end, currchar)); // Draw the gutter space for(char j = 0; j < gutter_space; ++j) - drawImage(font, 1, font_height, curr_x + font_width[currchar] + j, y, 0); - + drawImage(font, 1, font_height, curr_x + chr_width + j, y, 0); } - curr_x += font_width[currchar] + gutter_space; + curr_x += chr_width + gutter_space; ++i; } } // Gives you the width, in columns, of a particular string. -int HT1632Class::getTextWidth(const char text [], const char font_width [], char font_height, char gutter_space) { +int HT1632Class::getTextWidth(const char text [], int font_end [], uint8_t gutter_space) { int wd = 0; char i = 0; char currchar; while(true){ - if(text[i] == '\0') - return wd - gutter_space; - - currchar = text[i] - 32; - if(currchar >= 65 && currchar <= 90) // If character is lower-case, automatically make it upper-case - currchar -= 32; // Make this character uppercase. - if(currchar < 0 || currchar >= 64) { // If out of bounds, skip + if (text[i] == '\0') { + return wd - gutter_space; + } + + currchar = text[i] - 32; + if (currchar >= 65 && currchar <= 90) { // If character is lower-case, automatically make it upper-case + currchar -= 32; // Make this character uppercase. + } + + if (currchar < 0 || currchar >= 64) { // If out of bounds, skip + ++i; + continue; // Skip this character. + } + + wd += getCharWidth(font_end, currchar) + gutter_space; ++i; - continue; // Skip this character. } - wd += font_width[currchar] + gutter_space; - ++i; +} + +int HT1632Class::getCharWidth(int font_end [], uint8_t font_index) { + if(font_index == 0) { + return font_end[0]; + } + // The width is the difference between the ending index of + // this and the previous characters: + return font_end[font_index] - font_end[font_index - 1]; +} + +int HT1632Class::getCharOffset(int font_end [], uint8_t font_index) { + if(font_index == 0) { + return 0; } + // The offset is in the ending index of the previous character: + return font_end[font_index - 1]; } -*/ /* * MID LEVEL FUNCTIONS @@ -156,8 +175,6 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { select(); - Serial.write("End initialize"); - for(uint8_t i = 0; i < _numActivePins; ++i) { drawTarget(i); clear(); @@ -344,7 +361,7 @@ void HT1632Class::writeCommand(char data) { // Integer write to display. Used to write commands/addresses. // PRECONDITION: WR is LOW void HT1632Class::writeData(byte data, uint8_t len) { - for(int j = len-1, t = 1 << (len - 1); j>=0; --j, t >>= 1){ + for(int j = len - 1, t = 1 << (len - 1); j >= 0; --j, t >>= 1){ // Set the DATA pin to the correct state digitalWrite(_pinDATA, ((data & t) == 0)?LOW:HIGH); NOP(); // Delay @@ -355,21 +372,7 @@ void HT1632Class::writeData(byte data, uint8_t len) { digitalWrite(_pinWR, LOW); } } -// REVERSED Integer write to display. Used to write cell values. -// PRECONDITION: WR is LOW -void HT1632Class::writeDataRev(byte data, uint8_t len) { - for(uint8_t j = 0; j < len; ++j){ - // Set the DATA pin to the correct state - digitalWrite(_pinDATA, data & 1); - NOP(); // Delay - // Raise the WR momentarily to allow the device to capture the data - digitalWrite(_pinWR, HIGH); - NOP(); // Delay - // Lower it again, in preparation for the next cycle. - digitalWrite(_pinWR, LOW); - data >>= 1; - } -} + // Write single bit to display, used as padding between commands. // PRECONDITION: WR is LOW void HT1632Class::writeSingleBit() { @@ -396,41 +399,4 @@ void HT1632Class::select() { } } -/* - * HELPER FUNCTIONS - * "Would you like some fries with that?" - */ -/* -void HT1632Class::recursiveWriteUInt (int inp) { - if(inp <= 0) return; - int rd = inp % 10; - recursiveWriteUInt(inp/10); - Serial.write(48+rd); -} - -void HT1632Class::writeInt (int inp) { - Serial.write("@ "); - if(inp == 0) - Serial.write('0'); - else - if (inp < 0){ - Serial.write('-'); - recursiveWriteUInt(-inp); - } else { - recursiveWriteUInt(inp); - } - Serial.write('\n'); -} - -void HT1632Class::writeByte (byte inp) { - uint8_t a = 0b1 << 7; - while (a) { - Serial.write((a & inp)?'1':'0'); - a >>= 1; - } - Serial.write("\n"); -} -*/ - HT1632Class HT1632; - diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 206d3b4..26dd733 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -127,11 +127,8 @@ class HT1632Class void initialize(uint8_t, uint8_t); void select(); void select(char mask); - - // Debugging functions, write to Serial. -// void writeInt(int); -// void recursiveWriteUInt(int); -// void writeByte(byte b); + int getCharWidth(int font_end [], uint8_t font_index); + int getCharOffset(int font_end [], uint8_t font_index); public: void begin(uint8_t pinCS1, uint8_t pinWR, uint8_t pinDATA); @@ -144,8 +141,8 @@ class HT1632Class void transition(uint8_t mode, int time = 1000); // Time is in milliseconds. void clear(); void drawImage(const uint8_t * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int offset = 0); -// void drawText(const char [], int x, int y, const char font [], const char font_width [], char font_height, int font_glyph_step, char gutter_space = 1); -// int getTextWidth(const char [], const char font_width [], char font_height, char gutter_space = 1); + void drawText(const char text [], int x, int y, byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); + int getTextWidth(const char text [], int font_end [], uint8_t gutter_space = 1); void setBrightness(char brightness, char selectionmask = 0b00010000); }; diff --git a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino index d62efd3..6add1b1 100644 --- a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino +++ b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino @@ -6,8 +6,6 @@ int i = 0; int wd; void setup () { - Serial.begin(9600); - Serial.write("Started!"); HT1632.begin(12, 10, 9); // Buffer swap transition example. diff --git a/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino b/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino new file mode 100644 index 0000000..a634051 --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino @@ -0,0 +1,25 @@ +#include +#include +#include + +int i = 0; +int wd; +char disp [] = "Hello, how are you?"; + +void setup () { + HT1632.begin(12, 10, 9); + + wd = HT1632.getTextWidth(disp, FONT_5X4_END); +} + +void loop () { + + HT1632.drawTarget(BUFFER_BOARD(1)); + HT1632.clear(); + HT1632.drawText(disp, OUT_SIZE - i, 2, FONT_5X4, FONT_5X4_END, FONT_5X4_HEIGHT); + HT1632.render(); + + i = (i+1)%(wd + OUT_SIZE); + + delay(50); +} diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index 17e5bc3..0c336a0 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -77,7 +77,7 @@ byte FONT_5X4 [] = { }; // If your number goes above 255, change this to int. -uint8_t FONT_5X4_END [] = { +int FONT_5X4_END [] = { 1, 2, 5, 10, 14, 19, 23, 24, 26, 28, 31, 36, 38, 41, 42, 46, 49, 52, 56, 59, 63, 66, 70, 74, From 8886a03e86deee45af370d4cc325b6e6eb9caaf5 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 15:54:14 +0800 Subject: [PATCH 08/45] Added community font, updated image and font conversion utility. --- Arduino/HT1632/font_5x4.h | 1 - Arduino/HT1632/images.h | 1 - Utilities/font_conv.html | 144 +++++++++++++++++++++++++++++------ Utilities/image_drawing.html | 2 +- 4 files changed, 120 insertions(+), 28 deletions(-) diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index 0c336a0..e389e37 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -76,7 +76,6 @@ byte FONT_5X4 [] = { 0b00001000, 0b00001000, 0b00001000, // _ }; -// If your number goes above 255, change this to int. int FONT_5X4_END [] = { 1, 2, 5, 10, 14, 19, 23, 24, 26, 28, 31, 36, 38, 41, 42, 46, diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index 39559d1..cf64848 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -24,7 +24,6 @@ byte IMG_HEART [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 - byte IMG_SPEAKER_A [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; #define IMG_SPEAKER_WIDTH 6 diff --git a/Utilities/font_conv.html b/Utilities/font_conv.html index 74036cb..8d74f8b 100644 --- a/Utilities/font_conv.html +++ b/Utilities/font_conv.html @@ -2,7 +2,7 @@ -LED Screen Paint +Font Upgrade + + + +Font Code: +
+
+

+
+

From f5e1f0ba29f2003e3a63a88e7c007000aa16031c Mon Sep 17 00:00:00 2001
From: Gaurav Manek 
Date: Mon, 28 Jul 2014 17:51:11 +0800
Subject: [PATCH 11/45] Fixed U character

---
 .../HT1632_Text_Large/HT1632_Text_Large.ino   | 21 ----
 .../sketch_HT1632_sample_code.ino             | 98 -------------------
 Arduino/HT1632/font_8x4.h                     |  4 +-
 Arduino/HT1632/images.h                       | 24 ++++-
 4 files changed, 22 insertions(+), 125 deletions(-)
 delete mode 100644 Arduino/HT1632/examples/HT1632_Text_Large/HT1632_Text_Large.ino
 delete mode 100644 Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino

diff --git a/Arduino/HT1632/examples/HT1632_Text_Large/HT1632_Text_Large.ino b/Arduino/HT1632/examples/HT1632_Text_Large/HT1632_Text_Large.ino
deleted file mode 100644
index 5231fcb..0000000
--- a/Arduino/HT1632/examples/HT1632_Text_Large/HT1632_Text_Large.ino
+++ /dev/null
@@ -1,21 +0,0 @@
-#include 
-#include 
-#include 
-
-char c [] = "S\0";
-
-void setup () {
-  Serial.begin(9600);
-  HT1632.begin(12, 10, 9);
-}
-
-void loop () {
-  while(!Serial.available());
-  int ct = Serial.read();
-  c[0] = (char) ct;
-  HT1632.drawTarget(BUFFER_BOARD(1));
-  HT1632.clear();
-  HT1632.drawText(c, 0, 0, FONT_8X4, FONT_8X4_END, FONT_8X4_HEIGHT);
-  HT1632.render();
-  delay(50);
-}
diff --git a/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino b/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino
deleted file mode 100644
index 73e8d20..0000000
--- a/Arduino/HT1632/examples/sketch_HT1632_sample_code/sketch_HT1632_sample_code.ino
+++ /dev/null
@@ -1,98 +0,0 @@
-#include 
-#include 
-#include 
-
-int i = 0;
-int wd;
-
-void setup () {
-  Serial.begin(9600);
-  HT1632.begin(12, 10, 9);
-  
-  /* 
-  // Multiple screen control
-  HT1632.drawTarget(BUFFER_BOARD(1));
-  HT1632.drawText("Hello!", 0, 1, FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH);
-  HT1632.render();
-  
-  HT1632.drawTarget(BUFFER_SECONDARY);
-  HT1632.drawText("Foo", 0, 1, FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH);
-  HT1632.render();
-  
-  HT1632.drawTarget(BUFFER_BOARD(2));
-  HT1632.drawText("Bar", 0, 1, FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH);
-  HT1632.render();
-  //*/
-    
-  //*
-  // Buffer swap transition example.
-  // Fill board buffer with one image
-  HT1632.drawTarget(BUFFER_BOARD(1));
-  HT1632.drawImage(IMG_SPEAKER_A, IMG_SPEAKER_WIDTH,  IMG_SPEAKER_HEIGHT, 0, 0);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 8, 0);
-  HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH,  IMG_MUSIC_HEIGHT, 13, 1);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 23, 0);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 28, 1);
-  
-  // Fill secondary buffer with another image
-  HT1632.drawTarget(BUFFER_SECONDARY);
-  HT1632.drawImage(IMG_SPEAKER_B, IMG_SPEAKER_WIDTH,  IMG_SPEAKER_HEIGHT, 0, 0);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 8, 1);
-  HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH,  IMG_MUSIC_HEIGHT, 13, 0);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 23, 1);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 28, 0);
-  
-  HT1632.drawTarget(BUFFER_BOARD(1));
-  
-  HT1632.render();
-  
-  //HT1632.transition(TRANSITION_FADE, 4000);
-  //*/
-  wd = HT1632.getTextWidth("Hello, how are you?", FONT_5X4_WIDTH, FONT_5X4_HEIGHT);
-}
-
-void loop () {
-  
-  // Font rendering example
-  
-  HT1632.transition(TRANSITION_BUFFER_SWAP);
-  HT1632.render();
-  
-  /*
-  HT1632.drawTarget(BUFFER_BOARD(1));
-  HT1632.clear();
-  HT1632.drawText("Hello, how are you?", 2*OUT_SIZE - i, 2, FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH);
-  HT1632.render();
-  
-  HT1632.drawTarget(BUFFER_BOARD(2));
-  HT1632.clear();
-  HT1632.drawText("Hello, how are you?", OUT_SIZE - i, 2, FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH);
-  HT1632.render();
-  
-  
-  i = (i+1)%(wd + OUT_SIZE * 2);
-  //*/
-  
-  /*
-  // Simple rendering example
-  HT1632.clear();
-  HT1632.drawImage(i%2 ? IMG_SPEAKER_A:IMG_SPEAKER_B, IMG_SPEAKER_WIDTH,  IMG_SPEAKER_HEIGHT, 0, 0);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 8, (i)%2);
-  HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH,  IMG_MUSIC_HEIGHT, 13, (i+1)%2);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 23, (i)%2);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 28, (i+1)%2);
-  //HT1632.transition(TRANSITION_BUFFER_SWAP);
-  Serial.write('\n');
-  HT1632.render();
-  ++i;
-  //*/
-  
-  /*
-  // Example of automatic clipping and data preservation.
-  HT1632.drawImage(IMG_MAIL, IMG_MAIL_WIDTH,  IMG_MAIL_HEIGHT, 12, 0);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 12, i);
-  HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH,  IMG_MUSICNOTE_HEIGHT, 18, -i);
-  //*/
-  
-  delay(200);
-}
diff --git a/Arduino/HT1632/font_8x4.h b/Arduino/HT1632/font_8x4.h
index 7b0dd2c..f376b63 100644
--- a/Arduino/HT1632/font_8x4.h
+++ b/Arduino/HT1632/font_8x4.h
@@ -52,7 +52,7 @@ byte FONT_8X4 [] = {
   0b11111111, 0b10001001, 0b10001001, 0b10000001,               // E
   0b11111111, 0b10010000, 0b10010000, 0b10000000,               // F
   0b01111110, 0b10000001, 0b10001001, 0b01001110,               // G
-  0b11111111, 0b00010000, 0b00010000, 0b11111111,               // H
+  0b11111111, 0b00001000, 0b00001000, 0b11111111,               // H
   0b10000001, 0b11111111, 0b10000001,                           // I
   0b10000110, 0b10000001, 0b10000001, 0b11111110,               // J
   0b11111111, 0b00010000, 0b00101000, 0b11000111,               // K
@@ -65,7 +65,7 @@ byte FONT_8X4 [] = {
   0b11111111, 0b10001000, 0b10001100, 0b01110011,               // R
   0b01100010, 0b10010001, 0b10001001, 0b01000110,               // S
   0b10000000, 0b11111111, 0b10000000,                           // T
-  0b11111111, 0b00000001, 0b00000001, 0b11111111,               // U
+  0b11111110, 0b00000001, 0b00000001, 0b11111110,               // U
   0b11111110, 0b00000001, 0b00000110, 0b11111000,               // V
   0b11111100, 0b00000011, 0b00011100, 0b00000011, 0b11111100,   // W
   0b10000001, 0b01100110, 0b00011000, 0b01100110, 0b10000001,   // X
diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h
index 8ff4c92..fe67822 100644
--- a/Arduino/HT1632/images.h
+++ b/Arduino/HT1632/images.h
@@ -4,6 +4,10 @@
  * Gaurav Manek, 2014
  */
 
+//
+// Online Services:
+//
+
 byte IMG_MAIL [] = {0b11111111, 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10000101, 0b10000101, 0b10001001};
 #define IMG_MAIL_WIDTH 	8
 #define IMG_MAIL_HEIGHT 8
@@ -12,6 +16,14 @@ byte IMG_FB [] = {0b00111111, 0b01000000, 0b10000100, 0b10011111, 0b10100100, 0b
 #define IMG_FB_WIDTH 	 8
 #define IMG_FB_HEIGHT 	 8
 
+byte IMG_TWITTER [] = {0b01111110, 0b10000001, 0b10111001, 0b10010101, 0b10010101, 0b10000001, 0b01111110};
+#define IMG_TWITTER_WIDTH 	 7
+#define IMG_TWITTER_HEIGHT 	 8
+
+//
+// Music:
+//
+
 byte IMG_MUSIC [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100};
 #define IMG_MUSIC_WIDTH 	 8
 #define IMG_MUSIC_HEIGHT 	 8
@@ -20,11 +32,15 @@ byte IMG_MUSICNOTE [] = {0b00000100, 0b00001110, 0b11111100, 0b01000000};
 #define IMG_MUSICNOTE_WIDTH 	 4
 #define IMG_MUSICNOTE_HEIGHT 	 7
 
-byte IMG_HEART [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100};
-#define IMG_HEART_WIDTH 	 9
-#define IMG_HEART_HEIGHT 	 8
-
 byte IMG_SPEAKER_A [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000};
 byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000};
 #define IMG_SPEAKER_WIDTH 	 6
 #define IMG_SPEAKER_HEIGHT 	 8
+
+//
+// Emotions:
+//
+
+byte IMG_HEART [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100};
+#define IMG_HEART_WIDTH 	 9
+#define IMG_HEART_HEIGHT 	 8

From 5e0e1e02b30fc9994bf3fd2e7a4f6076a9b2ce36 Mon Sep 17 00:00:00 2001
From: Gaurav Manek 
Date: Mon, 28 Jul 2014 17:52:02 +0800
Subject: [PATCH 12/45] Reordered and renamed examples.

---
 .../HT1632_Text_8X4/HT1632_Text_8X4.ino       | 25 +++++++++++++++++++
 .../HT1632_Text_From_Serial.ino               | 21 ++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino
 create mode 100644 Arduino/HT1632/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino

diff --git a/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino b/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino
new file mode 100644
index 0000000..a4f8b07
--- /dev/null
+++ b/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino
@@ -0,0 +1,25 @@
+#include 
+#include 
+#include 
+
+int i = 0;
+int wd;
+char disp [] = "Hello, how are you?";
+
+void setup () {
+  HT1632.begin(12, 10, 9);
+  
+  wd = HT1632.getTextWidth(disp, FONT_8X4_END);
+}
+
+void loop () {
+  
+  HT1632.drawTarget(BUFFER_BOARD(1));
+  HT1632.clear();
+  HT1632.drawText(disp, OUT_SIZE - i, 0, FONT_8X4, FONT_8X4_END, FONT_8X4_HEIGHT);
+  HT1632.render();
+  
+  i = (i+1)%(wd + OUT_SIZE);
+  
+  delay(100);
+}
diff --git a/Arduino/HT1632/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino b/Arduino/HT1632/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino
new file mode 100644
index 0000000..5231fcb
--- /dev/null
+++ b/Arduino/HT1632/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino
@@ -0,0 +1,21 @@
+#include 
+#include 
+#include 
+
+char c [] = "S\0";
+
+void setup () {
+  Serial.begin(9600);
+  HT1632.begin(12, 10, 9);
+}
+
+void loop () {
+  while(!Serial.available());
+  int ct = Serial.read();
+  c[0] = (char) ct;
+  HT1632.drawTarget(BUFFER_BOARD(1));
+  HT1632.clear();
+  HT1632.drawText(c, 0, 0, FONT_8X4, FONT_8X4_END, FONT_8X4_HEIGHT);
+  HT1632.render();
+  delay(50);
+}

From 5b90847122a5a1b3665f15080f0edb78865a03c1 Mon Sep 17 00:00:00 2001
From: Gaurav Manek 
Date: Mon, 28 Jul 2014 22:14:23 +0800
Subject: [PATCH 13/45] Fix heart image.

---
 .../examples/HT1632_Heart/HT1632_Heart.ino    | 26 +++++++++++++++++++
 Arduino/HT1632/images.h                       |  2 +-
 2 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino

diff --git a/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino b/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino
new file mode 100644
index 0000000..f289fc1
--- /dev/null
+++ b/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino
@@ -0,0 +1,26 @@
+#include 
+#include 
+#include 
+
+int i = 0;
+int wd;
+
+void setup () {
+  HT1632.begin(12, 10, 9);
+}
+
+void loop () {
+  // The definitions for IMG_HEART and its width and height are available in images.h.
+  // This step only performs the drawing in internal memory. 
+  HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH,  IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0);
+  
+  HT1632.render(); // This updates the display on the screen.
+  
+  delay(1000);
+  
+  HT1632.clear(); // This zeroes out the internal memory.
+  
+  HT1632.render(); // This updates the screen display.
+  
+  delay(1000);
+}
diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h
index fe67822..50efcdd 100644
--- a/Arduino/HT1632/images.h
+++ b/Arduino/HT1632/images.h
@@ -41,6 +41,6 @@ byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111
 // Emotions:
 //
 
-byte IMG_HEART [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100};
+byte IMG_HEART [] = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, 0b11111110, 0b11111100, 0b11111000, 0b01110000};
 #define IMG_HEART_WIDTH 	 9
 #define IMG_HEART_HEIGHT 	 8

From c6088ed821486f2f5b3a1eebc6a9985b4cd5c3f0 Mon Sep 17 00:00:00 2001
From: Gaurav Manek 
Date: Mon, 28 Jul 2014 22:14:53 +0800
Subject: [PATCH 14/45] Updated README and UPGRADE

---
 README.markdown => README.md | 94 ++++++++++++++++++++----------------
 UPGRADE.md                   | 41 ++++++++++++++++
 2 files changed, 94 insertions(+), 41 deletions(-)
 rename README.markdown => README.md (71%)
 create mode 100644 UPGRADE.md

diff --git a/README.markdown b/README.md
similarity index 71%
rename from README.markdown
rename to README.md
index 33e85c6..becb2a9 100644
--- a/README.markdown
+++ b/README.md
@@ -1,9 +1,11 @@
-HT1632 for Arduino v1.0
+HT1632 for Arduino v2.0
 =======================
 
+__NOTE:__ This new version of the software changes the underlying data format - upgrading is easy and largely automated. See [upgrade instructions](UPGRADE.md).
+
 This is a powerful library that allows an Arduino to interface with the popular __Holtek HT1632C__ LED driver. It allows programmers to directly perform advanced drawing of images and text with minimal code, using a similar "state machine" paradigm to OpenGL.
 
-Do note that the (now depreciated) __Holtek HT1632__ LED driver is *theoretically* compatible with this library, but requires slightly different initialization.
+Do note that the (now deprecated) __Holtek HT1632__ LED driver is *theoretically* compatible with this library, but requires slightly different initialization.
 
 Quick Start
 ===========
@@ -11,10 +13,10 @@ Quick Start
 Code
 ----
 
-Here's some sample code to draw a blinking heart on the middle of a single screen.
+Here's some sample code to draw a blinking heart on the middle of a single screen:
 
-```c++
-#include 
+```c
+#include  // Include this before  or any font.
 #include 
 
 void setup () {
@@ -24,26 +26,25 @@ void setup () {
 }
 
 void loop () {
-	HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH,  IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0);
-	// The definitions for IMG_HEART and its width and height are available in images.h.
-	// This step only performs the drawing in internal memory. 
-	HT1632.render();
-	// This updates the display on the screen.
-	
-	delay(1000);
-	
-	HT1632.clear();
-	// This zeroes out the internal memory.
-	HT1632.render();
-	// This updates the screen display.
-	
-	delay(1000);
+  // The definitions for IMG_HEART and its width and height are available in images.h.
+  // This step only performs the drawing in internal memory. 
+  HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH,  IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0);
+  
+  HT1632.render(); // This updates the display on the screen.
+  
+  delay(1000);
+  
+  HT1632.clear(); // This zeroes out the internal memory.
+  
+  HT1632.render(); // This updates the screen display.
+  
+  delay(1000);
 }
 ```
 
 Before running the code, go to HT1632.h and change the following definitions, if needed. This needs to be done only __once__.
 
-```c++
+```c
 // Size of COM and OUT in bits:
 #define COM_SIZE 8
 #define OUT_SIZE 32
@@ -76,18 +77,33 @@ Image Drawing
 
 This project includes an image-drawing utility, written in HTML5 (using the canvas tag) and JavaScript. It has been tested on Firefox 3.6.* on OSX.
 
-The editor provides the data in a ready-to-paste format that allows for quick drawing of fonts and/or images. It can load previously drawn images as well.
+The editor provides the data in a ready-to-paste format that allows for quick drawing of fonts and/or images. It can load previously drawn images as well (even those from v1 -- see [upgrading instructions](UPGRADE.md) for more details).
+
+It's use should be self-evident. You can find it in `Utilities/image_drawing.html`.
+
+Font Creation
+-------------
+
+Fonts are defined as a series of images of equal height and variable width. (__Note:__ currently, fonts are limited to at most one byte per column. We'll fix this soon.) The bytes making up each character, from ASCII char 32 (space) onwards, are appended together without any byte alignment.
+
+An array, `FONT_8X4_END`, encodes information necessary to extract the width and the offset of the character from the font array. The element at position `i` encodes the first index of character `i + 1`.
+
+__Generating FONT_NAME_NUM__
+
+This array can be generated automatically using `Utilities/font_end_generate.html`. Make sure your font has one character per line (with no trailing newline) and paste it into the tool.
+
+If you want to skip character `i`, simply set `FONT_NAME_NUM[i] = FONT_NAME_NUM[i - 1]` or `FONT_NAME_NUM[0] = 0` if `i == 0`. Using the `font_end_generate.html` tool, just leave a blank line.
 
-It's use should be self-evident. You can find it in "Utilities/Image drawing/". 
 
 Advanced Use
 ============
 
+There are a few examples in `Arduino/HT1632/examples/`.
+
 Brightness Control
 ------------------
 
-The HT1632C comes with a 15-level PWM control option. You can control the brightness (from 1/16 to 16/16 of the duty cycle) of the current drawing target using the  `setBrightness(level)` function, where level is a number from 1 to 16.
-__level must never be zero!__
+The HT1632C comes with a 15-level PWM control option. You can control the brightness (from 1/16 to 16/16 of the duty cycle) of the current drawing target using the  `setBrightness(level)` function, where level is a number from 1 to 16. __level must never be zero!__
 
 If you want to simultaneously set multiple boards to the same brightness level, you can pass a bitmask as an optional second argument, like so: `setBrightness(8, 0b0101)`. The rightmost bit is the first screen, while the fourth bit from the right corresponds to the fourth screen. In the above example, the first and third screen are set to half brightness, while the second and third remain unchanged.
 
@@ -98,9 +114,9 @@ This library supports up to 4 chips at a time (though technically more can be ru
 
 All drawing occurs on the first display by default. The `drawTarget(BUFFER_BOARD(x))` function allows you to choose to write output to the board selected by `pinCSx`. The example below shows how scrolling text can be implemented using this:
 
-```c++
-#include 
+```c
 #include 
+#include 
 
 int wd; 
 int i = 0;
@@ -143,9 +159,9 @@ In addition to one buffer for each board, one additional buffer (the secondary b
 Here's an example showing this buffer being used to render a two-frame animation much more efficiently than redrawing each frame from scratch:
 
 
-```c++
-#include 
+```c
 #include 
+#include 
 
 void setup () {
 	HT1632.begin(pinCS1, pinWR, pinDATA);
@@ -180,17 +196,13 @@ void loop () {
 Notice that all the drawing is done in the setup() function? The loop function just shuffles the data around in memory.
 
 Note: Only three transitions are currently available. 
-
-  
-    
-  
-  
-    
-  
-  
-    
-  
-
`TRANSITION_BUFFER_SWAP`Swap the current buffer and the transition buffer. This is the only transition that preserves the contents of the current buffer.
`TRANSITION_NONE`Simply copy the buffer.
`TRANSITION_FADE`Uses the PWM feature to fade through black. Does not preserve current brightness level.
+ +Transition | Description +-----------|------------ +`TRANSITION_BUFFER_SWAP` | Swap the current buffer and the transition buffer. This is the only transition that preserves the contents of the current buffer. +`TRANSITION_NONE` | Simply copy the buffer. +`TRANSITION_FADE` | Uses the PWM feature to fade through black. Does not preserve current brightness level. + Bugs & Features =============== @@ -205,5 +217,5 @@ Future Plans 1. Support for direct pixel access and primitive drawing. 2. Support for advanced transitions (moving entire screen contents around with a single command). -3. "Export" feature that transmits the screen contents over Serial, so that animations can be captured in realtime. - +3. Support for fonts taller than 8px. +4. Allow `FONT_8X4_END` arrays to be either 2-byte `int`s or 1-byte `uint8_t`s diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 0000000..8baa44e --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,41 @@ +Upgrade Instruction from v1.0 +============================= + +Why bother? +----------- + +Because: + - Images, fonts and buffers are smaller, with a minimum 50% reduction in size. + - Drawing is faster, the inner loop of the copying engine has been rewritten. + - Bugfixes, notably the ability to copy images of any arbitrary size. + - Compiled code size. + + +How to upgrade +-------------- + +__Code__ + +1. You need to include `HT1632.h` before `images.h` or any font file. +2. The newer functions require the images/fonts to be updated. +3. All calls to `HT1632.drawText` need to have the `font_glyph_step` argument removed. +4. All calls to `HT1632.getTextWidth` need to have the `font_height` argument removed. +5. All references to `FONT_NAME_WIDTH` need to be changed to `FONT_NAME_END`. + +__Images__ + +Your images need to be updated. The upgrade tool is built into the image drawing utility in `Utilities/image_drawing.html`. To use it: + +1. Copy the source array of the image (everything between `{` and `}`). +2. Open `image_drawing.html`. +3. Click `Version 1.0`. +4. Change the width and height values to match your image. +5. Paste the source array. +6. Click `Version 2.0`. +7. Copy the new array and replace the old version in your source code. + +__Fonts__ + +Your fonts need to be updated. The upgrade tool is in `Utilities/font_conv.html`, and should be self-explanatory. Do note that this tool is experimental - if you have trouble converting a particular font file, raise an issue on GitHub. + +The new font format is described in the [README](README.md). From 93394c9c03a07b9595bba732f959e2476303dd45 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 23:01:12 +0800 Subject: [PATCH 15/45] Added support for multi-bytes-per-column font. --- Arduino/HT1632/HT1632.cpp | 18 +++++++++--------- Arduino/HT1632/HT1632.h | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 5a6d1f5..66a0d62 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -33,7 +33,7 @@ void HT1632Class::drawText(char text [], int x, int y, byte font [], int font_en break; // Stop rendering - all other characters are no longer within the screen // Check to see if character is not too far left. - int chr_width = getCharWidth(font_end, currchar); + int chr_width = getCharWidth(font_end, font_height, currchar); if(curr_x + chr_width + gutter_space >= 0){ drawImage(font, chr_width, font_height, curr_x, y, getCharOffset(font_end, currchar)); @@ -48,7 +48,7 @@ void HT1632Class::drawText(char text [], int x, int y, byte font [], int font_en } // Gives you the width, in columns, of a particular string. -int HT1632Class::getTextWidth(char text [], int font_end [], uint8_t gutter_space) { +int HT1632Class::getTextWidth(char text [], int font_end [], uint8_t font_height, uint8_t gutter_space) { int wd = 0; char i = 0; char currchar; @@ -68,18 +68,20 @@ int HT1632Class::getTextWidth(char text [], int font_end [], uint8_t gutter_spac continue; // Skip this character. } - wd += getCharWidth(font_end, currchar) + gutter_space; + wd += getCharWidth(font_end, font_height, currchar) + gutter_space; ++i; } } -int HT1632Class::getCharWidth(int font_end [], uint8_t font_index) { +int HT1632Class::getCharWidth(int font_end [], uint8_t font_height, uint8_t font_index) { + uint8_t bytesPerColumn = (font_height >> 3) + ((font_height & 0b111)?1:0); // Assumes that PIXELS_PER_BYTE is 8 + if(font_index == 0) { return font_end[0]; } // The width is the difference between the ending index of // this and the previous characters: - return font_end[font_index] - font_end[font_index - 1]; + return (font_end[font_index] - font_end[font_index - 1])/bytesPerColumn; } int HT1632Class::getCharOffset(int font_end [], uint8_t font_index) { @@ -195,10 +197,8 @@ void HT1632Class::drawTarget(uint8_t targetBuffer) { #endif void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { - uint8_t bytesPerColumn = height/PIXELS_PER_BYTE; - // Equivalent to taking Math.ceil(), without working with floats - if (bytesPerColumn * PIXELS_PER_BYTE < height) - bytesPerColumn++; + // Assuming that we are using 8 PIXELS_PER_BYTE, this does the equivalent of Math.ceil(height/PIXELS_PER_BYTE): + uint8_t bytesPerColumn = (height >> 3) + ((height & 0b111)?1:0); // Sanity checks if(y + height < 0 || x + width < 0 || y > COM_SIZE || x > OUT_SIZE) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 7ef43db..4fefeec 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -127,7 +127,7 @@ class HT1632Class void initialize(uint8_t, uint8_t); void select(); void select(char mask); - int getCharWidth(int font_end [], uint8_t font_index); + int getCharWidth(int font_end [], uint8_t font_height, uint8_t font_index); int getCharOffset(int font_end [], uint8_t font_index); public: @@ -142,7 +142,7 @@ class HT1632Class void clear(); void drawImage(byte img [], uint8_t width, uint8_t height, int8_t x, int8_t y, int offset = 0); void drawText(char text [], int x, int y, byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); - int getTextWidth(char text [], int font_end [], uint8_t gutter_space = 1); + int getTextWidth(char text [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); void setBrightness(char brightness, char selectionmask = 0b00010000); }; From 7f416d6e6ca9a4a8acc3a688ffaa3e78a7889298 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 23:01:39 +0800 Subject: [PATCH 16/45] Added ifndef preprocessor instructions. --- Arduino/HT1632/font_5x4.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index e389e37..97ebac9 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -6,6 +6,9 @@ * Gaurav Manek, 2011 */ +#ifndef __FONT5X4_H +#define __FONT5X4_H + #define FONT_5X4_HEIGHT 5 // Number of bytes per glyph @@ -87,3 +90,4 @@ int FONT_5X4_END [] = { 193, 196, 200, 202, 206, 208, 211, 214 }; +#endif // __FONT5X4_H From 8a38ce5dc27e0f85aa06d861e3241411ae38a421 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 23:13:29 +0800 Subject: [PATCH 17/45] Extended examples, fixed references to getTestWidth --- .../HT1632_Sailboat/HT1632_Sailboat.ino | 26 +++++++++++++++++++ .../examples/HT1632_Text/HT1632_Text.ino | 2 +- .../HT1632_Text_8X4/HT1632_Text_8X4.ino | 2 +- Arduino/HT1632/images.h | 8 ++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 Arduino/HT1632/examples/HT1632_Sailboat/HT1632_Sailboat.ino diff --git a/Arduino/HT1632/examples/HT1632_Sailboat/HT1632_Sailboat.ino b/Arduino/HT1632/examples/HT1632_Sailboat/HT1632_Sailboat.ino new file mode 100644 index 0000000..e815b83 --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Sailboat/HT1632_Sailboat.ino @@ -0,0 +1,26 @@ +#include +#include +#include + +int i = 0; +int wd; + +void setup () { + HT1632.begin(12, 10, 9); +} + +void loop () { + HT1632.clear(); + // This step only performs the drawing in internal memory. + HT1632.drawImage(IMG_SAILBOAT, IMG_SAILBOAT_WIDTH, IMG_SAILBOAT_HEIGHT, i, 0); + // If the image intersects with the end, + if (i > OUT_SIZE - IMG_SAILBOAT_WIDTH) { + // Draw it wrapping around. + HT1632.drawImage(IMG_SAILBOAT, IMG_SAILBOAT_WIDTH, IMG_SAILBOAT_HEIGHT, i - OUT_SIZE, 0); + } + HT1632.render(); // This updates the display on the screen. + + delay(100); + + i = (i + 1) % (OUT_SIZE); +} diff --git a/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino b/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino index 1ac2701..0555af1 100644 --- a/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino +++ b/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino @@ -9,7 +9,7 @@ char disp [] = "Hello, how are you?"; void setup () { HT1632.begin(12, 10, 9); - wd = HT1632.getTextWidth(disp, FONT_5X4_END); + wd = HT1632.getTextWidth(disp, FONT_5X4_END, FONT_5X4_HEIGHT); } void loop () { diff --git a/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino b/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino index a4f8b07..3a61e04 100644 --- a/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino +++ b/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino @@ -9,7 +9,7 @@ char disp [] = "Hello, how are you?"; void setup () { HT1632.begin(12, 10, 9); - wd = HT1632.getTextWidth(disp, FONT_8X4_END); + wd = HT1632.getTextWidth(disp, FONT_8X4_END, FONT_8X4_HEIGHT); } void loop () { diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index 50efcdd..f006d43 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -44,3 +44,11 @@ byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111 byte IMG_HEART [] = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, 0b11111110, 0b11111100, 0b11111000, 0b01110000}; #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 + +// +// Things: +// + +byte IMG_SAILBOAT [] = {0b00000010, 0b00100011, 0b01100011, 0b11111111, 0b01111011, 0b00111011, 0b00011011, 0b00001010}; +#define IMG_SAILBOAT_WIDTH 8 +#define IMG_SAILBOAT_HEIGHT 8 From ec2ecf923a23cfe7f63cde993974ac7b0827cf6a Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 23:13:50 +0800 Subject: [PATCH 18/45] README update. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index becb2a9..c1aaad0 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ It's use should be self-evident. You can find it in `Utilities/image_drawing.htm Font Creation ------------- -Fonts are defined as a series of images of equal height and variable width. (__Note:__ currently, fonts are limited to at most one byte per column. We'll fix this soon.) The bytes making up each character, from ASCII char 32 (space) onwards, are appended together without any byte alignment. +Fonts are defined as a series of images of equal height and variable width. (__Note:__ Currently, fonts are only tested to at most one byte per column.) The bytes making up each character, from ASCII char 32 (space) onwards, are appended together without any byte alignment. An array, `FONT_8X4_END`, encodes information necessary to extract the width and the offset of the character from the font array. The element at position `i` encodes the first index of character `i + 1`. @@ -217,5 +217,5 @@ Future Plans 1. Support for direct pixel access and primitive drawing. 2. Support for advanced transitions (moving entire screen contents around with a single command). -3. Support for fonts taller than 8px. +3. Test support for fonts taller than 8px. 4. Allow `FONT_8X4_END` arrays to be either 2-byte `int`s or 1-byte `uint8_t`s From 6b7ebe0ab509ea18297d8628d755bd084e3b6c23 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Mon, 28 Jul 2014 23:31:38 +0800 Subject: [PATCH 19/45] Minor documentation changes. --- UPGRADE.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 8baa44e..b9116c0 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -10,6 +10,8 @@ Because: - Bugfixes, notably the ability to copy images of any arbitrary size. - Compiled code size. +For example, the 8x4 font has been compressed from 640 bytes to 237 bytes! + How to upgrade -------------- @@ -19,8 +21,7 @@ __Code__ 1. You need to include `HT1632.h` before `images.h` or any font file. 2. The newer functions require the images/fonts to be updated. 3. All calls to `HT1632.drawText` need to have the `font_glyph_step` argument removed. -4. All calls to `HT1632.getTextWidth` need to have the `font_height` argument removed. -5. All references to `FONT_NAME_WIDTH` need to be changed to `FONT_NAME_END`. +4. All references to `FONT_NAME_WIDTH` need to be changed to `FONT_NAME_END`. __Images__ From c03ada3ec91d71531e1fad6b2b998ee82d808d20 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Tue, 29 Jul 2014 12:49:54 +0800 Subject: [PATCH 20/45] Added PROGMEM support. --- Arduino/HT1632/HT1632.cpp | 10 +++++----- Arduino/HT1632/HT1632.h | 1 + Arduino/HT1632/font_5x4.h | 2 +- Arduino/HT1632/font_8x4.h | 2 +- Arduino/HT1632/images.h | 18 +++++++++--------- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 66a0d62..916acfc 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -1,5 +1,9 @@ #include "HT1632.h" +#if PIXELS_PER_BYTE != 8 + #error "The current drawImage, drawText and getTextWidth implementation requires PIXELS_PER_BYTE == 8" +#endif + /* * HIGH LEVEL FUNCTIONS * Functions that perform advanced tasks using lower-level @@ -192,10 +196,6 @@ void HT1632Class::drawTarget(uint8_t targetBuffer) { _tgtBuffer = targetBuffer; } -#if PIXELS_PER_BYTE != 8 - #error "The current drawImage implementation requires PIXELS_PER_BYTE == 8" -#endif - void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { // Assuming that we are using 8 PIXELS_PER_BYTE, this does the equivalent of Math.ceil(height/PIXELS_PER_BYTE): uint8_t bytesPerColumn = (height >> 3) + ((height & 0b111)?1:0); @@ -252,7 +252,7 @@ void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, dst_copyMask <<= (8 - (dst_y & 0b111) - copyInNextStep); // Shift the data to the bits of highest significance - uint8_t copyData = img[img_offset + (bytesPerColumn * src_x) + (src_y >> 3)] << (src_y & 0b111); + uint8_t copyData = pgm_read_byte(&img[img_offset + (bytesPerColumn * src_x) + (src_y >> 3)]) << (src_y & 0b111); // Shift data to match the destination place value. copyData >>= (dst_y & 0b111); diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 4fefeec..979b23b 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -12,6 +12,7 @@ #define HT1632_h #include +#include // Custom typedefs typedef unsigned char uint8_t; diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index 97ebac9..9f2a4be 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -12,7 +12,7 @@ #define FONT_5X4_HEIGHT 5 // Number of bytes per glyph -byte FONT_5X4 [] = { +prog_uchar FONT_5X4 [] PROGMEM = { 0b00000000, // 0b11101000, // ! 0b11000000, 0b00000000, 0b11000000, // " diff --git a/Arduino/HT1632/font_8x4.h b/Arduino/HT1632/font_8x4.h index f376b63..271d710 100644 --- a/Arduino/HT1632/font_8x4.h +++ b/Arduino/HT1632/font_8x4.h @@ -11,7 +11,7 @@ #define FONT_8X4_HEIGHT 8 -byte FONT_8X4 [] = { +prog_uchar FONT_8X4 [] PROGMEM = { 0b00000000, // SPACE 0b01110000, 0b11111101, 0b01110000, // ! 0b11000000, 0b00000000, 0b11000000, // " diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index f006d43..60696bd 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -8,15 +8,15 @@ // Online Services: // -byte IMG_MAIL [] = {0b11111111, 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10000101, 0b10000101, 0b10001001}; +prog_uchar IMG_MAIL [] PROGMEM = {0b11111111, 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10000101, 0b10000101, 0b10001001}; #define IMG_MAIL_WIDTH 8 #define IMG_MAIL_HEIGHT 8 -byte IMG_FB [] = {0b00111111, 0b01000000, 0b10000100, 0b10011111, 0b10100100, 0b10100000, 0b10000000, 0b10000000}; +prog_uchar IMG_FB [] PROGMEM = {0b00111111, 0b01000000, 0b10000100, 0b10011111, 0b10100100, 0b10100000, 0b10000000, 0b10000000}; #define IMG_FB_WIDTH 8 #define IMG_FB_HEIGHT 8 -byte IMG_TWITTER [] = {0b01111110, 0b10000001, 0b10111001, 0b10010101, 0b10010101, 0b10000001, 0b01111110}; +prog_uchar IMG_TWITTER [] PROGMEM = {0b01111110, 0b10000001, 0b10111001, 0b10010101, 0b10010101, 0b10000001, 0b01111110}; #define IMG_TWITTER_WIDTH 7 #define IMG_TWITTER_HEIGHT 8 @@ -24,16 +24,16 @@ byte IMG_TWITTER [] = {0b01111110, 0b10000001, 0b10111001, 0b10010101, 0b1001010 // Music: // -byte IMG_MUSIC [] = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100}; +prog_uchar IMG_MUSIC [] PROGMEM = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100}; #define IMG_MUSIC_WIDTH 8 #define IMG_MUSIC_HEIGHT 8 -byte IMG_MUSICNOTE [] = {0b00000100, 0b00001110, 0b11111100, 0b01000000}; +prog_uchar IMG_MUSICNOTE [] PROGMEM = {0b00000100, 0b00001110, 0b11111100, 0b01000000}; #define IMG_MUSICNOTE_WIDTH 4 #define IMG_MUSICNOTE_HEIGHT 7 -byte IMG_SPEAKER_A [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; -byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; +prog_uchar IMG_SPEAKER_A [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; +prog_uchar IMG_SPEAKER_B [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; #define IMG_SPEAKER_WIDTH 6 #define IMG_SPEAKER_HEIGHT 8 @@ -41,7 +41,7 @@ byte IMG_SPEAKER_B [] = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111 // Emotions: // -byte IMG_HEART [] = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, 0b11111110, 0b11111100, 0b11111000, 0b01110000}; +prog_uchar IMG_HEART [] PROGMEM = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, 0b11111110, 0b11111100, 0b11111000, 0b01110000}; #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 @@ -49,6 +49,6 @@ byte IMG_HEART [] = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, // Things: // -byte IMG_SAILBOAT [] = {0b00000010, 0b00100011, 0b01100011, 0b11111111, 0b01111011, 0b00111011, 0b00011011, 0b00001010}; +prog_uchar IMG_SAILBOAT [] PROGMEM = {0b00000010, 0b00100011, 0b01100011, 0b11111111, 0b01111011, 0b00111011, 0b00011011, 0b00001010}; #define IMG_SAILBOAT_WIDTH 8 #define IMG_SAILBOAT_HEIGHT 8 From 5d916edd17c422aa7d96c718de4df0a1818d89f7 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Tue, 29 Jul 2014 12:54:28 +0800 Subject: [PATCH 21/45] Changed tool to use PROGMEM as well. --- Utilities/font_conv.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities/font_conv.html b/Utilities/font_conv.html index 99efeeb..c99e74f 100644 --- a/Utilities/font_conv.html +++ b/Utilities/font_conv.html @@ -22,7 +22,7 @@ var src = FONT_CODE.split(",").map(function (x){return trim(x).replace("0b", "")}); // $('binary_out').value = src.join("+"); - var rv = "byte FONT_NAME [] = {"; + var rv = "prog_uchar FONT_NAME [] PROGMEM = {"; for(var i = 0; i < 64; ++i){ sb = i * FONT_CODE_STEP; rv += "\n\t"; From 63070f9a3d6c4deec0903cd0b743404d7b529c20 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Tue, 29 Jul 2014 13:19:33 +0800 Subject: [PATCH 22/45] Fixed comments describing the standard command list. --- Arduino/HT1632/HT1632.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 979b23b..2fd43fa 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -90,7 +90,6 @@ typedef unsigned char byte; #define HT1632_ID_WR 0b101 /* ID = 101 - Write RAM */ #define HT1632_ID_LEN 3 /* IDs are 3 bits */ -// Do note that SYSON has been changed to SYSEN #define HT1632_CMD_SYSDIS 0x00 /* CMD= 0000-0000-x Turn off oscil */ #define HT1632_CMD_SYSEN 0x01 /* CMD= 0000-0001-x Enable system oscil */ #define HT1632_CMD_LEDOFF 0x02 /* CMD= 0000-0010-x LED duty cycle gen off */ @@ -98,8 +97,8 @@ typedef unsigned char byte; #define HT1632_CMD_BLOFF 0x08 /* CMD= 0000-1000-x Blink ON */ #define HT1632_CMD_BLON 0x09 /* CMD= 0000-1001-x Blink Off */ #define HT1632_CMD_SLVMD 0x10 /* CMD= 0001-00xx-x Slave Mode */ -#define HT1632_CMD_MSTMD 0x14 /* CMD= 0001-01xx-x Master Mode */ -#define HT1632_CMD_RCCLK 0x18 /* CMD= 0001-10xx-x Use on-chip clock */ +#define HT1632_CMD_MSTMD 0x14 /* CMD= 0001-01xx-x Master Mode, on-chip clock */ +#define HT1632_CMD_RCCLK 0x18 /* CMD= 0001-10xx-x Master Mode, external clock */ #define HT1632_CMD_EXTCLK 0x1C /* CMD= 0001-11xx-x Use external clock */ #define HT1632_CMD_COMS00 0x20 /* CMD= 0010-ABxx-x commons options */ #define HT1632_CMD_COMS01 0x24 /* CMD= 0010-ABxx-x commons options */ From 6f32b8a7110f6b7252abea9e94ef43fb946ab182 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 00:51:37 +0800 Subject: [PATCH 23/45] Updated examples --- .../HT1632_Animation/HT1632_Animation.ino | 34 +++++++++++++++++ .../examples/HT1632_Buffer/HT1632_Buffer.ino | 38 ------------------- .../HT1632_Text_8X4_Multidisplay.ino | 30 +++++++++++++++ 3 files changed, 64 insertions(+), 38 deletions(-) create mode 100644 Arduino/HT1632/examples/HT1632_Animation/HT1632_Animation.ino delete mode 100644 Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino create mode 100644 Arduino/HT1632/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino diff --git a/Arduino/HT1632/examples/HT1632_Animation/HT1632_Animation.ino b/Arduino/HT1632/examples/HT1632_Animation/HT1632_Animation.ino new file mode 100644 index 0000000..bc6218f --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Animation/HT1632_Animation.ino @@ -0,0 +1,34 @@ +#include +#include +#include + +int i = 0; + +void setup () { + HT1632.begin(12, 10, 9); +} + +void loop () { + // Clear the previous image contents: + HT1632.clear(); + + // Draw a different image based on the frame number: + if(i++ % 2 == 0) { + HT1632.drawImage(IMG_SPEAKER_A, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 0); + HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 1); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 1); + } else { + HT1632.drawImage(IMG_SPEAKER_B, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 1); + HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 0); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 1); + HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 0); + } + + // Perform the drawing: + HT1632.render(); + + delay(200); +} diff --git a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino b/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino deleted file mode 100644 index 6add1b1..0000000 --- a/Arduino/HT1632/examples/HT1632_Buffer/HT1632_Buffer.ino +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -int i = 0; -int wd; - -void setup () { - HT1632.begin(12, 10, 9); - - // Buffer swap transition example. - // Fill board buffer with one image - HT1632.drawTarget(BUFFER_BOARD(1)); - HT1632.drawImage(IMG_SPEAKER_A, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 0); - HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 1); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 1); - - // Fill secondary buffer with another image - HT1632.drawTarget(BUFFER_SECONDARY); - HT1632.drawImage(IMG_SPEAKER_B, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 1); - HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 1); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 0); - - HT1632.drawTarget(BUFFER_BOARD(1)); - - HT1632.render(); -} - -void loop () { - HT1632.transition(TRANSITION_BUFFER_SWAP); - HT1632.render(); - - delay(200); -} diff --git a/Arduino/HT1632/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino b/Arduino/HT1632/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino new file mode 100644 index 0000000..b43e071 --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino @@ -0,0 +1,30 @@ +#include +#include +#include + +int i = 0; +int wd; +char disp [] = "Hello, how are you?"; + +void setup () { + HT1632.begin(12, 13, 10, 9); + + wd = HT1632.getTextWidth(disp, FONT_8X4_END, FONT_8X4_HEIGHT); +} + +void loop () { + + HT1632.renderTarget(0); + HT1632.clear(); + HT1632.drawText(disp, OUT_SIZE * 2 - i, 0, FONT_8X4, FONT_8X4_END, FONT_8X4_HEIGHT); + HT1632.render(); + + HT1632.renderTarget(1); + HT1632.clear(); + HT1632.drawText(disp, OUT_SIZE - i, 0, FONT_8X4, FONT_8X4_END, FONT_8X4_HEIGHT); + HT1632.render(); + + i = (i+1)%(wd + OUT_SIZE * 2); + + delay(100); +} From aaaef6cf98e17c0a7213aadf48b06266cbb4a620 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 00:56:50 +0800 Subject: [PATCH 24/45] Updated documentation. --- README.md | 96 +++--------------------------------------------------- UPGRADE.md | 17 ++++++++++ 2 files changed, 21 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index c1aaad0..bc3e3c9 100644 --- a/README.md +++ b/README.md @@ -112,96 +112,9 @@ Multiple HT1632s This library supports up to 4 chips at a time (though technically more can be run concurrently). To take advantage of this, specify multiple CS pins in the initialization. -All drawing occurs on the first display by default. The `drawTarget(BUFFER_BOARD(x))` function allows you to choose to write output to the board selected by `pinCSx`. The example below shows how scrolling text can be implemented using this: +All rendering occurs on the first display by default. A scrolling text example is available in `HT1632/examples/HT1632_Text_8X4_Multidisplay/`. -```c -#include -#include - -int wd; -int i = 0; - -void setup () { - HT1632.begin(pinCS1, pinCS2, pinWR, pinDATA); - wd = HT1632.getTextWidth("Hello, how are you?", FONT_5X4_WIDTH, FONT_5X4_HEIGHT); -} - -void loop () { - // Select board 1 as the target of subsequent drawing/rendering operations. - HT1632.drawTarget(BUFFER_BOARD(1)); - HT1632.clear(); - - HT1632.drawText("Hello, how are you?", 2*OUT_SIZE - i, 2, - FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH); - - HT1632.render(); // Board 1's contents is updated. - - // Select board 2 as the target of subsequent drawing/rendering operations. - HT1632.drawTarget(BUFFER_BOARD(2)); - HT1632.clear(); - - HT1632.drawText("Hello, how are you?", OUT_SIZE - i, 2, - FONT_5X4, FONT_5X4_WIDTH, FONT_5X4_HEIGHT, FONT_5X4_STEP_GLYPH); - - HT1632.render(); // Board 2's contents is updated. - - i = (i+1)%(wd + OUT_SIZE * 2); // Make it repeating. -} -``` - -Secondary Buffer ----------------- - -In addition to one buffer for each board, one additional buffer (the secondary buffer) is provided. It acts like a drawing target in every way, except that it cannot be rendered. `drawTarget(BUFFER_SECONDARY)` function call allows you to select this buffer. - -*This buffer is currently of limited use. Future expansions plan to use this for transitions.* - -Here's an example showing this buffer being used to render a two-frame animation much more efficiently than redrawing each frame from scratch: - - -```c -#include -#include - -void setup () { - HT1632.begin(pinCS1, pinWR, pinDATA); - - // Draw one image on the board buffer. - HT1632.drawTarget(BUFFER_BOARD(1)); // This line is unnecessary, this is the default draw target. - HT1632.drawImage(IMG_SPEAKER_A, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 0); - HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 1); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 1); - - // Draw another image on the secondary buffer. - HT1632.drawTarget(BUFFER_SECONDARY); - HT1632.drawImage(IMG_SPEAKER_B, IMG_SPEAKER_WIDTH, IMG_SPEAKER_HEIGHT, 0, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 8, 1); - HT1632.drawImage(IMG_MUSIC, IMG_MUSIC_WIDTH, IMG_MUSIC_HEIGHT, 13, 0); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 23, 1); - HT1632.drawImage(IMG_MUSICNOTE, IMG_MUSICNOTE_WIDTH, IMG_MUSICNOTE_HEIGHT, 28, 0); - - HT1632.drawTarget(BUFFER_BOARD(1)); - HT1632.render(); // Render the initial image. -} - -void loop () { - delay(500); - - HT1632.transition(TRANSITION_BUFFER_SWAP); - HT1632.render(); -} -``` -Notice that all the drawing is done in the setup() function? The loop function just shuffles the data around in memory. - -Note: Only three transitions are currently available. - -Transition | Description ------------|------------ -`TRANSITION_BUFFER_SWAP` | Swap the current buffer and the transition buffer. This is the only transition that preserves the contents of the current buffer. -`TRANSITION_NONE` | Simply copy the buffer. -`TRANSITION_FADE` | Uses the PWM feature to fade through black. Does not preserve current brightness level. +Do note that all drawing happens to a single buffer. You need to `clear()` the contents of the buffer if drawing different graphics to different screens. To draw the same image to multiple screens, call `renderTarget()` and `render()` once per target. Bugs & Features @@ -216,6 +129,5 @@ Future Plans ------------ 1. Support for direct pixel access and primitive drawing. -2. Support for advanced transitions (moving entire screen contents around with a single command). -3. Test support for fonts taller than 8px. -4. Allow `FONT_8X4_END` arrays to be either 2-byte `int`s or 1-byte `uint8_t`s +2. Test support for fonts taller than 8px. +3. Allow `FONT_8X4_END` arrays to be either 2-byte `int`s or 1-byte `uint8_t`s diff --git a/UPGRADE.md b/UPGRADE.md index b9116c0..f699127 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -16,6 +16,23 @@ For example, the 8x4 font has been compressed from 640 bytes to 237 bytes! How to upgrade -------------- +__Structure__ + +A single buffer is used for all write operations. This means that the following functions, macros and constants have been removed: + +```c +void HT1632.transition(uint8_t mode, int time = 1000); // Removed + +void HT1632.drawTarget(uint8_t targetBuffer); // Replaced by: +void HT1632.renderTarget(uint8_t targetBuffer); + +BUFFER_BOARD(n) // Just use: +(n - 1) // Board number of pin to use. + +SECONDARY_BUFFER // Removed +``` + + __Code__ 1. You need to include `HT1632.h` before `images.h` or any font file. From 6d3743f225124f6e0b766d7db5b270b051ab9114 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 01:19:06 +0800 Subject: [PATCH 25/45] Updated library, with a single render target and channel support. --- Arduino/HT1632/HT1632.cpp | 100 +++++++++++++++----------------------- Arduino/HT1632/HT1632.h | 55 ++++++--------------- 2 files changed, 54 insertions(+), 101 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 916acfc..c956231 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -133,12 +133,8 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { _pinWR = pinWR; _pinDATA = pinDATA; - for(uint8_t i=0; i<_numActivePins; ++i){ + for (uint8_t i = 0; i < _numActivePins; ++i){ pinMode(_pinCS[i], OUTPUT); - // Allocate new memory for mem - mem[i] = (byte *)malloc(ADDR_SPACE_SIZE); - drawTarget(i); - clear(); // Clean out mem } pinMode(_pinWR, OUTPUT); @@ -146,8 +142,11 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { select(); - mem[4] = (byte *)malloc(ADDR_SPACE_SIZE); - drawTarget(4); + for (uint8_t i = 0; i < NUM_CHANNEL; ++i) { + // Allocate new memory for each channel + mem[i] = (byte *)malloc(ADDR_SPACE_SIZE); + } + // Clear all memory clear(); // Send configuration to chip: @@ -191,9 +190,16 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { drawTarget(0); } -void HT1632Class::drawTarget(uint8_t targetBuffer) { - if(targetBuffer == 0x04 || (targetBuffer >= 0 && targetBuffer < _numActivePins)) - _tgtBuffer = targetBuffer; +void HT1632Class::selectChannel(uint8_t channel) { + if(channel < NUM_CHANNEL) { + _tgtChannel = channel; + } +} + +void HT1632Class::renderTarget(uint8_t target) { + if(target < _numActivePins) { + _tgtRender = channel; + } } void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { @@ -257,8 +263,8 @@ void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, copyData >>= (dst_y & 0b111); // Perform the copy - mem[_tgtBuffer][GET_ADDR_FROM_X_Y(dst_x, dst_y)] = // Put in destination - (mem[_tgtBuffer][GET_ADDR_FROM_X_Y(dst_x, dst_y)] & ~dst_copyMask) | // All bits not in the mask from destination + mem[_tgtChannel][GET_ADDR_FROM_X_Y(dst_x, dst_y)] = // Put in destination + (mem[_tgtChannel][GET_ADDR_FROM_X_Y(dst_x, dst_y)] & ~dst_copyMask) | // All bits not in the mask from destination (copyData & dst_copyMask); // All bits in the mask from source src_y += copyInNextStep; @@ -271,25 +277,31 @@ void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, } void HT1632Class::clear(){ - for(char i=0; i < ADDR_SPACE_SIZE; ++i) - mem[_tgtBuffer][i] = 0x00; // Needs to be redrawn + for(uint8_t c = 0; c < NUM_CHANNEL; ++c) { + for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { + mem[c][i] = 0x00; // Needs to be redrawn + } + } } -// Draw the contents of map to screen, for memory addresses that have the needsRedrawing flag +// Draw the contents of mem void HT1632Class::render() { - if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) { + if(_tgtRender >= _numActivePins) { return; } - select(0b0001 << _tgtBuffer); // Selecting the chip + select(0b0001 << _tgtRender); // Selecting the chip writeData(HT1632_ID_WR, HT1632_ID_LEN); writeData(0, HT1632_ADDR_LEN); // Selecting the memory address - for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { - // Write the higher bits before the the lower bits. - writeData(mem[_tgtBuffer][i] >> HT1632_WORD_LEN, HT1632_WORD_LEN); // Write the data in reverse. - writeData(mem[_tgtBuffer][i], HT1632_WORD_LEN); // Write the data in reverse. + // Write the channels in order + for(uint8_t c = 0; c < NUM_CHANNEL; ++c) { + for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { + // Write the higher bits before the the lower bits. + writeData(mem[c][i] >> HT1632_WORD_LEN, HT1632_WORD_LEN); // Write the data in reverse. + writeData(mem[c][i], HT1632_WORD_LEN); // Write the data in reverse. + } } select(); // Close the stream at the end @@ -299,10 +311,11 @@ void HT1632Class::render() { // Uses the PWM feature to set the brightness. void HT1632Class::setBrightness(char brightness, char selectionmask) { if(selectionmask == 0b00010000) { - if(_tgtBuffer < _numActivePins) - selectionmask = 0b0001 << _tgtBuffer; - else - return; + if(_tgtRender < _numActivePins) { + selectionmask = 0b0001 << _tgtRender; + } else { + return; + } } select(selectionmask); @@ -311,43 +324,6 @@ void HT1632Class::setBrightness(char brightness, char selectionmask) { select(); } -void HT1632Class::transition(uint8_t mode, int time){ - if(_tgtBuffer >= _numActivePins || _tgtBuffer < 0) - return; - - switch(mode) { - case TRANSITION_BUFFER_SWAP: - { - byte * tmp = mem[_tgtBuffer]; - mem[_tgtBuffer] = mem[BUFFER_SECONDARY]; - mem[BUFFER_SECONDARY] = tmp; - } - break; - case TRANSITION_NONE: - for(char i=0; i < ADDR_SPACE_SIZE; ++i) - mem[_tgtBuffer][i] = mem[BUFFER_SECONDARY][i]; // Needs to be redrawn - break; - case TRANSITION_FADE: - time /= 32; - for(int i = 15; i > 0; --i) { - setBrightness(i); - delay(time); - } - clear(); - render(); - delay(time); - transition(TRANSITION_BUFFER_SWAP); - render(); - delay(time); - for(int i = 2; i <= 16; ++i) { - setBrightness(i); - delay(time); - } - break; - } - -} - /* * LOWER LEVEL FUNCTIONS diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 2fd43fa..093397e 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -30,53 +30,28 @@ typedef unsigned char byte; #define OUT_SIZE 32 // COM_SIZE MUST be either 8 or 16. -// Pixels in a single byte of the internal image representation: -#define PIXELS_PER_BYTE 8 - -// Target buffer -// Each board has a "render" buffer, and all boards share one "secondary" buffer. All calls to -// render() draw the contents of the render buffer of the currently selected board to the board -// itself. All calls to any drawing function (including clear()) only affect the selected buffer -// of the selected board. you can move the contents of the secondary buffer to the render -// buffer by calling transition(), with an appropriate transition. See transition() for more details. -// board_num = [1..4] -#define BUFFER_BOARD(board_num) ((board_num)-1) -#define BUFFER_SECONDARY 0x04 - -// Transition Modes -// Transitions copies the contents of the "secondary" buffer to the currently selected board buffer. -// Pass one of these transition types to the transition() function and the contents of the -// "secondary" buffer will be moved to that using some animation. transition() is a blocking function. -// In all transitions other than the first one, the contents of the board buffer is lost and render() -// is automatically called. -#define TRANSITION_BUFFER_SWAP 0x00 - // Swap the current buffer and the transition buffer. This is the only transition that preserves - // the contents of the current buffer. -#define TRANSITION_NONE 0x01 - // Simply copy the buffer. -#define TRANSITION_FADE 0x02 - // Uses the PWM feature to fade through black. Does not preserve current brightness level. -#define TRANSITION_WIPE_FROM_RIGHT 0x03 -// Wrap settings -// For advanced rendering (currently only text rendering) - -// Address space size (number of 4-bit words in HT1632 memory) -// Exactly equal to the number of 4-bit address spaces available. -#define ADDR_SPACE_SIZE (COM_SIZE * OUT_SIZE / PIXELS_PER_BYTE) +// Number of color channels. The default is a single color channel. +#define NUM_CHANNEL 1 // Use N-MOS (if 1) or P-MOS (if 0): #define USE_NMOS 1 // There are known issues with this. If the default doesn't work, // try changing the value. -// NOTE: THIS HARDCODES THE DIMENSIONS OF THE 3208! CHANGE! -#define GET_ADDR_FROM_X_Y(_x,_y) ((_x)*((COM_SIZE)/(PIXELS_PER_BYTE))+(_y)/(PIXELS_PER_BYTE)) - /* * END USER OPTIONS * Don't edit anything below unless you know what you are doing! */ - + + + // Pixels in a single byte of the internal image representation: +#define PIXELS_PER_BYTE 8 + +// Address space size (number of 4-bit words in HT1632 memory) +// Exactly equal to the number of 4-bit address spaces available. +#define ADDR_SPACE_SIZE (COM_SIZE * OUT_SIZE / PIXELS_PER_BYTE) +#define GET_ADDR_FROM_X_Y(_x,_y) ((_x)*((COM_SIZE)/(PIXELS_PER_BYTE))+(_y)/(PIXELS_PER_BYTE)) + // NO-OP Definition #define NOP(); __asm__("nop\n\t"); // The HT1632 requires at least 50 ns between the change in data and the rising @@ -118,7 +93,8 @@ class HT1632Class uint8_t _numActivePins; uint8_t _pinWR; uint8_t _pinDATA; - uint8_t _tgtBuffer; + uint8_t _tgtRender; + uint8_t _tgtChannel; byte * mem [5]; void writeCommand(char); void writeData(byte, uint8_t); @@ -136,7 +112,8 @@ class HT1632Class void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinWR, uint8_t pinDATA); void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinCS4, uint8_t pinWR, uint8_t pinDATA); void sendCommand(uint8_t command); - void drawTarget(uint8_t targetBuffer); + void renderTarget(uint8_t targetScreen); + void selectChannel(uint8_t channel); void render(); void transition(uint8_t mode, int time = 1000); // Time is in milliseconds. void clear(); From 972a27fb44ad4120e61b931cedcc54c939d014e6 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 01:35:39 +0800 Subject: [PATCH 26/45] Added defaults for different boards. --- Arduino/HT1632/HT1632.h | 56 ++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 093397e..05c1b47 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -25,18 +25,50 @@ typedef unsigned char byte; * Change these options */ -// Size of COM and OUT in bits: -#define COM_SIZE 8 -#define OUT_SIZE 32 -// COM_SIZE MUST be either 8 or 16. - -// Number of color channels. The default is a single color channel. -#define NUM_CHANNEL 1 - -// Use N-MOS (if 1) or P-MOS (if 0): -#define USE_NMOS 1 -// There are known issues with this. If the default doesn't work, -// try changing the value. +// Uncomment the line that matches the board you have, or edit the +// settings in the else block: + +// SureElectronics 32X16 Bicolor LED Dot Matrix Unit Board +// #define TYPE_3216_BICOLOR 1 + +// SureElectronics 32X08 Monochrome LED Dot Matrix Unit Board +#define TYPE_3208_MONO 1 + +// SureElectronics 16X08 Bicolor (emulation) +// #define TYPE_1608_DEBUG 1 + +#if defined TYPE_3216_BICOLOR + #define COM_SIZE 16 + #define OUT_SIZE 32 + #define NUM_CHANNEL 2 + #define USE_NMOS 1 +#elif defined TYPE_3208_MONO + #define COM_SIZE 8 + #define OUT_SIZE 32 + #define NUM_CHANNEL 1 + #define USE_NMOS 1 +#elif defined TYPE_1608_DEBUG + #define COM_SIZE 8 + #define OUT_SIZE 16 + #define NUM_CHANNEL 2 + #define USE_NMOS 1 +#else + // SET YOUR CUSTOM VALUES HERE, AND COMMENT THE NEXT LINE + #error "Pick a board type!" + + // Size of COM and OUT in bits: + #define COM_SIZE 8 + #define OUT_SIZE 32 + // COM_SIZE MUST be either 8 or 16. + + // Number of color channels. The default is a single color channel. + #define NUM_CHANNEL 1 + + // Use N-MOS (if 1) or P-MOS (if 0): + #define USE_NMOS 1 + // There are known issues with this. If the default doesn't work, + // try changing the value. +#endif /* * END USER OPTIONS From 774042dccc7aa59087df76c9d24e9fa91ad52621 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 01:59:12 +0800 Subject: [PATCH 27/45] Added examples. --- .../examples/HT1632_Heart/HT1632_Heart.ino | 1 - .../HT1632_Heart_Bicolor.ino | 38 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino diff --git a/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino b/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino index f289fc1..1e8f052 100644 --- a/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino +++ b/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino @@ -3,7 +3,6 @@ #include int i = 0; -int wd; void setup () { HT1632.begin(12, 10, 9); diff --git a/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino b/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino new file mode 100644 index 0000000..8138961 --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino @@ -0,0 +1,38 @@ +#include +#include +#include + +int i = 0; + +void setup () { + // Working with Bicolor displays. + // Make sure that a bicolor display is set in HT1632.h + HT1632.begin(12, 10, 9); +} + +void loop () { + // Draws a heart that changes color every second: + // This is a 4-frame animation, with frame number i in range [0..3] + + // Zero all data in all channels: + HT1632.clear(); + + if (i & 0b01) { // On frames 1 and 3: + HT1632.selectChannel(0); // Select the first channel + // Draw a heart: + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0); + } + + if (i & 0b10) { // On frames 2 and 3: + HT1632.selectChannel(1); // Select the second channel + // Draw a heart: + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0); + } + + HT1632.render(); // This sends the data in both channels to the screen. + + // Get the next number in the sequence, wrapping from 3 back to 0: + i = (i + 1) & 0b11; + + delay(1000); +} From 0b3067ba8f1afd482a2490bc7158d2948fb4c699 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 02:01:01 +0800 Subject: [PATCH 28/45] Minor error fixes. --- Arduino/HT1632/HT1632.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index c956231..c1bc917 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -180,14 +180,13 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { select(); + // Clear all screens by default: for(uint8_t i = 0; i < _numActivePins; ++i) { - drawTarget(i); - clear(); - // Perform the initial rendering + renderTarget(i); render(); } - // Set drawTarget to default board. - drawTarget(0); + // Set renderTarget to the first board. + renderTarget(0); } void HT1632Class::selectChannel(uint8_t channel) { @@ -198,7 +197,7 @@ void HT1632Class::selectChannel(uint8_t channel) { void HT1632Class::renderTarget(uint8_t target) { if(target < _numActivePins) { - _tgtRender = channel; + _tgtRender = target; } } From c52d597ad0702989b623ed36902582387861576c Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 02:01:30 +0800 Subject: [PATCH 29/45] Updated Syntax Highlighting instructions. --- Arduino/HT1632/keywords.txt | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Arduino/HT1632/keywords.txt b/Arduino/HT1632/keywords.txt index 87cc814..b56aefe 100644 --- a/Arduino/HT1632/keywords.txt +++ b/Arduino/HT1632/keywords.txt @@ -6,20 +6,21 @@ # Datatypes (KEYWORD1) ####################################### -HT1632 KEYWORD1 +HT1632 KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -begin KEYWORD2 -sendCommand KEYWORD2 -drawTarget KEYWORD2 -render KEYWORD2 -transition KEYWORD2 -clear KEYWORD2 -drawImage KEYWORD2 -drawText KEYWORD2 +begin KEYWORD2 +sendCommand KEYWORD2 +renderTarget KEYWORD2 +selectChannel KEYWORD2 +render KEYWORD2 +transition KEYWORD2 +clear KEYWORD2 +drawImage KEYWORD2 +drawText KEYWORD2 getTextWidth KEYWORD2 setBrightness KEYWORD2 @@ -27,8 +28,5 @@ setBrightness KEYWORD2 # Constants (LITERAL1) ####################################### -TRANSITION_BUFFER_SWAP LITERAL1 -TRANSITION_NONE LITERAL1 -TRANSITION_FADE LITERAL1 -BUFFER_BOARD LITERAL1 -BUFFER_SECONDARY LITERAL1 \ No newline at end of file +COM_SIZE LITERAL1 +OUT_SIZE LITERAL1 \ No newline at end of file From e9fc20954c9aa08a4a54ff3d85dfc98d6e137cf7 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sat, 2 Aug 2014 02:01:42 +0800 Subject: [PATCH 30/45] Updated documentation. --- README.md | 25 +++++++++++++------------ UPGRADE.md | 3 ++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index bc3e3c9..aa00dd3 100644 --- a/README.md +++ b/README.md @@ -42,19 +42,8 @@ void loop () { } ``` -Before running the code, go to HT1632.h and change the following definitions, if needed. This needs to be done only __once__. +Before running the code, go to HT1632.h and check the `USER OPTIONS` section and follow the instructions to specify the type of board you are using. -```c -// Size of COM and OUT in bits: -#define COM_SIZE 8 -#define OUT_SIZE 32 -// COM_SIZE MUST be either 8 or 16. - -// Use N-MOS (if 1) or P-MOS (if 0): -#define USE_NMOS 1 -``` - -The defaults shown here (and in the code) are suitable for the SureElectronics 3208 series display boards. Explanation ----------- @@ -100,6 +89,16 @@ Advanced Use There are a few examples in `Arduino/HT1632/examples/`. +Bicolor Displays +---------------- + +This library natively supports Bicolor displays, using the `selectChannel(n)` function to switch to color channel `n` before rendering images. Calls to `clear()` and `render()` automatically operate on all channels. + +__NOTE:__ Make sure you have set the board type in `HT1632.h`. If you specify a wrong `NUM_CHANNEL` value, it won't work properly. + +An example is available in `HT1632/examples/HT1632_Heart_Bicolor/`. + + Brightness Control ------------------ @@ -116,6 +115,8 @@ All rendering occurs on the first display by default. A scrolling text example i Do note that all drawing happens to a single buffer. You need to `clear()` the contents of the buffer if drawing different graphics to different screens. To draw the same image to multiple screens, call `renderTarget()` and `render()` once per target. +Multiple HT1632s, each with multiple color channels, are supported natively. + Bugs & Features =============== diff --git a/UPGRADE.md b/UPGRADE.md index f699127..d778ea0 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -18,7 +18,7 @@ How to upgrade __Structure__ -A single buffer is used for all write operations. This means that the following functions, macros and constants have been removed: +A single buffer is used for all compositing operations. The following functions, macros and constants have been removed: ```c void HT1632.transition(uint8_t mode, int time = 1000); // Removed @@ -32,6 +32,7 @@ BUFFER_BOARD(n) // Just use: SECONDARY_BUFFER // Removed ``` +New mechanisms for working with color channels have been added, and are documented in [the README](README.md) __Code__ From 855551cfdeb0f39622f3275991e0160ac852884f Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sun, 7 Sep 2014 13:08:45 -0400 Subject: [PATCH 31/45] Support for one Bicolor board tested and working. --- Arduino/HT1632/HT1632.cpp | 105 +++++++++++++++++++++++++++++++----- Arduino/HT1632/HT1632.h | 12 +++-- Arduino/HT1632/keywords.txt | 1 + 3 files changed, 101 insertions(+), 17 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index c1bc917..ff8bed6 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -161,17 +161,15 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { writeData(HT1632_ID_CMD, HT1632_ID_LEN); // Command mode writeCommand(HT1632_CMD_SYSDIS); // Turn off system oscillator - // N-MOS or P-MOS open drain output and 8 or 16 common option -#if USE_NMOS == 1 && COM_SIZE == 8 + + // Custom initialization from each: +#if defined TYPE_3208_MONO + writeCommand(HT1632_CMD_COMS00); +#elif defined TYPE_3216_BICOLOR writeCommand(HT1632_CMD_COMS00); -#elif USE_NMOS == 1 && COM_SIZE == 16 - writeCommand(HT1632_CMD_COMS01); -#elif USE_NMOS == 0 && COM_SIZE == 8 - writeCommand(HT1632_CMD_COMS10); -#elif USE_NMOS == 0 && COM_SIZE == 16 - writeCommand(HT1632_CMD_COMS11); + writeCommand(HT1632_CMD_RCCLK); // Master Mode, external clock #else -#error Invalid USE_NMOS or COM_SIZE values! Change the values in HT1632.h. + writeCommand(HT1632_CMD_COMS00); #endif writeCommand(HT1632_CMD_SYSEN); //Turn on system @@ -283,6 +281,60 @@ void HT1632Class::clear(){ } } +#if defined TYPE_3216_BICOLOR +// Draw the contents of mem +void HT1632Class::render() { + if(_tgtRender >= _numActivePins) { + return; + } + + // Write chip-by-chip: + uint8_t _pinForCS = _pinCS[_tgtRender]; + + for (uint8_t nChip = 0; nChip < NUM_ACTIVE_CHIPS; ++nChip) { + // Select a single sub-chip: + digitalWrite(_pinForCS, HIGH); + for(uint8_t tmp = 0; tmp < NUM_ACTIVE_CHIPS; tmp++){ + if (tmp == nChip) { + digitalWrite(_pinForCS, LOW); + pulseCLK(); + digitalWrite(_pinForCS, HIGH); + } else { + pulseCLK(); + } + } + + // Output data! + writeData(HT1632_ID_WR, HT1632_ID_LEN); + writeData(0, HT1632_ADDR_LEN); // Selecting the memory address + + // Write the channels in order + for(uint8_t c = 0; c < NUM_CHANNEL; ++c) { + //for(uint8_t i = (nChip & 0b1)?0:(ADDR_SPACE_SIZE >> 1); i < (nChip & 0b1)?(ADDR_SPACE_SIZE >> 1):ADDR_SPACE_SIZE; ++i) { + uint8_t i, iMax; + + if(nChip & 0b1) { // If we're writing to the chips on the left + i = 0; // Start from zero + iMax = ADDR_SPACE_SIZE/2; // Stop at the halfway point. + } else { // If we're writing to the chips on the right + i = ADDR_SPACE_SIZE/2; // Start from the halfway point. + iMax = ADDR_SPACE_SIZE; // Stop at the end of the buffer. + } + + // If we are not (top-row chip) + if(!(nChip & 0b10)) { + ++i; // Write only odd-numbered bytes. + } + + for(; i < iMax; i+=2) { // Write every other byte. + // Write the higher bits before the the lower bits. + writeData(mem[c][i] >> HT1632_WORD_LEN, HT1632_WORD_LEN); + writeData(mem[c][i], HT1632_WORD_LEN); + } + } + } +} +#elif defined TYPE_3208_MONO // Draw the contents of mem void HT1632Class::render() { if(_tgtRender >= _numActivePins) { @@ -305,6 +357,7 @@ void HT1632Class::render() { select(); // Close the stream at the end } +#endif // Set the brightness to an integer level between 1 and 16 (inclusive). // Uses the PWM feature to set the brightness. @@ -360,18 +413,42 @@ void HT1632Class::writeSingleBit() { // Lower it again, in preparation for the next cycle. digitalWrite(_pinWR, LOW); } + +void HT1632Class::setCLK(uint8_t pinCLK) { + _pinCLK = pinCLK; + pinMode(_pinCLK, OUTPUT); + digitalWrite(_pinCLK, LOW); +} + +inline void HT1632Class::pulseCLK() { + digitalWrite(_pinCLK, HIGH); + NOP(); + digitalWrite(_pinCLK, LOW); +} + +#if defined TYPE_3216_BICOLOR +// This is used to send initialization commands, and so selects all chips +// in the selected board. +void HT1632Class::select(uint8_t mask) { + for(uint8_t i=0, t=1; i<_numActivePins; ++i, t <<= 1){ + digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); + } + for (uint8_t tmp = 0; tmp < NUM_ACTIVE_CHIPS; tmp++) { + pulseCLK(); + } +} +#elif defined TYPE_3208_MONO // Choose a chip. This function sets the correct CS line to LOW, and the rest to HIGH // Call the function with no arguments to deselect all chips. // Call the function with a bitmask (0b4321) to select specific chips. 0b1111 selects all. -void HT1632Class::select(char mask) { - for(int i=0, t=1; i<_numActivePins; ++i, t <<= 1){ +void HT1632Class::select(uint8_t mask) { + for(uint8_t i=0, t=1; i<_numActivePins; ++i, t <<= 1){ digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); } } +#endif void HT1632Class::select() { - for(int i=0; i<_numActivePins; ++i) { - digitalWrite(_pinCS[i], HIGH); - } + select(0); } HT1632Class HT1632; diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 05c1b47..ba0092d 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -29,10 +29,10 @@ typedef unsigned char byte; // settings in the else block: // SureElectronics 32X16 Bicolor LED Dot Matrix Unit Board -// #define TYPE_3216_BICOLOR 1 +#define TYPE_3216_BICOLOR 1 // SureElectronics 32X08 Monochrome LED Dot Matrix Unit Board -#define TYPE_3208_MONO 1 +// #define TYPE_3208_MONO 1 // SureElectronics 16X08 Bicolor (emulation) // #define TYPE_1608_DEBUG 1 @@ -42,6 +42,8 @@ typedef unsigned char byte; #define OUT_SIZE 32 #define NUM_CHANNEL 2 #define USE_NMOS 1 + // Number of chips in a single Bicolor board: + #define NUM_ACTIVE_CHIPS 4 #elif defined TYPE_3208_MONO #define COM_SIZE 8 #define OUT_SIZE 32 @@ -125,6 +127,8 @@ class HT1632Class uint8_t _numActivePins; uint8_t _pinWR; uint8_t _pinDATA; + uint8_t _pinCLK; + uint8_t _currSelectionMask; uint8_t _tgtRender; uint8_t _tgtChannel; byte * mem [5]; @@ -134,15 +138,17 @@ class HT1632Class void writeSingleBit(); void initialize(uint8_t, uint8_t); void select(); - void select(char mask); + void select(uint8_t mask); int getCharWidth(int font_end [], uint8_t font_height, uint8_t font_index); int getCharOffset(int font_end [], uint8_t font_index); + inline void pulseCLK(); public: void begin(uint8_t pinCS1, uint8_t pinWR, uint8_t pinDATA); void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinWR, uint8_t pinDATA); void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinWR, uint8_t pinDATA); void begin(uint8_t pinCS1, uint8_t pinCS2, uint8_t pinCS3, uint8_t pinCS4, uint8_t pinWR, uint8_t pinDATA); + void setCLK(uint8_t pinCLK); void sendCommand(uint8_t command); void renderTarget(uint8_t targetScreen); void selectChannel(uint8_t channel); diff --git a/Arduino/HT1632/keywords.txt b/Arduino/HT1632/keywords.txt index b56aefe..9e27279 100644 --- a/Arduino/HT1632/keywords.txt +++ b/Arduino/HT1632/keywords.txt @@ -23,6 +23,7 @@ drawImage KEYWORD2 drawText KEYWORD2 getTextWidth KEYWORD2 setBrightness KEYWORD2 +setCLK KEYWORD2 ####################################### # Constants (LITERAL1) From 91830ceeded66223301f8c14fd4dc29fe432fbdb Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sun, 7 Sep 2014 13:37:48 -0400 Subject: [PATCH 32/45] Documentation update --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aa00dd3..ca4fd65 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,8 @@ HT1632 for Arduino v2.0 __NOTE:__ This new version of the software changes the underlying data format - upgrading is easy and largely automated. See [upgrade instructions](UPGRADE.md). -This is a powerful library that allows an Arduino to interface with the popular __Holtek HT1632C__ LED driver. It allows programmers to directly perform advanced drawing of images and text with minimal code, using a similar "state machine" paradigm to OpenGL. +This is a powerful library that allows an Arduino to interface with the popular __Holtek HT1632C__ LED driver. It allows programmers to directly perform advanced drawing of images and text with minimal code. -Do note that the (now deprecated) __Holtek HT1632__ LED driver is *theoretically* compatible with this library, but requires slightly different initialization. Quick Start =========== @@ -94,10 +93,11 @@ Bicolor Displays This library natively supports Bicolor displays, using the `selectChannel(n)` function to switch to color channel `n` before rendering images. Calls to `clear()` and `render()` automatically operate on all channels. -__NOTE:__ Make sure you have set the board type in `HT1632.h`. If you specify a wrong `NUM_CHANNEL` value, it won't work properly. - An example is available in `HT1632/examples/HT1632_Heart_Bicolor/`. +__NOTE:__ You need to call `HT1632.setCLK(PIN_NUMBER_CLK);` before calling `begin()`, where `PIN_NUMBER_CLK` is the Arduino pin connected to the `CLK` of your Bicolor board. Refer to the example. + +__NOTE:__ Make sure you have set the board type in `HT1632.h`. If you specify a wrong `NUM_CHANNEL` value, it won't work properly. Brightness Control ------------------ @@ -126,6 +126,8 @@ Known Issues 1. Initialization doesn't automatically assign a single HT1632C as the RC Master - some unknown bug prevents this from working. As a result, multiple HT1632Cs only need the power and data pins connected, leaving the OSC and SYNC pins disconnected. +2. A single Arduino cannot support both a Mono-color and a Bi-color display. + Future Plans ------------ From 7fb6f6a706b3abd1d99edb00f32885b8407ea5e5 Mon Sep 17 00:00:00 2001 From: Gaurav Manek Date: Sun, 7 Sep 2014 13:38:53 -0400 Subject: [PATCH 33/45] Added and updated Bicolor examples. --- .../HT1632_Heart_Bicolor.ino | 18 ++++---- .../HT1632_Heart_Multiple_Bicolor.ino | 42 +++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 Arduino/HT1632/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino diff --git a/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino b/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino index 8138961..a14f852 100644 --- a/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino +++ b/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino @@ -3,36 +3,36 @@ #include int i = 0; +int j = 0; void setup () { // Working with Bicolor displays. // Make sure that a bicolor display is set in HT1632.h + HT1632.setCLK(13); HT1632.begin(12, 10, 9); } void loop () { - // Draws a heart that changes color every second: - // This is a 4-frame animation, with frame number i in range [0..3] - // Zero all data in all channels: HT1632.clear(); - if (i & 0b01) { // On frames 1 and 3: + if (~i & 0b01) { // On frames 1 and 3: HT1632.selectChannel(0); // Select the first channel // Draw a heart: - HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0); + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, j - IMG_HEART_WIDTH, 3); } - if (i & 0b10) { // On frames 2 and 3: + if (~i & 0b10) { // On frames 2 and 3: HT1632.selectChannel(1); // Select the second channel // Draw a heart: - HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, (OUT_SIZE - IMG_HEART_WIDTH)/2, 0); + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, j - IMG_HEART_WIDTH, 3); } HT1632.render(); // This sends the data in both channels to the screen. // Get the next number in the sequence, wrapping from 3 back to 0: - i = (i + 1) & 0b11; + i = (i + 1) % 3; + j = (j + 1) % (OUT_SIZE + IMG_HEART_WIDTH * 2); - delay(1000); + delay(150); } diff --git a/Arduino/HT1632/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino b/Arduino/HT1632/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino new file mode 100644 index 0000000..df99119 --- /dev/null +++ b/Arduino/HT1632/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino @@ -0,0 +1,42 @@ +#include +#include +#include + +int j = 0; + +void setup () { + // Working with Bicolor displays. + // Make sure that a bicolor display is set in HT1632.h + HT1632.setCLK(13); + HT1632.begin(12, 6, 10, 9); +} + +void loop () { + // Zero all data in all channels: + HT1632.renderTarget(0); + HT1632.clear(); + + HT1632.selectChannel(0); // Red heart on first screen: + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, j - IMG_HEART_WIDTH, 3); + + HT1632.selectChannel(1); // Green heart on first screen: + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, OUT_SIZE * 2 - j, 3); + + HT1632.render(); // This sends the data in both channels to the screen. + + HT1632.renderTarget(1); + HT1632.clear(); + + HT1632.selectChannel(0); // Red heart on second screen: + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, j - IMG_HEART_WIDTH - OUT_SIZE, 3); + + HT1632.selectChannel(1); // Green heart on second screen: + HT1632.drawImage(IMG_HEART, IMG_HEART_WIDTH, IMG_HEART_HEIGHT, OUT_SIZE - j, 3); + + HT1632.render(); + + // Get the next number in the sequence, wrapping from 3 back to 0: + j = (j + 1) % (OUT_SIZE * 2); + + delay(50); +} From 214f67b8404cb15efef201e8676d532d6d9a4f04 Mon Sep 17 00:00:00 2001 From: Flavio Fernandes Date: Sun, 7 Sep 2014 20:34:53 -0400 Subject: [PATCH 34/45] Fix PGM syntax to comply with latest Arduino IDE (rev 1.5.7) See: http://postwarrior.com/arduino-ethershield-error-prog_char-does-not-name-a-type/ --- Arduino/HT1632/HT1632.cpp | 6 +++--- Arduino/HT1632/HT1632.h | 6 +++--- Arduino/HT1632/font_5x4.h | 2 +- Arduino/HT1632/font_8x4.h | 4 ++-- Arduino/HT1632/images.h | 18 +++++++++--------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index ff8bed6..fbe74b7 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -10,7 +10,7 @@ * functions go here: */ -void HT1632Class::drawText(char text [], int x, int y, byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space) { +void HT1632Class::drawText(const byte text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space) { int curr_x = x; char i = 0; char currchar; @@ -52,7 +52,7 @@ void HT1632Class::drawText(char text [], int x, int y, byte font [], int font_en } // Gives you the width, in columns, of a particular string. -int HT1632Class::getTextWidth(char text [], int font_end [], uint8_t font_height, uint8_t gutter_space) { +int HT1632Class::getTextWidth(const byte text [], int font_end [], uint8_t font_height, uint8_t gutter_space) { int wd = 0; char i = 0; char currchar; @@ -199,7 +199,7 @@ void HT1632Class::renderTarget(uint8_t target) { } } -void HT1632Class::drawImage(byte * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { +void HT1632Class::drawImage(const byte * img, uint8_t width, uint8_t height, int8_t x, int8_t y, int img_offset) { // Assuming that we are using 8 PIXELS_PER_BYTE, this does the equivalent of Math.ceil(height/PIXELS_PER_BYTE): uint8_t bytesPerColumn = (height >> 3) + ((height & 0b111)?1:0); diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index ba0092d..18b2df2 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -155,9 +155,9 @@ class HT1632Class void render(); void transition(uint8_t mode, int time = 1000); // Time is in milliseconds. void clear(); - void drawImage(byte img [], uint8_t width, uint8_t height, int8_t x, int8_t y, int offset = 0); - void drawText(char text [], int x, int y, byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); - int getTextWidth(char text [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); + void drawImage(const byte img [], uint8_t width, uint8_t height, int8_t x, int8_t y, int offset = 0); + void drawText(const byte text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); + int getTextWidth(const byte text [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); void setBrightness(char brightness, char selectionmask = 0b00010000); }; diff --git a/Arduino/HT1632/font_5x4.h b/Arduino/HT1632/font_5x4.h index 9f2a4be..1011233 100644 --- a/Arduino/HT1632/font_5x4.h +++ b/Arduino/HT1632/font_5x4.h @@ -12,7 +12,7 @@ #define FONT_5X4_HEIGHT 5 // Number of bytes per glyph -prog_uchar FONT_5X4 [] PROGMEM = { +const byte FONT_5X4 [] PROGMEM = { 0b00000000, // 0b11101000, // ! 0b11000000, 0b00000000, 0b11000000, // " diff --git a/Arduino/HT1632/font_8x4.h b/Arduino/HT1632/font_8x4.h index 271d710..832dd14 100644 --- a/Arduino/HT1632/font_8x4.h +++ b/Arduino/HT1632/font_8x4.h @@ -11,7 +11,7 @@ #define FONT_8X4_HEIGHT 8 -prog_uchar FONT_8X4 [] PROGMEM = { +const byte FONT_8X4 [] PROGMEM = { 0b00000000, // SPACE 0b01110000, 0b11111101, 0b01110000, // ! 0b11000000, 0b00000000, 0b11000000, // " @@ -89,4 +89,4 @@ int FONT_8X4_END [] = { 213, 218, 222, 224, 228, 230, 233, 237 }; -#endif // __FONT8X4_H \ No newline at end of file +#endif // __FONT8X4_H diff --git a/Arduino/HT1632/images.h b/Arduino/HT1632/images.h index 60696bd..65d11af 100644 --- a/Arduino/HT1632/images.h +++ b/Arduino/HT1632/images.h @@ -8,15 +8,15 @@ // Online Services: // -prog_uchar IMG_MAIL [] PROGMEM = {0b11111111, 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10000101, 0b10000101, 0b10001001}; +const byte IMG_MAIL [] PROGMEM = {0b11111111, 0b11000001, 0b10100001, 0b10010001, 0b10001001, 0b10000101, 0b10000101, 0b10001001}; #define IMG_MAIL_WIDTH 8 #define IMG_MAIL_HEIGHT 8 -prog_uchar IMG_FB [] PROGMEM = {0b00111111, 0b01000000, 0b10000100, 0b10011111, 0b10100100, 0b10100000, 0b10000000, 0b10000000}; +const byte IMG_FB [] PROGMEM = {0b00111111, 0b01000000, 0b10000100, 0b10011111, 0b10100100, 0b10100000, 0b10000000, 0b10000000}; #define IMG_FB_WIDTH 8 #define IMG_FB_HEIGHT 8 -prog_uchar IMG_TWITTER [] PROGMEM = {0b01111110, 0b10000001, 0b10111001, 0b10010101, 0b10010101, 0b10000001, 0b01111110}; +const byte IMG_TWITTER [] PROGMEM = {0b01111110, 0b10000001, 0b10111001, 0b10010101, 0b10010101, 0b10000001, 0b01111110}; #define IMG_TWITTER_WIDTH 7 #define IMG_TWITTER_HEIGHT 8 @@ -24,16 +24,16 @@ prog_uchar IMG_TWITTER [] PROGMEM = {0b01111110, 0b10000001, 0b10111001, 0b10010 // Music: // -prog_uchar IMG_MUSIC [] PROGMEM = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100}; +const byte IMG_MUSIC [] PROGMEM = {0b00000010, 0b00000111, 0b11111110, 0b11000000, 0b11000000, 0b11000100, 0b11001110, 0b11111100}; #define IMG_MUSIC_WIDTH 8 #define IMG_MUSIC_HEIGHT 8 -prog_uchar IMG_MUSICNOTE [] PROGMEM = {0b00000100, 0b00001110, 0b11111100, 0b01000000}; +const byte IMG_MUSICNOTE [] PROGMEM = {0b00000100, 0b00001110, 0b11111100, 0b01000000}; #define IMG_MUSICNOTE_WIDTH 4 #define IMG_MUSICNOTE_HEIGHT 7 -prog_uchar IMG_SPEAKER_A [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; -prog_uchar IMG_SPEAKER_B [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; +const byte IMG_SPEAKER_A [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10100101, 0b00011000}; +const byte IMG_SPEAKER_B [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b01000010, 0b10111101, 0b00000000}; #define IMG_SPEAKER_WIDTH 6 #define IMG_SPEAKER_HEIGHT 8 @@ -41,7 +41,7 @@ prog_uchar IMG_SPEAKER_B [] PROGMEM = {0b00011000, 0b00011000, 0b00111100, 0b010 // Emotions: // -prog_uchar IMG_HEART [] PROGMEM = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, 0b11111110, 0b11111100, 0b11111000, 0b01110000}; +const byte IMG_HEART [] PROGMEM = {0b01110000, 0b11111000, 0b11111100, 0b11111110, 0b01111111, 0b11111110, 0b11111100, 0b11111000, 0b01110000}; #define IMG_HEART_WIDTH 9 #define IMG_HEART_HEIGHT 8 @@ -49,6 +49,6 @@ prog_uchar IMG_HEART [] PROGMEM = {0b01110000, 0b11111000, 0b11111100, 0b1111111 // Things: // -prog_uchar IMG_SAILBOAT [] PROGMEM = {0b00000010, 0b00100011, 0b01100011, 0b11111111, 0b01111011, 0b00111011, 0b00011011, 0b00001010}; +const byte IMG_SAILBOAT [] PROGMEM = {0b00000010, 0b00100011, 0b01100011, 0b11111111, 0b01111011, 0b00111011, 0b00011011, 0b00001010}; #define IMG_SAILBOAT_WIDTH 8 #define IMG_SAILBOAT_HEIGHT 8 From f6cd9ea5fa5b4b32a5a94f531b6f62377001ebd5 Mon Sep 17 00:00:00 2001 From: Martin Peters Date: Wed, 22 Oct 2014 17:20:22 +0200 Subject: [PATCH 35/45] added set/getPixel and fill/fillAll --- Arduino/HT1632/HT1632.cpp | 45 +++++++++++++++++++++++++++++++++++++++ Arduino/HT1632/HT1632.h | 9 ++++++++ 2 files changed, 54 insertions(+) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index fbe74b7..979dfd4 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -273,6 +273,51 @@ void HT1632Class::drawImage(const byte * img, uint8_t width, uint8_t height, int } } +void HT1632Class::setPixel(uint8_t x, uint8_t y) { + if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) + return; + mem[_tgtChannel][GET_ADDR_FROM_X_Y(x, y)] |= (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE); +} +void HT1632Class::clearPixel(uint8_t x, uint8_t y) { + if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) + return; + mem[_tgtChannel][GET_ADDR_FROM_X_Y(x, y)] &= ~((0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE)); +} +uint8_t HT1632Class::getPixel(uint8_t x, uint8_t y) { + if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) + return 0; + return mem[_tgtChannel][GET_ADDR_FROM_X_Y(x, y)] & (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE); +} + +void HT1632Class::setPixel(uint8_t x, uint8_t y, uint8_t channel) { + if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) + return; + mem[channel][GET_ADDR_FROM_X_Y(x, y)] |= (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE); +} +void HT1632Class::clearPixel(uint8_t x, uint8_t y, uint8_t channel) { + if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) + return; + mem[channel][GET_ADDR_FROM_X_Y(x, y)] &= ~((0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE)); +} +uint8_t HT1632Class::getPixel(uint8_t x, uint8_t y, uint8_t channel) { + if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) + return 0; + return mem[channel][GET_ADDR_FROM_X_Y(x, y)] & (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE); +} + +void HT1632Class::fill() { + for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { + mem[_tgtChannel][i] = 0xFF; + } +} +void HT1632Class::fillAll() { + for(uint8_t c = 0; c < NUM_CHANNEL; ++c) { + for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { + mem[c][i] = 0xFF; // Needs to be redrawn + } + } +} + void HT1632Class::clear(){ for(uint8_t c = 0; c < NUM_CHANNEL; ++c) { for(uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 18b2df2..e765449 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -159,6 +159,15 @@ class HT1632Class void drawText(const byte text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); int getTextWidth(const byte text [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); void setBrightness(char brightness, char selectionmask = 0b00010000); + + void setPixel(uint8_t x, uint8_t y); + void clearPixel(uint8_t x, uint8_t y); + uint8_t getPixel(uint8_t x, uint8_t y); + void setPixel(uint8_t x, uint8_t y, uint8_t channel); + void clearPixel(uint8_t x, uint8_t y, uint8_t channel); + uint8_t getPixel(uint8_t x, uint8_t y, uint8_t channel); + void fill(); + void fillAll(); }; extern HT1632Class HT1632; From 04c83986ec17e83a3b2f8bd265f0b8510d2d75a6 Mon Sep 17 00:00:00 2001 From: Martin Peters Date: Wed, 22 Oct 2014 17:24:10 +0200 Subject: [PATCH 36/45] added makro for bit mask generation in pixel ops --- Arduino/HT1632/HT1632.cpp | 6 +++--- Arduino/HT1632/HT1632.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 979dfd4..9cdcb96 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -292,17 +292,17 @@ uint8_t HT1632Class::getPixel(uint8_t x, uint8_t y) { void HT1632Class::setPixel(uint8_t x, uint8_t y, uint8_t channel) { if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) return; - mem[channel][GET_ADDR_FROM_X_Y(x, y)] |= (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE); + mem[channel][GET_ADDR_FROM_X_Y(x, y)] |= GET_BIT_FROM_Y(y); } void HT1632Class::clearPixel(uint8_t x, uint8_t y, uint8_t channel) { if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) return; - mem[channel][GET_ADDR_FROM_X_Y(x, y)] &= ~((0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE)); + mem[channel][GET_ADDR_FROM_X_Y(x, y)] &= ~(GET_BIT_FROM_Y(y)); } uint8_t HT1632Class::getPixel(uint8_t x, uint8_t y, uint8_t channel) { if( x < 0 || x > OUT_SIZE || y < 0 || y > COM_SIZE ) return 0; - return mem[channel][GET_ADDR_FROM_X_Y(x, y)] & (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE); + return mem[channel][GET_ADDR_FROM_X_Y(x, y)] & GET_BIT_FROM_Y(y); } void HT1632Class::fill() { diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index e765449..cdd754c 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -85,6 +85,7 @@ typedef unsigned char byte; // Exactly equal to the number of 4-bit address spaces available. #define ADDR_SPACE_SIZE (COM_SIZE * OUT_SIZE / PIXELS_PER_BYTE) #define GET_ADDR_FROM_X_Y(_x,_y) ((_x)*((COM_SIZE)/(PIXELS_PER_BYTE))+(_y)/(PIXELS_PER_BYTE)) +#define GET_BIT_FROM_Y(_y) ( (0b1 << PIXELS_PER_BYTE-1) >> (y % PIXELS_PER_BYTE) ) // NO-OP Definition #define NOP(); __asm__("nop\n\t"); From 7787e1ade7c6def09d52b0e54b28a49b57cb67c1 Mon Sep 17 00:00:00 2001 From: futureshape Date: Sun, 23 Nov 2014 15:27:09 +0000 Subject: [PATCH 37/45] Use char instead of byte for text --- Arduino/HT1632/HT1632.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index cdd754c..54db3b2 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -157,8 +157,8 @@ class HT1632Class void transition(uint8_t mode, int time = 1000); // Time is in milliseconds. void clear(); void drawImage(const byte img [], uint8_t width, uint8_t height, int8_t x, int8_t y, int offset = 0); - void drawText(const byte text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); - int getTextWidth(const byte text [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); + void drawText(const char text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); + int getTextWidth(const char text [], int font_end [], uint8_t font_height, uint8_t gutter_space = 1); void setBrightness(char brightness, char selectionmask = 0b00010000); void setPixel(uint8_t x, uint8_t y); From 84c991c0d944055bc034e6e6e3083f6bcc038cb3 Mon Sep 17 00:00:00 2001 From: futureshape Date: Sun, 23 Nov 2014 15:28:14 +0000 Subject: [PATCH 38/45] Use char instead of byte for text --- Arduino/HT1632/HT1632.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index 9cdcb96..c4de2dd 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -10,7 +10,7 @@ * functions go here: */ -void HT1632Class::drawText(const byte text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space) { +void HT1632Class::drawText(const char text [], int x, int y, const byte font [], int font_end [], uint8_t font_height, uint8_t gutter_space) { int curr_x = x; char i = 0; char currchar; @@ -52,7 +52,7 @@ void HT1632Class::drawText(const byte text [], int x, int y, const byte font [], } // Gives you the width, in columns, of a particular string. -int HT1632Class::getTextWidth(const byte text [], int font_end [], uint8_t font_height, uint8_t gutter_space) { +int HT1632Class::getTextWidth(const char text [], int font_end [], uint8_t font_height, uint8_t gutter_space) { int wd = 0; char i = 0; char currchar; From 83358c8409a46533fb7d7b83debd81a34117158a Mon Sep 17 00:00:00 2001 From: biohazardxxx Date: Tue, 6 Oct 2015 23:38:50 +0200 Subject: [PATCH 39/45] support for ESP8266 --- Arduino/HT1632/HT1632.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index 54db3b2..cdab04a 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -12,7 +12,14 @@ #define HT1632_h #include -#include +#ifdef __AVR__ + #include + #include +#elif defined(ESP8266) + #include +#else + #define PROGMEM +#endif // Custom typedefs typedef unsigned char uint8_t; From aab42504bda697a4a9aa51ee2b9cf4a6c63a9ed4 Mon Sep 17 00:00:00 2001 From: biohazardxxx Date: Tue, 3 Nov 2015 07:36:35 +0100 Subject: [PATCH 40/45] removed not needed IO include --- Arduino/HT1632/HT1632.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index cdab04a..c72dc4e 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -13,7 +13,6 @@ #include #ifdef __AVR__ - #include #include #elif defined(ESP8266) #include From 64f066a621f26eea7942848ed63f6cf56e39833e Mon Sep 17 00:00:00 2001 From: EXTREMEGABEL Date: Mon, 30 May 2016 21:59:59 +0200 Subject: [PATCH 41/45] Sure Electronics 24x16 Support Part 1 Modified The files To Natively Support my Sure Electronics 24x16 Monochrome Thing --- Arduino/HT1632/HT1632.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Arduino/HT1632/HT1632.cpp b/Arduino/HT1632/HT1632.cpp index c4de2dd..7483f06 100644 --- a/Arduino/HT1632/HT1632.cpp +++ b/Arduino/HT1632/HT1632.cpp @@ -168,6 +168,8 @@ void HT1632Class::initialize(uint8_t pinWR, uint8_t pinDATA) { #elif defined TYPE_3216_BICOLOR writeCommand(HT1632_CMD_COMS00); writeCommand(HT1632_CMD_RCCLK); // Master Mode, external clock +#elif defined TYPE_2416_MONO + writeCommand(HT1632_CMD_COMS01); #else writeCommand(HT1632_CMD_COMS00); #endif @@ -402,6 +404,29 @@ void HT1632Class::render() { select(); // Close the stream at the end } +#elif defined TYPE_2416_MONO + // Draw the contents of mem + void HT1632Class::render() { + if (_tgtRender >= _numActivePins) { + return; + } + + select(0b0001 << _tgtRender); // Selecting the chip + + writeData(HT1632_ID_WR, HT1632_ID_LEN); + writeData(0, HT1632_ADDR_LEN); // Selecting the memory address + + // Write the channels in order + for (uint8_t c = 0; c < NUM_CHANNEL; ++c) { + for (uint8_t i = 0; i < ADDR_SPACE_SIZE; ++i) { + // Write the higher bits before the the lower bits. + writeData(mem[c][i] >> HT1632_WORD_LEN, HT1632_WORD_LEN); // Write the data in reverse. + writeData(mem[c][i], HT1632_WORD_LEN); // Write the data in reverse. + } + } + + select(); // Close the stream at the end + } #endif // Set the brightness to an integer level between 1 and 16 (inclusive). @@ -491,6 +516,15 @@ void HT1632Class::select(uint8_t mask) { digitalWrite(_pinCS[i], (t & mask)?LOW:HIGH); } } +#elif defined TYPE_2416_MONO +// Choose a chip. This function sets the correct CS line to LOW, and the rest to HIGH +// Call the function with no arguments to deselect all chips. +// Call the function with a bitmask (0b4321) to select specific chips. 0b1111 selects all. +void HT1632Class::select(uint8_t mask) { + for (uint8_t i = 0, t = 1; i<_numActivePins; ++i, t <<= 1) { + digitalWrite(_pinCS[i], (t & mask) ? LOW : HIGH); + } +} #endif void HT1632Class::select() { select(0); From d613c6ce34c212edec0ebf688976ead8947ca020 Mon Sep 17 00:00:00 2001 From: EXTREMEGABEL Date: Mon, 30 May 2016 22:01:23 +0200 Subject: [PATCH 42/45] Sure Electronics 24x16 Support Part 2 --- Arduino/HT1632/HT1632.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Arduino/HT1632/HT1632.h b/Arduino/HT1632/HT1632.h index c72dc4e..f43c8aa 100644 --- a/Arduino/HT1632/HT1632.h +++ b/Arduino/HT1632/HT1632.h @@ -40,6 +40,9 @@ typedef unsigned char byte; // SureElectronics 32X08 Monochrome LED Dot Matrix Unit Board // #define TYPE_3208_MONO 1 +// SureElectronics 24x16 Monochrome LED Dot Matrix Unit Board +#define TYPE_2416_MONO 1 + // SureElectronics 16X08 Bicolor (emulation) // #define TYPE_1608_DEBUG 1 @@ -55,6 +58,11 @@ typedef unsigned char byte; #define OUT_SIZE 32 #define NUM_CHANNEL 1 #define USE_NMOS 1 +#elif defined TYPE_2416_MONO + #define COM_SIZE 16 + #define OUT_SIZE 24 + #define NUM_CHANNEL 1 + #define USE_NMOS 1 #elif defined TYPE_1608_DEBUG #define COM_SIZE 8 #define OUT_SIZE 16 From 95c533306a105ef1e85d8c2a4ab9d24154bfa540 Mon Sep 17 00:00:00 2001 From: shaehnic Date: Wed, 27 Jun 2018 00:39:15 -0700 Subject: [PATCH 43/45] Added 8x5 font Adds a new 8x5 font that behaves like a 7-high font for 2-line (x16) displays --- Arduino/HT1632/font_8x5.h | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 Arduino/HT1632/font_8x5.h diff --git a/Arduino/HT1632/font_8x5.h b/Arduino/HT1632/font_8x5.h new file mode 100644 index 0000000..416b112 --- /dev/null +++ b/Arduino/HT1632/font_8x5.h @@ -0,0 +1,116 @@ +/* + * A nice 8-Height font with variable width up to 5 pixels. + * Most characters are in the top 7 pixels, and the bottom pixel is used sparingly. + * This makes an attractive vertical spacing for two-line displays. + * + * The font is the work of Pawel A Hernik, from fonts.h in: + * "MAX7219 functions by Pawel A. Hernik" + * Found in hareeshmu's ESP Matrix Pixel Clock project here: + * https://github.com/hareeshmu/ESP-Matrix-Pixel-Clock/blob/master/max7219.h + * + * Reformatted and inverted for use with HT1632 by Steve Haehnichen 2018-06-27 + */ +#ifndef __FONT8X5_H +#define __FONT8X5_H + +#define FONT_8X5_HEIGHT 8 + +const byte FONT_8X5 [] PROGMEM = { + 0b00000000, // space + 0b11111010, // ! + 0b11000000, 0b00000000, 0b11000000, // " + 0b00101000, 0b01111100, 0b00101000, 0b01111100, 0b00101000, // # + 0b00100100, 0b01010110, 0b11010100, 0b01001000, // $ + 0b11000110, 0b11001000, 0b00010000, 0b00100110, 0b11000110, // % + 0b01101100, 0b10010010, 0b01101010, 0b00000100, 0b00001010, // & + 0b11000000, // ' + + 0b00111000, 0b01000100, 0b10000010, // ( + 0b10000010, 0b01000100, 0b00111000, // ) + 0b00010100, 0b00011000, 0b01110000, 0b00011000, 0b00010100, // * + 0b00010000, 0b00010000, 0b01111100, 0b00010000, 0b00010000, // + + 0b00001101, 0b00001110, // , + 0b00010000, 0b00010000, 0b00010000, 0b00010000, // - + 0b00000010, // . + 0b00000110, 0b00111000, 0b11000000, // / + + 0b01111100, 0b10000010, 0b10000010, 0b01111100, // 0 + 0b01000010, 0b11111110, 0b00000010, // 1 + 0b01000110, 0b10001010, 0b10010010, 0b01100010, // 2 + 0b01000100, 0b10000010, 0b10010010, 0b01101100, // 3 + 0b00011000, 0b00101000, 0b01001000, 0b11111110, // 4 + 0b11100100, 0b10100010, 0b10100010, 0b10011100, // 5 + 0b01111100, 0b10010010, 0b10010010, 0b01001100, // 6 + 0b10000110, 0b10001000, 0b10010000, 0b11100000, // 7 + + 0b01101100, 0b10010010, 0b10010010, 0b01101100, // 8 + 0b01100100, 0b10010010, 0b10010010, 0b01111100, // 9 + 0b00100010, // : + 0b00000001, 0b00001010, // ; + 0b00001000, 0b00010100, 0b00100010, // < + 0b00101000, 0b00101000, 0b00101000, // = + 0b00100010, 0b00010100, 0b00001000, // > + 0b01000000, 0b10011010, 0b10010000, 0b01100000, // ? + + 0b01111100, 0b10010010, 0b10101010, 0b10111010, 0b01110000, // @ + 0b01111110, 0b10001000, 0b10001000, 0b01111110, // A + 0b11111110, 0b10010010, 0b10010010, 0b01101100, // B + 0b01111100, 0b10000010, 0b10000010, 0b01000100, // C + 0b11111110, 0b10000010, 0b10000010, 0b01111100, // D + 0b11111110, 0b10010010, 0b10010010, 0b10000010, // E + 0b11111110, 0b10010000, 0b10010000, 0b10000000, // F + 0b01111100, 0b10000010, 0b10010010, 0b01011110, // G + + 0b11111110, 0b00010000, 0b00010000, 0b11111110, // H + 0b10000010, 0b11111110, 0b10000010, // I + 0b00001100, 0b00000010, 0b10000010, 0b11111100, // J + 0b11111110, 0b00010000, 0b00101000, 0b11000110, // K + 0b11111110, 0b00000010, 0b00000010, 0b00000010, // L + 0b11111110, 0b01000000, 0b00110000, 0b01000000, 0b11111110, // M + 0b11111110, 0b00100000, 0b00010000, 0b00001000, 0b11111110, // N + 0b01111100, 0b10000010, 0b10000010, 0b01111100, // O + + 0b11111110, 0b10010000, 0b10010000, 0b01100000, // P + 0b01111100, 0b10000010, 0b10000010, 0b01111101, // Q + 0b11111110, 0b10010000, 0b10010000, 0b01101110, // R + 0b01100100, 0b10010010, 0b10010010, 0b01001100, // S + 0b10000000, 0b10000000, 0b11111110, 0b10000000, 0b10000000, // T + 0b11111100, 0b00000010, 0b00000010, 0b11111100, // U + 0b11110000, 0b00001100, 0b00000010, 0b00001100, 0b11110000, // V + 0b11111100, 0b00000010, 0b00011100, 0b00000010, 0b11111100, // W + + 0b11000110, 0b00101000, 0b00010000, 0b00101000, 0b11000110, // X + 0b11100000, 0b00010000, 0b00001110, 0b00010000, 0b11100000, // Y + 0b10000110, 0b10001010, 0b10010010, 0b11100010, // Z + 0b11111110, 0b10000010, // [ + 0b10000000, 0b01100000, 0b00011000, 0b00000110, // \ + 0b10000010, 0b11111110, // ] + 0b01000000, 0b10000000, 0b01000000, // ^ + 0b00000010, 0b00000010, 0b00000010, 0b00000010, // _ +}; + +// Offsets generated by font_end_generate.html +int FONT_8X5_END [] = +{ + 1, 2, 5, 10, 14, 19, 24, 25, + 28, 31, 36, 41, 43, 47, 48, 51, + 55, 58, 62, 66, 70, 74, 78, 82, + 86, 90, 91, 93, 96, 99, 102, 106, + 111, 115, 119, 123, 127, 131, 135, 139, + 143, 146, 150, 154, 158, 163, 168, 172, + 176, 180, 184, 188, 193, 197, 202, 207, + 212, 217, 221, 223, 227, 229, 232, 236 +}; +#endif // __FONT8X5_H + +/* + Character widths: + 1, 1, 3, 5, 4, 5, 5, 1, + 3, 3, 5, 5, 2, 4, 1, 3, + 4, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 1, 2, 3, 3, 3, 4, + 5, 4, 4, 4, 4, 4, 4, 4, + 4, 3, 4, 4, 4, 5, 5, 4, + 4, 4, 4, 4, 5, 4, 5, 5, + 5, 5, 4, 2, 4, 2, 3, 4 +*/ From 3519b72611d3795d9b5d636d4d33d0e2d99b0552 Mon Sep 17 00:00:00 2001 From: per1234 Date: Tue, 10 Jul 2018 16:44:24 -0700 Subject: [PATCH 44/45] Move library to root of repository A popular library installation technique is to download the library via GitHub's Clone or download > Download ZIP and then use the Arduino IDE's Sketch > Include Library > Add .ZIP Library on the downloaded file. This requires the library to be in the root of the repository, not in a subfolder. If the library is not in the root of the repository this installation technique fails: Specified folder/zip file does not contain a valid library This is the standard repository structure used in all official Arduino libraries: https://github.com/arduino-libraries This move is also required if you wanted to add your library to the Arduino Library Manager index, which provides an even easier installation option. --- Arduino/HT1632/HT1632.cpp => HT1632.cpp | 0 Arduino/HT1632/HT1632.h => HT1632.h | 0 .../examples => examples}/HT1632_Animation/HT1632_Animation.ino | 0 .../HT1632/examples => examples}/HT1632_Heart/HT1632_Heart.ino | 0 .../HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino | 0 .../HT1632_Heart_Multiple_Bicolor.ino | 0 .../examples => examples}/HT1632_Sailboat/HT1632_Sailboat.ino | 0 {Arduino/HT1632/examples => examples}/HT1632_Text/HT1632_Text.ino | 0 .../examples => examples}/HT1632_Text_8X4/HT1632_Text_8X4.ino | 0 .../HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino | 0 .../HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino | 0 Arduino/HT1632/font_5x4.h => font_5x4.h | 0 Arduino/HT1632/font_8x4.h => font_8x4.h | 0 Arduino/HT1632/font_8x5.h => font_8x5.h | 0 Arduino/HT1632/images.h => images.h | 0 Arduino/HT1632/keywords.txt => keywords.txt | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename Arduino/HT1632/HT1632.cpp => HT1632.cpp (100%) rename Arduino/HT1632/HT1632.h => HT1632.h (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Animation/HT1632_Animation.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Heart/HT1632_Heart.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Sailboat/HT1632_Sailboat.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Text/HT1632_Text.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Text_8X4/HT1632_Text_8X4.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino (100%) rename {Arduino/HT1632/examples => examples}/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino (100%) rename Arduino/HT1632/font_5x4.h => font_5x4.h (100%) rename Arduino/HT1632/font_8x4.h => font_8x4.h (100%) rename Arduino/HT1632/font_8x5.h => font_8x5.h (100%) rename Arduino/HT1632/images.h => images.h (100%) rename Arduino/HT1632/keywords.txt => keywords.txt (100%) diff --git a/Arduino/HT1632/HT1632.cpp b/HT1632.cpp similarity index 100% rename from Arduino/HT1632/HT1632.cpp rename to HT1632.cpp diff --git a/Arduino/HT1632/HT1632.h b/HT1632.h similarity index 100% rename from Arduino/HT1632/HT1632.h rename to HT1632.h diff --git a/Arduino/HT1632/examples/HT1632_Animation/HT1632_Animation.ino b/examples/HT1632_Animation/HT1632_Animation.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Animation/HT1632_Animation.ino rename to examples/HT1632_Animation/HT1632_Animation.ino diff --git a/Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino b/examples/HT1632_Heart/HT1632_Heart.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Heart/HT1632_Heart.ino rename to examples/HT1632_Heart/HT1632_Heart.ino diff --git a/Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino b/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino rename to examples/HT1632_Heart_Bicolor/HT1632_Heart_Bicolor.ino diff --git a/Arduino/HT1632/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino b/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino rename to examples/HT1632_Heart_Multiple_Bicolor/HT1632_Heart_Multiple_Bicolor.ino diff --git a/Arduino/HT1632/examples/HT1632_Sailboat/HT1632_Sailboat.ino b/examples/HT1632_Sailboat/HT1632_Sailboat.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Sailboat/HT1632_Sailboat.ino rename to examples/HT1632_Sailboat/HT1632_Sailboat.ino diff --git a/Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino b/examples/HT1632_Text/HT1632_Text.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Text/HT1632_Text.ino rename to examples/HT1632_Text/HT1632_Text.ino diff --git a/Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino b/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Text_8X4/HT1632_Text_8X4.ino rename to examples/HT1632_Text_8X4/HT1632_Text_8X4.ino diff --git a/Arduino/HT1632/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino b/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino rename to examples/HT1632_Text_8X4_Multidisplay/HT1632_Text_8X4_Multidisplay.ino diff --git a/Arduino/HT1632/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino b/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino similarity index 100% rename from Arduino/HT1632/examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino rename to examples/HT1632_Text_From_Serial/HT1632_Text_From_Serial.ino diff --git a/Arduino/HT1632/font_5x4.h b/font_5x4.h similarity index 100% rename from Arduino/HT1632/font_5x4.h rename to font_5x4.h diff --git a/Arduino/HT1632/font_8x4.h b/font_8x4.h similarity index 100% rename from Arduino/HT1632/font_8x4.h rename to font_8x4.h diff --git a/Arduino/HT1632/font_8x5.h b/font_8x5.h similarity index 100% rename from Arduino/HT1632/font_8x5.h rename to font_8x5.h diff --git a/Arduino/HT1632/images.h b/images.h similarity index 100% rename from Arduino/HT1632/images.h rename to images.h diff --git a/Arduino/HT1632/keywords.txt b/keywords.txt similarity index 100% rename from Arduino/HT1632/keywords.txt rename to keywords.txt From baca5cea0e903269c206d692821f47d54ece7a91 Mon Sep 17 00:00:00 2001 From: per1234 Date: Sun, 9 Sep 2018 04:58:22 -0700 Subject: [PATCH 45/45] Use a single tab field separator in keywords.txt Each field of keywords.txt is separated by a single true tab. When you use multiple tabs it causes the field to be interpreted as empty. On Arduino IDE 1.6.5 and newer an empty KEYWORD_TOKENTYPE causes the default editor.function.style highlighting to be used (as with KEYWORD2, KEYWORD3). On Arduino IDE 1.6.4 and older it causes the keyword to not be recognized for any special highlighting. Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords --- keywords.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/keywords.txt b/keywords.txt index 9e27279..e7d53bc 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,28 +6,28 @@ # Datatypes (KEYWORD1) ####################################### -HT1632 KEYWORD1 +HT1632 KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -begin KEYWORD2 -sendCommand KEYWORD2 +begin KEYWORD2 +sendCommand KEYWORD2 renderTarget KEYWORD2 selectChannel KEYWORD2 -render KEYWORD2 -transition KEYWORD2 -clear KEYWORD2 -drawImage KEYWORD2 -drawText KEYWORD2 +render KEYWORD2 +transition KEYWORD2 +clear KEYWORD2 +drawImage KEYWORD2 +drawText KEYWORD2 getTextWidth KEYWORD2 setBrightness KEYWORD2 -setCLK KEYWORD2 +setCLK KEYWORD2 ####################################### # Constants (LITERAL1) ####################################### -COM_SIZE LITERAL1 -OUT_SIZE LITERAL1 \ No newline at end of file +COM_SIZE LITERAL1 +OUT_SIZE LITERAL1