diff --git a/examples/LCDemo7Segment/LCDemo7Segment.ino b/examples/LCDemo7Segment/LCDemo7Segment.ino index a75f32f9..16c119f8 100644 --- a/examples/LCDemo7Segment/LCDemo7Segment.ino +++ b/examples/LCDemo7Segment/LCDemo7Segment.ino @@ -3,18 +3,28 @@ /* 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 + ***** Check pin numbers will probably not work with your hardware ***** We have only a single MAX72XX. */ -LedControl lc=LedControl(12,11,10,1); +#define TRACE_ON + +#define LC_DATA_PIN 8 +#define LC_LOAD_PIN 7 +#define LC_CLK_PIN 6 +#define LC_MODULE_COUNT 1 + +LedControl lc=LedControl(LC_DATA_PIN,LC_CLK_PIN,LC_LOAD_PIN,LC_MODULE_COUNT); +bool rotate=false; /* we always wait a bit between updates of the display */ -unsigned long delaytime=250; +unsigned long delaytime=500; void setup() { + #ifdef TRACE_ON + char compile_signature[] = "--- START (Build: " __DATE__ " " __TIME__ ") ---"; + Serial.begin(9600); + Serial.println(compile_signature); + #endif /* The MAX72XX is in power-saving mode on startup, we have to do a wakeup call @@ -26,30 +36,67 @@ void setup() { lc.clearDisplay(0); } +/* Loop over demonstration sequences. Comment unnecessary if u like*/ +void loop() { + + writeArduinoOn7Segment(); // expects 1 digit + scrollDigits(); // expects 4 digits + writeArduinoString(); // expects 8 digits + writeGoStringOnPositions(); // expects 8 digits + traverseCodepage(); // expects 8 digits + rotate=!rotate; + lc.setRotate180(0,rotate); +} + /* This method will display the characters for the word "Arduino" one after the other on digit 0. */ + void writeArduinoOn7Segment() { + lc.clearDisplay(0); lc.setChar(0,0,'a',false); delay(delaytime); - lc.setRow(0,0,0x05); + lc.setChar(0,0,'r',false); delay(delaytime); lc.setChar(0,0,'d',false); delay(delaytime); - lc.setRow(0,0,0x1c); + lc.setChar(0,0,'u',false); delay(delaytime); - lc.setRow(0,0,B00010000); + lc.setChar(0,0,'i',false); delay(delaytime); - lc.setRow(0,0,0x15); + lc.setChar(0,0,'n',false); delay(delaytime); - lc.setRow(0,0,0x1D); + lc.setChar(0,0,'o',false); delay(delaytime); lc.clearDisplay(0); delay(delaytime); } +/* + This method will display the String + "Arduino" on a 8 digit 7 Seg display + */ +void writeArduinoString() { + lc.setString(0,7,"Arduino",0x02); + delay(delaytime*5); +} + +/* + This method will display the String + "Go" at different locations and demonstrate how the other digirs are preseved + */ + +void writeGoStringOnPositions() { + lc.setString(0,7,"________",0x55); + for(int i=1;i<8;i++) + { + lc.setString(0,i,"Go",0x80); + delay(delaytime); + } +} + /* This method will scroll all the hexa-decimal numbers and letters on the display. You will need at least @@ -67,7 +114,27 @@ void scrollDigits() { delay(delaytime); } -void loop() { - writeArduinoOn7Segment(); - scrollDigits(); +/* + This method will travers over the whole codepage in 4 byte steps + showing the characters on the rightside and the offset in decimal on the left + */ + +void traverseCodepage() +{ + String offsetAsString; + lc.clearDisplay(0); + lc.setString(0,7,"Codepage",0); + delay(delaytime*2); + lc.clearDisplay(0); + for (int i=0;i<128;i+=4) { + offsetAsString=String(i); + lc.setString(0,4+offsetAsString.length(),offsetAsString,0); + lc.setChar(0,3,i,false); + lc.setChar(0,2,i+1,false); + lc.setChar(0,1,i+2,false); + lc.setChar(0,0,i+3,false); + delay(delaytime*4); + } } + + diff --git a/keywords.txt b/keywords.txt index 9d2a94f1..8fd43417 100644 --- a/keywords.txt +++ b/keywords.txt @@ -21,6 +21,7 @@ setRow KEYWORD2 setColumn KEYWORD2 setDigit KEYWORD2 setChar KEYWORD2 +setString KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/src/LedControl.cpp b/src/LedControl.cpp index e43211fd..0fd68d10 100644 --- a/src/LedControl.cpp +++ b/src/LedControl.cpp @@ -43,7 +43,7 @@ #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, byte rotate180Flags) { SPI_MOSI=dataPin; SPI_CLK=clkPin; SPI_CS=csPin; @@ -57,6 +57,7 @@ LedControl::LedControl(int dataPin, int clkPin, int csPin, int numDevices) { SPI_MOSI=dataPin; for(int i=0;i<64;i++) status[i]=0x00; + rotate180=rotate180Flags; for(int i=0;i>3))|(B00000001&v); //Rotate pabcdefg -> pdefabcg + } if(dp) v|=B10000000; status[offset+digit]=v; @@ -183,29 +188,58 @@ void LedControl::setChar(int addr, int digit, char value, boolean dp) { index=32; } v=pgm_read_byte_near(charTable + index); + if(bitRead(rotate180,addr)) { + digit=7-digit; + v=(B01110000&(v<<3))|(B00001110&(v>>3))|(B00000001&v); //Rotate pabcdefg -> pdefabcg + } if(dp) v|=B10000000; status[offset+digit]=v; spiTransfer(addr, digit+1,v); } +void LedControl::setString(int addr, int digit, String theString,uint8_t dotpattern) +{ + + if(addr<0 || addr>=maxDevices) + return; + if(digit<0 || digit>7) + return; + for(int i=0;i=maxDevices) return; + } + } +} + 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; + int maxbytes=maxDevices*2; // two bytes (opcode+data) for every device - 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::setRotate180(int addr, boolean isRotated) { + bitWrite(rotate180,addr,isRotated); +}; + diff --git a/src/LedControl.h b/src/LedControl.h index cdfaa1f5..4234b13f 100644 --- a/src/LedControl.h +++ b/src/LedControl.h @@ -39,23 +39,35 @@ * Segments to be switched on for characters and digits on * 7-Segment Displays */ + +/* The following table is used to translate an ascii byte value + * to the corresponding 7segment bitmap pattern with segmentmapping "pabcdefg" + * To give the easyest usability with the most possible response, lower or upper case versions of + * letters are replaced by the other size, when the original size could not be designed properly. + * (Check the Comments to see the replacements) + * Also some designs are ambigous (e.g. 2 and Z, 0 and O, ( and C ). + * This must be sovled by giving good context, choosing good words. + * which lies in the responsibility of the final design. + * Some other designs are more a possibility, then a real representation, but may be more useful then just blank (e.g. :<=>) + */ const static byte charTable [] PROGMEM = { - 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,B00010101,B00011101, - B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, - B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000 +// 0/8 1/9 2/A 3/B 4/C 5/D 6/E 7/F + B01111110,B00110000,B01101101,B01111001, B00110011,B01011011,B01011111,B01110000, // (0) 0123 4567 + B01111111,B01111011,B01110111,B00011111, B00001101,B00111101,B01001111,B01000111, // (8) 89AB CDEF + B01100000,B00011000,B00001100,B01000010, B01101100,B01011010,B00110001,B00000111, // (16) •••• •••• + B01000000,B01001000,B01001001,B00000000, B00000000,B00000000,B00000000,B00000000, // (24) •••• •••• + B00000000,B00000000,B00100010,B00000000, B00000000,B00000000,B00000000,B00100000, // (32) ×"× ×××' + B01001110,B01111000,B01100011,B00000000, B10000000,B00000001,B10000000,B00100100, // (40) ()*× ,-./ + B01111110,B00110000,B01101101,B01111001, B00110011,B01011011,B01011111,B01110000, // (48) 0123 4567 + B01111111,B01111011,B00001001,B00000000, B00000000,B01000011,B01000001,B01100001, // (56) 89:× ×<=> + B00000000,B01110111,B01111111,B01001110, B00111101,B01001111,B01000111,B01011110, // (64) ×ABC DEFG + B00110111,B00000110,B00111100,B00000000, B00001110,B00000000,B00010101,B01111110, // (72) HIJ× L×nO + B01100111,B00000000,B00000000,B01011011, B00001111,B00111110,B00000000,B00000000, // (80) P××S tU×× + B00000000,B00111011,B01101101,B00000000, B00000000,B00010010,B01100010,B00001000, // (88) ×YZ× ×\^_ + B00000010,B01110111,B00011111,B00001101, B00111101,B01001111,B01000111,B01011110, // (96) `Abc dEFG + B00010111,B00010000,B00111100,B00000000, B00110000,B00000000,B00010101,B00011101, //(104) hiJ× l×no + B01100111,B00000000,B00000101,B01011011, B00001111,B00011100,B00000000,B00000000, //(112) P×rS tu×× + B00000000,B00111011,B01101101,B00000000, B00000110,B00000000,B00100101,B00000000 //(120) ×YZ× |×~× }; class LedControl { @@ -65,16 +77,19 @@ class LedControl { /* 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]; + /* led-status for 8 devices with 8 elements containing 8 leds (7 segments + DP) */ + byte status[64]; + /* bit flag, if display of device is rotated by 180 degrees */ + byte rotate180=0; + /* Data is shifted out of this pin*/ - int SPI_MOSI; + byte SPI_MOSI; /* The clock is signaled on this pin */ - int SPI_CLK; + byte SPI_CLK; /* This one is driven LOW for chip selectzion */ - int SPI_CS; - /* The maximum number of devices we use */ - int maxDevices; + byte SPI_CS; + /* The maximum number of 7 segment devices we use */ + byte maxDevices; public: /* @@ -84,13 +99,14 @@ class LedControl { * clockPin pin for the clock * csPin pin for selecting the device * numDevices maximum number of devices that can be controled + * rotate180Flags Flag for every device if it is mounted rotated by 180 degrees */ - LedControl(int dataPin, int clkPin, int csPin, int numDevices=1); + LedControl(int dataPin, int clkPin, int csPin, int numDevices=1, uint8_t rotate180Flags=0); /* * Gets the number of devices attached to this LedControl. * Returns : - * int the number of devices on this LedControl + * int the number of devices on this LedControl (1..n) */ int getDeviceCount(); @@ -108,7 +124,7 @@ class LedControl { * See datasheet for sideeffects of the scanlimit on the brightness * of the display. * Params : - * addr address of the display to control + * addr address of the display to control (0..n-1) * limit number of digits to be displayed (1..8) */ void setScanLimit(int addr, int limit); @@ -116,7 +132,7 @@ class LedControl { /* * Set the brightness of the display. * Params: - * addr the address of the display to control + * addr the address of the display to control (0..n-1) * intensity the brightness of the display. (0..15) */ void setIntensity(int addr, int intensity); @@ -131,7 +147,7 @@ class LedControl { /* * Set the status of a single Led. * Params : - * addr address of the display + * addr address of the display (0..n-1) * row the row of the Led (0..7) * col the column of the Led (0..7) * state If true the led is switched on, @@ -142,7 +158,7 @@ class LedControl { /* * Set all 8 Led's in a row to a new state * Params: - * addr address of the display + * addr address of the display (0..n-1) * row row which is to be set (0..7) * value each bit set to 1 will light up the * corresponding Led. @@ -152,7 +168,7 @@ class LedControl { /* * Set all 8 Led's in a column to a new state * Params: - * addr address of the display + * addr address of the display (0..n-1) * col column which is to be set (0..7) * value each bit set to 1 will light up the * corresponding Led. @@ -162,7 +178,7 @@ class LedControl { /* * Display a hexadecimal digit on a 7-Segment Display * Params: - * addr address of the display + * addr address of the display (0..n-1) * digit the position of the digit on the display (0..7) * value the value to be displayed. (0x00..0x0F) * dp sets the decimal point. @@ -170,18 +186,44 @@ class LedControl { 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 + * Display a character (according to ascii codepage) on a 7-Segment display. + * For the available characters check the char table + * in the upper part of this header file. + + * Params: + * addr address of the display (0..n-1) * 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); + + /* + * Display a string on a 7-Segment display. Starting at th defined the position + * Progressing left to right and ending with the last character. + * Digits after the string will not be changed) + * For the available characters check the char table + * in the upper part of this header file. + * Params: + * addr address of the display the string starts on (0..n-1) + * digit the start position of the string on the display (0..7) + * theString the character to be displayed. + * dotpattern Bitpattern to set the dots additionally along the string starting with the leftmost bit + */ + void setString(int addr, int startDigit, String theString, uint8_t dotpattern); + + /* + * Define if the character font and digit adress of a deviceare in calculated normal + * or for 180 dregee rotated display(Decimal points up) + + * Params: + * addr address of the display (0..n-1) + * isRotated boolean to set the rotation of the display + + */ + void setRotate180(int addr, boolean isRotated); + + }; #endif //LedControl.h