From b8ea9b170dd078108d10f586b4fafe8dee087335 Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 8 Dec 2017 15:33:21 +0100 Subject: [PATCH 1/5] Added scrollEnd() function --- LedMatrix.cpp | 206 +++++++++++++++++++++++---------------------- LedMatrix.h | 225 ++++++++++++++++++++++++++------------------------ 2 files changed, 224 insertions(+), 207 deletions(-) diff --git a/LedMatrix.cpp b/LedMatrix.cpp index 560339e..019e25f 100644 --- a/LedMatrix.cpp +++ b/LedMatrix.cpp @@ -6,9 +6,9 @@ * Heavily influenced by the code and the blog posts from https://github.com/nickgammon/MAX7219_Dot_Matrix */ LedMatrix::LedMatrix(byte numberOfDevices, byte slaveSelectPin) { - myNumberOfDevices = numberOfDevices; - mySlaveSelectPin = slaveSelectPin; - cols = new byte[numberOfDevices * 8]; + myNumberOfDevices = numberOfDevices; + mySlaveSelectPin = slaveSelectPin; + cols = new byte[numberOfDevices * 8]; } /** @@ -16,151 +16,161 @@ LedMatrix::LedMatrix(byte numberOfDevices, byte slaveSelectPin) { * slaveSelectPin: which pin is controlling the CS/SS pin of the first module? */ void LedMatrix::init() { - pinMode(mySlaveSelectPin, OUTPUT); - - SPI.begin (); - SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV128); - for(byte device = 0; device < myNumberOfDevices; device++) { - sendByte (device, MAX7219_REG_SCANLIMIT, 7); // show all 8 digits - sendByte (device, MAX7219_REG_DECODEMODE, 0); // using an led matrix (not digits) - sendByte (device, MAX7219_REG_DISPLAYTEST, 0); // no display test - sendByte (device, MAX7219_REG_INTENSITY, 0); // character intensity: range: 0 to 15 - sendByte (device, MAX7219_REG_SHUTDOWN, 1); // not in shutdown mode (ie. start it up) - } + pinMode(mySlaveSelectPin, OUTPUT); + + SPI.begin (); + SPI.setDataMode(SPI_MODE0); + SPI.setClockDivider(SPI_CLOCK_DIV128); + for(byte device = 0; device < myNumberOfDevices; device++) { + sendByte (device, MAX7219_REG_SCANLIMIT, 7); // show all 8 digits + sendByte (device, MAX7219_REG_DECODEMODE, 0); // using an led matrix (not digits) + sendByte (device, MAX7219_REG_DISPLAYTEST, 0); // no display test + sendByte (device, MAX7219_REG_INTENSITY, 0); // character intensity: range: 0 to 15 + sendByte (device, MAX7219_REG_SHUTDOWN, 1); // not in shutdown mode (ie. start it up) + } } void LedMatrix::sendByte (const byte device, const byte reg, const byte data) { - int offset=device; - int maxbytes=myNumberOfDevices; - - for(int i=0;i 0) { - myText = myNextText; - myNextText = ""; - calculateTextAlignmentOffset(); - } + myTextOffset = (myTextOffset - 1) % ((int)myText.length() * myCharWidth + myNumberOfDevices * 8); + if (myTextOffset == 0 && myNextText.length() > 0) { + myText = myNextText; + myNextText = ""; + calculateTextAlignmentOffset(); + } } void LedMatrix::oscillateText() { - int maxColumns = (int)myText.length() * myCharWidth; - int maxDisplayColumns = myNumberOfDevices * 8; - if (maxDisplayColumns > maxColumns) { - return; - } - if (myTextOffset - maxDisplayColumns == -maxColumns) { - increment = 1; - } - if (myTextOffset == 0) { - increment = -1; - } - myTextOffset += increment; + int maxColumns = (int)myText.length() * myCharWidth; + int maxDisplayColumns = myNumberOfDevices * 8; + if (maxDisplayColumns > maxColumns) { + return; + } + if (myTextOffset - maxDisplayColumns == -maxColumns) { + increment = 1; + } + if (myTextOffset == 0) { + increment = -1; + } + myTextOffset += increment; } void LedMatrix::drawText() { - char letter; - int position = 0; - for (int i = 0; i < myText.length(); i++) { - letter = myText.charAt(i); - for (byte col = 0; col < 8; col++) { - position = i * myCharWidth + col + myTextOffset + myTextAlignmentOffset; - if (position >= 0 && position < myNumberOfDevices * 8) { - setColumn(position, pgm_read_byte (&cp437_font [letter] [col])); - } + char letter; + int position = 0; + for (int i = 0; i < myText.length(); i++) { + letter = myText.charAt(i); + for (byte col = 0; col < 8; col++) { + position = i * myCharWidth + col + myTextOffset + myTextAlignmentOffset; + if (position >= 0 && position < myNumberOfDevices * 8) { + setColumn(position, pgm_read_byte (&cp437_font [letter] [col])); + } + } } - } } void LedMatrix::setColumn(int column, byte value) { - if (column < 0 || column >= myNumberOfDevices * 8) { - return; - } - cols[column] = value; + if (column < 0 || column >= myNumberOfDevices * 8) { + return; + } + cols[column] = value; } void LedMatrix::setPixel(byte x, byte y) { - bitWrite(cols[x], y, true); -} \ No newline at end of file + bitWrite(cols[x], y, true); +} + +bool LedMatrix::scrollEnd(){ + return scroll; +} diff --git a/LedMatrix.h b/LedMatrix.h index d622e54..4c761b2 100644 --- a/LedMatrix.h +++ b/LedMatrix.h @@ -22,114 +22,121 @@ #define TEXT_ALIGN_RIGHT_END 3 // End of text is just outside the left side of the display class LedMatrix { - + public: - - /** - * Constructor. - * numberOfDisplays: number of connected devices - * slaveSelectPin: CS (or SS) pin connected to your ESP8266 - */ - LedMatrix(byte numberOfDisplays, byte slaveSelectPin); - - /** - * Initializes the SPI interface - */ - void init(); - - /** - * Sets the intensity on all devices. - * intensity: 0-15 - */ - void setIntensity(byte intensity); - - /** - * Sets the width in pixels for one character. - * Default is 7. - */ - void setCharWidth(byte charWidth); - - /** - * Sets the text alignment. - * Default is TEXT_ALIGN_LEFT_END. - * - */ - void setTextAlignment(byte textAlignment); - - /** - * Send a byte to a specific device. - */ - void sendByte (const byte device, const byte reg, const byte data); - - /** - * Send a byte to all devices (convenience method). - */ - void sendByte (const byte reg, const byte data); - - /** - * Turn on pixel at position (x,y). - */ - void setPixel(byte x, byte y); - - /** - * Clear the frame buffer. - */ - void clear(); - - /** - * Draw the currently set text at the current offset. - */ - void drawText(); - - /** - * Set the current text. - */ - void setText(String text); - - /** - * Set the text that will replace the current text after a complete scroll - * cycle. - */ - void setNextText(String nextText); - - /** - * Set a specific column with a byte value to the framebuffer. - */ - void setColumn(int column, byte value); - - /** - * Writes the framebuffer to the displays. - */ - void commit(); - - /** - * Scroll the text to the right. - */ - void scrollTextRight(); - - /** - * Scroll the text to the left. - */ - void scrollTextLeft(); - - /** - * Oscilate the text between the two limits. - */ - void oscillateText(); - + +/** + * Constructor. + * numberOfDisplays: number of connected devices + * slaveSelectPin: CS (or SS) pin connected to your ESP8266 + */ +LedMatrix(byte numberOfDisplays, byte slaveSelectPin); + +/** + * Initializes the SPI interface + */ +void init(); + +/** + * Sets the intensity on all devices. + * intensity: 0-15 + */ +void setIntensity(byte intensity); + +/** + * Sets the width in pixels for one character. + * Default is 7. + */ +void setCharWidth(byte charWidth); + +/** + * Sets the text alignment. + * Default is TEXT_ALIGN_LEFT_END. + * + */ +void setTextAlignment(byte textAlignment); + +/** + * Send a byte to a specific device. + */ +void sendByte (const byte device, const byte reg, const byte data); + +/** + * Send a byte to all devices (convenience method). + */ +void sendByte (const byte reg, const byte data); + +/** + * Turn on pixel at position (x,y). + */ +void setPixel(byte x, byte y); + +/** + * Clear the frame buffer. + */ +void clear(); + +/** + * Draw the currently set text at the current offset. + */ +void drawText(); + +/** + * Set the current text. + */ +void setText(String text); + +/** + * Set the text that will replace the current text after a complete scroll + * cycle. + */ +void setNextText(String nextText); + +/** + * Set a specific column with a byte value to the framebuffer. + */ +void setColumn(int column, byte value); + +/** + * Writes the framebuffer to the displays. + */ +void commit(); + +/** + * Scroll the text to the right. + */ +void scrollTextRight(); + +/** + * Scroll the text to the left. + */ +void scrollTextLeft(); + +/** + * Oscilate the text between the two limits. + */ +void oscillateText(); + +/** + * Return 1 when the array is completely displayed + */ +bool scrollEnd(); + private: - byte* cols; - byte spiregister[8]; - byte spidata[8]; - String myText; - String myNextText; - int myTextOffset = 1; - int myTextAlignmentOffset = 0; - int increment = -1; - byte myNumberOfDevices = 0; - byte mySlaveSelectPin = 0; - byte myCharWidth = 7; - byte myTextAlignment = 1; - - void calculateTextAlignmentOffset(); -}; \ No newline at end of file +byte* cols; +byte spiregister[8]; +byte spidata[8]; +String myText; +String myNextText; +int myTextOffset = 1; +int myTextAlignmentOffset = 0; +int increment = -1; +byte myNumberOfDevices = 0; +byte mySlaveSelectPin = 0; +byte myCharWidth = 7; +byte myTextAlignment = 1; +byte n=0; +bool scroll = 0; + +void calculateTextAlignmentOffset(); +}; From 70a2e361b4de0001ef7f7341e4ca547f4e22c1a6 Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 8 Dec 2017 15:45:15 +0100 Subject: [PATCH 2/5] update --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 52779d7..2de4641 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +Original version by "squix78". + # MAX7219LedMatrix Library for the ESP8266 on Arduino IDE displaying text on one or multiple MAX7219 8x8 led matrices. @@ -13,6 +15,7 @@ Currently this library supports the following operations: - write text with a simple font - scroll text left or right - oscillate text between the two ends +- notify when the word is completely displayed You're welcome to [read in my blog](http://blog.squix.ch/2015/04/esp8266arduino-max7219-8x8-led-matrix.html) how this library came about. @@ -37,6 +40,7 @@ void loop() { ledMatrix.clear(); ledMatrix.scrollTextLeft(); ledMatrix.drawText(); + //int a = ledMatrix.scrollEnd(); // it return 1 when the word is completely displayed ledMatrix.commit(); // commit transfers the byte buffer to the displays delay(200); } From e5d260e5ffd3e9c134ecf1c2757616d44d3688bd Mon Sep 17 00:00:00 2001 From: Dave Date: Tue, 12 Dec 2017 23:15:09 +0100 Subject: [PATCH 3/5] added rotation defined in LedMatrix.h --- LedMatrix.cpp | 41 +++++++++++++++++++++++++++++++---------- LedMatrix.h | 4 ++-- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/LedMatrix.cpp b/LedMatrix.cpp index 019e25f..0108702 100644 --- a/LedMatrix.cpp +++ b/LedMatrix.cpp @@ -9,6 +9,7 @@ LedMatrix::LedMatrix(byte numberOfDevices, byte slaveSelectPin) { myNumberOfDevices = numberOfDevices; mySlaveSelectPin = slaveSelectPin; cols = new byte[numberOfDevices * 8]; + xcols = new byte[numberOfDevices * 8]; } /** @@ -45,17 +46,10 @@ void LedMatrix::sendByte (const byte device, const byte reg, const byte data) { digitalWrite(mySlaveSelectPin,LOW); // now shift out the data for(int i=0; i> bits) : 0); + sendByte(col / 8, col % 8 + 1, xcols[col]); + } } } @@ -172,5 +188,10 @@ void LedMatrix::setPixel(byte x, byte y) { } bool LedMatrix::scrollEnd(){ - return scroll; + int maxColumns = (int)myText.length() * myCharWidth; + byte maxDisplayColumns = myNumberOfDevices * 8; + + if (myTextOffset == 0) return 1; + + else return 0; } diff --git a/LedMatrix.h b/LedMatrix.h index 4c761b2..d42d1bf 100644 --- a/LedMatrix.h +++ b/LedMatrix.h @@ -124,6 +124,7 @@ bool scrollEnd(); private: byte* cols; +byte* xcols; byte spiregister[8]; byte spidata[8]; String myText; @@ -135,8 +136,7 @@ byte myNumberOfDevices = 0; byte mySlaveSelectPin = 0; byte myCharWidth = 7; byte myTextAlignment = 1; -byte n=0; -bool scroll = 0; +bool deviceOrientation = 1; // 1 is vertical - 0 is horizontal void calculateTextAlignmentOffset(); }; From d0653561475cb1e918644b47eeb383a2ec09b6dd Mon Sep 17 00:00:00 2001 From: Dave Date: Sun, 17 Dec 2017 15:02:42 +0100 Subject: [PATCH 4/5] update --- LedMatrix.cpp | 24 ++++++++++++++++++------ LedMatrix.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/LedMatrix.cpp b/LedMatrix.cpp index 0108702..6b7766d 100644 --- a/LedMatrix.cpp +++ b/LedMatrix.cpp @@ -39,9 +39,10 @@ void LedMatrix::sendByte (const byte device, const byte reg, const byte data) { spidata[i] = (byte)0; spiregister[i] = (byte)0; } - // put our device data into the array +// put our device data into the array spiregister[offset] = reg; spidata[offset] = data; + // enable the line digitalWrite(mySlaveSelectPin,LOW); // now shift out the data @@ -109,16 +110,17 @@ void LedMatrix::commit() { for (col = 0; col < myNumberOfDevices * 8; col++) { sendByte(col / 8, col % 8 + 1, cols[col]); } - } else if(deviceOrientation == 1) { // orient the device vertically + } + else if(deviceOrientation == 1 ) { // orient the device vertically for (col = 0; col < myNumberOfDevices * 8; col++) { xcols[col] = 0; } // little inefficient, can be enhanced, rotate the matrix ! for (col = 0; col < myNumberOfDevices * 8; col++) { - - for(byte bits = 0; bits < 8; bits++) + for(byte bits = 0; bits < 8; bits++) { xcols[col] |= ((cols[bits + 8*(col/8)] & (index << (col%8))) ? (B10000000 >> bits) : 0); + } sendByte(col / 8, col % 8 + 1, xcols[col]); } } @@ -170,7 +172,18 @@ void LedMatrix::drawText() { for (byte col = 0; col < 8; col++) { position = i * myCharWidth + col + myTextOffset + myTextAlignmentOffset; if (position >= 0 && position < myNumberOfDevices * 8) { - setColumn(position, pgm_read_byte (&cp437_font [letter] [col])); + if (flip==0) { + setColumn(position, pgm_read_byte (&cp437_font [letter] [col])); + } + else { + // flip char (byte) + byte x = pgm_read_byte (&cp437_font [letter] [col]); + // byte x = data; + x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa); + x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc); + x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0); + setColumn(position, x); + } } } } @@ -190,7 +203,6 @@ void LedMatrix::setPixel(byte x, byte y) { bool LedMatrix::scrollEnd(){ int maxColumns = (int)myText.length() * myCharWidth; byte maxDisplayColumns = myNumberOfDevices * 8; - if (myTextOffset == 0) return 1; else return 0; diff --git a/LedMatrix.h b/LedMatrix.h index d42d1bf..6c18fbf 100644 --- a/LedMatrix.h +++ b/LedMatrix.h @@ -137,6 +137,7 @@ byte mySlaveSelectPin = 0; byte myCharWidth = 7; byte myTextAlignment = 1; bool deviceOrientation = 1; // 1 is vertical - 0 is horizontal +bool flip = 0; // void calculateTextAlignmentOffset(); }; From ce0e544e436a766b11445a5fcd381213cf5ee7e2 Mon Sep 17 00:00:00 2001 From: Dave Date: Sun, 17 Dec 2017 15:06:56 +0100 Subject: [PATCH 5/5] update --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2de4641..b6238c8 100644 --- a/README.md +++ b/README.md @@ -7,16 +7,18 @@ This library displays text and sets specific pixels on one or multiple 8x8 led m These modules are relatively cheep and can be daisy chained which makes it easy to get a led text bar up and running You can find modules e.g. with [Banggood](http://www.banggood.com/2Pcs-MAX7219-Dot-Matrix-MCU-LED-Display-Control-Module-Kit-For-Arduino-p-945280.html?p=0P21061109440201501M) (<-affiliate link). -For details about the MAX7219 theory, wiring, schematic, etc. there's a great post by Nick Gammon: http://www.gammon.com.au/forum/?id=11516 - +For details about the MAX7219 theory, wiring, schematic, etc. there's a great post by Nick Gammon: http://www.gammon.com.au/forum/?id=11516 + Currently this library supports the following operations: - set pixels - write text with a simple font -- scroll text left or right +- scroll text left or right +- translate 90° - oscillate text between the two ends - notify when the word is completely displayed - +- flip string + You're welcome to [read in my blog](http://blog.squix.ch/2015/04/esp8266arduino-max7219-8x8-led-matrix.html) how this library came about. ## Example