TM1638 LED controller. Max 80 LEDs, Max 24 Key scan. Supports LED&KEY, QYF-TM1638 and JY-LKM1638 module.

Dependents:   mbed_TM1638 Otjimaniya RL0201-V1

See here for more information.

Revision:
4:b2bbdc58967e
Parent:
3:25ddabfadc8c
--- a/TM1638.cpp	Tue Jan 19 18:58:22 2016 +0000
+++ b/TM1638.cpp	Sun Jan 31 12:11:06 2016 +0000
@@ -1,6 +1,7 @@
 /* mbed TM1638 Library, for TM1638 LED controller
  * Copyright (c) 2015, v01: WH, Initial version
  *               2016, v02: WH, Added ASCII alphabet display selector, refactored display and keyboard defines 
+ *               2016, v03: WH, Added QYF-TM1638 and LKM1638, refactoring of writeData() 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -98,12 +99,13 @@
   _writeCmd(TM1638_DSP_CTRL_CMD, _display | _bright );  // Display control cmd, display on/off, brightness   
 }
 
+
 /** Write databyte to TM1638
+  *  @param  char data byte written at given address
   *  @param  int address display memory location to write byte
-  *  @param  char data byte written at given address
   *  @return none
   */ 
-void TM1638::writeData(int address, char data) {
+void TM1638::writeData(char data, int address) {
   _cs=0;
   wait_us(1);    
   _spi.write(_flip(TM1638_ADDR_SET_CMD | (address & TM1638_ADDR_MSK))); // Set Address cmd
@@ -114,23 +116,28 @@
   _cs=1;             
 }
 
+
 /** Write Display datablock to TM1638
-  *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata (starting at address 0)
-  *  @param  length number bytes to write (valide range 0..TM1638_DISPLAY_MEM (=16), starting at address 0)     
+  *  @param  DisplayData_t data Array of TM1638_DISPLAY_MEM (=16) bytes for displaydata
+  *  @param  length number bytes to write (valid range 0..TM1638_DISPLAY_MEM (=16), when starting at address 0)
+  *  @param  int address display memory location to write bytes (default = 0)   
   *  @return none
   */ 
-void TM1638::writeData(DisplayData_t data, int length) {
+void TM1638::writeData(DisplayData_t data, int length, int address) {
   _cs=0;
   wait_us(1);    
-  _spi.write(_flip(TM1638_ADDR_SET_CMD | 0x00)); // Set Address at 0
-      
+       
 // sanity check
+  address &= TM1638_ADDR_MSK;
   if (length < 0) {length = 0;}
-  if (length > TM1638_DISPLAY_MEM) {length = TM1638_DISPLAY_MEM;}
+  if ((length + address) > TM1638_DISPLAY_MEM) {length = (TM1638_DISPLAY_MEM - address);}
 
-//  for (int idx=0; idx<TM1638_DISPLAY_MEM; idx++) {  
+  // _spi.write(_flip(TM1638_ADDR_SET_CMD | 0x00)); // Set Address at 0
+  _spi.write(_flip(TM1638_ADDR_SET_CMD | address)); // Set Address
+
   for (int idx=0; idx<length; idx++) {    
-    _spi.write(_flip(data[idx])); // data 
+    //_spi.write(_flip(data[idx])); // data 
+    _spi.write(_flip(data[address + idx])); // data 
   }
   
   wait_us(1);
@@ -319,12 +326,13 @@
 
    icn =        icon  & 0xFFFF;
   addr = (icon >> 24) & 0xFF; 
-  addr = (addr - 1) << 1;   // * PT1638_BYTES_PER_GRID
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
     
   //Save char...and set bits for icon to write
   _displaybuffer[addr]   = _displaybuffer[addr]   | LO(icn);      
   _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn);      
-  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+//  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
 }
 
 /** Clr Icon
@@ -342,7 +350,8 @@
   //Save char...and clr bits for icon to write
   _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(icn);      
   _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn);      
-  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+//  writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
 }
 
 
@@ -386,14 +395,15 @@
       if (_column > 0) {
         //Translate between _column and displaybuffer entries
         //Add DP to bitpattern of digit left of current column.
-        addr = (_column - 1) << 1; // * PT1638_BYTES_PER_GRID
+        addr = (_column - 1) << 1; // * TM1638_BYTES_PER_GRID
       
         //Save icons...and set bits for decimal point to write
         _displaybuffer[addr]   = _displaybuffer[addr] | pattern;
 //        _displaybuffer[addr+1] = _displaybuffer[addr+1] | pattern;
 
-        writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
-        
+//        writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+        writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);    
+          
         //No Cursor Update
       }
     }
@@ -444,8 +454,9 @@
       _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | pattern;
 //      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern;
 
-      writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
-                                
+//      writeData(_displaybuffer, (LEDKEY8_NR_GRIDS * TM1638_BYTES_PER_GRID));
+      writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);
+      
       //Update Cursor
       _column++;
       if (_column > (LEDKEY8_NR_DIGITS - 1)) {
@@ -464,3 +475,508 @@
 }
 
 #endif
+
+
+#if (QYF_TEST == 1) 
+// Derived class for TM1638 used in QYF-TM1638 display unit
+//
+
+/** Constructor for class for driving TM1638 LED controller as used in QYF
+  *
+  *  @brief Supports 8 Digits of 7 Segments + DP. Also supports a scanned keyboard of 16 keys.
+  *   
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+TM1638_QYF::TM1638_QYF(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) {
+  _column  = 0;
+  _columns = QYF_NR_DIGITS;    
+}  
+
+#if(0)
+#if DOXYGEN_ONLY
+    /** Write a character to the Display
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formatted string to the Display
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formatting the string.
+     */
+    int printf(const char* format, ...);   
+#endif
+#endif
+
+/** Locate cursor to a screen column
+  *
+  * @param column  The horizontal position from the left, indexed from 0
+  */
+void TM1638_QYF::locate(int column) {
+  //sanity check
+  if (column < 0) {column = 0;}
+  if (column > (_columns - 1)) {column = _columns - 1;}  
+  
+  _column = column;       
+}
+
+
+/** Number of screen columns
+  *
+  * @param none
+  * @return columns
+  */
+int TM1638_QYF::columns() {
+    return _columns;
+}
+
+    
+/** Clear the screen and locate to 0
+  * @param bool clrAll Clear Icons also (default = false)
+  */ 
+void TM1638_QYF::cls(bool clrAll) {  
+
+  if (clrAll) {
+    //clear local buffer (including Icons)
+    for (int idx=0; idx < (QYF_NR_GRIDS << 1); idx++) {
+      _displaybuffer[idx] = 0x00;  
+    }
+  }  
+  else {
+    //clear local buffer (preserving Icons)
+    for (int idx=0; idx < QYF_NR_GRIDS; idx++) {
+      _displaybuffer[(idx<<1)]     = _displaybuffer[(idx<<1)]     & MASK_ICON_GRID[idx][0];  
+      _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1];
+    }  
+  }
+
+  writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+
+  _column = 0;   
+}     
+
+/** Set Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_QYF::setIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and set bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   | LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn);      
+//  writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);    
+}
+
+/** Clr Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_QYF::clrIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and clr bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn);      
+//  writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);  
+}
+
+
+/** Set User Defined Characters (UDC)
+  *
+  * @param unsigned char udc_idx  The Index of the UDC (0..7)
+  * @param int udc_data           The bitpattern for the UDC (8 bits)       
+  */
+void TM1638_QYF::setUDC(unsigned char udc_idx, int udc_data) {
+
+  //Sanity check
+  if (udc_idx > (QYF_NR_UDC-1)) {
+    return;
+  }
+  // Mask out Icon bits?
+
+  _UDC_7S[udc_idx] = LO(udc_data);
+}
+
+
+/** Write a single character (Stream implementation)
+  */
+int TM1638_QYF::_putc(int value) {
+    bool validChar = false;
+    char pattern   = 0x00;
+    char bit       = 0x00;
+        
+    if ((value == '\n') || (value == '\r')) {
+      //No character to write
+      validChar = false;
+      
+      //Update Cursor      
+      _column = 0;
+    }
+    else if ((value == '.') || (value == ',')) {
+      //No character to write
+      validChar = false;
+      pattern = S7_DP; // placeholder for all DPs
+      
+      // Check to see that DP can be shown for current column
+      if (_column > 0) {
+        //Add DP to bitpattern of digit left of current column.
+        bit = 1 << (8 - _column); // bitposition for the previous _column
+
+        _displaybuffer[14] = (_displaybuffer[14] | bit); // set bit
+
+        writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+        
+        //No Cursor Update
+      }
+    }
+    else if ((value >= 0) && (value < QYF_NR_UDC)) {
+      //Character to write
+      validChar = true;
+      pattern = _UDC_7S[value];
+    }  
+    
+#if (SHOW_ASCII == 1)
+    //display all ASCII characters
+    else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - FONT_7S_START];
+    } // else
+#else    
+    //display only digits and hex characters      
+    else if (value == '-') {
+      //Character to write
+      validChar = true;
+      pattern = C7_MIN;         
+    }
+    else if ((value >= (int)'0') && (value <= (int) '9')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - (int) '0'];
+    }
+    else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'A'];
+    }
+    else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'a'];
+    } //else
+#endif
+
+    if (validChar) {
+      //Character to write
+
+      // Very annoying bitmapping :(
+      // This display module uses a single byte of each grid to drive a specific segment of all digits.
+      // So the bits in byte 0 (Grid 1) drive all A-segments, the bits in byte 2 (Grid 2) drive all B-segments etc.
+      // Bit0 is for the segment in Digit 8, Bit1 is for the segment in Digit 7 etc.. This bit manipulation is handled in _putc().
+      
+      bit = 1 << (7 - _column); // bitposition for the current _column
+
+      if (pattern & S7_A) {_displaybuffer[0] = (_displaybuffer[0] | bit); } // set bit
+      else                {_displaybuffer[0] = (_displaybuffer[0] & ~bit);} // clr bit       
+
+      if (pattern & S7_B) {_displaybuffer[2] = (_displaybuffer[2] | bit); } // set bit
+      else                {_displaybuffer[2] = (_displaybuffer[2] & ~bit);} // clr bit       
+
+      if (pattern & S7_C) {_displaybuffer[4] = (_displaybuffer[4] | bit); } // set bit
+      else                {_displaybuffer[4] = (_displaybuffer[4] & ~bit);} // clr bit       
+
+      if (pattern & S7_D) {_displaybuffer[6] = (_displaybuffer[6] | bit); } // set bit
+      else                {_displaybuffer[6] = (_displaybuffer[6] & ~bit);} // clr bit       
+
+      if (pattern & S7_E) {_displaybuffer[8] = (_displaybuffer[8] | bit); } // set bit
+      else                {_displaybuffer[8] = (_displaybuffer[8] & ~bit);} // clr bit       
+
+      if (pattern & S7_F) {_displaybuffer[10] = (_displaybuffer[10] | bit); } // set bit
+      else                {_displaybuffer[10] = (_displaybuffer[10] & ~bit);} // clr bit       
+
+      if (pattern & S7_G) {_displaybuffer[12] = (_displaybuffer[12] | bit); } // set bit
+      else                {_displaybuffer[12] = (_displaybuffer[12] & ~bit);} // clr bit       
+
+      if (pattern & S7_DP) {_displaybuffer[14] = (_displaybuffer[14] | bit); } // set bit
+      else                 {_displaybuffer[14] = (_displaybuffer[14] & ~bit);} // clr bit       
+
+      //Save icons...and set bits for character to write
+//      _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | pattern;
+//      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern;
+
+      writeData(_displaybuffer, (QYF_NR_GRIDS * TM1638_BYTES_PER_GRID));
+                                
+      //Update Cursor
+      _column++;
+      if (_column > (QYF_NR_DIGITS - 1)) {
+        _column = 0;
+      }
+
+    } // if validChar           
+
+    return value;
+}
+
+
+// get a single character (Stream implementation)
+int TM1638_QYF::_getc() {
+    return -1;
+}
+
+#endif
+
+
+
+#if (LKM1638_TEST == 1) 
+// Derived class for TM1638 used in LMK1638 display unit
+//
+
+/** Constructor for class for driving TM1638 LED controller as used in LKM1638
+  *
+  *  @brief Supports 8 Digits of 7 Segments + DP + Bi-Color LED Icons. Also supports a scanned keyboard of 8.
+  *   
+  *  @param  PinName mosi, miso, sclk, cs SPI bus pins
+  */
+TM1638_LKM1638::TM1638_LKM1638(PinName mosi, PinName miso, PinName sclk, PinName cs) : TM1638(mosi, miso, sclk, cs) {
+  _column  = 0;
+  _columns = LKM1638_NR_DIGITS;    
+}  
+
+#if(0)
+#if DOXYGEN_ONLY
+    /** Write a character to the Display
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formatted string to the Display
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formatting the string.
+     */
+    int printf(const char* format, ...);   
+#endif
+#endif
+
+/** Locate cursor to a screen column
+  *
+  * @param column  The horizontal position from the left, indexed from 0
+  */
+void TM1638_LKM1638::locate(int column) {
+  //sanity check
+  if (column < 0) {column = 0;}
+  if (column > (_columns - 1)) {column = _columns - 1;}  
+  
+  _column = column;       
+}
+
+
+/** Number of screen columns
+  *
+  * @param none
+  * @return columns
+  */
+int TM1638_LKM1638::columns() {
+    return _columns;
+}
+
+    
+/** Clear the screen and locate to 0
+  * @param bool clrAll Clear Icons also (default = false)
+  */ 
+void TM1638_LKM1638::cls(bool clrAll) {  
+
+  if (clrAll) {
+    //clear local buffer (including Icons)
+    for (int idx=0; idx < (LKM1638_NR_GRIDS << 1); idx++) {
+      _displaybuffer[idx] = 0x00;  
+    }
+  }  
+  else {
+    //clear local buffer (preserving Icons)
+    for (int idx=0; idx < LKM1638_NR_GRIDS; idx++) {
+      _displaybuffer[(idx<<1)]     = _displaybuffer[(idx<<1)]     & MASK_ICON_GRID[idx][0];  
+      _displaybuffer[(idx<<1) + 1] = _displaybuffer[(idx<<1) + 1] & MASK_ICON_GRID[idx][1];
+    }  
+  }
+
+  writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+
+  _column = 0;   
+}     
+
+/** Set Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_LKM1638::setIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and set bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   | LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] | HI(icn);      
+//  writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
+}
+
+/** Clr Icon
+  *
+  * @param Icon icon Enums Icon has Grid position encoded in 8 MSBs, Icon pattern encoded in 16 LSBs
+  * @return none
+  */
+void TM1638_LKM1638::clrIcon(Icon icon) {
+  int addr, icn;
+
+   icn =        icon  & 0xFFFF;
+  addr = (icon >> 24) & 0xFF; 
+  addr = (addr - 1) << 1;   // * TM1638_BYTES_PER_GRID
+    
+  //Save char...and clr bits for icon to write
+  _displaybuffer[addr]   = _displaybuffer[addr]   & ~LO(icn);      
+  _displaybuffer[addr+1] = _displaybuffer[addr+1] & ~HI(icn);      
+//  writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+  writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);      
+}
+
+
+/** Set User Defined Characters (UDC)
+  *
+  * @param unsigned char udc_idx  The Index of the UDC (0..7)
+  * @param int udc_data           The bitpattern for the UDC (8 bits)       
+  */
+void TM1638_LKM1638::setUDC(unsigned char udc_idx, int udc_data) {
+
+  //Sanity check
+  if (udc_idx > (LKM1638_NR_UDC-1)) {
+    return;
+  }
+  // Mask out Icon bits?
+
+  _UDC_7S[udc_idx] = LO(udc_data);
+}
+
+
+/** Write a single character (Stream implementation)
+  */
+int TM1638_LKM1638::_putc(int value) {
+    int addr;
+    bool validChar = false;
+    char pattern   = 0x00;
+    
+    if ((value == '\n') || (value == '\r')) {
+      //No character to write
+      validChar = false;
+      
+      //Update Cursor      
+      _column = 0;
+    }
+    else if ((value == '.') || (value == ',')) {
+      //No character to write
+      validChar = false;
+      pattern = S7_DP; // placeholder for all DPs
+      
+      // Check to see that DP can be shown for current column
+      if (_column > 0) {
+        //Translate between _column and displaybuffer entries
+        //Add DP to bitpattern of digit left of current column.
+        addr = (_column - 1) << 1; // * TM1638_BYTES_PER_GRID
+      
+        //Save icons...and set bits for decimal point to write
+        _displaybuffer[addr]   = _displaybuffer[addr] | pattern;
+//        _displaybuffer[addr+1] = _displaybuffer[addr+1] | pattern;
+
+//        writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+        writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);    
+          
+        //No Cursor Update
+      }
+    }
+    else if ((value >= 0) && (value < LKM1638_NR_UDC)) {
+      //Character to write
+      validChar = true;
+      pattern = _UDC_7S[value];
+    }  
+    
+#if (SHOW_ASCII == 1)
+    //display all ASCII characters
+    else if ((value >= FONT_7S_START) && (value <= FONT_7S_END)) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - FONT_7S_START];
+    } // else
+#else    
+    //display only digits and hex characters      
+    else if (value == '-') {
+      //Character to write
+      validChar = true;
+      pattern = C7_MIN;         
+    }
+    else if ((value >= (int)'0') && (value <= (int) '9')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[value - (int) '0'];
+    }
+    else if ((value >= (int) 'A') && (value <= (int) 'F')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'A'];
+    }
+    else if ((value >= (int) 'a') && (value <= (int) 'f')) {   
+      //Character to write
+      validChar = true;
+      pattern = FONT_7S[10 + value - (int) 'a'];
+    } //else
+#endif
+
+    if (validChar) {
+      //Character to write
+ 
+      //Translate between _column and displaybuffer entries
+      addr = _column << 1; // * TM1638_BYTES_PER_GRID
+
+      //Save icons...and set bits for character to write
+      _displaybuffer[addr]   = (_displaybuffer[addr]   & MASK_ICON_GRID[_column][0]) | pattern;
+//      _displaybuffer[addr+1] = (_displaybuffer[addr+1] & MASK_ICON_GRID[_column][0]) | pattern;
+
+//      writeData(_displaybuffer, (LKM1638_NR_GRIDS * TM1638_BYTES_PER_GRID));
+      writeData(_displaybuffer, TM1638_BYTES_PER_GRID, addr);
+      
+      //Update Cursor
+      _column++;
+      if (_column > (LKM1638_NR_DIGITS - 1)) {
+        _column = 0;
+      }
+
+    } // if validChar           
+
+    return value;
+}
+
+
+// get a single character (Stream implementation)
+int TM1638_LKM1638::_getc() {
+    return -1;
+}
+
+#endif
+