Advertisement
Guest User

Untitled

a guest
Jul 20th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.14 KB | None | 0 0
  1. #define FONT_WIDTH 8
  2. #define INTERCHAR_SPACE 1
  3. #define ASCII_OFFSET 0x20 // ASSCI code of 1st char in font array
  4.  
  5. String myMessage = " /c#000044Welcome to /c#004400/bZillow!/b";
  6.  
  7. const uint8_t Font5x7[] PROGMEM = {
  8. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  9. 0x00,0x00,0x60,0xfa,0xfa,0x60,0x00,0x00,
  10. 0x00,0xc0,0xc0,0x00,0xc0,0xc0,0x00,0x00,
  11. 0x28,0xfe,0xfe,0x28,0xfe,0xfe,0x28,0x00,
  12. 0x24,0x74,0xd6,0xd6,0x5c,0x48,0x00,0x00,
  13. 0x62,0x66,0x0c,0x18,0x30,0x66,0x46,0x00,
  14. 0x0c,0x5e,0xf2,0xba,0xec,0x5e,0x12,0x00,
  15. 0x20,0xe0,0xc0,0x00,0x00,0x00,0x00,0x00,
  16. 0x00,0x38,0x7c,0xc6,0x82,0x00,0x00,0x00,
  17. 0x00,0x82,0xc6,0x7c,0x38,0x00,0x00,0x00,
  18. 0x10,0x54,0x7c,0x38,0x38,0x7c,0x54,0x10,
  19. 0x10,0x10,0x7c,0x7c,0x10,0x10,0x00,0x00,
  20. 0x00,0x01,0x07,0x06,0x00,0x00,0x00,0x00,
  21. 0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
  22. 0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x00,
  23. 0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,
  24. 0x7c,0xfe,0x8e,0x9a,0xb2,0xfe,0x7c,0x00,
  25. 0x02,0x42,0xfe,0xfe,0x02,0x02,0x00,0x00,
  26. 0x46,0xce,0x9a,0x92,0xf6,0x66,0x00,0x00,
  27. 0x44,0xc6,0x92,0x92,0xfe,0x6c,0x00,0x00,
  28. 0x18,0x38,0x68,0xca,0xfe,0xfe,0x0a,0x00,
  29. 0xe4,0xe6,0xa2,0xa2,0xbe,0x9c,0x00,0x00,
  30. 0x3c,0x7e,0xd2,0x92,0x9e,0x0c,0x00,0x00,
  31. 0xc0,0xc0,0x8e,0x9e,0xf0,0xe0,0x00,0x00,
  32. 0x6c,0xfe,0x92,0x92,0xfe,0x6c,0x00,0x00,
  33. 0x60,0xf2,0x92,0x96,0xfc,0x78,0x00,0x00,
  34. 0x00,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
  35. 0x00,0x01,0x67,0x66,0x00,0x00,0x00,0x00,
  36. 0x10,0x38,0x6c,0xc6,0x82,0x00,0x00,0x00,
  37. 0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,
  38. 0x00,0x82,0xc6,0x6c,0x38,0x10,0x00,0x00,
  39. 0x40,0xc0,0x8a,0x9a,0xf0,0x60,0x00,0x00,
  40. 0x7c,0xfe,0x82,0xba,0xba,0xf8,0x78,0x00,
  41. 0x3e,0x7e,0xc8,0xc8,0x7e,0x3e,0x00,0x00,
  42. 0x82,0xfe,0xfe,0x92,0x92,0xfe,0x6c,0x00,
  43. 0x38,0x7c,0xc6,0x82,0x82,0xc6,0x44,0x00,
  44. 0x82,0xfe,0xfe,0x82,0xc6,0x7c,0x38,0x00,
  45. 0x82,0xfe,0xfe,0x92,0xba,0x82,0xc6,0x00,
  46. 0x82,0xfe,0xfe,0x92,0xb8,0x80,0xc0,0x00,
  47. 0x38,0x7c,0xc6,0x82,0x8a,0xce,0x4e,0x00,
  48. 0xfe,0xfe,0x10,0x10,0xfe,0xfe,0x00,0x00,
  49. 0x00,0x82,0xfe,0xfe,0x82,0x00,0x00,0x00,
  50. 0x0c,0x0e,0x02,0x82,0xfe,0xfc,0x80,0x00,
  51. 0x82,0xfe,0xfe,0x10,0x38,0xee,0xc6,0x00,
  52. 0x82,0xfe,0xfe,0x82,0x02,0x06,0x0e,0x00,
  53. 0xfe,0xfe,0x70,0x38,0x70,0xfe,0xfe,0x00,
  54. 0xfe,0xfe,0x60,0x30,0x18,0xfe,0xfe,0x00,
  55. 0x38,0x7c,0xc6,0x82,0xc6,0x7c,0x38,0x00,
  56. 0x82,0xfe,0xfe,0x92,0x90,0xf0,0x60,0x00,
  57. 0x78,0xfc,0x84,0x8e,0xfe,0x7a,0x00,0x00,
  58. 0x82,0xfe,0xfe,0x90,0x98,0xfe,0x66,0x00,
  59. 0x64,0xf6,0xb2,0x9a,0xce,0x4c,0x00,0x00,
  60. 0xc0,0x82,0xfe,0xfe,0x82,0xc0,0x00,0x00,
  61. 0xfe,0xfe,0x02,0x02,0xfe,0xfe,0x00,0x00,
  62. 0xf8,0xfc,0x06,0x06,0xfc,0xf8,0x00,0x00,
  63. 0xfe,0xfe,0x0c,0x18,0x0c,0xfe,0xfe,0x00,
  64. 0xc2,0xe6,0x3c,0x18,0x3c,0xe6,0xc2,0x00,
  65. 0xe0,0xf2,0x1e,0x1e,0xf2,0xe0,0x00,0x00,
  66. 0xe2,0xc6,0x8e,0x9a,0xb2,0xe6,0xce,0x00,
  67. 0x00,0xfe,0xfe,0x82,0x82,0x00,0x00,0x00,
  68. 0x80,0xc0,0x60,0x30,0x18,0x0c,0x06,0x00,
  69. 0x00,0x82,0x82,0xfe,0xfe,0x00,0x00,0x00,
  70. 0x10,0x30,0x60,0xc0,0x60,0x30,0x10,0x00,
  71. 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
  72. 0x00,0x00,0xc0,0xe0,0x20,0x00,0x00,0x00,
  73. 0x04,0x2e,0x2a,0x2a,0x3c,0x1e,0x02,0x00,
  74. 0x82,0xfe,0xfc,0x12,0x12,0x1e,0x0c,0x00,
  75. 0x1c,0x3e,0x22,0x22,0x36,0x14,0x00,0x00,
  76. 0x0c,0x1e,0x12,0x92,0xfc,0xfe,0x02,0x00,
  77. 0x1c,0x3e,0x2a,0x2a,0x3a,0x18,0x00,0x00,
  78. 0x12,0x7e,0xfe,0x92,0xc0,0x40,0x00,0x00,
  79. 0x19,0x3d,0x25,0x25,0x1f,0x3e,0x20,0x00,
  80. 0x82,0xfe,0xfe,0x10,0x20,0x3e,0x1e,0x00,
  81. 0x00,0x22,0xbe,0xbe,0x02,0x00,0x00,0x00,
  82. 0x06,0x07,0x01,0x01,0xbf,0xbe,0x00,0x00,
  83. 0x82,0xfe,0xfe,0x08,0x1c,0x36,0x22,0x00,
  84. 0x00,0x82,0xfe,0xfe,0x02,0x00,0x00,0x00,
  85. 0x3e,0x3e,0x18,0x1c,0x38,0x3e,0x1e,0x00,
  86. 0x3e,0x3e,0x20,0x20,0x3e,0x1e,0x00,0x00,
  87. 0x1c,0x3e,0x22,0x22,0x3e,0x1c,0x00,0x00,
  88. 0x21,0x3f,0x1f,0x25,0x24,0x3c,0x18,0x00,
  89. 0x18,0x3c,0x24,0x25,0x1f,0x3f,0x21,0x00,
  90. 0x22,0x3e,0x1e,0x32,0x20,0x38,0x18,0x00,
  91. 0x12,0x3a,0x2a,0x2a,0x2e,0x24,0x00,0x00,
  92. 0x00,0x20,0x7c,0xfe,0x22,0x24,0x00,0x00,
  93. 0x3c,0x3e,0x02,0x02,0x3c,0x3e,0x02,0x00,
  94. 0x38,0x3c,0x06,0x06,0x3c,0x38,0x00,0x00,
  95. 0x3c,0x3e,0x0e,0x1c,0x0e,0x3e,0x3c,0x00,
  96. 0x22,0x36,0x1c,0x08,0x1c,0x36,0x22,0x00,
  97. 0x39,0x3d,0x05,0x05,0x3f,0x3e,0x00,0x00,
  98. 0x32,0x26,0x2e,0x3a,0x32,0x26,0x00,0x00,
  99. 0x10,0x10,0x7c,0xee,0x82,0x82,0x00,0x00,
  100. 0x00,0x00,0x00,0xee,0xee,0x00,0x00,0x00,
  101. 0x82,0x82,0xee,0x7c,0x10,0x10,0x00,0x00,
  102. 0x40,0xc0,0x80,0xc0,0x40,0xc0,0x80,0x00,
  103. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  104. };
  105. const uint8_t Sprites8x8[] PROGMEM = {
  106. 0x10,0x3f,0x7f,0xff,0xf8,0x78,0x3f,0x10
  107. };
  108.  
  109. #define PIXELS 60*4 // Number of pixels in the string. I am using 4 meters of 96LED/M
  110.  
  111. #define PIXEL_PORT PORTD // Port of the pin the pixels are connected to
  112. #define PIXEL_DDR DDRD // Port of the pin the pixels are connected to
  113.  
  114. #define READY_FOR_MESSAGE_SIGNAL "READYMESSAGE#_-#CANARY#_-#READYMESSAGE"
  115.  
  116. #define BAUD_RATE 9600
  117.  
  118. #define WAIT_FOR_INPUT_DURATION 100
  119.  
  120. #define DEBUG false
  121.  
  122. static const uint8_t onBits = 0b11111111; // Bit pattern to write to port to turn on all pins connected to LED strips.
  123.  
  124. // Phase #1 - Always 1 - 5 cycles, Phase #2 - Data part - 8 cycles, Phase #3 - Always 0 - 7 cycles
  125. #define T1H 814 // Width of a 1 bit in ns - 13 cycles
  126. #define T1L 438 // Width of a 1 bit in ns - 7 cycles
  127.  
  128. #define T0H 312 // Width of a 0 bit in ns - 5 cycles
  129. #define T0L 936 // Width of a 0 bit in ns - 15 cycles
  130.  
  131. #define RES 500000 // Width of the low gap between bits to cause a frame to latch
  132. #define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives
  133. #define CYCLES_PER_SEC (F_CPU)
  134. #define NS_PER_CYCLE ( NS_PER_SEC / CYCLES_PER_SEC )
  135. #define NS_TO_CYCLES(n) ( (n) / NS_PER_CYCLE )
  136.  
  137. struct FormattingState {
  138. uint8_t red;
  139. uint8_t green;
  140. uint8_t blue;
  141. bool isBlinkEnabled;
  142. bool isEscapedSlash;
  143. };
  144.  
  145. struct FormattingState currentFormattingState;
  146. struct FormattingState startOfOutputFormattingState;
  147.  
  148. bool isBlinkFrame;
  149.  
  150. void setup() {
  151. PIXEL_DDR |= onBits; // Set used pins to output mode
  152.  
  153. // initialize formatting state
  154. currentFormattingState.red = 0x00;
  155. currentFormattingState.green = 0x00;
  156. currentFormattingState.blue = 0x40;
  157. currentFormattingState.isBlinkEnabled = false;
  158. currentFormattingState.isEscapedSlash = false;
  159. startOfOutputFormattingState = currentFormattingState;
  160. }
  161.  
  162. void loop() {
  163. String messageIterator = myMessage;
  164.  
  165. while (messageIterator.length()) {
  166.  
  167. // restore the startOfOutputFormattingState (since we're starting to output the message again)
  168. currentFormattingState = startOfOutputFormattingState;
  169.  
  170. // process the escape characters at the current position of the message
  171. messageIterator = processEscapeCharacters(messageIterator.c_str());
  172.  
  173. // after processing escape characters, it's possible that we are now at the end of our string, in which case stop
  174. if (!messageIterator) {
  175. break;
  176. }
  177.  
  178. // update the startOfOutputFormatting state in case it has now changed
  179. startOfOutputFormattingState = currentFormattingState;
  180.  
  181. // step though each column of the 1st char for smooth scrolling
  182. for (uint8_t step = 0; step < FONT_WIDTH + INTERCHAR_SPACE ; step++) {
  183.  
  184. noInterrupts();
  185.  
  186. sendString(messageIterator.c_str(), step);
  187.  
  188. interrupts();
  189.  
  190. delay(10);
  191. }
  192.  
  193. // toggle the isBlinkFrame (for any blinking text)
  194. isBlinkFrame = !isBlinkFrame;
  195.  
  196. messageIterator = messageIterator.substring(1);
  197. }
  198.  
  199. requestNewMessage();
  200. }
  201.  
  202. // Show the passed string. The last letter of the string will be in the rightmost pixels of the display.
  203. // Skip is how many cols of the 1st char to skip for smooth scrolling
  204. static inline void sendString(const char *str , uint8_t skip) {
  205.  
  206. unsigned int maximumNumberOfVisibleCharacters = PIXELS / (FONT_WIDTH + INTERCHAR_SPACE);
  207.  
  208. // First char is special case because it can be stepped for smooth scrolling
  209. sendChar(*str, skip, currentFormattingState.red, currentFormattingState.green, currentFormattingState.blue);
  210.  
  211. while (++str && maximumNumberOfVisibleCharacters-- > 0) {
  212. str = processEscapeCharacters(str);
  213.  
  214. // after processing escape characters, it's possible that we are now at the end of our string, in which case stop
  215. if(!*str) {
  216. break;
  217. }
  218.  
  219. sendChar(*str, 0, currentFormattingState.red, currentFormattingState.green, currentFormattingState.blue);
  220. }
  221.  
  222. show();
  223. }
  224.  
  225. // Send the pixels to form the specified char, not including interchar space
  226. // skip is the number of pixels to skip at the begining to enable sub-char smooth scrolling
  227. // TODO: Subtract the offset from the char before starting the send sequence to save time if nessisary
  228. // TODO: Also could pad the begining of the font table to aovid the offset subtraction at the cost of 20*8 bytes of progmem
  229. // TODO: Could pad all chars out to 8 bytes wide to turn the the multiply by FONT_WIDTH into a shift
  230. static inline void sendChar(uint8_t character, uint8_t skip, uint8_t r, uint8_t g, uint8_t b) {
  231.  
  232. const uint8_t *charbase = Font5x7 + (( character - ' ') * FONT_WIDTH ) ;
  233.  
  234. uint8_t col = FONT_WIDTH;
  235.  
  236. while (skip--) {
  237. charbase++;
  238. col--;
  239. }
  240.  
  241. while (col--) {
  242. sendRowRGB(pgm_read_byte_near(charbase++), r, g, b);
  243. }
  244.  
  245. col = INTERCHAR_SPACE;
  246.  
  247. while (col--) {
  248. sendRowRGB(0, r, g, b); // Interchar space
  249. }
  250. }
  251.  
  252. // Send 3 bytes of color data (R,G,B) for a signle pixel down all the connected stringsat the same time
  253. // A 1 bit in "row" means send the color, a 0 bit means send black.
  254. static inline void sendRowRGB( uint8_t row, uint8_t r, uint8_t g, uint8_t b ) {
  255. // on a blink frame when blink is enabled, don't draw anything for this row
  256. if (currentFormattingState.isBlinkEnabled && isBlinkFrame) {
  257. row = 0;
  258. }
  259.  
  260. if (DEBUG) {
  261. // output to serial for testing
  262. printRowToSerial(row);
  263. }
  264.  
  265. sendBitx8(row, g , onBits); // WS2812 takes colors in GRB order
  266. sendBitx8(row, r , onBits); // WS2812 takes colors in GRB order
  267. sendBitx8(row, b , onBits); // WS2812 takes colors in GRB order
  268. }
  269.  
  270. // Sends a full 8 bits down all the pins, represening a single color of 1 pixel
  271. // We walk though the 8 bits in colorbyte one at a time. If the bit is 1 then we send the 8 bits of row out. Otherwise we send 0.
  272. // We send onBits at the first phase of the signal generation. We could just send 0xff, but that mught enable pull-ups on pins that we are not using.
  273.  
  274.  
  275. // OnBits is the mask of which bits are connected to strips. We pass it on so that we
  276. // do not turn on unused pins becuase this would enable the pullup. Also, hopefully passing this
  277. // will cause the compiler to allocate a Register for it and avoid a reload every pass.
  278. static inline void sendBitx8(const uint8_t row, const uint8_t colorbyte, const uint8_t onBits) {
  279.  
  280. asm volatile (
  281.  
  282. "L_%=: \n\r"
  283.  
  284. "out %[port], %[onBits] \n\t" // (1 cycles) - send either T0H or the first part of T1H. Onbits is a mask of which bits have strings attached.
  285.  
  286. // Next determine if we are going to be sending 1s or 0s based on the current bit in the color....
  287.  
  288. "mov r0, %[bitwalker] \n\t" // (1 cycles)
  289. "and r0, %[colorbyte] \n\t" // (1 cycles) - is the current bit in the color byte set?
  290. "breq OFF_%= \n\t" // (1 cycles) - bit in color is 0, then send full zero row (takes 2 cycles if branch taken, count the extra 1 on the target line)
  291.  
  292. // If we get here, then we want to send a 1 for every row that has an ON dot...
  293. "nop \n\t " // (1 cycles)
  294. "out %[port], %[row] \n\t" // (1 cycles) - set the output bits to [row] This is phase for T0H-T1H.
  295. // ==========
  296. // (5 cycles) - T0H (Phase #1)
  297.  
  298.  
  299. "nop \n\t nop \n\t " // (2 cycles)
  300. "nop \n\t nop \n\t " // (2 cycles)
  301. "nop \n\t nop \n\t " // (2 cycles)
  302. "nop \n\t " // (1 cycles)
  303.  
  304. "out %[port], __zero_reg__ \n\t" // (1 cycles) - set the output bits to 0x00 based on the bit in colorbyte. This is phase for T0H-T1H
  305. // ==========
  306. // (8 cycles) - Phase #2
  307.  
  308. "ror %[bitwalker] \n\t" // (1 cycles) - get ready for next pass. On last pass, the bit will end up in C flag
  309.  
  310. "brcs DONE_%= \n\t" // (1 cycles) Exit if carry bit is set as a result of us walking all 8 bits. We assume that the process around us will tak long enough to cover the phase 3 delay
  311.  
  312. "nop \n\t \n\t " // (1 cycles) - When added to the 5 cycles in S:, we gte the 7 cycles of T1L
  313.  
  314. "jmp L_%= \n\t" // (3 cycles)
  315. // (1 cycles) - The OUT on the next pass of the loop
  316. // ==========
  317. // (7 cycles) - T1L
  318.  
  319.  
  320. "OFF_%=: \n\r" // (1 cycles) Note that we land here becuase of breq, which takes takes 2 cycles
  321.  
  322. "out %[port], __zero_reg__ \n\t" // (1 cycles) - set the output bits to 0x00 based on the bit in colorbyte. This is phase for T0H-T1H
  323. // ==========
  324. // (5 cycles) - T0H
  325.  
  326. "ror %[bitwalker] \n\t" // (1 cycles) - get ready for next pass. On last pass, the bit will end up in C flag
  327.  
  328. "brcs DONE_%= \n\t" // (1 cycles) Exit if carry bit is set as a result of us walking all 8 bits. We assume that the process around us will tak long enough to cover the phase 3 delay
  329.  
  330. "nop \n\t nop \n\t " // (2 cycles)
  331. "nop \n\t nop \n\t " // (2 cycles)
  332. "nop \n\t nop \n\t " // (2 cycles)
  333. "nop \n\t nop \n\t " // (2 cycles)
  334. "nop \n\t " // (1 cycles)
  335.  
  336. "jmp L_%= \n\t" // (3 cycles)
  337. // (1 cycles) - The OUT on the next pass of the loop
  338. // ==========
  339. //(15 cycles) - T0L
  340.  
  341.  
  342. "DONE_%=: \n\t"
  343.  
  344. // Don't need an explicit delay here since the overhead that follows will always be long enough
  345.  
  346. ::
  347. [port] "I" (_SFR_IO_ADDR(PIXEL_PORT)),
  348. [row] "d" (row),
  349. [onBits] "d" (onBits),
  350. [colorbyte] "d" (colorbyte ), // Phase 2 of the signal where the actual data bits show up.
  351. [bitwalker] "r" (0x80) // Alocate a register to hold a bit that we will walk down though the color byte
  352.  
  353. );
  354. }
  355.  
  356.  
  357. // Just wait long enough without sending any bots to cause the pixels to latch and display the last sent frame
  358. void show() {
  359. delayMicroseconds( (RES / 1000UL) + 1); // Round up since the delay must be _at_least_ this long (too short might not work, too long not a problem)
  360. }
  361.  
  362.  
  363. ////////////////////////////////
  364. // Escape characters helpers
  365. ////////////////////////////////
  366.  
  367. static inline int hexCharToInt(const char* c) {
  368. return (*c > '9') ? *c - 'A' + 10 : *c - '0';
  369. }
  370.  
  371. static inline const char* processColor(const char* str) {
  372. if (*str == '#') {
  373. str++;
  374. currentFormattingState.red = (hexCharToInt(str++) << 4) + hexCharToInt(str++);
  375. currentFormattingState.green = (hexCharToInt(str++) << 4) + hexCharToInt(str++);
  376. currentFormattingState.blue = (hexCharToInt(str++) << 4) + hexCharToInt(str++);
  377. }
  378. return str;
  379. }
  380.  
  381. static inline const char* processEscapeCharacter(const char* str) {
  382. switch (*++str) {
  383. case 'c':
  384. // process color
  385. str = processColor(++str);
  386. break;
  387.  
  388. case 'b':
  389. // toggle blinkEnabled
  390. currentFormattingState.isBlinkEnabled = !currentFormattingState.isBlinkEnabled;
  391. str++;
  392. break;
  393.  
  394. case '/':
  395. currentFormattingState.isEscapedSlash = true;
  396. break;
  397. }
  398.  
  399. return str;
  400. }
  401.  
  402. static inline const char* processEscapeCharacters(const char* str) {
  403. currentFormattingState.isEscapedSlash = false;
  404.  
  405. while (*str == '/' && *(str + 1)) {
  406. // if this slash is for an escaped slash, then skip the character
  407. if (currentFormattingState.isEscapedSlash) {
  408. str++;
  409. }
  410. else {
  411. str = processEscapeCharacter(str);
  412. }
  413. }
  414.  
  415. // if we encountered an escapedSlash, then return to it so it can be printed
  416. // NOTE: this code will not work if there is an escaped slash followed immediately by another slash :(
  417. if (currentFormattingState.isEscapedSlash) {
  418. str--;
  419. }
  420.  
  421. return str;
  422. }
  423.  
  424. ////////////////////////////////
  425. // Communication
  426. ////////////////////////////////
  427. // Requests a new message via serial
  428. static inline void requestNewMessage() {
  429. Serial.begin(BAUD_RATE);
  430.  
  431. // inform connection that we're ready
  432. Serial.println(READY_FOR_MESSAGE_SIGNAL);
  433.  
  434. // wait for input to arrive
  435. delay(WAIT_FOR_INPUT_DURATION);
  436.  
  437. // see if we got anything
  438. if (Serial.available()) {
  439. myMessage = "";
  440.  
  441. while(Serial.available()) {
  442. myMessage += Serial.readString();
  443. delay(100);
  444. }
  445. }
  446.  
  447. Serial.end();
  448. }
  449.  
  450. ////////////////////////////////
  451. // Debug
  452. ////////////////////////////////
  453. // Debug method to print a row to serial
  454. static inline void printRowToSerial(uint8_t row) {
  455. Serial.begin(BAUD_RATE);
  456. for (int i = 0; i < 7; i++ ) {
  457. Serial.print( ((row >> i) & 0x01) ? " " : "##");
  458. }
  459. Serial.println( ((row >> 7) & 0x01) ? " " : "##");
  460. Serial.end();
  461. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement