NetAgent

CM-5 Canton LED Display v1 Teensy 3.2

Jun 12th, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.01 KB | None | 0 0
  1. // 64x32 LED display matrix
  2. // based upon original code from canton-electonics
  3. // Arduino 1.0.5 UNO R3
  4. //#include <arv/pgmspace.h>
  5.  
  6. //VIDEO here: https://youtu.be/9cinW4gzyfM
  7.  
  8. IntervalTimer myTimer;
  9.  
  10. #define HEIGHT 16
  11. #define WIDTH 64 //64
  12.  
  13. #define HEIGHTR 64 //64
  14. #define WIDTHR 16  //16
  15.  
  16. #define ROWCHANGE 4   //Rows change direction every X rows //default is 4
  17. #define INVERT 0      //LEDs will be lit in reverse order resaulting in more LED active at once //default is 0
  18. #define MOVEDELAY 500 //How much delay should there be before the rows move //default is 131, CM5 rate is 200ms
  19.  
  20. // Connections to board
  21. const byte latchPin = 8;
  22. const byte clockPin = 12;
  23. const byte data_R1 = 11;
  24. const byte data_R2 = 10;
  25. const byte en_74138 = 2;
  26. const byte la_74138 = 3;
  27. const byte lb_74138 = 4;
  28. const byte lc_74138 = 5;
  29. const byte ld_74138 = 6;
  30.  
  31. byte ScanRow = 0;
  32. unsigned long counter;
  33. int n = 0;
  34.  
  35. byte buffer[256] = { // Display buffer (which is scanned by the interrupt timer) of 8x32 bytes
  36.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  37.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  38.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  39.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  40.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  41.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  42.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  43.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  45.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  46.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  48.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  49.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  50.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  52. };
  53.  
  54. // set a single pixel on or off
  55. void HardwarePlot(byte x, byte y, byte z) {
  56.  
  57.   if (z == 0) {
  58.     //bitWrite(buffer[(y << 3) + (x >> 3)], 7 - (x & 7), 0xFF);
  59.     bitWrite(buffer[(y * 8) + (x >> 3)], 7 - (x & 7), 0xFF);
  60.   } else {
  61.     //bitWrite(buffer[(y << 3) + (x >> 3)], 7 - (x & 7), 0x00);
  62.     bitWrite(buffer[(y * 8) + (x >> 3)], 7 - (x & 7), 0x00);
  63.   }
  64. };
  65.  
  66. void shiftOut(byte row) { // fast routine to shove out 8 columns into two rows via board's shift registers
  67.   for (byte column = 0; column < 8; column++) {
  68.     byte index = column + (row << 3);
  69.     for (byte i = 0; i < 8; i++) {
  70.       PORTB &= ~(3 << (data_R1 - 8)); // data_R2 is LOW; data_R1 is LOW;
  71.       PORTB &= ~(1 << (clockPin - 8)); // digitalWrite(clockPin,LOW);
  72.       PORTB |= !((buffer[index] >> (7 - i)) & 0x01) << (data_R1 - 8); // top set of rows
  73.       PORTB |= !((buffer[index + 128] >> (7 - i)) & 0x01) << (data_R2 - 8); // bottom set of rows
  74.       PORTB |= 1 << (clockPin - 8); // digitalWrite(clockPin,HIGH);
  75.     };
  76.   };
  77. };
  78.  
  79. // Scan a pair of rows on to the display from "buffer" via the interrupt
  80. void pnt() {
  81.   cli();
  82.   // digitalWrite(en_74138, HIGH); // Turn off display
  83.  
  84.   shiftOut(ScanRow); // Shift out 8 (or 16) columns
  85.   digitalWrite(latchPin, LOW);
  86.   digitalWrite(latchPin, HIGH);
  87.   PORTD = (ScanRow << 3); // Highlight row: pins 3 4 5 6 (la_74138 lb_74138 lc_74138 ld_74138)
  88.  
  89.   // digitalWrite(en_74138, LOW); // Turn on display
  90.   ScanRow++; // Do the next pair of rows next time this routine is called
  91.   ScanRow &= 0x0F;
  92.   // if (ScanRow==16)ScanRow=0;
  93.   sei();
  94.   // digitalWrite(en_74138, HIGH);
  95.  
  96. };
  97.  
  98. void setup() {
  99.  
  100.   pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT);
  101.   pinMode(data_R1, OUTPUT);
  102.   //pinMode(data_R2,OUTPUT);
  103.  
  104.   pinMode(en_74138, OUTPUT);
  105.   pinMode(la_74138, OUTPUT); pinMode(lb_74138, OUTPUT);
  106.   pinMode(lc_74138, OUTPUT); pinMode(ld_74138, OUTPUT);
  107.  
  108.   digitalWrite(en_74138, LOW);
  109.   digitalWrite(data_R1, HIGH);
  110.   //digitalWrite(data_R2, HIGH);
  111.  
  112.   //setTime(1421491560);
  113.   // Teensy3Clock.set(1454166313); // set the RTC
  114.   // setTime(15,02,19,9,2014); // h:m:s:day:month:year
  115.  
  116.   //setSyncProvider(getTeensy3Time);
  117.   //setSyncInterval(9000);
  118.  
  119.  
  120.   myTimer.begin(pnt, 800);//1200 old //200 optimum //400
  121.  
  122. };
  123.  
  124.  
  125. // Note that there's no need to do anything with the screen in the main loop.
  126. // Whatever's in "buffer" is constantly scanned out.
  127. void loop() {
  128.  
  129.   cm5();
  130.  
  131. };
  132.  
  133. long long array[2][16];
  134.  
  135. byte getPixel(byte x, byte y, byte whichArray) {
  136.  
  137.   unsigned long long temp = (1ULL << y);
  138.   if (array[whichArray][x] & temp) {
  139.     return 1; //the yth bit was set, so return 1.
  140.   }
  141.   else {
  142.     return 0; //the yth bit was clear, so return 0;
  143.   }
  144. }
  145.  
  146. void setPixel(byte x, byte y, byte whichArray, byte pixel) {
  147.  
  148.   unsigned long long temp = (1ULL << y);
  149.   if (pixel) {
  150.     array[whichArray][x] |= temp;
  151.   }
  152.   else {
  153.     array[whichArray][x] &= ~temp;
  154.   }
  155. }
  156.  
  157.  
  158. void clearArray(byte no) {
  159.   byte i, j; for (j = 0; j < HEIGHT; j++) {
  160.     for (i = 0; i < WIDTH; i++ ) {
  161.       setPixel(i, j, no, 0);
  162.     }
  163.   }
  164. }
  165.  
  166. #define RNUM_SEED 0xBAD
  167. static uint16_t rnum = RNUM_SEED;
  168.  
  169. void paintCM5() {
  170.   int i, j; bool pixel;
  171.  
  172.   for (i = 0; i < WIDTHR; i++ ) {
  173.     for (j = 0; j < HEIGHTR; j++) {
  174.  
  175.       pixel = getPixel(i, j, 0);
  176.  
  177.       if (j & ROWCHANGE) {
  178.         if (pixel == 1 ) {
  179.           HardwarePlot(j, i, 0);
  180.         }
  181.         else {
  182.           HardwarePlot(j, i, 1);
  183.         }
  184.       }
  185.       else if (pixel == 1 ) {
  186.         HardwarePlot(j, (WIDTHR - 1) - i, 0);
  187.  
  188.       }
  189.       else {
  190.         HardwarePlot(j, (WIDTHR - 1) - i, 1);
  191.  
  192.       }
  193.  
  194.     }
  195.   }
  196. }
  197.  
  198. static uint16_t get_random_bit(void)
  199. {
  200. #define X rnum
  201.  
  202.   uint16_t lfsr_bit = ((X >> 0) ^ (X >> 1) ^ (X >> 3) ^ (X >> 12)) & 1;
  203.  
  204.   uint16_t rand_bit = (X | (X >> 2)) & 1;
  205.  
  206. #undef X
  207.  
  208.   rnum = (lfsr_bit << 15) | (rnum >> 1);
  209.  
  210.   return rand_bit;
  211.  
  212. }
  213.  
  214. void cm5() {
  215.  
  216.   int pixel, i, j;
  217.   int count = 0;
  218.   clearArray(0);
  219.   //cm5 mode 7
  220.   uint16_t gen_bit;
  221.  
  222.   uint16_t rnum = 1;
  223.  
  224.   while (count < 3080) {
  225.  
  226.     for (j = 63; j >= 0; j-- ) {
  227.  
  228.  
  229.       uint16_t bit = get_random_bit();
  230.  
  231.       if (bit == 0) {
  232.         setPixel(16, j, 0, 1);
  233.       }
  234.     }
  235.  
  236.     for (j = 0; j < 64; j++) {
  237.       for (i = 0; i < 16 + 1; i++) {
  238.         pixel = getPixel(i + 1, j, 0); if (pixel == 1) setPixel(i, j, 0, 1); else setPixel(i, j, 0, 0);
  239.       }
  240.     }
  241.  
  242.     count++;
  243.  
  244.  
  245.     if (count > 0) {
  246.       paintCM5();
  247.       delay(MOVEDELAY); //131
  248.     }
  249.   }
  250. }
Advertisement
Add Comment
Please, Sign In to add comment