Advertisement
WolfLarsen33

TM16xx.tar

Mar 22nd, 2021
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 92.08 KB | None | 0 0
  1. TM16xx/ 0040777 0000000 0000000 00000000000 14026135507 007066 5 ustar 00 TM16xx/documents/ 0040777 0000000 0000000 00000000000 14026135626 011071 5 ustar 00 TM16xx/examples/ 0040777 0000000 0000000 00000000000 14026125125 010677 5 ustar 00 TM16xx/examples/TM1640_basic/ 0040777 0000000 0000000 00000000000 14026125035 012673 5 ustar 00 TM16xx/examples/TM1640_basic/TM1640_basic.ino 0100777 0000000 0000000 00000003420 14026127010 015370 0 ustar 00 /*
  2. Basic library example for TM1640. Kept small to fit in the limited space of an ATtiny44.
  3. Library based on TM1638 library by Ricardo Batista, adapted by Maxint-RD MMOLE 2018.
  4. Confirmed to work in the following environments:
  5. ATtiny44A using Arduino IDE 1.8.2 and ATTinyCore (8MHz, LTO enabled), 3232 bytes flash, 103 bytes RAM
  6. ATtiny44A using Arduino IDE 1.8.2 and ATtiny Microcontrolers (8MHz), 3212 bytes flash, 103 bytes RAM ==> 2892/95 ==> 2878/95
  7. Only compiled: not tested yet:
  8. Arduino Nano using Arduino IDE 1.8.2, Nano (Old Bootloader)), 3176 bytes flash, 95 bytes RAM
  9. For more information see https://github.com/maxint-rd/TM16xx
  10. */
  11. #include <TM1640.h>
  12.  
  13. #if !defined(LED_BUILTIN)
  14. #define LED_BUILTIN 4
  15. #endif
  16.  
  17. // Define a 4-digit display module. Pin suggestions:
  18. // ESP8266 (Wemos D1): data pin 5 (D1), clock pin 4 (D2)
  19. // ATtiny44A: data pin 9, clock pin 10 (LED_BUILTIN: 8 on ATTinyCore)
  20. TM1640 module(9, 10, 4); // data, clock, 4 digits
  21.  
  22. void setup()
  23. {
  24. pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
  25. module.setDisplayToString("HALO");
  26. delay(500); // wait
  27. //module.clearDisplay();
  28. }
  29.  
  30. void loop()
  31. {
  32. digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
  33. module.setupDisplay(true, 7); // sometimes noise on the line may change the intensity level
  34. int nTime = ((millis() / 1000) / 60) * 100 + (millis() / 1000) % 60; // minutes+seconds as integer
  35. module.setDisplayToDecNumber(nTime, _BV(4)); // display dot on digit 4
  36. delay(500); // wait
  37. digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
  38. module.setDisplayToDecNumber(nTime, _BV(3)); // display colon on digit 3
  39. delay(500); // wait
  40. } TM16xx/examples/TM1640_matrix/ 0040777 0000000 0000000 00000000000 14026127000 013110 5 ustar 00 TM16xx/examples/TM1640_matrix/TM1640_matrix.ino 0100777 0000000 0000000 00000006534 14026126674 016066 0 ustar 00 /*
  41. Matrix library example for TM1640. Kept small to fit in the limited space of an ATtiny44.
  42. NOTE: compile using LTO enabled!
  43. Library based on TM1638 library by Ricardo Batista, adapted by Maxint-RD MMOLE 2018.
  44. Confirmed to work in the following environments:
  45. * ATtiny44A using Arduino IDE 1.8.2 and ATTinyCore (8MHz, LTO enabled), 3232 bytes flash, 103 bytes RAM ==> 3086/137 ==> 2996/141 ==> 3000/115
  46. * ATtiny44A using Arduino IDE 1.8.2 and ATtiny Microcontrolers (8MHz), 3212 bytes flash, 103 bytes RAM == 3056/137 ==> 2976/115
  47. * WeMos D1-mini and TM1640 8x8 MatrixLED Shield using Arduino IDE 1.6.10: DIN=D7/13/MOSI, CLK=D5/14/SCK, 248644 bytes flash, 32312 bytes RAM
  48. Only compiled: not tested yet:
  49. * Arduino Nano using Arduino IDE 1.8.2, Nano (Old Bootloader)), 3388 bytes flash, 119 bytes RAM => 3298/115
  50. For more information see https://github.com/maxint-rd/TM16xx
  51. */
  52. #include <TM1640.h>
  53. #include <TM16xxMatrix.h>
  54.  
  55. #if !defined(LED_BUILTIN)
  56. #define LED_BUILTIN 4
  57. #endif
  58.  
  59. // Define a 4-digit display module. Pin suggestions:
  60. // ESP8266 (Wemos D1): data pin 5 (D1), clock pin 4 (D2)
  61. // ATtiny44A: data pin 9, clock pin 10 (LED_BUILTIN: 8 in ATtiny Core)
  62. //TM1640 module(9, 10, 4); // data, clock, 4 digits
  63. TM1640 module(13, 14); // For ESP8266/WeMos D1-mini: DIN=D7/13/MOSI, CLK=D5/14/SCK
  64. #define MATRIX_NUMCOLUMNS 8
  65. #define MATRIX_NUMROWS 8
  66. TM16xxMatrix matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS); // TM16xx object, columns, rows
  67.  
  68. void setup()
  69. {
  70. pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
  71. module.setDisplayToString("HALO");
  72. delay(500); // wait
  73. module.clearDisplay();
  74.  
  75. // all at once
  76. matrix.setAll(true);
  77. delay(200);
  78.  
  79. // Columns binary
  80. for(int i=0; i<MATRIX_NUMCOLUMNS; i++)
  81. {
  82. for(int j=0; j<=0xFF; j++)
  83. {
  84. matrix.setColumn(i,j);
  85. delay(5);
  86. }
  87. delay(200);
  88. }
  89. matrix.setAll(false);
  90.  
  91. // One pixel, column by column
  92. for(int i=0; i<MATRIX_NUMCOLUMNS; i++)
  93. {
  94. for(int j=0; j<MATRIX_NUMROWS; j++)
  95. {
  96. matrix.setPixel(i,j, true);
  97. delay(50);
  98. matrix.setPixel(i,j, false);
  99. }
  100. }
  101.  
  102. // One pixel, row by row
  103. for(int i=0; i<MATRIX_NUMROWS; i++)
  104. {
  105. for(int j=0; j<MATRIX_NUMCOLUMNS; j++)
  106. {
  107. matrix.setPixel(j,i, true);
  108. delay(50);
  109. matrix.setPixel(j,i, false);
  110. }
  111. }
  112. }
  113.  
  114. void loop()
  115. {
  116. /*
  117. digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
  118. module.setupDisplay(true, 7); // sometimes noise on the line may change the intensity level
  119. int nTime=((millis()/1000)/60)*100+(millis()/1000)%60; // minutes+seconds as integer
  120. module.setDisplayToDecNumber(nTime, _BV(4)); // display dot on digit 4
  121. delay(500); // wait
  122. digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
  123. module.setDisplayToDecNumber(nTime, _BV(3)); // display colon on digit 3
  124. delay(500); // wait
  125. */
  126. static bool fLoop=true;
  127.  
  128. // Fill/unfill columns
  129. for(int i=0; i<MATRIX_NUMROWS; i++)
  130. {
  131. for(int j=0; j<MATRIX_NUMCOLUMNS; j++)
  132. {
  133. matrix.setPixel(j, i, fLoop);
  134. delay(50);
  135. }
  136. /*
  137. for(int j=0; j<8; j++)
  138. {
  139. matrix.setPixel(i,j, false);
  140. delay(50);
  141. }
  142. */
  143. }
  144. fLoop=!fLoop;
  145. digitalWrite(LED_BUILTIN, fLoop); // turn the LED on (HIGH is the voltage level)
  146. }
  147. TM16xx/examples/TM16xxMatrix_Snake/ 0040777 0000000 0000000 00000000000 14026125130 014250 5 ustar 00 TM16xx/examples/TM16xxMatrix_Snake/TM16xxMatrix_Snake.ino 0100777 0000000 0000000 00000005760 14026127051 020350 0 ustar 00 /*
  148. * TM16xxMatrix_Snake Example
  149. *
  150. * Example to demonstrate TM16xxMatrix library.
  151. * Based on Snake.pde example of the MAX72xxPanel library
  152. *
  153. * Confirmed to work in the following environments:
  154. * - ATtiny44A using Arduino IDE 1.8.2 and ATtiny Microcontrolers (8MHz), DIN=9, CLK=10, 3976 bytes flash, 149 bytes RAM ==> 3962/149
  155. * - ATtiny44A using Arduino IDE 1.8.2 and ATTinyCore (8MHz, LTO enabled), DIN=9, CLK=10, 3974 bytes flash, 149 bytes RAM
  156. * - Arduino Nano and TM1637 5x6 mini-matrix using Arduino IDE 1.8.2, Nano (Old Bootloader), 4126 bytes flash, 149 bytes RAM
  157. * - WeMos D1-mini and TM1640 8x8 MatrixLED Shield using Arduino IDE 1.6.10: DIN=D7/13/MOSI, CLK=D5/14/SCK, 249176 bytes flash, 32356 bytes RAM
  158. *
  159. **/
  160.  
  161. #include <TM1640.h>
  162. #include <TM16xxMatrix.h>
  163.  
  164. //TM1640 module(9, 10); // DIN=9, CLK=10
  165. TM1640 module(13, 14); // For ESP8266/WeMos D1-mini: DIN=D7/13/MOSI, CLK=D5/14/SCK
  166. #define MATRIX_NUMCOLUMNS 8
  167. #define MATRIX_NUMROWS 8
  168. TM16xxMatrix matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS); // TM16xx object, columns, rows
  169.  
  170. const int pinRandom = A0;
  171.  
  172. const int wait = 100; // In milliseconds
  173. const int length = 8;
  174.  
  175. int x[length], y[length];
  176. int ptr, nextPtr;
  177.  
  178. void setup()
  179. {
  180. // flash the matrix (using relative slow matrix.setAll)
  181. matrix.setAll(true);
  182. delay(200);
  183. module.setupDisplay(true, 2); // set intensity lower
  184. delay(400);
  185. matrix.setAll(false); // Note: module.clearDisplay() doesn't clear the offscreen bitmap!
  186.  
  187. // Reset all variables
  188. for ( ptr = 0; ptr < length; ptr++ ) {
  189. x[ptr] = MATRIX_NUMCOLUMNS / 2;
  190. y[ptr] = MATRIX_NUMROWS / 2;
  191. }
  192. nextPtr = 0;
  193.  
  194. randomSeed(analogRead(pinRandom)); // Initialize random generator
  195. }
  196.  
  197. void loop()
  198. {
  199. // Shift pointer to the next segment
  200. ptr = nextPtr;
  201. nextPtr = next(ptr);
  202.  
  203. matrix.setPixel(x[ptr], y[ptr], true); // Draw the head of the snake
  204. //matrix.write(); // Send bitmap to display
  205.  
  206. delay(wait);
  207.  
  208. if ( ! occupied(nextPtr) ) {
  209. matrix.setPixel(x[nextPtr], y[nextPtr], false); // Remove the tail of the snake
  210. }
  211.  
  212. for ( int attempt = 0; attempt < 10; attempt++ ) {
  213.  
  214. // Jump at random one step up, down, left, or right
  215. switch ( random(4) ) {
  216. case 0: x[nextPtr] = constrain(x[ptr] + 1, 0, MATRIX_NUMCOLUMNS - 1); y[nextPtr] = y[ptr]; break;
  217. case 1: x[nextPtr] = constrain(x[ptr] - 1, 0, MATRIX_NUMCOLUMNS - 1); y[nextPtr] = y[ptr]; break;
  218. case 2: y[nextPtr] = constrain(y[ptr] + 1, 0, MATRIX_NUMROWS - 1); x[nextPtr] = x[ptr]; break;
  219. case 3: y[nextPtr] = constrain(y[ptr] - 1, 0, MATRIX_NUMROWS - 1); x[nextPtr] = x[ptr]; break;
  220. }
  221.  
  222. if ( ! occupied(nextPtr) ) {
  223. break; // The spot is empty, break out the for loop
  224. }
  225. }
  226. }
  227.  
  228. boolean occupied(int ptrA) {
  229. for ( int ptrB = 0 ; ptrB < length; ptrB++ ) {
  230. if ( ptrA != ptrB ) {
  231. if ( equal(ptrA, ptrB) ) {
  232. return true;
  233. }
  234. }
  235. }
  236.  
  237. return false;
  238. }
  239.  
  240. int next(int ptr) {
  241. return (ptr + 1) % length;
  242. }
  243.  
  244. boolean equal(int ptrA, int ptrB) {
  245. return x[ptrA] == x[ptrB] && y[ptrA] == y[ptrB];
  246. } TM16xx/keywords.txt 0100777 0000000 0000000 00000003473 14026127620 011502 0 ustar 00 #######################################
  247. # Syntax Coloring Map For TM16xx Lib
  248. #######################################
  249.  
  250. #######################################
  251. # Datatypes (KEYWORD1)
  252. #######################################
  253.  
  254. TM16xx KEYWORD1
  255. TM1620 KEYWORD1
  256. TM1628 KEYWORD1
  257. TM1637 KEYWORD1
  258. TM1638 KEYWORD1
  259. InvertedTM1638 KEYWORD1
  260. TM1638QYF KEYWORD1
  261. TM1640 KEYWORD1
  262. TM1650 KEYWORD1
  263. TM1668 KEYWORD1
  264. TM16xxMatrix KEYWORD1
  265. TM16xxDisplay KEYWORD1
  266. TM16xxMatrixGFX KEYWORD1
  267. TM16xxButtons KEYWORD1
  268.  
  269. #######################################
  270. # Methods and Functions (KEYWORD2)
  271. #######################################
  272.  
  273. setupDisplay KEYWORD2
  274. setDisplayToHexNumber KEYWORD2
  275. setDisplayToDecNumber KEYWORD2
  276. setDisplayToBinNumber KEYWORD2
  277. setDisplayDigit KEYWORD2
  278. setDisplay KEYWORD2
  279. clearDisplay KEYWORD2
  280. setDisplayToString KEYWORD2
  281. setLED KEYWORD2
  282. setLEDs KEYWORD2
  283. setRGBLED KEYWORD2
  284. setRGBLEDs KEYWORD2
  285. getButtons KEYWORD2
  286. sendCommand KEYWORD2
  287. sendData KEYWORD2
  288. sendChar KEYWORD2
  289. send KEYWORD2
  290. receive KEYWORD2
  291. setMirror KEYWORD2
  292. setPixel KEYWORD2
  293. getPixel KEYWORD2
  294. setPressTicks KEYWORD2
  295. attachRelease KEYWORD2
  296. attachClick KEYWORD2
  297. attachDoubleClick KEYWORD2
  298. attachLongPressStart KEYWORD2
  299. attachLongPressStop KEYWORD2
  300. attachDuringLongPress KEYWORD2
  301. tick KEYWORD2
  302. isLongPressed KEYWORD2
  303. getPressedTicks KEYWORD2
  304.  
  305. #######################################
  306. # Constants (LITERAL1)
  307. #######################################
  308. TM1638_COLOR_RED LITERAL1
  309. TM1638_COLOR_GREEN LITERAL1
  310.  
  311. TM1668_COLOR_NONE LITERAL1
  312. TM1668_COLOR_RED LITERAL1
  313. TM1668_COLOR_GREEN LITERAL1
  314. TM1668_COLOR_BLUE LITERAL1
  315. TM1668_COLOR_WHITE LITERAL1
  316. TM1668_COLOR_YELLOW LITERAL1
  317. TM1668_COLOR_PURPLE LITERAL1
  318. TM1668_COLOR_AQUA LITERAL1
  319. TM1668_DISPMODE_4x13 LITERAL1
  320. TM1668_DISPMODE_5x12 LITERAL1
  321. TM1668_DISPMODE_6x11 LITERAL1
  322. TM1668_DISPMODE_7x10 LITERAL1
  323. TM1650_DISPMODE_4x7 LITERAL1
  324. TM1650_DISPMODE_4x8 LITERAL1 TM16xx/library.properties 0100777 0000000 0000000 00000001021 14026127576 012651 0 ustar 00 name=TM16xx LEDs and Buttons
  325. version=0.4.3
  326. author=Maxint
  327. maintainer=Maxint R&D <mm_rd@maxint.nl>
  328. sentence=TM16xx library for Arduino. Supports LED and KEY modules based on TM1638 and similar chips.
  329. paragraph=Drive 7-segment displays or LED matrix displays that use a TM16xx chip. Read button states. Support modules/projects based on TM1620, TM1628, TM1637, TM1638, TM1640, TM1650, TM1668 and similar chips. Examples included.
  330. category=Signal Input/Output
  331. url=https://github.com/maxint-rd/TM16xx
  332. architectures=*
  333. includes=TM16xx.h TM16xx/README.md 0100777 0000000 0000000 00000035165 14026127545 010362 0 ustar 00 TM16xx
  334.  
  335. Arduino TM16xx library for LED & KEY and LED Matrix modules based on TM1638, TM1637, TM1640 and similar chips. Simply use print() on 7-segment displays and use Adafruit GFX on matrix displays.
  336. TM16xx LEDs and Buttons library
  337.  
  338. This Arduino library facilitates driving LED displays using TM16xx LED driver chips. The TM16xx chip family allows driving 7-segment LED displays or LED matrices. Next to built-in high-frequency LED multiplexing, they offer control of LED brightness. Most TM16xx chips also support reading key-scan data for button presses. Using this library you can simply use print() on a 7-segment display or use Adafruit GFX on a LED matrix. Currently this library supports the TM1620, TM1628, TM1630, TM1637, TM1638, TM1640, TM1650 and TM1668 chips. Note that there are similar chips made by other manufacturers that may be compatible with the Titan Micro chips. For instance: the HBS640 by WINRISE is compatible with the TM1640.
  339.  
  340. Made by Maxint R&D. See https://github.com/maxint-rd/
  341.  
  342. Initial version was based on the TM1638 library by Ricardo Batista. Further inspiration from the TM1637 library by Avishay, the Max72xxPanel library by Mark Ruys and the OneButton library by Matthias Hertel.
  343. Table of contents
  344.  
  345. TM16xx chip features
  346. Library structure
  347. Basic usage
  348. TM16xxDisplay class
  349. TM16xxMatrix class
  350. TM16xxMatrixGFX class
  351. TM16xxButtons class
  352. New in this library
  353. Features & limitations
  354. More information
  355.  
  356. TM16xx chip features
  357. Type segments x digits buttons interface
  358. TM1620 8 x 6 - 10 x 4 n/a DIN/CLK/STB
  359. TM1628 10 x 7 - 13 x 4 10 x 2 multi DIO/CLK/STB
  360. TM1630 7 x 5 - 8 x 4 7 x 1 multi DIO/CLK/STB
  361. TM1637 8 x 6 (common anode) 8 x 2 single DIO/CLK
  362. TM1638 10 x 8 8 x 3 multi DIO/CLK/STB
  363. TM1640 8 x 16 n/a DIN/CLK
  364. TM1650 8 x 4 7 x 4 single DIO/CLK (SDA/SCL)
  365. TM1668 10 x 7 - 13 x 4 10 x 2 multi DIO/CLK/STB
  366.  
  367. See the documents folder for datasheets containing more information about these chips and their pinouts.
  368. Library structure
  369.  
  370. This library has a layered structure to simplify the support of multiple TM16xx chips. By using a base class that provides a uniform API, your application doesn't need chip specific code. Likewise, the library can offer common functionality in display specific classes that support multiple chips.
  371.  
  372. The figure below illustrates that concept:
  373.  
  374. Layered structure
  375. Basic usage
  376.  
  377. To use this library you need to include the class that matches the chip on your module and instantiate the object:
  378.  
  379. #include <TM1638.h>
  380.  
  381. TM1638 module(8, 9, 7); // DIO=8, CLK=9, STB=7
  382.  
  383. In the setup() function you can set the intensity of the display, but that's not mandatory:
  384.  
  385. void setup() {
  386. module.setupDisplay(true, 2); // on=true, intensity-2 (range 0-7)
  387. module.setDisplayToString("HALO"); // display simple text
  388. }
  389.  
  390. In the loop() function you can use basic display methods provided by the base class:
  391.  
  392. void loop() {
  393. int nTime = ((millis() / 1000) / 60) * 100 + (millis() / 1000) % 60; // convert time to minutes+seconds as integer
  394. module.setDisplayToDecNumber(nTime, _BV(4)); // display milliseconds with dot on digit 4
  395. }
  396.  
  397. For the easy to use print() method and more advance display methods you can use the TM16xxDisplay class.
  398.  
  399. The TM16xx chip makes it easy to see if a button is pressed. To check if a button was pressed you can use the getButtons() method:
  400.  
  401. uint32_t dwButtons=module.getButtons();
  402. Serial.println(dwButtons, HEX);
  403.  
  404. Please note that while you don't need to write any code for debouncing, the button state may be reset when you display something. For advanced detection of button clicks, double clicks and long presses you can use the TM16xxButtons class.
  405. TM16xxDisplay class
  406.  
  407. The TM16xxDisplay class adds some bytes to the memory footprint, but it provides the familiar easy to use print() and println() functions. Next to that it also provides some more advanced display methods. To use that class on top of the base class, all you need to do is instantiate it, refering to the chip specific class:
  408.  
  409. TM1638 module(8, 9, 7); // DIO=8, CLK=9, STB=7
  410. TM16xxDisplay display(&module, 8); // TM16xx object, 8 digits
  411.  
  412. Simple print example using the TM16xxDisplay class:
  413.  
  414. #include <TM1638.h>
  415. #include <TM16xxDisplay.h>
  416.  
  417. TM1638 module(8, 9, 7); // DIO=8, CLK=9, STB=7
  418. TM16xxDisplay display(&module, 8); // TM16xx object, 8 digits
  419.  
  420. void setup() {
  421. display.println(F("HELLO !"));
  422. }
  423.  
  424. int nCount=0;
  425. void loop() {
  426. delay(1000);
  427. display.print("Count:");
  428. display.println(nCount++);
  429. }
  430.  
  431. See TM16xxDisplay.h for the provided methods.
  432. TM16xxMatrix class
  433.  
  434. The TM16xxMatrix class provides basic methods for using a single LED-matrix module. For more advanced graphics use the TM16xxMatrixGFX class. To use the TM16xxMatrix class on top of the base class, all you need to do is instantiate it, refering to the chip specific class:
  435.  
  436. TM1640 module(9, 10); // DIN=9, CLK=10
  437. #define MATRIX_NUMCOLUMNS 16
  438. #define MATRIX_NUMROWS 8
  439. TM16xxMatrix matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS); // TM16xx object, columns, rows
  440.  
  441. Note that the TM1640 has sufficient outputs to drive two 8x8 matrices.
  442.  
  443. These methods can be used to set the pixels of the matrix:
  444.  
  445. matrix.setAll(true); // set all pixels on
  446. matrix.setPixel(5,6, true); // set one pixel on
  447. matrix.setPixel(3,2, false); // set another pixel off
  448.  
  449. See TM16xxMatrix.h for the provided methods.
  450. TM16xxMatrixGFX class
  451.  
  452. The TM16xxMatrixGFX class implements the popular Adafruit GFX interface to drive one or more TM16xx based LED-matrix modules. To use the TM16xxMatrixGFX class you first need to include the proper header files:
  453.  
  454. #include <Adafruit_GFX.h>
  455. #include <TM1640.h>
  456. #include <TM16xxMatrixGFX.h>
  457.  
  458. Then you can instantiate the TM16xxMatrixGFX class, refering to the chip specific class:
  459.  
  460. TM1640 module(13, 14); // For ESP8266/WeMos D1-mini: DIN=D7/13/MOSI, CLK=D5/14/SCK
  461. #define MATRIX_NUMCOLUMNS 8
  462. #define MATRIX_NUMROWS 8
  463. TM16xxMatrixGFX matrix(&module, MATRIX_NUMCOLUMNS, MATRIX_NUMROWS); // TM16xx object, columns, rows
  464.  
  465. Note that the TM1640 has sufficient outputs to drive two 8x8 matrices. The WeMOS D1 Mini Matrix LED Shield also uses the TM1640, but has only one 8x8 matrix.
  466.  
  467. These methods can be used to draw on the matrix:
  468.  
  469. matrix.setIntensity(1); // Use a value between 0 and 7 for brightness
  470. matrix.fillScreen(LOW); // Clear the matrix
  471. matrix.drawPixel(1, 4, HIGH); // set one pixel in the memory bitmap on
  472. matrix.write(); // Send the memory bitmap to the display
  473.  
  474. In addition all the Adafruit GFX methods can be used, e.g.:
  475.  
  476. matrix.drawChar(0, 0, 'A', HIGH, LOW, 1);
  477. matrix.drawLine(0, matrix. height(), matrix.width(), 0, HIGH);
  478. matrix.drawRect(0, 0, 6, 6, HIGH);
  479.  
  480. Multiple identical modules can be combined to form a large matrix. The data line can be shared to reduce the number of pins:
  481.  
  482. TM1640 module(D7, D5); // For ESP8266/WeMos D1-mini: DIN=D7/13/MOSI, CLK=D5/14/SCK
  483. TM1640 module2(D7, D6); // For ESP8266/WeMos D1-mini: shared DIN=D7/13/MOSI, different CLK
  484. TM16xx * modules[]={&module,&module2}; // put modules in an array
  485. TM16xxMatrixGFX matrix(modules, MODULE_SIZECOLUMNS, MODULE_SIZEROWS, 2, 1); // modules, size of each module, size combined
  486.  
  487. See Adafruit GFX documentation and TM16xxMatrixGFX.h for the provided methods. See the library examples for more information.
  488. TM16xxButtons class
  489.  
  490. The TM16xxButtons class enlarges the footprint a bit, but based on the popular OneButton library library, it adds more advanced methods to use buttons. Next to simply polling the state of each button, you can define callback functions that will be called when a button is released, clicked, double-clicked or long pressed. To use this class on top of the base class, all you need to do is include the proper headers and instantiate the buttons object, refering to the chip specific class, for example:
  491.  
  492. #include <TM1638.h>
  493. #include <TM16xxButtons.h>
  494.  
  495. TM1638 module(8, 9, 7); // DIO=8, CLK=9, STB=7
  496. TM16xxButtons buttons(&module); // TM16xx object
  497.  
  498. Then you define the functions you want to use to handle the button events:
  499.  
  500. void fnClick(byte nButton)
  501. { // byte nButton is the button-number (first button is number 0)
  502. Serial.print(F("Button "));
  503. Serial.print(nButton);
  504. Serial.println(F(" click."));
  505. }
  506.  
  507. In setup() you need to attach the callback function:
  508.  
  509. void setup()
  510. {
  511. .
  512. .
  513. buttons.attachClick(fnClick);
  514. }
  515.  
  516. (BTW. Besides a click function, you can also attach a function to handle release, doubleclick and longpress events).
  517.  
  518. In loop() you need to call the tick() function that detects all state changes and calls the callback functions as needed:
  519.  
  520. void loop()
  521. {
  522. buttons.tick();
  523. .
  524. .
  525. // do your other things
  526. }
  527.  
  528. To implement a shift key, you can use the isPressed() function. See TM16xxButtons.h for the provided methods and the Button clicks example for more information.
  529. New in this library
  530.  
  531. Added library functionality:
  532.  
  533. Revised library structure to simplify support of other TM16xx chips.
  534. Basic functionality in base class for a uniform API.
  535. Support for TM1637. Note: TM1637 does not support simultaneous button presses. (Method derived from TM1637 library but using pins in standard output mode when writing).
  536. Support for TM1668. Note: TM1668 can be used in 10x7 - 13x4 display modes. Datasheet partly translated.
  537. Support for TM1650. Note: TM1650 can be used in 8x4 or 7x4 display mode. Datasheet fully translated.
  538. Reduced required RAM memory by using PROGMEM fonts.
  539. Support for ATtiny44A and ESP8266 in addition to regular Arduinos.
  540. Separate classes for LED matrix and advanced LED display support.
  541. Simple display of text and numbers on 7-segment displays using familiar print() and println() methods.
  542. Support for the Adafruit GFX graphics library for advanced graphics on a LED matrix.
  543. Full support for QYF-TM1638 module (8 digit common anode LED display and 4x4 keypad)
  544. Support for TM1638 in Anode Mode (10 digit common anode LED 8 segment display) [TM1638Anode.h]
  545. Support for combining multiple modules into one large Adafruit GFX matrix.
  546. Support for scanning all possible keys (K1, K2 and K3 lines) on TM1638.
  547. Support for release, click, doubleclick and long press button detection using callback functions.
  548. Added library examples.
  549. Support for TM1620 (thanks @eddwhite)
  550. Support for TM1630 (thanks @tokuhira)
  551. Support for TM1628. Note: TM1628 can be used in 10x7 - 13x4 display modes.
  552.  
  553. Functionality in original library by Ricardo Batista:
  554.  
  555. Support for the TM1638 and TM1640, including common anode TM1638 module;
  556. Helper methods for displaying numbers in decimal, hexadecimal and binary;
  557. Support for multiple chained TM1638 and for TM1638 in inverted position;
  558. Support for dimming the display and LEDs and for writing text;
  559. Reading simultaneous button presses on TM1638;
  560.  
  561. Features & limitations
  562.  
  563. The current version of this library supports ESP8266/ESP32, Atmel ATmega (e.g. ATmega328 and ATmega168) and Atmel ATtiny MCUs. Due to the required memory, the smallest ATtiny MCU supported is the ATtiny44. Please let me know if you've successfully used this library with other MCUs.
  564. The TM16xx chips offer no support for daisychaining multiple chips, but when separate Clk or Latch lines are used the Din line can be shared for combined displays.
  565. The library doesn't support combining multiple 7-segment modules into one display, but it is possible to define multiple display objects for multiple different modules. See the TM1638_TM1637ex_two_modules example.
  566. The TM16xxMatrixGFX class does support combining multiple LED Matrix module into one large matrix. Please note that the TM1640 supports up to 16 digits or an 8x16 LED matrix.
  567. The QYF-TM1638 module (TM138 with common anode display) is fully supported. Please note that while multiple buttons can be pressed, pressing more than two buttons can give faulty results due to the lack of short-out preventing diodes on the module.
  568. The popular TM1638 LED & KEY module comes in a number of varieties. My version has some odd button wiring sequence: S1=KS1, S5=KS2, S2=KS3, S6=KS4, S3=KS5, S7=KS6, S4=KS7, S8=KS8
  569. The TM1668 class has experimental support for using RGB LEDs on Grids 5-7. Some information about the wiring can be found in the example code. Most likely future versions will have a specific class for using RGB LEDs. The TM1680 has 8x24 outputs which sounds ideal for creating a 8x8 RGB matrix. Unfortunately these chips don't support individual LED brightness, only intensity of the whole display.
  570. The TM1650 datasheet mentions SDA and SCL pins. The used protocol resembles I2C, but lacks addressing. For that reason this library doesn't use the I2C Wire library, but (slow) bitbanging using digitalWrite.
  571. The WeMOS D1 mini Matrix LED Shield and the TM1640 Mini LED Matrix 8x16 by Maxint R&D have R1 on the right-top. Call setMirror(true) to reverse the x-mirrorring.
  572. When using TM16xxButtons, the amount of memory used can become too large. To preserve RAM memory on smaller MCUs such as the ATtiny44A, the number of buttons is limited to 8 on the ATtiny MCUs. This can be changed by setting the maximum in the TM16xxButtons.h header file:
  573.  
  574. #define TM16XX_BUTTONS_MAXBUTTONS 8 // Note: changing this define requires recompilation of the library
  575.  
  576. An alternative RAM preserving implementation using dynamic memory allocation is optional, but not suitable for small MCUs as using malloc/free will increase the required FLASH program space by over 600 bytes. Modify the TM16XX_OPT_BUTTONS_... defines in the header file at your own risk.
  577.  
  578. More information
  579. Examples
  580.  
  581. See the library examples for more information on how to use this library. See also the original examples by Ricardo Batista. Most will still work or only require minor changes.
  582. Links
  583.  
  584. Manufacturer: Titan Micro Electronics - LED driver datasheets
  585. Original TM1638/TM1640 library: https://github.com/rjbatista/tm1638-library
  586. TM1637 library used for reference: https://github.com/avishorp/TM1637
  587. A TM1637 library optimized for speed and size: https://github.com/Erriez/ErriezTM1637
  588. TM1650 library that uses the Wire interface: https://github.com/mozgy/Mozz_TM1650
  589. MAX7219 LED Matrix library: https://github.com/markruys/arduino-Max72xxPanel
  590. OneButton multi-state buttons: https://github.com/mathertel/OneButton
  591. Adafruit GFX library: https://github.com/adafruit/Adafruit-GFX-Library
  592. Adafruit GFX documentation: https://learn.adafruit.com/adafruit-gfx-graphics-library
  593. Matrix transposition used in TM1638QYF: https://www.chessprogramming.org/Flipping_Mirroring_and_Rotating#Anti-Diagonal
  594.  
  595. Disclaimer
  596.  
  597. All code on this GitHub account, including this library is provided to you on an as-is basis without guarantees and with all liability dismissed. It may be used at your own risk. Unfortunately I have no means to provide support.
  598. TM16xx/src/ 0040777 0000000 0000000 00000000000 14026124625 007654 5 ustar 00 TM16xx/src/TM1640.cpp 0100777 0000000 0000000 00000004146 14026127121 011212 0 ustar 00 /*
  599. TM1640.cpp - Library implementation for TM1640.
  600. Copyright (C) 2011 Ricardo Batista (rjbatista <at> gmail <dot> com)
  601. Adjusted for TM1640 by Maxint R&D, based on orignal code. See https://github.com/maxint-rd/
  602. This program is free software: you can redistribute it and/or modify
  603. it under the terms of the version 3 GNU General Public License as
  604. published by the Free Software Foundation.
  605. This program is distributed in the hope that it will be useful,
  606. but WITHOUT ANY WARRANTY; without even the implied warranty of
  607. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  608. GNU General Public License for more details.
  609. You should have received a copy of the GNU General Public License
  610. along with this program. If not, see <http://www.gnu.org/licenses/>.
  611. */
  612.  
  613. #if defined(ARDUINO) && ARDUINO >= 100
  614. #include "Arduino.h"
  615. #else
  616. #include "WProgram.h"
  617. #endif
  618.  
  619. #include "TM1640.h"
  620.  
  621. TM1640::TM1640(byte dataPin, byte clockPin, byte numDigits, boolean activateDisplay, byte intensity)
  622. : TM16xx(dataPin, clockPin, dataPin, TM1640_MAX_POS, numDigits, activateDisplay, intensity)
  623. { // NOTE: Like the TM1637, the TM1640 only has DIO and CLK. Therefor the DIO-pin is initialized as strobe in the constructor
  624. clearDisplay();
  625. setupDisplay(activateDisplay, intensity);
  626. }
  627.  
  628. /*
  629. void TM1640::bitDelay()
  630. {
  631. //delayMicroseconds(5);
  632. }
  633. */
  634.  
  635. void TM1640::start()
  636. { // if needed derived classes can use different patterns to start a command (eg. for TM1637)
  637. // Datasheet: The starting condition of data input is: when CLK is high, the DIN becomes low from high;
  638. digitalWrite(dataPin, LOW);
  639. digitalWrite(clockPin, LOW);
  640. bitDelay();
  641. }
  642.  
  643. void TM1640::stop()
  644. { // if needed derived classes can use different patterns to stop a command (eg. for TM1637)
  645. // datasheet: the ending condition is: when CLK is high, the DIN becomes high from low.
  646. digitalWrite(clockPin, HIGH);
  647. digitalWrite(dataPin, HIGH);
  648. bitDelay();
  649. }
  650.  
  651. void TM1640::send(byte data)
  652. {
  653. // MOLE 180514: TM1640 wants data and clock to be low after sending the data
  654. TM16xx::send(data);
  655. digitalWrite(clockPin, LOW); // first clock low
  656. digitalWrite(dataPin, LOW); // then data low
  657. bitDelay();
  658. } TM16xx/src/TM1640.h 0100777 0000000 0000000 00000002503 14026130322 010647 0 ustar 00 /*
  659. TM1640.h - Library for TM1640.
  660. Copyright (C) 2011 Ricardo Batista <rjbatista at gmail dot com>
  661. Adjusted for TM1640 by Maxint R&D, based on orignal code. See https://github.com/maxint-rd/
  662. This program is free software: you can redistribute it and/or modify
  663. it under the terms of the version 3 GNU General Public License as
  664. published by the Free Software Foundation.
  665. This program is distributed in the hope that it will be useful,
  666. but WITHOUT ANY WARRANTY; without even the implied warranty of
  667. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  668. GNU General Public License for more details.
  669. You should have received a copy of the GNU General Public License
  670. along with this program. If not, see <http://www.gnu.org/licenses/>.
  671. */
  672.  
  673. #ifndef TM1640_h
  674. #define TM1640_h
  675.  
  676. #if defined(ARDUINO) && ARDUINO >= 100
  677. #include "Arduino.h"
  678. #else
  679. #include "WProgram.h"
  680. #endif
  681.  
  682. #include "TM16xx.h"
  683.  
  684. #define TM1640_MAX_POS 16
  685.  
  686. class TM1640 : public TM16xx
  687. {
  688. public:
  689. // Instantiate a TM1640 module specifying data and clock pins, number of digits, the display state, the starting intensity (0-7).
  690. TM1640(byte dataPin, byte clockPin, byte numDigits=16, boolean activateDisplay = true, byte intensity = 7);
  691.  
  692. protected:
  693. //virtual void bitDelay();
  694. virtual void start();
  695. virtual void stop();
  696. virtual void send(byte data);
  697. };
  698. #endif
  699. TM16xx/src/TM16xx.cpp 0100777 0000000 0000000 00000014447 14026127460 011441 0 ustar 00 /*
  700. TM16xx.h - Library for TM1637, TM1638 and similar chips.
  701. Modified by Maxint R&D. See https://github.com/maxint-rd/
  702. Copyright (C) 2011 Ricardo Batista (rjbatista <at> gmail <dot> com)
  703. This program is free software: you can redistribute it and/or modify
  704. it under the terms of the version 3 GNU General Public License as
  705. published by the Free Software Foundation.
  706. This program is distributed in the hope that it will be useful,
  707. but WITHOUT ANY WARRANTY; without even the implied warranty of
  708. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  709. GNU General Public License for more details.
  710. You should have received a copy of the GNU General Public License
  711. along with this program. If not, see <http://www.gnu.org/licenses/>.
  712. */
  713.  
  714. #if defined(ARDUINO) && ARDUINO >= 100
  715. #include "Arduino.h"
  716. #else
  717. #include "WProgram.h"
  718. #endif
  719.  
  720. #include "TM16xx.h"
  721. //#include "string.h"
  722.  
  723. TM16xx::TM16xx(byte dataPin, byte clockPin, byte strobePin, byte maxDisplays, byte digits, boolean activateDisplay, byte intensity)
  724. {
  725. this->dataPin = dataPin;
  726. this->clockPin = clockPin;
  727. this->strobePin = strobePin;
  728. this->_maxDisplays = maxDisplays;
  729. this->digits = digits;
  730.  
  731. pinMode(dataPin, OUTPUT);
  732. pinMode(clockPin, OUTPUT);
  733. pinMode(strobePin, OUTPUT);
  734.  
  735. digitalWrite(strobePin, HIGH);
  736. digitalWrite(clockPin, HIGH);
  737.  
  738. //sendCommand(TM16XX_CMD_DISPLAY | (activateDisplay ? 8 : 0) | min(7, intensity)); // display command: on or intensity
  739.  
  740. /*
  741. sendCommand(TM16XX_CMD_DATA_AUTO); // data command: set data mode to auto-increment write mode
  742. start();
  743. send(TM16XX_CMD_ADDRESS); // address command + address C0H
  744. for (int i = 0; i < 16; i++) { // TM1638 and TM1640 have 16 data addresses, TM1637 and TM1668 have less, but will wrap.
  745. send(0x00);
  746. }
  747. stop();
  748. */
  749. // Note: calling these methods should be done in constructor of derived class in order to use properly initialized members!
  750. /*
  751. clearDisplay();
  752. setupDisplay(activateDisplay, intensity);
  753. */
  754. }
  755.  
  756. void TM16xx::setupDisplay(boolean active, byte intensity)
  757. {
  758. sendCommand(TM16XX_CMD_DISPLAY | (active ? 8 : 0) | min(7, intensity));
  759. }
  760.  
  761. void TM16xx::clearDisplay()
  762. { // Clear all data registers. The number of registers depends on the chip.
  763. // TM1638 (10x8): 10 segments per grid, stored in two bytes. The first byte contains the first 8 display segments, second byte has seg9+seg10 => 16 bytes
  764. // TM1640 (8x16): one byte per grid => 16 bytes
  765. // TM1637 (8x6): one byte per grid => 6 bytes
  766. // TM1668 (10x7 - 14x3): two bytes per grid => 14 bytes
  767. sendCommand(TM16XX_CMD_DATA_AUTO); // set auto increment addressing mode
  768.  
  769. // send the address followed by bulk-sending of the data to clear the display memory
  770. start();
  771. send(TM16XX_CMD_ADDRESS);
  772. for (int i = 0; i < _maxDisplays; i++) {
  773. send(0x00);
  774. if(_maxSegments>8)
  775. send(0x00); // send second byte (applicable to TM1638 and TM1668)
  776. }
  777. stop();
  778.  
  779. }
  780.  
  781. void TM16xx::setSegments(byte segments, byte position)
  782. { // set 8 leds on common grd as specified
  783. // TODO: support 10-14 segments on chips like TM1638/TM1668
  784. if(position<_maxDisplays)
  785. sendData(position, segments);
  786. //sendData(TM16XX_CMD_ADDRESS | position, segments);
  787. }
  788.  
  789. void TM16xx::sendChar(byte pos, byte data, boolean dot)
  790. {
  791. /*
  792. if(pos<_maxDisplays)
  793. sendData(pos, data | (dot ? 0b10000000 : 0));
  794. */
  795. setSegments(data | (dot ? 0b10000000 : 0), pos);
  796. }
  797.  
  798. void TM16xx::setDisplayDigit(byte digit, byte pos, boolean dot, const byte numberFont[])
  799. {
  800. sendChar(pos, pgm_read_byte_near(numberFont + (digit & 0xF)), dot);
  801. }
  802.  
  803. void TM16xx::setDisplayToDecNumber(int nNumber, byte bDots) // byte bDots=0
  804. { // Function to display a decimal number on a n-digit clock display.
  805. // Kept simple to fit in ATtiny44A
  806. // For extended display features use the TM16xxDisplay class
  807.  
  808. // TODO: support large displays such as 8segx16 on TM1640
  809. for(byte nPos=1; nPos<=digits; nPos++)
  810. {
  811. setDisplayDigit(nNumber % 10, digits - nPos, bDots&_BV(nPos));
  812. nNumber/=10;
  813. }
  814. }
  815.  
  816. void TM16xx::clearDisplayDigit(byte pos, boolean dot)
  817. {
  818. sendChar(pos, 0, dot);
  819. }
  820.  
  821. void TM16xx::setDisplay(const byte values[], byte size)
  822. { // send an array of values to the display
  823. for (byte i = 0; i < size; i++) {
  824. sendChar(i, pgm_read_byte_near(values+i), 0);
  825. }
  826. }
  827.  
  828. void TM16xx::setDisplayToString(const char* string, const word dots, const byte pos, const byte font[])
  829. {
  830. for (int i = 0; i < digits - pos; i++) {
  831. if (string[i] != '\0') {
  832. sendChar(i + pos, pgm_read_byte_near(font+(string[i] - 32)), (dots & (1 << (digits - i - 1))) != 0);
  833. } else {
  834. break;
  835. }
  836. }
  837. }
  838.  
  839. // key-scanning method, implemented in chip specific derived class
  840. uint32_t TM16xx::getButtons()
  841. { // return state of up to 32 keys.
  842. return(0);
  843. }
  844.  
  845.  
  846. //
  847. // Protected methods
  848. //
  849.  
  850. void TM16xx::bitDelay()
  851. { // if needed derived classes can add a delay (eg. for TM1637)
  852. //delayMicroseconds(50);
  853. }
  854.  
  855. void TM16xx::start()
  856. { // if needed derived classes can use different patterns to start a command (eg. for TM1637)
  857. digitalWrite(strobePin, LOW);
  858. bitDelay();
  859. }
  860.  
  861. void TM16xx::stop()
  862. { // if needed derived classes can use different patterns to stop a command (eg. for TM1637)
  863. digitalWrite(strobePin, HIGH);
  864. bitDelay();
  865. }
  866.  
  867. void TM16xx::send(byte data)
  868. {
  869. // MMOLE 180203: shiftout does something, but is not okay (tested on TM1668)
  870. //shiftOut(dataPin, clockPin, LSBFIRST, data);
  871. for (int i = 0; i < 8; i++) {
  872. digitalWrite(clockPin, LOW);
  873. bitDelay();
  874. digitalWrite(dataPin, data & 1 ? HIGH : LOW);
  875. bitDelay();
  876. data >>= 1;
  877. digitalWrite(clockPin, HIGH);
  878. bitDelay();
  879. }
  880. bitDelay(); // NOTE: TM1638 specifies a Twait between bytes of minimal 1us.
  881. }
  882.  
  883. void TM16xx::sendCommand(byte cmd)
  884. {
  885. start();
  886. send(cmd);
  887. stop();
  888. }
  889.  
  890. void TM16xx::sendData(byte address, byte data)
  891. {
  892. sendCommand(TM16XX_CMD_DATA_FIXED); // use fixed addressing for data
  893. start();
  894. send(TM16XX_CMD_ADDRESS | address); // address command + address
  895. send(data);
  896. stop();
  897. }
  898.  
  899. byte TM16xx::receive()
  900. {
  901. byte temp = 0;
  902.  
  903. // Pull-up on
  904. pinMode(dataPin, INPUT);
  905. digitalWrite(dataPin, HIGH);
  906.  
  907. for (int i = 0; i < 8; i++) {
  908. temp >>= 1;
  909.  
  910. digitalWrite(clockPin, LOW);
  911. bitDelay(); // NOTE: on TM1637 reading keys should be slower than 250Khz (see datasheet p3)
  912.  
  913. if (digitalRead(dataPin)) {
  914. temp |= 0x80;
  915. }
  916.  
  917. digitalWrite(clockPin, HIGH);
  918. bitDelay();
  919. }
  920.  
  921. // Pull-up off
  922. pinMode(dataPin, OUTPUT);
  923. digitalWrite(dataPin, LOW);
  924.  
  925. return temp;
  926. } TM16xx/src/TM16xx.h 0100777 0000000 0000000 00000007733 14026127460 011106 0 ustar 00 /*
  927. TM16xx.h - Library for TM1637, TM1638 and similar chips.
  928. Copyright (C) 2011 Ricardo Batista <rjbatista at gmail dot com>
  929. Modified by Maxint R&D. See https://github.com/maxint-rd/
  930. This program is free software: you can redistribute it and/or modify
  931. it under the terms of the version 3 GNU General Public License as
  932. published by the Free Software Foundation.
  933. This program is distributed in the hope that it will be useful,
  934. but WITHOUT ANY WARRANTY; without even the implied warranty of
  935. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  936. GNU General Public License for more details.
  937. You should have received a copy of the GNU General Public License
  938. along with this program. If not, see <http://www.gnu.org/licenses/>.
  939. */
  940.  
  941. #ifndef TM16XX_h
  942. #define TM16XX_h
  943.  
  944. #if defined(ARDUINO) && ARDUINO >= 100
  945. #include "Arduino.h"
  946. #else
  947. #include "WProgram.h"
  948. #endif
  949.  
  950. #if !defined(max)
  951. // MMOLE 180325:
  952. // min, max are no macro in ESP core 2.3.9 libraries, see https://github.com/esp8266/Arduino/issues/398
  953. #define min(a,b) ((a)<(b)?(a):(b))
  954. #define max(a,b) ((a)>(b)?(a):(b))
  955. #endif
  956.  
  957. #define TM16XX_CMD_DATA_AUTO 0x40
  958. #define TM16XX_CMD_DATA_READ 0x42 // command to read data used on two wire interfaces of TM1637
  959. #define TM16XX_CMD_DATA_FIXED 0x44
  960. #define TM16XX_CMD_DISPLAY 0x80
  961. #define TM16XX_CMD_ADDRESS 0xC0
  962.  
  963. #include "TM16xxFonts.h"
  964.  
  965. class TM16xx
  966. {
  967. public:
  968. /**
  969. * Instantiate a tm16xx module specifying data, clock and stobe pins,
  970. * the maximum number of displays supported by the chip,
  971. * the number of digits used to display numbers or text,
  972. * display state and the starting intensity (0-7).
  973. */
  974. TM16xx(byte dataPin, byte clockPin, byte strobePin, byte maxDisplays, byte digits, boolean activateDisplay=true, byte intensity=7);
  975.  
  976. /** Set the display (segments and LEDs) active or off and intensity (range from 0-7). */
  977. virtual void setupDisplay(boolean active, byte intensity);
  978.  
  979. /** Clear the display */
  980. virtual void clearDisplay();
  981. virtual void setSegments(byte segments, byte position);
  982.  
  983. // Basic display functions. For additional display features use the TM16xxDisplay class
  984. /** Set a single display at pos (starting at 0) to a digit (left to right) */
  985. virtual void setDisplayDigit(byte digit, byte pos=0, boolean dot=false, const byte numberFont[] = TM16XX_NUMBER_FONT);
  986. /** Set the display to a decimal number */
  987. virtual void setDisplayToDecNumber(int nNumber, byte bDots=0);
  988. /** Clear a single display at pos (starting at 0, left to right) */
  989. virtual void clearDisplayDigit(byte pos, boolean dot=false);
  990. /** Set the display to the values (left to right) */
  991. virtual void setDisplay(const byte values[], byte size=8);
  992.  
  993. /** Set the display to the string (defaults to built in font) */
  994. virtual void setDisplayToString(const char* string, const word dots=0, const byte pos=0, const byte font[] = TM16XX_FONT_DEFAULT);
  995. virtual void sendChar(byte pos, byte data, boolean dot); // made public to allow calling from TM16xxDisplay
  996.  
  997. // Key-scanning functions
  998. // Note: not all TM16xx chips support key-scanning and sizes are different per chip
  999. // Up to 32 key states are supported, but specific chips may support less keys or less combinations
  1000. // The chip specific derived class method will return a 32-bit value representing the state of each key, containing 0 if no key is pressed
  1001. virtual uint32_t getButtons(); // return state of up to 32 keys.
  1002.  
  1003. protected:
  1004. // virtual void sendChar(byte pos, byte data, boolean dot);
  1005. virtual void bitDelay();
  1006. virtual void start();
  1007. virtual void stop();
  1008. virtual void send(byte data);
  1009. virtual void sendCommand(byte led);
  1010. virtual void sendData(byte add, byte data);
  1011. virtual byte receive();
  1012. byte _maxDisplays=2; // maximum number of digits (grids), chip-dependent
  1013. byte _maxSegments=8; // maximum number of segments per display, chip-dependent
  1014.  
  1015. byte digits; // number of digits in the display, module dependent
  1016. byte dataPin;
  1017. byte clockPin;
  1018. byte strobePin;
  1019. };
  1020.  
  1021. #endif TM16xx/src/TM16xxButtons.cpp 0100777 0000000 0000000 00000020630 14026127460 013007 0 ustar 00 /*
  1022. TM16xxButtons.cpp - Buttons class for TM16xx.
  1023. The TM16xxButtons class supports the key-scanning features of TM16xx chips, such as TM1637 or TM1638.
  1024. It extends the getButtons() function of the base class and provides these features:
  1025. - setting callback functions
  1026. - multi-state keys (similar to OneButton): Press, LongPress, Click, Doubleclick
  1027. These are some TM16xx chips that support key-scanning:
  1028. TM1637 8 x 2 single DIO/CLK
  1029. TM1638 8 x 3 multi DIO/CLK/STB
  1030. TM1668 10 x 2 multi DIO/CLK/STB
  1031. Made by Maxint R&D. See https://github.com/maxint-rd/
  1032. Partially based on OneButton library by Matthias Hertel. See https://github.com/mathertel/OneButton
  1033. */
  1034.  
  1035. //#define TM16XX_DEBUG 1
  1036.  
  1037. #include "TM16xxButtons.h"
  1038.  
  1039. // constructor
  1040. TM16xxButtons::TM16xxButtons(TM16xx *pTM16xx, byte nNumButtons) : _nNumButtons(nNumButtons), _pTM16xx(pTM16xx)
  1041. {
  1042. // TODO: reduce memory by using dynamic memory allocation instead of static arrays for button states
  1043. // requires additional constructor parameter to allow less than TM16XX_BUTTONS_MAXBUTTONS
  1044.  
  1045. //_pTM16xx=pTM16xx;
  1046. #if(TM16XX_OPT_BUTTONS_MALLOC)
  1047. _state=malloc(_nNumButtons*sizeof(byte));
  1048. _startTime=malloc(_nNumButtons*sizeof(unsigned long));
  1049. _stopTime=malloc(_nNumButtons*sizeof(unsigned long));
  1050. #endif
  1051.  
  1052. reset();
  1053. }
  1054.  
  1055.  
  1056.  
  1057. // explicitly set the number of millisec that have to pass by before a click is
  1058. // detected.
  1059. void TM16xxButtons::setClickTicks(int ticks)
  1060. {
  1061. _clickTicks = ticks;
  1062. } // setClickTicks
  1063.  
  1064.  
  1065. // explicitly set the number of millisec that have to pass by before a long
  1066. // button press is detected.
  1067. void TM16xxButtons::setLongPressTicks(int ticks)
  1068. {
  1069. _longPressTicks = ticks;
  1070. } // setLongPressTicks
  1071.  
  1072. #if(TM16XX_OPT_BUTTONS_EVENT)
  1073. // set function for release event
  1074. void TM16xxButtons::attachEventHandler(callbackTM16xxButtonsEvent newFunction)
  1075. {
  1076. _eventFunc = newFunction;
  1077. } // attachEventHandler
  1078. #else
  1079. void TM16xxButtons::attachRelease(callbackTM16xxButtons newFunction)
  1080. {
  1081. _releaseFunc = newFunction;
  1082. } // attachRelease
  1083.  
  1084. // set function for click event
  1085. void TM16xxButtons::attachClick(callbackTM16xxButtons newFunction)
  1086. {
  1087. _clickFunc = newFunction;
  1088. } // attachClick
  1089.  
  1090. // set function for doubleClick event
  1091. void TM16xxButtons::attachDoubleClick(callbackTM16xxButtons newFunction)
  1092. {
  1093. _doubleClickFunc = newFunction;
  1094. } // attachDoubleClick
  1095.  
  1096.  
  1097. // set function for longPressStart event
  1098. void TM16xxButtons::attachLongPressStart(callbackTM16xxButtons newFunction)
  1099. {
  1100. _longPressStartFunc = newFunction;
  1101. } // attachLongPressStart
  1102.  
  1103. // set function for longPressStop event
  1104. void TM16xxButtons::attachLongPressStop(callbackTM16xxButtons newFunction)
  1105. {
  1106. _longPressStopFunc = newFunction;
  1107. } // attachLongPressStop
  1108.  
  1109. // set function for during longPress event
  1110. void TM16xxButtons::attachDuringLongPress(callbackTM16xxButtons newFunction)
  1111. {
  1112. _duringLongPressFunc = newFunction;
  1113. } // attachDuringLongPress
  1114. #endif
  1115.  
  1116. // function to get the current long pressed state
  1117. bool TM16xxButtons::isPressed(byte nButton)
  1118. {
  1119. if(nButton>=_nNumButtons) return(false);
  1120. return(_state[nButton]==TM16XX_BUTTONS_STATE_PRESSED || _state[nButton]==TM16XX_BUTTONS_STATE_DBLPRESS || _state[nButton]==TM16XX_BUTTONS_STATE_LPRESS);
  1121. }
  1122.  
  1123. // function to get the current long pressed state
  1124. bool TM16xxButtons::isLongPressed(byte nButton)
  1125. {
  1126. if(nButton>=_nNumButtons) return(false);
  1127. return(_state[nButton]==TM16XX_BUTTONS_STATE_LPRESS);
  1128. }
  1129.  
  1130. int TM16xxButtons::getPressedTicks(byte nButton)
  1131. {
  1132. if(nButton>=_nNumButtons) return(0);
  1133. return((_stopTime[nButton] - _startTime[nButton])); // uint16_t subtraction may overflow, but is still fine 0x01 - 0xFC = 0x05
  1134. }
  1135.  
  1136. void TM16xxButtons::reset(void)
  1137. {
  1138. for(byte n=0; n<_nNumButtons; n++)
  1139. {
  1140. _state[n] = TM16XX_BUTTONS_STATE_START; // restart.
  1141. _startTime[n] = 0;
  1142. _stopTime[n] = 0;
  1143. }
  1144. }
  1145.  
  1146.  
  1147. /**
  1148. * @brief Check input of the configured pin and then advance the finite state
  1149. * machine (FSM).
  1150. */
  1151. uint32_t TM16xxButtons::tick(void)
  1152. { // update the state of each button and call callback functions as needed
  1153. uint32_t dwButtons=_pTM16xx->getButtons();
  1154. #ifdef TM16XX_DEBUG
  1155. Serial.print(F("TM16xxButtons: "));
  1156. Serial.print(dwButtons, HEX);
  1157. Serial.print(F(", state: "));
  1158. for(byte n=0; n<_nNumButtons; n++)
  1159. {
  1160. tick(n, (dwButtons&bit(n))>0); // MMOLE 181103: _BV only works on 16-bit values!
  1161. Serial.print(_state[n]);
  1162. }
  1163. Serial.print(F(" "));
  1164. #else
  1165. for(byte n=0; n<_nNumButtons; n++)
  1166. tick(n, dwButtons&bit(n)); // MMOLE 181103: _BV only works on 16-bit values!
  1167. #endif
  1168. return(dwButtons);
  1169. }
  1170.  
  1171. /**
  1172. * @brief Advance the finite state machine (FSM) using the given level.
  1173. */
  1174. void TM16xxButtons::tick(byte nButton, bool activeLevel)
  1175. {
  1176. //unsigned long now = millis(); // current (relative) time in msecs.
  1177. uint16_t now = (uint16_t) millis(); // current (relative) time in msecs. To safe RAM we only use the bottom word (16 bits for instead of 32 for approx. 50 days)
  1178.  
  1179. // Implementation of the state machine
  1180. switch(_state[nButton])
  1181. {
  1182. case TM16XX_BUTTONS_STATE_START: // waiting for button being pressed.
  1183. if (activeLevel)
  1184. {
  1185. _state[nButton] = TM16XX_BUTTONS_STATE_PRESSED; // step to pressed state
  1186. _startTime[nButton] = now; // remember starting time
  1187. } // if
  1188. break;
  1189.  
  1190. case TM16XX_BUTTONS_STATE_PRESSED: // waiting for button being released.
  1191. if (!activeLevel)
  1192. {
  1193. _state[nButton] = TM16XX_BUTTONS_STATE_RELEASED; // step to released state
  1194. _stopTime[nButton] = now; // remember stopping time
  1195. #if(TM16XX_OPT_BUTTONS_EVENT)
  1196. if (_eventFunc)
  1197. _eventFunc(TM16XX_BUTTONS_EVENT_RELEASE, nButton);
  1198. #else
  1199. if (_releaseFunc)
  1200. _releaseFunc(nButton);
  1201. #endif
  1202. }
  1203. else if ((activeLevel) && ((unsigned long)(now - _startTime[nButton]) > _longPressTicks))
  1204. {
  1205. _state[nButton] = TM16XX_BUTTONS_STATE_LPRESS; // step to long press state
  1206. _stopTime[nButton] = now; // remember stopping time
  1207. #if(TM16XX_OPT_BUTTONS_EVENT)
  1208. if (_eventFunc)
  1209. {
  1210. _eventFunc(TM16XX_BUTTONS_EVENT_LONGPRESSSTART, nButton);
  1211. _eventFunc(TM16XX_BUTTONS_EVENT_LONGPRESSBUSY, nButton);
  1212. }
  1213. #else
  1214. if (_longPressStartFunc)
  1215. _longPressStartFunc(nButton);
  1216. if (_duringLongPressFunc)
  1217. _duringLongPressFunc(nButton);
  1218. #endif
  1219. } else {
  1220. // wait. Stay in this state.
  1221. } // if
  1222. break;
  1223.  
  1224. case TM16XX_BUTTONS_STATE_RELEASED: // waiting for button being pressed the second time or timeout.
  1225. #if(TM16XX_OPT_BUTTONS_EVENT)
  1226. if ((unsigned long)(now - _startTime[nButton]) > _clickTicks)
  1227. #else
  1228. if (_doubleClickFunc == NULL || (unsigned long)(now - _startTime[nButton]) > _clickTicks)
  1229. #endif
  1230. {
  1231. // this was only a single short click
  1232. #if(TM16XX_OPT_BUTTONS_EVENT)
  1233. if (_eventFunc)
  1234. _eventFunc(TM16XX_BUTTONS_EVENT_CLICK, nButton);
  1235. #else
  1236. if (_clickFunc)
  1237. _clickFunc(nButton);
  1238. #endif
  1239. _state[nButton] = TM16XX_BUTTONS_STATE_START; // restart.
  1240. }
  1241. else if ((activeLevel))
  1242. {
  1243. _state[nButton] = TM16XX_BUTTONS_STATE_DBLPRESS; // step to doubleclick state
  1244. _startTime[nButton] = now; // remember starting time
  1245. } // if
  1246. break;
  1247.  
  1248. case TM16XX_BUTTONS_STATE_DBLPRESS: // waiting for button being released finally.
  1249. if ((!activeLevel))
  1250. {
  1251. // this was a 2 click sequence.
  1252. _state[nButton] = TM16XX_BUTTONS_STATE_START; // restart.
  1253. _stopTime[nButton] = now; // remember stopping time
  1254. #if(TM16XX_OPT_BUTTONS_EVENT)
  1255. if (_eventFunc)
  1256. {
  1257. _eventFunc(TM16XX_BUTTONS_EVENT_RELEASE, nButton);
  1258. _eventFunc(TM16XX_BUTTONS_EVENT_DOUBLECLICK, nButton);
  1259. }
  1260. #else
  1261. if (_releaseFunc)
  1262. _releaseFunc(nButton);
  1263. if (_doubleClickFunc)
  1264. _doubleClickFunc(nButton);
  1265. #endif
  1266. } // if
  1267. break;
  1268.  
  1269. case TM16XX_BUTTONS_STATE_LPRESS: // waiting for button being release after long press.
  1270. if (!activeLevel)
  1271. {
  1272. _state[nButton] = TM16XX_BUTTONS_STATE_START; // restart.
  1273. _stopTime[nButton] = now; // remember stopping time
  1274. #if(TM16XX_OPT_BUTTONS_EVENT)
  1275. if (_eventFunc)
  1276. {
  1277. _eventFunc(TM16XX_BUTTONS_EVENT_RELEASE, nButton);
  1278. _eventFunc(TM16XX_BUTTONS_EVENT_LONGPRESSSTOP, nButton);
  1279. }
  1280. #else
  1281. if (_releaseFunc)
  1282. _releaseFunc(nButton);
  1283. if (_longPressStopFunc)
  1284. _longPressStopFunc(nButton);
  1285. #endif
  1286. }
  1287. else
  1288. {
  1289. // button is being long pressed
  1290. #if(TM16XX_OPT_BUTTONS_EVENT)
  1291. if (_eventFunc)
  1292. _eventFunc(TM16XX_BUTTONS_EVENT_LONGPRESSBUSY, nButton);
  1293. #else
  1294. if (_duringLongPressFunc)
  1295. _duringLongPressFunc(nButton);
  1296. #endif
  1297. } // if
  1298. break;
  1299. } // switch
  1300. } // TM16xxButtons.tick(nButton) TM16xx/src/TM16xxButtons.h 0100777 0000000 0000000 00000012202 14026127460 012450 0 ustar 00 /*
  1301. TM16xxButtons.h - Buttons class for TM16xx.
  1302. The TM16xxButtons class supports the key-scanning features of TM16xx chips, such as TM1637 or TM1638.
  1303. It extends the getButtons() function of the base class and provides these features:
  1304. - setting callback functions
  1305. - multi-state keys (similar to OneButton): Press, LongPress, Click, Doubleclick
  1306. These are some TM16xx chips that support key-scanning:
  1307. TM1637 8 x 2 single DIO/CLK
  1308. TM1638 8 x 3 multi DIO/CLK/STB
  1309. TM1668 10 x 2 multi DIO/CLK/STB
  1310. Made by Maxint R&D. See https://github.com/maxint-rd/
  1311. Partially based on OneButton library by Matthias Hertel. See https://github.com/mathertel/OneButton
  1312. */
  1313. #ifndef _TM16XX_BUTTONS_H
  1314. #define _TM16XX_BUTTONS_H
  1315.  
  1316. #include "TM16xx.h"
  1317.  
  1318. #define TM16XX_OPT_BUTTONS_EVENT 0 // use a single callback function instead of multiple (more flash, less heap)
  1319. #define TM16XX_OPT_BUTTONS_MALLOC 0 // use malloc to reserve button-state memory (more flash, less heap)
  1320.  
  1321. #ifndef TM16XX_BUTTONS_MAXBUTTONS
  1322. #if defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny13__) || defined(__AVR_ATtiny44__)
  1323. #define TM16XX_BUTTONS_MAXBUTTONS 8 // WARNING: changing this define outside of the header file requires recompilation of the library;
  1324. // using without full recompile may cause very obscure crashes/resets
  1325. #else
  1326. #define TM16XX_BUTTONS_MAXBUTTONS 32 // maximum number of buttons supported (determines heap used when not using malloc)
  1327. #endif
  1328. #endif
  1329.  
  1330. #define TM16XX_BUTTONS_STATE_START 0
  1331. #define TM16XX_BUTTONS_STATE_PRESSED 1
  1332. #define TM16XX_BUTTONS_STATE_RELEASED 2
  1333. #define TM16XX_BUTTONS_STATE_DBLPRESS 3
  1334. #define TM16XX_BUTTONS_STATE_LPRESS 4
  1335.  
  1336.  
  1337. #if(TM16XX_OPT_BUTTONS_EVENT)
  1338. #define TM16XX_BUTTONS_EVENT_RELEASE 10
  1339. #define TM16XX_BUTTONS_EVENT_CLICK 20
  1340. #define TM16XX_BUTTONS_EVENT_DOUBLECLICK 30
  1341. #define TM16XX_BUTTONS_EVENT_LONGPRESSSTART 40
  1342. #define TM16XX_BUTTONS_EVENT_LONGPRESSSTOP 50
  1343. #define TM16XX_BUTTONS_EVENT_LONGPRESSBUSY 60
  1344. #endif
  1345.  
  1346. // ----- Callback function types -----
  1347.  
  1348. extern "C" {
  1349. typedef void (*callbackTM16xxButtons)(byte nButton);
  1350. #if(TM16XX_OPT_BUTTONS_EVENT)
  1351. typedef void (*callbackTM16xxButtonsEvent)(byte btEvent, byte nButton);
  1352. #endif
  1353. }
  1354.  
  1355. class TM16xxButtons
  1356. {
  1357. public:
  1358. TM16xxButtons(TM16xx *pTM16xx, byte nNumButtons=TM16XX_BUTTONS_MAXBUTTONS);
  1359.  
  1360.  
  1361. // set # millisec after single click is assumed.
  1362. void setClickTicks(int ticks);
  1363.  
  1364. // set # millisec after long press is assumed.
  1365. void setLongPressTicks(int ticks);
  1366.  
  1367. // attach functions that will be called when button was pressed in the
  1368. // specified way.
  1369. #if(TM16XX_OPT_BUTTONS_EVENT)
  1370. void attachEventHandler(callbackTM16xxButtonsEvent newFunction);
  1371. #else
  1372. void attachRelease(callbackTM16xxButtons newFunction);
  1373. void attachClick(callbackTM16xxButtons newFunction);
  1374. void attachDoubleClick(callbackTM16xxButtons newFunction);
  1375. void attachLongPressStart(callbackTM16xxButtons newFunction);
  1376. void attachLongPressStop(callbackTM16xxButtons newFunction);
  1377. void attachDuringLongPress(callbackTM16xxButtons newFunction);
  1378. #endif
  1379. uint32_t tick(void);
  1380. /**
  1381. * @brief Call this function every time the input level has changed.
  1382. * Using this function no digital input pin is checked because the current
  1383. * level is given by the parameter.
  1384. */
  1385. void tick(byte nButton, bool level);
  1386.  
  1387. bool isPressed(byte nButton);
  1388. bool isLongPressed(byte nButton);
  1389. int getPressedTicks(byte nButton);
  1390. void reset(void);
  1391.  
  1392. protected:
  1393. TM16xx *_pTM16xx;
  1394.  
  1395. private:
  1396. byte _nNumButtons;
  1397. unsigned int _clickTicks = 500; // number of ticks that have to pass by
  1398. // before a click is detected.
  1399. unsigned int _longPressTicks = 1000; // number of ticks that have to pass by
  1400. // before a long button press is detected
  1401.  
  1402. // These variables will hold functions acting as event source.
  1403. #if(TM16XX_OPT_BUTTONS_EVENT)
  1404. callbackTM16xxButtonsEvent _eventFunc = NULL;
  1405. #else
  1406. callbackTM16xxButtons _releaseFunc = NULL;
  1407. callbackTM16xxButtons _clickFunc = NULL;
  1408. callbackTM16xxButtons _doubleClickFunc = NULL;
  1409. callbackTM16xxButtons _longPressStartFunc = NULL;
  1410. callbackTM16xxButtons _longPressStopFunc = NULL;
  1411. callbackTM16xxButtons _duringLongPressFunc = NULL;
  1412. #endif
  1413.  
  1414. // These variables that hold information across the upcoming tick calls.
  1415. // They are initialized once on program start and are updated every time the
  1416. // tick function is called.
  1417. #if(TM16XX_OPT_BUTTONS_MALLOC)
  1418. byte *_state; // allocated memory array
  1419. unsigned long *_startTime; // allocated memory array, value is set in state TM16XX_BUTTONS_STATE_PRESSED
  1420. unsigned long *_stopTime; // allocated memory array, value is set in state TM16XX_BUTTONS_STATE_RELEASED
  1421. #else
  1422. byte _state[TM16XX_BUTTONS_MAXBUTTONS]; // = TM16XX_BUTTONS_STATE_START;
  1423. //unsigned long _startTime[TM16XX_BUTTONS_MAXBUTTONS]; // will be set in state TM16XX_BUTTONS_STATE_PRESSED
  1424. //unsigned long _stopTime[TM16XX_BUTTONS_MAXBUTTONS]; // will be set in state TM16XX_BUTTONS_STATE_RELEASED
  1425. uint16_t _startTime[TM16XX_BUTTONS_MAXBUTTONS]; // will be set in state TM16XX_BUTTONS_STATE_PRESSED
  1426. uint16_t _stopTime[TM16XX_BUTTONS_MAXBUTTONS]; // will be set in state TM16XX_BUTTONS_STATE_RELEASED
  1427. #endif
  1428. };
  1429. #endif TM16xx/src/TM16xxDisplay.cpp 0100777 0000000 0000000 00000011653 14026127460 012763 0 ustar 00 /*
  1430. TM16xxDisplay.h - LED Display library for TM16xx.
  1431. Methods for driving 7-segment LED displays using TM16xx chips.
  1432. Made by Maxint R&D. See https://github.com/maxint-rd/
  1433. Based on TM1638/1640 library by Ricardo Batista.
  1434. */
  1435. #include "TM16xxDisplay.h"
  1436. #include "string.h"
  1437.  
  1438. TM16xxDisplay::TM16xxDisplay(TM16xx *pTM16xx, byte nNumDigits)
  1439. {
  1440. _pTM16xx=pTM16xx;
  1441. _nNumDigits=nNumDigits;
  1442. }
  1443.  
  1444. void TM16xxDisplay::setIntensity(byte intensity)
  1445. { // set the intensity of the module; range 0-7, 0=off, 7=bright
  1446. _pTM16xx->setupDisplay(intensity!=0, intensity);
  1447. }
  1448.  
  1449.  
  1450. void TM16xxDisplay::setDisplayToString(const char* string, const word dots, const byte pos, const byte font[])
  1451. { // call basic implementation
  1452. _pTM16xx->setDisplayToString(string, dots, pos, font);
  1453. }
  1454.  
  1455. void TM16xxDisplay::setDisplayToString(const String string, const word dots, const byte pos, const byte font[])
  1456. { // additional implementation using String class (uses more memory than char * version)
  1457. int stringLength = string.length();
  1458.  
  1459. for (int i = 0; i < _nNumDigits - pos; i++) {
  1460. if (i < stringLength) {
  1461. _pTM16xx->sendChar(i + pos, pgm_read_byte_near(font+(string.charAt(i) - 32)), (dots & (1 << (_nNumDigits - i - 1))) != 0);
  1462. } else {
  1463. break;
  1464. }
  1465. }
  1466. }
  1467.  
  1468. void TM16xxDisplay::setDisplayToError()
  1469. { // set the display to Error text
  1470. _pTM16xx->setDisplay(TM16XX_ERROR_DATA, 8);
  1471.  
  1472. // MMOLE TODO: just use clear before instead?
  1473. for (int i = 8; i < _nNumDigits; i++) {
  1474. _pTM16xx->clearDisplayDigit(i, false);
  1475. }
  1476. }
  1477.  
  1478. void TM16xxDisplay::setDisplayToHexNumber(unsigned long number, byte dots, boolean leadingZeros, const byte numberFont[])
  1479. {
  1480. for (int i = 0; i < _nNumDigits; i++) {
  1481. if (!leadingZeros && number == 0) {
  1482. _pTM16xx->clearDisplayDigit(_nNumDigits - i - 1, (dots & (1 << i)) != 0);
  1483. } else {
  1484. _pTM16xx->setDisplayDigit(number & 0xF, _nNumDigits - i - 1, (dots & (1 << i)) != 0, numberFont);
  1485. number >>= 4;
  1486. }
  1487. }
  1488. }
  1489.  
  1490. void TM16xxDisplay::setDisplayToDecNumberAt(unsigned long number, byte dots, byte startingPos, boolean leadingZeros, const byte numberFont[])
  1491. {
  1492. if (number > 99999999L) {
  1493. setDisplayToError();
  1494. } else {
  1495. for (int i = 0; i < _nNumDigits - startingPos; i++) {
  1496. if (number != 0) {
  1497. _pTM16xx->setDisplayDigit(number % 10, _nNumDigits - i - 1, (dots & (1 << i)) != 0, numberFont);
  1498. number /= 10;
  1499. } else {
  1500. if (leadingZeros) {
  1501. _pTM16xx->setDisplayDigit(0, _nNumDigits - i - 1, (dots & (1 << i)) != 0, numberFont);
  1502. } else {
  1503. _pTM16xx->clearDisplayDigit(_nNumDigits - i - 1, (dots & (1 << i)) != 0);
  1504. }
  1505. }
  1506. }
  1507. }
  1508. }
  1509.  
  1510. void TM16xxDisplay::setDisplayToDecNumber(unsigned long number, byte dots, boolean leadingZeros,
  1511. const byte numberFont[])
  1512. {
  1513. setDisplayToDecNumberAt(number, dots, 0, leadingZeros, numberFont);
  1514. }
  1515.  
  1516. void TM16xxDisplay::setDisplayToSignedDecNumber(signed long number, byte dots, boolean leadingZeros, const byte numberFont[])
  1517. {
  1518. if (number >= 0) {
  1519. setDisplayToDecNumberAt(number, dots, 0, leadingZeros, numberFont);
  1520. } else {
  1521. if (-number > 9999999L) {
  1522. setDisplayToError();
  1523. } else {
  1524. setDisplayToDecNumberAt(-number, dots, 1, leadingZeros, numberFont);
  1525. _pTM16xx->sendChar(0, MINUS, (dots & (0x80)) != 0);
  1526. }
  1527. }
  1528. }
  1529.  
  1530. void TM16xxDisplay::setDisplayToBinNumber(byte number, byte dots, const byte numberFont[])
  1531. {
  1532. for (int i = 0; i < _nNumDigits; i++) {
  1533. _pTM16xx->setDisplayDigit((number & (1 << i)) == 0 ? 0 : 1, _nNumDigits - i - 1, (dots & (1 << i)) != 0, numberFont);
  1534. }
  1535. }
  1536.  
  1537. void TM16xxDisplay::clear()
  1538. {
  1539. _pTM16xx->clearDisplay();
  1540. }
  1541.  
  1542. void TM16xxDisplay::setCursor(int8_t nPos)
  1543. { // Set the print position. Allow negative numbers to support scrolling
  1544. _nPrintPos=nPos;
  1545. }
  1546.  
  1547. /*
  1548. * Support for the Print class
  1549. *
  1550. * See https://playground.arduino.cc/Code/Printclass
  1551. *
  1552. */
  1553. size_t TM16xxDisplay::write(uint8_t c)
  1554. { //Code to display letter when given the ASCII code for it
  1555. static uint8_t cPrevious=' '; // remember last character prnted, to add a dot when needed
  1556. /*
  1557. Serial.print(F("Pos "));
  1558. Serial.print(_nPrintPos);
  1559. Serial.print(F(" chr "));
  1560. Serial.print(c);
  1561. Serial.print("=");
  1562. Serial.write(c);
  1563. Serial.print(F(", prev "));
  1564. Serial.print(cPrevious);
  1565. Serial.print("=");
  1566. Serial.write(cPrevious);
  1567. Serial.println("");
  1568. */
  1569. if(c=='\0' || c=='\n' || c=='\r' || _nPrintPos>=_nNumDigits)
  1570. {
  1571. while(_nPrintPos>0 && _nPrintPos<_nNumDigits)
  1572. { // clear the remainder of the line
  1573. _pTM16xx->clearDisplayDigit(_nPrintPos);
  1574. //Serial.println(_nPrintPos);
  1575. _nPrintPos++;
  1576. }
  1577. _nPrintPos=0;
  1578. return(0); // returning zero will stop printing rest of the string
  1579. }
  1580. bool fDot=false;
  1581. if(c=='.' || c==',' || c==':' || c==';')
  1582. {
  1583. c=cPrevious;
  1584. fDot=true;
  1585. if(_nPrintPos>0) _nPrintPos--; // use same position to display the dot
  1586. }
  1587. if(_nPrintPos>=0 && _nPrintPos<_nNumDigits)
  1588. _pTM16xx->sendChar(_nPrintPos, pgm_read_byte_near(TM16XX_FONT_DEFAULT+(c - 32)), fDot);
  1589. cPrevious=c;
  1590. _nPrintPos++;
  1591. return(1);
  1592. }
  1593.  
  1594. /* MMOLE: not called by print()
  1595. size_t TM16xxDisplay::write(const char *str)
  1596. {
  1597. Serial.println(F("write str"));
  1598. setDisplayToString(str);
  1599. _nPrintPos=0;
  1600. }
  1601. */ TM16xx/src/TM16xxDisplay.h 0100777 0000000 0000000 00000004772 14026127460 012434 0 ustar 00 /*
  1602. TM16xxDisplay.h - LED Display class for TM16xx.
  1603. The TM16xxDisplay class supports 7-segment LED displays of various sizes to be
  1604. connected to a TM16xx chip, such as TM1637 or TM1640.
  1605. These are the dimensions supported by the tested TM16xx chips:
  1606. TM1637 8x6 (common anode)
  1607. TM1638 10x8 (common cathode)
  1608. TM1640 8x16 (common cathode)
  1609. TM1650 8x4 (common cathode) (mode 7x4 not tested yet)
  1610. TM1668 10x7 (common cathode) (not supported yet: modes 11x6, 12x5, 13x4)
  1611. Made by Maxint R&D. See https://github.com/maxint-rd/
  1612. */
  1613.  
  1614. #ifndef _TM16XX_DISPLAY_H
  1615. #define _TM16XX_DISPLAY_H
  1616.  
  1617. #include "TM16xx.h"
  1618. #include <Print.h>
  1619. //#include "TM16xxFonts.h"
  1620.  
  1621. class TM16xxDisplay : public Print
  1622. {
  1623. public:
  1624. TM16xxDisplay(TM16xx *pTM16xx, byte nNumDigits);
  1625. void setIntensity(byte intensity); // intensity 0-7, 0=off, 7=bright
  1626.  
  1627. virtual void clear();
  1628.  
  1629. // Set the display to the String (defaults to built in font)
  1630. virtual void setDisplayToString(const char* string, const word dots=0, const byte pos=0, const byte font[] = TM16XX_FONT_DEFAULT);
  1631. virtual void setDisplayToString(String string, const word dots=0, const byte pos=0, const byte font[] = TM16XX_FONT_DEFAULT);
  1632. virtual void setDisplayToError();
  1633.  
  1634. // Set the display to a unsigned hexadecimal number (with or without leading zeros)
  1635. void setDisplayToHexNumber(unsigned long number, byte dots, boolean leadingZeros = true, const byte numberFont[] = TM16XX_NUMBER_FONT);
  1636. // Set the display to a unsigned decimal number (with or without leading zeros)
  1637. void setDisplayToDecNumber(unsigned long number, byte dots, boolean leadingZeros = true, const byte numberFont[] = TM16XX_NUMBER_FONT);
  1638. // Set the display to a signed decimal number (with or without leading zeros)
  1639. void setDisplayToSignedDecNumber(signed long number, byte dots, boolean leadingZeros = true, const byte numberFont[] = TM16XX_NUMBER_FONT);
  1640. // Set the display to a unsigned binary number
  1641. void setDisplayToBinNumber(byte number, byte dots, const byte numberFont[] = TM16XX_NUMBER_FONT);
  1642.  
  1643. // support for the Print class
  1644. void setCursor(int8_t nPos); // allows setting negative to support scrolled printing
  1645. using Print::write; // pull in write(str) and write(buf, size) from Print
  1646. virtual size_t write(uint8_t character);
  1647. /* virtual size_t write(const char *str); */
  1648.  
  1649. protected:
  1650. TM16xx *_pTM16xx;
  1651. byte _nNumDigits;
  1652. int8_t _nPrintPos=0;
  1653.  
  1654. private:
  1655. void setDisplayToDecNumberAt(unsigned long number, byte dots, byte startingPos, boolean leadingZeros, const byte numberFont[]);
  1656. };
  1657. #endif TM16xx/src/TM16xxFonts.h 0100777 0000000 0000000 00000007533 14026130270 012107 0 ustar 00 /*
  1658. TM16xxFonts.h - Font definition for TM16xx.
  1659. Copyright (C) 2011 Ricardo Batista (rjbatista <at> gmail <dot> com)
  1660. This program is free software: you can redistribute it and/or modify
  1661. it under the terms of the version 3 GNU General Public License as
  1662. published by the Free Software Foundation.
  1663. This program is distributed in the hope that it will be useful,
  1664. but WITHOUT ANY WARRANTY; without even the implied warranty of
  1665. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  1666. GNU General Public License for more details.
  1667. You should have received a copy of the GNU General Public License
  1668. along with this program. If not, see <http://www.gnu.org/licenses/>.
  1669. The bits are displayed by mapping bellow
  1670. -- 0 --
  1671. | |
  1672. 5 1
  1673. -- 6 --
  1674. 4 2
  1675. | |
  1676. -- 3 -- .7
  1677. */
  1678.  
  1679. #ifndef TM16XXFonts_h
  1680. #define TM16XXFonts_h
  1681.  
  1682. // definition for standard hexadecimal numbers
  1683. const PROGMEM byte TM16XX_NUMBER_FONT[] = {
  1684. 0b00111111, // 0
  1685. 0b00000110, // 1
  1686. 0b01011011, // 2
  1687. 0b01001111, // 3
  1688. 0b01100110, // 4
  1689. 0b01101101, // 5
  1690. 0b01111101, // 6
  1691. 0b00000111, // 7
  1692. 0b01111111, // 8
  1693. 0b01101111, // 9
  1694. 0b01110111, // A
  1695. 0b01111100, // B
  1696. 0b00111001, // C
  1697. 0b01011110, // D
  1698. 0b01111001, // E
  1699. 0b01110001 // F
  1700. };
  1701.  
  1702. const PROGMEM byte MINUS = 0b01000000;
  1703.  
  1704. // definition for error
  1705. const PROGMEM byte TM16XX_ERROR_DATA[] = {
  1706. 0b01111001, // E
  1707. 0b01010000, // r
  1708. 0b01010000, // r
  1709. 0b01011100, // o
  1710. 0b01010000, // r
  1711. 0,
  1712. 0,
  1713. 0
  1714. };
  1715.  
  1716. // definition for the displayable ASCII chars
  1717. const PROGMEM byte TM16XX_FONT_DEFAULT[] = {
  1718. 0b00000000, // (32) <space>
  1719. 0b10000110, // (33) !
  1720. 0b00100010, // (34) "
  1721. 0b01111110, // (35) #
  1722. 0b01101101, // (36) $
  1723. 0b00000000, // (37) %
  1724. 0b00000000, // (38) &
  1725. 0b00000010, // (39) '
  1726. 0b00110000, // (40) (
  1727. 0b00000110, // (41) )
  1728. 0b01100011, // (42) *
  1729. 0b00000000, // (43) +
  1730. 0b00000100, // (44) ,
  1731. 0b01000000, // (45) -
  1732. 0b10000000, // (46) .
  1733. 0b01010010, // (47) /
  1734. 0b00111111, // (48) 0
  1735. 0b00000110, // (49) 1
  1736. 0b01011011, // (50) 2
  1737. 0b01001111, // (51) 3
  1738. 0b01100110, // (52) 4
  1739. 0b01101101, // (53) 5
  1740. 0b01111101, // (54) 6
  1741. 0b00100111, // (55) 7
  1742. 0b01111111, // (56) 8
  1743. 0b01101111, // (57) 9
  1744. 0b00000000, // (58) :
  1745. 0b00000000, // (59) ;
  1746. 0b00000000, // (60) <
  1747. 0b01001000, // (61) =
  1748. 0b00000000, // (62) >
  1749. 0b01010011, // (63) ?
  1750. 0b01011111, // (64) @
  1751. 0b01110111, // (65) A
  1752. 0b01111111, // (66) B
  1753. 0b00111001, // (67) C
  1754. 0b00111111, // (68) D
  1755. 0b01111001, // (69) E
  1756. 0b01110001, // (70) F
  1757. 0b00111101, // (71) G
  1758. 0b01110110, // (72) H
  1759. 0b00000110, // (73) I
  1760. 0b00011111, // (74) J
  1761. 0b01101001, // (75) K
  1762. 0b00111000, // (76) L
  1763. 0b00010101, // (77) M
  1764. 0b00110111, // (78) N
  1765. 0b00111111, // (79) O
  1766. 0b01110011, // (80) P
  1767. 0b01100111, // (81) Q
  1768. 0b00110001, // (82) R
  1769. 0b01101101, // (83) S
  1770. 0b01111000, // (84) T
  1771. 0b00111110, // (85) U
  1772. 0b00101010, // (86) V
  1773. 0b00011101, // (87) W
  1774. 0b01110110, // (88) X
  1775. 0b01101110, // (89) Y
  1776. 0b01011011, // (90) Z
  1777. 0b00111001, // (91) [
  1778. 0b01100100, // (92) \ (this can't be the last char on a line, even in comment or it'll concat)
  1779. 0b00001111, // (93) ]
  1780. 0b00000000, // (94) ^
  1781. 0b00001000, // (95) _
  1782. 0b00100000, // (96) `
  1783. 0b01011111, // (97) a
  1784. 0b01111100, // (98) b
  1785. 0b01011000, // (99) c
  1786. 0b01011110, // (100) d
  1787. 0b01111011, // (101) e
  1788. 0b00110001, // (102) f
  1789. 0b01101111, // (103) g
  1790. 0b01110100, // (104) h
  1791. 0b00000100, // (105) i
  1792. 0b00001110, // (106) j
  1793. 0b01110101, // (107) k
  1794. 0b00110000, // (108) l
  1795. 0b01010101, // (109) m
  1796. 0b01010100, // (110) n
  1797. 0b01011100, // (111) o
  1798. 0b01110011, // (112) p
  1799. 0b01100111, // (113) q
  1800. 0b01010000, // (114) r
  1801. 0b01101101, // (115) s
  1802. 0b01111000, // (116) t
  1803. 0b00011100, // (117) u
  1804. 0b00101010, // (118) v
  1805. 0b00011101, // (119) w
  1806. 0b01110110, // (120) x
  1807. 0b01101110, // (121) y
  1808. 0b01000111, // (122) z
  1809. 0b01000110, // (123) {
  1810. 0b00000110, // (124) |
  1811. 0b01110000, // (125) }
  1812. 0b00000001, // (126) ~
  1813. };
  1814. #endif
  1815. TM16xx/src/TM16xxMatrix.cpp 0100777 0000000 0000000 00000001765 14026127460 012625 0 ustar 00 /*
  1816. TM16xxMatrix.h - LED Matrix library for TM16xx.
  1817. Made by Maxint R&D. See https://github.com/maxint-rd/
  1818. */
  1819. #include "TM16xxMatrix.h"
  1820.  
  1821. TM16xxMatrix::TM16xxMatrix(TM16xx *pTM16xx, byte nColumns, byte nRows)
  1822. {
  1823. _pTM16xx=pTM16xx;
  1824. _nColumns=nColumns;
  1825. _nRows=nRows;
  1826.  
  1827. // offscreen bitmap is required to set an individual pixel, while retaining the others
  1828. // TODO: use dynamic memory allocation for the off-screen bitmap
  1829. // as different chips support different sizes
  1830. }
  1831.  
  1832. void TM16xxMatrix::setColumn(byte nCol, byte bPixels)
  1833. {
  1834. _btColumns[nCol]=bPixels;
  1835. _pTM16xx->setSegments(bPixels, nCol);
  1836. }
  1837.  
  1838. void TM16xxMatrix::setAll(bool fOn)
  1839. {
  1840. for(byte nCol=0; nCol<_nColumns; nCol++)
  1841. setColumn(nCol, fOn?0xFF:0);
  1842. }
  1843.  
  1844. void TM16xxMatrix::setPixel(byte nCol, byte nRow, bool fOn)
  1845. {
  1846. byte btColumn=_btColumns[nCol];
  1847. if(fOn)
  1848. btColumn=btColumn | _BV(nRow);
  1849. else
  1850. btColumn=btColumn & ~_BV(nRow);
  1851. setColumn(nCol, btColumn);
  1852. }
  1853.  
  1854. bool TM16xxMatrix::getPixel(byte nCol, byte nRow)
  1855. {
  1856. return((_btColumns[nCol]&_BV(nRow))!=0);
  1857. } TM16xx/src/TM16xxMatrix.h 0100777 0000000 0000000 00000001761 14026127460 012266 0 ustar 00 /*
  1858. TM16xxMatrix.h - LED Matrix class for TM16xx.
  1859. The TM16xxMatrix class supports LED matrices of various sizes to be connected
  1860. to a TM16xx chip, such as TM1640 or TM1638.
  1861. These are the resolutions supported by the most popular TM16xx chips:
  1862. TM1637 8x6 (common anode)
  1863. TM1638 10x8 (common cathode)
  1864. TM1640 8x16 (common cathode)
  1865. TM1668 10x7 (common cathode)
  1866. Made by Maxint R&D. See https://github.com/maxint-rd/
  1867. */
  1868. #ifndef _TM16XX_MATRIX_H
  1869. #define _TM16XX_MATRIX_H
  1870.  
  1871. #include "TM16xx.h"
  1872.  
  1873. #define TM16XX_MATRIX_MAXCOLUMNS 16
  1874.  
  1875. class TM16xxMatrix
  1876. {
  1877. public:
  1878. TM16xxMatrix(TM16xx *pTM16xx, byte nColumns, byte nRows);
  1879. void setColumn(byte nCol, byte bPixels);
  1880. void setAll(bool fOn);
  1881. void setPixel(byte nCol, byte nRow, bool fOn);
  1882. bool getPixel(byte nCol, byte nRow);
  1883. inline byte getNumRows() { return(_nRows); }
  1884. inline byte getNumColumns() { return(_nColumns); }
  1885.  
  1886. protected:
  1887. TM16xx *_pTM16xx;
  1888. byte _nColumns;
  1889. byte _nRows;
  1890.  
  1891. byte _btColumns[TM16XX_MATRIX_MAXCOLUMNS]={0};
  1892. };
  1893. #endif TM16xx/src/TM16xxMatrixGFX.cpp 0100777 0000000 0000000 00000012200 14026127460 013154 0 ustar 00 /*
  1894. TM16xxMatrixGFX.h - Adafruit GFX LED Matrix library for TM16xx.
  1895. Made by Maxint R&D. See https://github.com/maxint-rd/
  1896. */
  1897. #include <Adafruit_GFX.h>
  1898. #include "TM16xxMatrixGFX.h"
  1899.  
  1900. #define TM16xxMatrixGFX_swap(a, b) { int16_t t = a; a = b; b = t; }
  1901.  
  1902. TM16xxMatrixGFX::TM16xxMatrixGFX(TM16xx *pModule, byte nColumns, byte nRows) : Adafruit_GFX(nRows, nColumns)
  1903. {
  1904. _nColumns=nColumns;
  1905. _nRows=nRows;
  1906. _fMirrorX=false;
  1907. _fMirrorY=false;
  1908.  
  1909. // Allocate a module array for just one module
  1910. _nModules=1;
  1911. _aModules=(TM16xx **)malloc(sizeof(TM16xx *));
  1912. _aModules[0]=pModule;
  1913.  
  1914. // An offscreen bitmap is required to set an individual pixel, while retaining the others
  1915. // We use dynamic memory allocation for the off-screen bitmap
  1916. // as different chips support different sizes
  1917. TM16xxMatrixGFX::bitmapSize = _nColumns;
  1918. TM16xxMatrixGFX::bitmap = (byte*)malloc(bitmapSize);
  1919. fillScreen(0);
  1920. }
  1921.  
  1922. TM16xxMatrixGFX::TM16xxMatrixGFX(TM16xx *aModules[], byte nColumns, byte nRows, byte nModulesCol, byte nModulesRow) : Adafruit_GFX(nRows*nModulesRow, nColumns*nModulesCol)
  1923. {
  1924. _nColumns=nColumns;
  1925. _nRows=nRows;
  1926. _fMirrorX=false;
  1927. _fMirrorY=false;
  1928.  
  1929. // Allocate memory to copy pointers to the modules
  1930. _nModules=nModulesRow*nModulesCol;
  1931. _aModules=(TM16xx **)malloc(_nModules*sizeof(TM16xx *));
  1932. for(byte n=0; n<_nModules; n++)
  1933. _aModules[n]=aModules[n];
  1934.  
  1935. // Allocate memory for the memory bitmap
  1936. _nModulesRow=nModulesRow;
  1937. _nModulesCol=nModulesCol;
  1938. TM16xxMatrixGFX::bitmapSize = _nColumns*nModulesRow*nModulesCol; // assume 8 rows per byte
  1939. TM16xxMatrixGFX::bitmap = (byte*)malloc(bitmapSize);
  1940. fillScreen(0);
  1941. }
  1942.  
  1943. void TM16xxMatrixGFX::setIntensity(byte intensity)
  1944. { // set the intensity of all modules
  1945. for(byte n=0; n<_nModules; n++)
  1946. _aModules[n]->setupDisplay(true, intensity);
  1947. }
  1948.  
  1949. void TM16xxMatrixGFX::setMirror(boolean fMirrorX, boolean fMirrorY) // fMirrorX=false, fMirrorY=false
  1950. {
  1951. _fMirrorX=fMirrorX;
  1952. _fMirrorY=fMirrorY;
  1953. }
  1954.  
  1955.  
  1956. void TM16xxMatrixGFX::fillScreen(uint16_t color)
  1957. { // set the offscreen bitmap to the specified color
  1958. memset(bitmap, color ? 0xff : 0, bitmapSize);
  1959. }
  1960.  
  1961. bool TM16xxMatrixGFX::convertToMemPos(int16_t &x, int16_t &y)
  1962. { // Convert x/y coordinates to bitmap memory position (array with rows of 8 pixels per byte)
  1963. // Given coordinates are passed by reference and changed to the required range
  1964. // Returns false if coordinates fall outside of canvas after processing rotation
  1965. if (rotation)
  1966. {
  1967. // Implement Adafruit's rotation.
  1968. byte tmp;
  1969. if ( rotation >= 2 ) { // rotation == 2 || rotation == 3
  1970. x = _width - 1 - x;
  1971. }
  1972.  
  1973. if ( rotation == 1 || rotation == 2 ) { // rotation == 1 || rotation == 2
  1974. y = _height - 1 - y;
  1975. }
  1976.  
  1977. if ( rotation & 1 ) { // rotation == 1 || rotation == 3
  1978. tmp = x; x = y; y = tmp;
  1979. }
  1980. }
  1981.  
  1982. if ( x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT ) {
  1983. // Ignore pixels outside the canvas.
  1984. return(false);
  1985. }
  1986.  
  1987. /* // TODO?: support for different module orientaton and layout? (currently only left-top to right-bottom)
  1988. // Translate the x, y coordinate according to the layout of the
  1989. // displays. They can be ordered and rotated (0, 90, 180, 270).
  1990. byte display = matrixPosition[(x >> 3) + hDisplays * (y >> 3)];
  1991. x &= 0b111;
  1992. y &= 0b111;
  1993. byte r = matrixRotation[display];
  1994. if ( r >= 2 ) { // 180 or 270 degrees
  1995. x = 7 - x;
  1996. }
  1997. if ( r == 1 || r == 2 ) { // 90 or 180 degrees
  1998. y = 7 - y;
  1999. }
  2000. if ( r & 1 ) { // 90 or 270 degrees
  2001. tmp = x; x = y; y = tmp;
  2002. }
  2003. byte d = display / hDisplays;
  2004. x += (display - d * hDisplays) << 3; // x += (display % hDisplays) * 8
  2005. y += d << 3; // y += (display / hDisplays) * 8
  2006. // Update the color bit in our bitmap buffer.
  2007. byte *ptr = bitmap + x + WIDTH * (y >> 3);
  2008. byte val = 1 << (y & 0b111);
  2009. if ( color ) {
  2010. *ptr |= val;
  2011. }
  2012. else {
  2013. *ptr &= ~val;
  2014. }
  2015. */
  2016.  
  2017. // mirror display (fMirrorX true for WeMOS mini matrix)
  2018. if(_fMirrorX)
  2019. x=WIDTH-x-1;
  2020. if(_fMirrorY)
  2021. y=HEIGHT-y-1;
  2022.  
  2023. // Translation for multiple modules.
  2024. if(_nModules>1)
  2025. { // Assume modules are identical and ordered left to right, top to bottom
  2026. // The columns are stacked in memory in module order
  2027. uint8_t _nModule=x/_nRows + _nModulesRow*(y/_nColumns);
  2028. y=y%_nColumns+(_nModule*_nColumns);
  2029. x=x%_nRows;
  2030. }
  2031. return(true);
  2032. }
  2033.  
  2034. void TM16xxMatrixGFX::drawPixel(int16_t xx, int16_t yy, uint16_t color)
  2035. { // set the specified pixel as wanted in the memory
  2036. // Operating in bytes is faster and takes less code to run. We don't
  2037. // need values above 200, so switch from 16 bit ints to 8 bit unsigned
  2038. // ints (bytes).
  2039. //int8_t x = xx;
  2040. //int8_t y = yy;
  2041.  
  2042. int16_t x = xx;
  2043. int16_t y = yy;
  2044.  
  2045. if(!convertToMemPos(x, y))
  2046. return;
  2047.  
  2048. if(color)
  2049. {
  2050. bitmap[y]|=(1<<x);
  2051. }
  2052. else
  2053. {
  2054. bitmap[y]&=~(1<<x);
  2055. }
  2056. }
  2057.  
  2058. // required for scroll support as implemented by Adafruit GFX pull request #60
  2059. uint16_t TM16xxMatrixGFX::getPixel(int16_t x, int16_t y)
  2060. {
  2061. if ((x < 0) || (x >= _width) || (y < 0) || (y >= _height))
  2062. return 0;
  2063.  
  2064. if(!convertToMemPos(x, y))
  2065. return 0;
  2066.  
  2067. return (bitmap[y+ (x/8)*WIDTH] >> (x%8)) & 0x1;
  2068. }
  2069.  
  2070. void TM16xxMatrixGFX::write()
  2071. { // write the memory to the display
  2072. for(uint8_t n=0;n<_nModules;n++)
  2073. {
  2074. for(uint8_t i=0;i<_nColumns;i++)
  2075. {
  2076. _aModules[n]->setSegments(bitmap[i+(n*_nColumns)],i);
  2077. }
  2078. }
  2079. } TM16xx/src/TM16xxMatrixGFX.h 0100777 0000000 0000000 00000003004 14026127460 012623 0 ustar 00 /*
  2080. TM16xxMatrixGFX.h - Adafruit GFX LED Matrix class for TM16xx.
  2081. The TM16xxMatrixGFX class supports LED matrices of various sizes to be connected
  2082. to a TM16xx chip, such as TM1640 or TM1638.
  2083. These are the resolutions supported by the most popular TM16xx chips:
  2084. TM1637 8x6 (common anode)
  2085. TM1638 10x8 (common cathode)
  2086. TM1640 8x16 (common cathode)
  2087. TM1668 10x7 (common cathode)
  2088. The library supports modules with either 8x8 or 8x16 pixels
  2089. Made by Maxint R&D. See https://github.com/maxint-rd/
  2090. */
  2091. #ifndef _TM16XX_MATRIXGFX_H
  2092. #define _TM16XX_MATRIXGFX_H
  2093.  
  2094. #include "TM16xx.h"
  2095.  
  2096. #define TM16XX_MATRIXGFX_MAXCOLUMNS 16
  2097.  
  2098. class TM16xxMatrixGFX : public Adafruit_GFX
  2099. {
  2100. public:
  2101. TM16xxMatrixGFX(TM16xx *pModule, byte nColumns, byte nRows);
  2102. TM16xxMatrixGFX(TM16xx *aModules[], byte nColumns, byte nRows, byte nModulesCol, byte nModulesRow); // module layout left-top to right-bottom
  2103. void setIntensity(byte intensity); // intensity 0-7, 0=off, 7=bright
  2104. void setMirror(boolean fMirrorX=false, boolean fMirrorY=false);
  2105. void fillScreen(uint16_t color);
  2106. void drawPixel(int16_t x, int16_t y, uint16_t color);
  2107. uint16_t getPixel(int16_t x, int16_t y); // required for scroll support as implemented by Adafruit GFX pull request #60
  2108.  
  2109. void write();
  2110.  
  2111. protected:
  2112. byte _nModules;
  2113. byte _nModulesCol;
  2114. byte _nModulesRow;
  2115. TM16xx **_aModules;
  2116.  
  2117. byte _nColumns;
  2118. byte _nRows;
  2119. boolean _fMirrorX;
  2120. boolean _fMirrorY;
  2121.  
  2122. byte *bitmap;
  2123. byte bitmapSize;
  2124.  
  2125. private:
  2126. bool convertToMemPos(int16_t &x, int16_t &y);
  2127. };
  2128. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement