diff --git a/LedControl added COMMON ANODE display support/LedControl.cpp b/LedControl added COMMON ANODE display support/LedControl.cpp new file mode 100644 index 0000000..3aa3570 --- /dev/null +++ b/LedControl added COMMON ANODE display support/LedControl.cpp @@ -0,0 +1,213 @@ +/* + * LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221 + * Copyright (c) 2007 Eberhard Fahle + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * This permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include "LedControl.h" + +//the opcodes for the MAX7221 and MAX7219 +#define OP_NOOP 0 +#define OP_DIGIT0 1 +#define OP_DIGIT1 2 +#define OP_DIGIT2 3 +#define OP_DIGIT3 4 +#define OP_DIGIT4 5 +#define OP_DIGIT5 6 +#define OP_DIGIT6 7 +#define OP_DIGIT7 8 +#define OP_DECODEMODE 9 +#define OP_INTENSITY 10 +#define OP_SCANLIMIT 11 +#define OP_SHUTDOWN 12 +#define OP_DISPLAYTEST 15 + +LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) { + SPI_MOSI=dataPin; + SPI_CLK=clkPin; + SPI_CS=csPin; + if(numDevices<=0 || numDevices>8 ) + numDevices=8; + maxDevices=numDevices; + pinMode(SPI_MOSI,OUTPUT); + pinMode(SPI_CLK,OUTPUT); + pinMode(SPI_CS,OUTPUT); + digitalWrite(SPI_CS,HIGH); + SPI_MOSI=dataPin; + for(int i=0;i<64;i++) + status[i]=0x00; + for(int i=0;i=maxDevices) + return; + if(b) + spiTransfer(addr, OP_SHUTDOWN,0); + else + spiTransfer(addr, OP_SHUTDOWN,1); +} + +void LedControl::setScanLimit(int addr, int limit) { + if(addr<0 || addr>=maxDevices) + return; + if(limit>=0 || limit<8) + spiTransfer(addr, OP_SCANLIMIT,limit); +} + +void LedControl::setIntensity(int addr, int intensity) { + if(addr<0 || addr>=maxDevices) + return; + if(intensity>=0 || intensity<16) + spiTransfer(addr, OP_INTENSITY,intensity); + +} + +void LedControl::clearDisplay(int addr) { + int offset; + + if(addr<0 || addr>=maxDevices) + return; + offset=addr*8; + for(int i=0;i<8;i++) { + status[offset+i]=0; + spiTransfer(addr, i+1,status[offset+i]); + } +} + +void LedControl::setLed(int addr, int row, int column, boolean state) { + int offset; + byte val=0x00; + + if(addr<0 || addr>=maxDevices) + return; + if(row<0 || row>7 || column<0 || column>7) + return; + offset=addr*8; + val=B10000000 >> column; + if(state) + status[offset+row]=status[offset+row]|val; + else { + val=~val; + status[offset+row]=status[offset+row]&val; + } + spiTransfer(addr, row+1,status[offset+row]); +} + +void LedControl::setRow(int addr, int row, byte value) { + int offset; + if(addr<0 || addr>=maxDevices) + return; + if(row<0 || row>7) + return; + offset=addr*8; + status[offset+row]=value; + spiTransfer(addr, row+1,status[offset+row]); +} + +void LedControl::setColumn(int addr, int col, byte value) { + byte val; + + if(addr<0 || addr>=maxDevices) + return; + if(col<0 || col>7) + return; + for(int row=0;row<8;row++) { + val=value >> (7-row); + val=val & 0x01; + setLed(addr,row,col,val); + } +} + +void LedControl::setDigit(int addr, int digit, byte value, boolean dp) { + int offset; + byte v; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7 || value>15) + return; + offset=addr*8; + v=charTable[value]; + if(dp) + v|=B10000000; + status[offset+digit]=v; + spiTransfer(addr, digit+1,v); + +} + +void LedControl::setChar(int addr, int digit, char value, boolean dp) { + int offset; + byte index,v; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7) + return; + offset=addr*8; + index=(byte)value; + if(index >127) { + //nothing define we use the space char + value=32; + } + v=charTable[index]; + if(dp) + v|=B10000000; + status[offset+digit]=v; + spiTransfer(addr, digit+1,v); +} + +void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) { + //Create an array with the data to shift out + int offset=addr*2; + int maxbytes=maxDevices*2; + + for(int i=0;i0;i--) + shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]); + //latch the data onto the display + digitalWrite(SPI_CS,HIGH); +} + + diff --git a/LedControl added COMMON ANODE display support/LedControl.h b/LedControl added COMMON ANODE display support/LedControl.h new file mode 100644 index 0000000..6f2e6c9 --- /dev/null +++ b/LedControl added COMMON ANODE display support/LedControl.h @@ -0,0 +1,188 @@ +/* + * LedControl.h - A library for controling Leds with a MAX7219/MAX7221 + * Copyright (c) 2007 Eberhard Fahle + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * This permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LedControl_h +#define LedControl_h + +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +/* + * Segments to be switched on for characters and digits on + * 7-Segment Displays + */ +const static byte charTable[128] = { + B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, + B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000, + B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, + B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, + B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, + B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000, + B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, + B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, + B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000 +}; + +class LedControl { + private : + /* The array for shifting the data to the devices */ + byte spidata[16]; + /* Send out a single command to the device */ + void spiTransfer(int addr, byte opcode, byte data); + + /* We keep track of the led-status for all 8 devices in this array */ + byte status[64]; + /* Data is shifted out of this pin*/ + int SPI_MOSI; + /* The clock is signaled on this pin */ + int SPI_CLK; + /* This one is driven LOW for chip selectzion */ + int SPI_CS; + /* The maximum number of devices we use */ + int maxDevices; + + public: + /* + * Create a new controler + * Params : + * dataPin pin on the Arduino where data gets shifted out + * clockPin pin for the clock + * csPin pin for selecting the device + * numDevices maximum number of devices that can be controled + */ + LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); + + /* + * Gets the number of devices attached to this LedControl. + * Returns : + * int the number of devices on this LedControl + */ + int getDeviceCount(); + + /* + * Set the shutdown (power saving) mode for the device + * Params : + * addr The address of the display to control + * status If true the device goes into power-down mode. Set to false + * for normal operation. + */ + void shutdown(int addr, bool status); + + /* + * Set the number of digits (or rows) to be displayed. + * See datasheet for sideeffects of the scanlimit on the brightness + * of the display. + * Params : + * addr address of the display to control + * limit number of digits to be displayed (1..8) + */ + void setScanLimit(int addr, int limit); + + /* + * Set the brightness of the display. + * Params: + * addr the address of the display to control + * intensity the brightness of the display. (0..15) + */ + void setIntensity(int addr, int intensity); + + /* + * Switch all Leds on the display off. + * Params: + * addr address of the display to control + */ + void clearDisplay(int addr); + + /* + * Set the status of a single Led. + * Params : + * addr address of the display + * row the row of the Led (0..7) + * col the column of the Led (0..7) + * state If true the led is switched on, + * if false it is switched off + */ + void setLed(int addr, int row, int col, boolean state); + + /* + * Set all 8 Led's in a row to a new state + * Params: + * addr address of the display + * row row which is to be set (0..7) + * value each bit set to 1 will light up the + * corresponding Led. + */ + void setRow(int addr, int row, byte value); + + /* + * Set all 8 Led's in a column to a new state + * Params: + * addr address of the display + * col column which is to be set (0..7) + * value each bit set to 1 will light up the + * corresponding Led. + */ + void setColumn(int addr, int col, byte value); + + /* + * Display a hexadecimal digit on a 7-Segment Display + * Params: + * addr address of the display + * digit the position of the digit on the display (0..7) + * value the value to be displayed. (0x00..0x0F) + * dp sets the decimal point. + */ + void setDigit(int addr, int digit, byte value, boolean dp); + + /* + * Display a character on a 7-Segment display. + * There are only a few characters that make sense here : + * '0','1','2','3','4','5','6','7','8','9','0', + * 'A','b','c','d','E','F','H','L','P', + * '.','-','_',' ' + * Params: + * addr address of the display + * digit the position of the character on the display (0..7) + * value the character to be displayed. + * dp sets the decimal point. + */ + void setChar(int addr, int digit, char value, boolean dp); +}; + +#endif //LedControl.h + + + diff --git a/LedControl added COMMON ANODE display support/LedControlCA.cpp b/LedControl added COMMON ANODE display support/LedControlCA.cpp new file mode 100644 index 0000000..2e36d27 --- /dev/null +++ b/LedControl added COMMON ANODE display support/LedControlCA.cpp @@ -0,0 +1,310 @@ +/* + * LedControl.cpp - A library for controling Leds with a MAX7219/MAX7221 + * Copyright (c) 2007 Eberhard Fahle + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * This permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include "LedControl.h" + +//the opcodes for the MAX7221 and MAX7219 +#define OP_NOOP 0 +#define OP_DIGIT0 1 +#define OP_DIGIT1 2 +#define OP_DIGIT2 3 +#define OP_DIGIT3 4 +#define OP_DIGIT4 5 +#define OP_DIGIT5 6 +#define OP_DIGIT6 7 +#define OP_DIGIT7 8 +#define OP_DECODEMODE 9 +#define OP_INTENSITY 10 +#define OP_SCANLIMIT 11 +#define OP_SHUTDOWN 12 +#define OP_DISPLAYTEST 15 + +LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices, bool anode) { + SPI_MOSI=dataPin; + SPI_CLK=clkPin; + SPI_CS=csPin; + if(numDevices<=0 || numDevices>8 ) + numDevices=8; + maxDevices=numDevices; + anodeMode=anode; + pinMode(SPI_MOSI,OUTPUT); + pinMode(SPI_CLK,OUTPUT); + pinMode(SPI_CS,OUTPUT); + digitalWrite(SPI_CS,HIGH); + SPI_MOSI=dataPin; + for(int i=0;i<64;i++) { + status[i]=0x00; + statusTransposed[i]=0x00; + } + for(int i=0;i=maxDevices) + return; + if(b) + spiTransfer(addr, OP_SHUTDOWN,0); + else + spiTransfer(addr, OP_SHUTDOWN,1); +} + +void LedControl::setScanLimit(int addr, int limit) { + if(addr<0 || addr>=maxDevices) + return; + if(limit>=0 || limit<8) + spiTransfer(addr, OP_SCANLIMIT,limit); +} + +void LedControl::setIntensity(int addr, int intensity) { + if(addr<0 || addr>=maxDevices) + return; + if(intensity>=0 || intensity<16) + spiTransfer(addr, OP_INTENSITY,intensity); + +} + +void LedControl::clearDisplay(int addr) { + int offset; + + if(addr<0 || addr>=maxDevices) + return; + offset=addr*8; + for(int i=0;i<8;i++) { + status[offset+i]=0; + } + if (anodeMode) { + transposeData(addr); + for(int i=0;i<8;i++) { + spiTransfer(addr, i+1, statusTransposed[offset+i]); + } + } else { + for(int i=0;i<8;i++) { + spiTransfer(addr, i+1, status[offset+i]); + } + } +} + +void LedControl::setLed(int addr, int row, int column, boolean state) { + int offset; + byte val=0x00; + + if(addr<0 || addr>=maxDevices) + return; + if(row<0 || row>7 || column<0 || column>7) + return; + offset=addr*8; + val=B10000000 >> column; + if(state) + status[offset+row]=status[offset+row]|val; + else { + val=~val; + status[offset+row]=status[offset+row]&val; + } + spiTransfer(addr, row+1,status[offset+row]); +} + +void LedControl::setRow(int addr, int row, byte value) { + int offset; + if(addr<0 || addr>=maxDevices) + return; + if(row<0 || row>7) + return; + offset=addr*8; + status[offset+row]=value; + spiTransfer(addr, row+1,status[offset+row]); +} + +void LedControl::setColumn(int addr, int col, byte value) { + byte val; + + if(addr<0 || addr>=maxDevices) + return; + if(col<0 || col>7) + return; + for(int row=0;row<8;row++) { + val=value >> (7-row); + val=val & 0x01; + setLed(addr,row,col,val); + } +} + +void LedControl::setDigit(int addr, int digit, byte value, boolean dp) { + int offset; + byte v; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7 || value>15) + return; + offset=addr*8; + v=charTable[value]; + if(dp) + v|=B10000000; + status[offset+digit]=v; + if (anodeMode) { + //transpose the digit matrix + transposeData(addr); + //send the entire set of digits + for(int i=0;i<8;i++) { + spiTransfer(addr, i+1, statusTransposed[offset+i]); + } + } else { + spiTransfer(addr, digit+1, v); + } +} + +void LedControl::setChar(int addr, int digit, char value, boolean dp) { + int offset; + byte index,v; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7) + return; + + offset=addr*8; + index=(byte)value; + if(index >127) { + //nothing defined we use the space char + value=32; + } + v=charTable[index]; + if(dp) + v|=B10000000; + status[offset+digit]=v; + if (anodeMode) { + //transpose the digit matrix + transposeData(addr); + //send the entire set of digits + for(int i=0;i<8;i++) { + spiTransfer(addr, i+1, statusTransposed[offset+i]); + } + } else { + spiTransfer(addr, digit+1, v); + } +} + +void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) { + //Create an array with the data to shift out + int offset=addr*2; + int maxbytes=maxDevices*2; + + for(int i=0;i0;i--) + shiftOut(SPI_MOSI,SPI_CLK,MSBFIRST,spidata[i-1]); + //latch the data onto the display + digitalWrite(SPI_CS,HIGH); +} + + +void LedControl::transposeData(int addr) { + int offset=addr*8; + byte a0, a1, a2, a3, a4, a5, a6, a7, + b0, b1, b2, b3, b4, b5, b6, b7; + + // Perform a bitwise transpose operation on an 8x8 bit matrix, stored as 8-byte array. + // We have to use the naive method because we're working on a 16-bit microprocessor. + + // Load the array into eight one-byte variables. + a0 = status[offset]; + a1 = status[offset+1]; + a2 = status[offset+2]; + a3 = status[offset+3]; + a4 = status[offset+4]; + a5 = status[offset+5]; + a6 = status[offset+6]; + a7 = status[offset+7]; + + // Magic happens. Credit goes to: http://www.hackersdelight.org/HDcode/transpose8.c.txt + b0 = (a0 & 128) | (a1 & 128)/2 | (a2 & 128)/4 | (a3 & 128)/8 | + (a4 & 128)/16 | (a5 & 128)/32 | (a6 & 128)/64 | (a7 )/128; + b1 = (a0 & 64)*2 | (a1 & 64) | (a2 & 64)/2 | (a3 & 64)/4 | + (a4 & 64)/8 | (a5 & 64)/16 | (a6 & 64)/32 | (a7 & 64)/64; + b2 = (a0 & 32)*4 | (a1 & 32)*2 | (a2 & 32) | (a3 & 32)/2 | + (a4 & 32)/4 | (a5 & 32)/8 | (a6 & 32)/16 | (a7 & 32)/32; + b3 = (a0 & 16)*8 | (a1 & 16)*4 | (a2 & 16)*2 | (a3 & 16) | + (a4 & 16)/2 | (a5 & 16)/4 | (a6 & 16)/8 | (a7 & 16)/16; + b4 = (a0 & 8)*16 | (a1 & 8)*8 | (a2 & 8)*4 | (a3 & 8)*2 | + (a4 & 8) | (a5 & 8)/2 | (a6 & 8)/4 | (a7 & 8)/8; + b5 = (a0 & 4)*32 | (a1 & 4)*16 | (a2 & 4)*8 | (a3 & 4)*4 | + (a4 & 4)*2 | (a5 & 4) | (a6 & 4)/2 | (a7 & 4)/4; + b6 = (a0 & 2)*64 | (a1 & 2)*32 | (a2 & 2)*16 | (a3 & 2)*8 | + (a4 & 2)*4 | (a5 & 2)*2 | (a6 & 2) | (a7 & 2)/2; + b7 = (a0 )*128| (a1 & 1)*64 | (a2 & 1)*32 | (a3 & 1)*16| + (a4 & 1)*8 | (a5 & 1)*4 | (a6 & 1)*2 | (a7 & 1); + + // Assemble into output array. + statusTransposed[offset] = b0; + statusTransposed[offset+1] = b1; + statusTransposed[offset+2] = b2; + statusTransposed[offset+3] = b3; + statusTransposed[offset+4] = b4; + statusTransposed[offset+5] = b5; + statusTransposed[offset+6] = b6; + statusTransposed[offset+7] = b7; + +} + +void LedControl::setDirectDigit(int addr, int digit, byte value) { + int offset; + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7) + return; + offset=addr*8; + status[offset+digit]=value; + if (anodeMode) { + transposeData(addr); + for(int i=0;i<8;i++) { + spiTransfer(addr, i+1, statusTransposed[offset+i]); + } + } else { + spiTransfer(addr, digit+1, value); + } +} + diff --git a/LedControl added COMMON ANODE display support/LedControlCA.h b/LedControl added COMMON ANODE display support/LedControlCA.h new file mode 100644 index 0000000..576ff0a --- /dev/null +++ b/LedControl added COMMON ANODE display support/LedControlCA.h @@ -0,0 +1,217 @@ +/* + * LedControl.h - A library for controling Leds with a MAX7219/MAX7221 + * Copyright (c) 2007 Eberhard Fahle + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * This permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LedControl_h +#define LedControl_h + +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +/* + * Segments to be switched on for characters and digits on + * 7-Segment Displays + */ +const static byte charTable[128] = { + B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, + B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000, + B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, + B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, + B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, + B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000, + B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, + B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, + B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, + B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000 +}; + +class LedControl { + private : + /* The array for shifting the data to the devices */ + byte spidata[16]; + /* Send out a single command to the device */ + void spiTransfer(int addr, byte opcode, byte data); + + /* We keep track of the led-status for all 8 devices in this array */ + byte status[64]; + /* We also keep track of the transposed version */ + byte statusTransposed[64]; + /* Data is shifted out of this pin*/ + int SPI_MOSI; + /* The clock is signaled on this pin */ + int SPI_CLK; + /* This one is driven LOW for chip selectzion */ + int SPI_CS; + /* The maximum number of devices we use */ + int maxDevices; + /* Choose whether we're using common cathode or common anode displays */ + bool anodeMode; + + + public: + /* + * Create a new controler + * Params : + * dataPin pin on the Arduino where data gets shifted out + * clockPin pin for the clock + * csPin pin for selecting the device + * numDevices maximum number of devices that can be controled + * anode false for common-cathode displays, true for common-anode displays + */ + LedControl(int dataPin, int clkPin, int csPin, int numDevices=1, bool anode=false); + /* + * Gets the number of devices attached to this LedControl. + * Returns : + * int the number of devices on this LedControl + */ + int getDeviceCount(); + + /* + * Set the shutdown (power saving) mode for the device + * Params : + * addr The address of the display to control + * status If true the device goes into power-down mode. Set to false + * for normal operation. + */ + void shutdown(int addr, bool status); + + /* + * Set the number of digits (or rows) to be displayed. + * See datasheet for sideeffects of the scanlimit on the brightness + * of the display. + * Params : + * addr address of the display to control + * limit number of digits to be displayed (1..8) + */ + void setScanLimit(int addr, int limit); + + /* + * Set the brightness of the display. + * Params: + * addr the address of the display to control + * intensity the brightness of the display. (0..15) + */ + void setIntensity(int addr, int intensity); + + /* + * Switch all Leds on the display off. + * Params: + * addr address of the display to control + */ + void clearDisplay(int addr); + + /* + * Set the status of a single Led. + * Params : + * addr address of the display + * row the row of the Led (0..7) + * col the column of the Led (0..7) + * state If true the led is switched on, + * if false it is switched off + */ + void setLed(int addr, int row, int col, boolean state); + + /* + * Set all 8 Led's in a row to a new state + * Params: + * addr address of the display + * row row which is to be set (0..7) + * value each bit set to 1 will light up the + * corresponding Led. + */ + void setRow(int addr, int row, byte value); + + /* + * Set all 8 Led's in a column to a new state + * Params: + * addr address of the display + * col column which is to be set (0..7) + * value each bit set to 1 will light up the + * corresponding Led. + */ + void setColumn(int addr, int col, byte value); + + /* + * Display a hexadecimal digit on a 7-Segment Display + * Params: + * addr address of the display + * digit the position of the digit on the display (0..7) + * value the value to be displayed. (0x00..0x0F) + * dp sets the decimal point. + */ + void setDigit(int addr, int digit, byte value, boolean dp); + + + + + /* + * Display a character on a 7-Segment display. + * There are only a few characters that make sense here : + * '0','1','2','3','4','5','6','7','8','9','0', + * 'A','b','c','d','E','F','H','L','P', + * '.','-','_',' ' + * Params: + * addr address of the display + * digit the position of the character on the display (0..7) + * value the character to be displayed. + * dp sets the decimal point. + */ + void setChar(int addr, int digit, char value, boolean dp); + + + /* + * Transpose data matrix for use with common-anode displays. + * Params: + * addr address of the display + */ + void transposeData(int addr); + + /* + * Light up segments of a 7-segment display directly by passing a binary value. + * The eight bits of the byte each refer to a segment: + * Byte: 0 0 0 0 0 0 0 0 + * Segments: DP A B C D E F G + * Params: + * addr address of the display + * digit the position of the character on the display (0..7) + * value the binary value to be displayed + */ + void setDirectDigit(int addr, int digit, byte value); + +}; + +#endif //LedControl.h + + + diff --git a/LedControl added COMMON ANODE display support/MAX7219 and Common Anode displays with LedControl - Arduino Forum.pdf b/LedControl added COMMON ANODE display support/MAX7219 and Common Anode displays with LedControl - Arduino Forum.pdf new file mode 100644 index 0000000..9faf8c0 Binary files /dev/null and b/LedControl added COMMON ANODE display support/MAX7219 and Common Anode displays with LedControl - Arduino Forum.pdf differ diff --git a/LedControl added COMMON ANODE display support/common-anode.patch b/LedControl added COMMON ANODE display support/common-anode.patch new file mode 100644 index 0000000..87f2319 --- /dev/null +++ b/LedControl added COMMON ANODE display support/common-anode.patch @@ -0,0 +1,228 @@ +Common subdirectories: LedControl-unpatched/examples and LedControl/examples +diff -u LedControl-unpatched/LedControl.cpp LedControl/LedControl.cpp +--- LedControl-unpatched/LedControl.cpp 2008-10-14 02:21:21.000000000 -0700 ++++ LedControl/LedControl.cpp 2012-09-02 01:24:35.000000000 -0700 +@@ -35,20 +35,23 @@ + #define OP_SHUTDOWN 12 + #define OP_DISPLAYTEST 15 + +-LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) { ++LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices, bool anode) { + SPI_MOSI=dataPin; + SPI_CLK=clkPin; + SPI_CS=csPin; + if(numDevices<=0 || numDevices>8 ) + numDevices=8; + maxDevices=numDevices; ++ anodeMode=anode; + pinMode(SPI_MOSI,OUTPUT); + pinMode(SPI_CLK,OUTPUT); + pinMode(SPI_CS,OUTPUT); + digitalWrite(SPI_CS,HIGH); + SPI_MOSI=dataPin; +- for(int i=0;i<64;i++) ++ for(int i=0;i<64;i++) { + status[i]=0x00; ++ statusTransposed[i]=0x00; ++ } + for(int i=0;i127) { +- //nothing define we use the space char ++ //nothing defined we use the space char + value=32; + } + v=charTable[index]; + if(dp) + v|=B10000000; + status[offset+digit]=v; +- spiTransfer(addr, digit+1,v); ++ if (anodeMode) { ++ //transpose the digit matrix ++ transposeData(addr); ++ //send the entire set of digits ++ for(int i=0;i<8;i++) { ++ spiTransfer(addr, i+1, statusTransposed[offset+i]); ++ } ++ } else { ++ spiTransfer(addr, digit+1, v); ++ } + } + + void LedControl::spiTransfer(int addr, volatile byte opcode, volatile byte data) { +@@ -202,4 +231,73 @@ + digitalWrite(SPI_CS,HIGH); + } + ++void LedControl::transposeData(int addr) { ++ int offset=addr*8; ++ byte a0, a1, a2, a3, a4, a5, a6, a7, ++ b0, b1, b2, b3, b4, b5, b6, b7; ++ ++ // Perform a bitwise transpose operation on an 8x8 bit matrix, stored as 8-byte array. ++ // We have to use the naive method because we're working on a 16-bit microprocessor. ++ ++ // Load the array into eight one-byte variables. ++ a0 = status[offset]; ++ a1 = status[offset+1]; ++ a2 = status[offset+2]; ++ a3 = status[offset+3]; ++ a4 = status[offset+4]; ++ a5 = status[offset+5]; ++ a6 = status[offset+6]; ++ a7 = status[offset+7]; ++ ++ // Magic happens. Credit goes to: http://www.hackersdelight.org/HDcode/transpose8.c.txt ++ b0 = (a0 & 128) | (a1 & 128)/2 | (a2 & 128)/4 | (a3 & 128)/8 | ++ (a4 & 128)/16 | (a5 & 128)/32 | (a6 & 128)/64 | (a7 )/128; ++ b1 = (a0 & 64)*2 | (a1 & 64) | (a2 & 64)/2 | (a3 & 64)/4 | ++ (a4 & 64)/8 | (a5 & 64)/16 | (a6 & 64)/32 | (a7 & 64)/64; ++ b2 = (a0 & 32)*4 | (a1 & 32)*2 | (a2 & 32) | (a3 & 32)/2 | ++ (a4 & 32)/4 | (a5 & 32)/8 | (a6 & 32)/16 | (a7 & 32)/32; ++ b3 = (a0 & 16)*8 | (a1 & 16)*4 | (a2 & 16)*2 | (a3 & 16) | ++ (a4 & 16)/2 | (a5 & 16)/4 | (a6 & 16)/8 | (a7 & 16)/16; ++ b4 = (a0 & 8)*16 | (a1 & 8)*8 | (a2 & 8)*4 | (a3 & 8)*2 | ++ (a4 & 8) | (a5 & 8)/2 | (a6 & 8)/4 | (a7 & 8)/8; ++ b5 = (a0 & 4)*32 | (a1 & 4)*16 | (a2 & 4)*8 | (a3 & 4)*4 | ++ (a4 & 4)*2 | (a5 & 4) | (a6 & 4)/2 | (a7 & 4)/4; ++ b6 = (a0 & 2)*64 | (a1 & 2)*32 | (a2 & 2)*16 | (a3 & 2)*8 | ++ (a4 & 2)*4 | (a5 & 2)*2 | (a6 & 2) | (a7 & 2)/2; ++ b7 = (a0 )*128| (a1 & 1)*64 | (a2 & 1)*32 | (a3 & 1)*16| ++ (a4 & 1)*8 | (a5 & 1)*4 | (a6 & 1)*2 | (a7 & 1); ++ ++ // Assemble into output array. ++ statusTransposed[offset] = b0; ++ statusTransposed[offset+1] = b1; ++ statusTransposed[offset+2] = b2; ++ statusTransposed[offset+3] = b3; ++ statusTransposed[offset+4] = b4; ++ statusTransposed[offset+5] = b5; ++ statusTransposed[offset+6] = b6; ++ statusTransposed[offset+7] = b7; ++ ++} ++ ++void LedControl::setDirectDigit(int addr, int digit, byte value) { ++ int offset; ++ ++ if(addr<0 || addr>=maxDevices) ++ return; ++ if(digit<0 || digit>7) ++ return; ++ offset=addr*8; ++ status[offset+digit]=value; ++ if (anodeMode) { ++ transposeData(addr); ++ for(int i=0;i<8;i++) { ++ spiTransfer(addr, i+1, statusTransposed[offset+i]); ++ } ++ } else { ++ spiTransfer(addr, digit+1, value); ++ } ++} ++ ++ ++ + +diff -u LedControl-unpatched/LedControl.h LedControl/LedControl.h +--- LedControl-unpatched/LedControl.h 2011-09-20 23:49:06.000000000 -0700 ++++ LedControl/LedControl.h 2012-09-02 00:18:47.000000000 -0700 +@@ -58,6 +58,8 @@ + + /* We keep track of the led-status for all 8 devices in this array */ + byte status[64]; ++ /* We also keep track of the transposed version */ ++ byte statusTransposed[64]; + /* Data is shifted out of this pin*/ + int SPI_MOSI; + /* The clock is signaled on this pin */ +@@ -66,6 +68,8 @@ + int SPI_CS; + /* The maximum number of devices we use */ + int maxDevices; ++ /* Choose whether we're using common cathode or common anode displays */ ++ bool anodeMode; + + public: + /* +@@ -75,8 +79,9 @@ + * clockPin pin for the clock + * csPin pin for selecting the device + * numDevices maximum number of devices that can be controled ++ * anode false for common-cathode displays, true for common-anode displays + */ +- LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); ++ LedControl(int dataPin, int clkPin, int csPin, int numDevices=1, bool anode=false); + + /* + * Gets the number of devices attached to this LedControl. +@@ -173,9 +178,25 @@ + * dp sets the decimal point. + */ + void setChar(int addr, int digit, char value, boolean dp); ++ ++ /* ++ * Transpose data matrix for use with common-anode displays. ++ * Params: ++ * addr address of the display ++ */ ++ void transposeData(int addr); ++ ++ /* ++ * Light up segments of a 7-segment display directly by passing a binary value. ++ * The eight bits of the byte each refer to a segment: ++ * Byte: 0 0 0 0 0 0 0 0 ++ * Segments: DP A B C D E F G ++ * Params: ++ * addr address of the display ++ * digit the position of the character on the display (0..7) ++ * value the binary value to be displayed ++ */ ++ void setDirectDigit(int addr, int digit, byte value); + }; + + #endif //LedControl.h +- +- +- diff --git a/LedControl added COMMON ANODE display support/examples/LCDemo7Segment/LCDemo7Segment.pde b/LedControl added COMMON ANODE display support/examples/LCDemo7Segment/LCDemo7Segment.pde new file mode 100644 index 0000000..a75f32f --- /dev/null +++ b/LedControl added COMMON ANODE display support/examples/LCDemo7Segment/LCDemo7Segment.pde @@ -0,0 +1,73 @@ +//We always have to include the library +#include "LedControl.h" + +/* + Now we need a LedControl to work with. + ***** These pin numbers will probably not work with your hardware ***** + pin 12 is connected to the DataIn + pin 11 is connected to the CLK + pin 10 is connected to LOAD + We have only a single MAX72XX. + */ +LedControl lc=LedControl(12,11,10,1); + +/* we always wait a bit between updates of the display */ +unsigned long delaytime=250; + +void setup() { + /* + The MAX72XX is in power-saving mode on startup, + we have to do a wakeup call + */ + lc.shutdown(0,false); + /* Set the brightness to a medium values */ + lc.setIntensity(0,8); + /* and clear the display */ + lc.clearDisplay(0); +} + + +/* + This method will display the characters for the + word "Arduino" one after the other on digit 0. + */ +void writeArduinoOn7Segment() { + lc.setChar(0,0,'a',false); + delay(delaytime); + lc.setRow(0,0,0x05); + delay(delaytime); + lc.setChar(0,0,'d',false); + delay(delaytime); + lc.setRow(0,0,0x1c); + delay(delaytime); + lc.setRow(0,0,B00010000); + delay(delaytime); + lc.setRow(0,0,0x15); + delay(delaytime); + lc.setRow(0,0,0x1D); + delay(delaytime); + lc.clearDisplay(0); + delay(delaytime); +} + +/* + This method will scroll all the hexa-decimal + numbers and letters on the display. You will need at least + four 7-Segment digits. otherwise it won't really look that good. + */ +void scrollDigits() { + for(int i=0;i<13;i++) { + lc.setDigit(0,3,i,false); + lc.setDigit(0,2,i+1,false); + lc.setDigit(0,1,i+2,false); + lc.setDigit(0,0,i+3,false); + delay(delaytime); + } + lc.clearDisplay(0); + delay(delaytime); +} + +void loop() { + writeArduinoOn7Segment(); + scrollDigits(); +} diff --git a/LedControl added COMMON ANODE display support/examples/LCDemoCascadedDevices/LCDemoCascadedDevices.pde b/LedControl added COMMON ANODE display support/examples/LCDemoCascadedDevices/LCDemoCascadedDevices.pde new file mode 100644 index 0000000..090b8dd --- /dev/null +++ b/LedControl added COMMON ANODE display support/examples/LCDemoCascadedDevices/LCDemoCascadedDevices.pde @@ -0,0 +1,52 @@ +//We always have to include the library +#include "LedControl.h" + +/* + Now we need a LedControl to work with. + ***** These pin numbers will probably not work with your hardware ***** + pin 12 is connected to the DataIn + pin 11 is connected to the CLK + pin 10 is connected to LOAD + ***** Please set the number of devices you have ***** + But the maximum default of 8 MAX72XX wil also work. + */ +LedControl lc=LedControl(12,11,10,8); + +/* we always wait a bit between updates of the display */ +unsigned long delaytime=500; + +/* + This time we have more than one device. + But all of them have to be initialized + individually. + */ +void setup() { + //we have already set the number of devices when we created the LedControl + int devices=lc.getDeviceCount(); + //we have to init all devices in a loop + for(int address=0;address