Advertisement
NetAgent

CM-5 Canton LED Display v1 Arduino Uno

Jun 12th, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.06 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/ez2HgJFPICY
  7.  
  8. #define HEIGHT 16
  9. #define WIDTH 64 //64
  10.  
  11. #define HEIGHTR 64 //64
  12. #define WIDTHR 16  //16
  13.  
  14. #define ROWCHANGE 4   //Rows change direction every X rows //default is 4
  15. #define INVERT 0      //LEDs will be lit in reverse order resulting in more LED active at once //default is 0
  16. #define MOVEDELAY 131 //How much delay should there be before the rows move //default is 131, CM5 rate is 200ms
  17.  
  18. // Connections to board
  19. const byte latchPin = 8;
  20. const byte clockPin = 12;
  21. const byte data_R1 = 11;
  22. const byte data_R2 = 10;
  23. const byte en_74138 = 2;
  24. const byte la_74138 = 3;
  25. const byte lb_74138 = 4;
  26. const byte lc_74138 = 5;
  27. const byte ld_74138 = 6;
  28.  
  29. byte ScanRow = 0;
  30. unsigned long counter;
  31. int n = 0;
  32.  
  33. byte buffer[256] = { // Display buffer (which is scanned by the interrupt timer) of 8x32 bytes
  34.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  35.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  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. };
  51.  
  52. // set a single pixel on or off
  53. void HardwarePlot(byte x, byte y, byte z) {
  54.  
  55.   if (z == 0) {
  56.     //bitWrite(buffer[(y << 3) + (x >> 3)], 7 - (x & 7), 0xFF);
  57.     bitWrite(buffer[(y * 8) + (x >> 3)], 7 - (x & 7), 0xFF);
  58.   } else {
  59.     //bitWrite(buffer[(y << 3) + (x >> 3)], 7 - (x & 7), 0x00);
  60.     bitWrite(buffer[(y * 8) + (x >> 3)], 7 - (x & 7), 0x00);
  61.   }
  62. };
  63.  
  64. void shiftOut(byte row) { // fast routine to shove out 8 columns into two rows via board's shift registers
  65.   for (byte column = 0; column < 8; column++) {
  66.     byte index = column + (row << 3);
  67.     for (byte i = 0; i < 8; i++) {
  68.       PORTB &= ~(3 << (data_R1 - 8)); // data_R2 is LOW; data_R1 is LOW;
  69.       PORTB &= ~(1 << (clockPin - 8)); // digitalWrite(clockPin,LOW);
  70.       PORTB |= !((buffer[index] >> (7 - i)) & 0x01) << (data_R1 - 8); // top set of rows
  71.       PORTB |= !((buffer[index + 128] >> (7 - i)) & 0x01) << (data_R2 - 8); // bottom set of rows
  72.       PORTB |= 1 << (clockPin - 8); // digitalWrite(clockPin,HIGH);
  73.     };
  74.   };
  75. };
  76.  
  77. // Scan a pair of rows on to the display from "buffer" via the interrupt
  78. ISR(TIMER2_COMPA_vect) {
  79.   cli();
  80.   digitalWrite(en_74138, HIGH); // Turn off display
  81.   shiftOut(ScanRow); // Shift out 8 columns
  82.   digitalWrite(latchPin, LOW);
  83.   digitalWrite(latchPin, HIGH);
  84.   PORTD = (ScanRow << 3) | (PORTD & 0X87); // Highlight row: pins 3 4 5 6 (la_74138 lb_74138 lc_74138 ld_74138)
  85.   digitalWrite(en_74138, LOW); // Turn on display
  86.   ScanRow++; // Do the next pair of rows next time this routine is called
  87.   if (ScanRow == 16) ScanRow = 0;
  88.   sei();
  89. };
  90.  
  91. void setup() {
  92.  
  93.   // Set up Timer2 as the scanning interrupt timer
  94.   cli(); // clear interrupts
  95.   TCCR2A = 0; TCCR2B = 0; TCNT2 = 0;
  96.   TCCR2B |= (1 << CS12) | (1 << CS10); // Set 1024 prescaler
  97.   // 160Hz scan rate = 10 frames/second (16 pairs of rows)
  98.   OCR2A = 97; // 97 = (16,000,000 / (1024*160)) - 1
  99.   TCCR2A |= (1 << WGM21); TIMSK2 |= (1 << OCIE2A);
  100.  
  101.   pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT);
  102.   pinMode(data_R1, OUTPUT); 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); digitalWrite(data_R2, HIGH);
  110.   counter = millis();
  111.   sei(); //allow interrupts
  112. };
  113.  
  114.  
  115. // Note that there's no need to do anything with the screen in the main loop.
  116. // Whatever's in "buffer" is constantly scanned out.
  117. void loop() {
  118.  
  119.   cm5();
  120.  
  121. };
  122.  
  123. long long array[2][16];
  124.  
  125. byte getPixel(byte x, byte y, byte whichArray) {
  126.  
  127.   unsigned long long temp = (1ULL << y);
  128.   if (array[whichArray][x] & temp) {
  129.     return 1; //the yth bit was set, so return 1.
  130.   }
  131.   else {
  132.     return 0; //the yth bit was clear, so return 0;
  133.   }
  134. }
  135.  
  136. void setPixel(byte x, byte y, byte whichArray, byte pixel) {
  137.  
  138.   unsigned long long temp = (1ULL << y);
  139.   if (pixel) {
  140.     array[whichArray][x] |= temp;
  141.   }
  142.   else {
  143.     array[whichArray][x] &= ~temp;
  144.   }
  145. }
  146.  
  147.  
  148. void clearArray(byte no) {
  149.   byte i, j; for (j = 0; j < HEIGHT; j++) {
  150.     for (i = 0; i < WIDTH; i++ ) {
  151.       setPixel(i, j, no, 0);
  152.     }
  153.   }
  154. }
  155.  
  156. #define RNUM_SEED 0xBAD
  157. static uint16_t rnum = RNUM_SEED;
  158.  
  159. void paintCM5() {
  160.   int i, j; bool pixel;
  161.  
  162.   for (i = 0; i < WIDTHR; i++ ) {
  163.     for (j = 0; j < HEIGHTR; j++) {
  164.  
  165.       pixel = getPixel(i, j, 0);
  166.  
  167.       if (j & ROWCHANGE) {
  168.         if (pixel == 1 ) {
  169.           HardwarePlot(j, i, 0);
  170.         }
  171.         else {
  172.           HardwarePlot(j, i, 1);
  173.         }
  174.       }
  175.       else if (pixel == 1 ) {
  176.         HardwarePlot(j, (WIDTHR - 1) - i, 0);
  177.  
  178.       }
  179.       else {
  180.         HardwarePlot(j, (WIDTHR - 1) - i, 1);
  181.  
  182.       }
  183.  
  184.     }
  185.   }
  186. }
  187.  
  188. static uint16_t get_random_bit(void)
  189. {
  190. #define X rnum
  191.  
  192.   uint16_t lfsr_bit = ((X >> 0) ^ (X >> 1) ^ (X >> 3) ^ (X >> 12)) & 1;
  193.  
  194.   uint16_t rand_bit = (X | (X >> 2)) & 1;
  195.  
  196. #undef X
  197.  
  198.   rnum = (lfsr_bit << 15) | (rnum >> 1);
  199.  
  200.   return rand_bit;
  201.  
  202. }
  203.  
  204. void cm5() {
  205.  
  206.   int pixel, i, j;
  207.   int count = 0;
  208.   clearArray(0);
  209.   //cm5 mode 7
  210.   uint16_t gen_bit;
  211.  
  212.   uint16_t rnum = 1;
  213.  
  214.   while (count < 3080) {
  215.  
  216.     for (j = 63; j >= 0; j-- ) {
  217.  
  218.  
  219.       uint16_t bit = get_random_bit();
  220.  
  221.       if (bit == 0) {
  222.         setPixel(16, j, 0, 1);
  223.       }
  224.     }
  225.  
  226.     for (j = 0; j < 64; j++) {
  227.       for (i = 0; i < 16 + 1; i++) {
  228.         pixel = getPixel(i + 1, j, 0); if (pixel == 1) setPixel(i, j, 0, 1); else setPixel(i, j, 0, 0);
  229.       }
  230.     }
  231.  
  232.     count++;
  233.  
  234.  
  235.     if (count > 0) {
  236.       paintCM5();
  237.       delay(MOVEDELAY); //131
  238.     }
  239.   }
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement