Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // 64x32 LED display matrix
- // based upon original code from canton-electonics
- // Arduino 1.0.5 UNO R3
- //#include <arv/pgmspace.h>
- //VIDEO here: https://youtu.be/ez2HgJFPICY
- #define HEIGHT 16
- #define WIDTH 64 //64
- #define HEIGHTR 64 //64
- #define WIDTHR 16 //16
- #define ROWCHANGE 4 //Rows change direction every X rows //default is 4
- #define INVERT 0 //LEDs will be lit in reverse order resulting in more LED active at once //default is 0
- #define MOVEDELAY 131 //How much delay should there be before the rows move //default is 131, CM5 rate is 200ms
- // Connections to board
- const byte latchPin = 8;
- const byte clockPin = 12;
- const byte data_R1 = 11;
- const byte data_R2 = 10;
- const byte en_74138 = 2;
- const byte la_74138 = 3;
- const byte lb_74138 = 4;
- const byte lc_74138 = 5;
- const byte ld_74138 = 6;
- byte ScanRow = 0;
- unsigned long counter;
- int n = 0;
- byte buffer[256] = { // Display buffer (which is scanned by the interrupt timer) of 8x32 bytes
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
- // set a single pixel on or off
- void HardwarePlot(byte x, byte y, byte z) {
- if (z == 0) {
- //bitWrite(buffer[(y << 3) + (x >> 3)], 7 - (x & 7), 0xFF);
- bitWrite(buffer[(y * 8) + (x >> 3)], 7 - (x & 7), 0xFF);
- } else {
- //bitWrite(buffer[(y << 3) + (x >> 3)], 7 - (x & 7), 0x00);
- bitWrite(buffer[(y * 8) + (x >> 3)], 7 - (x & 7), 0x00);
- }
- };
- void shiftOut(byte row) { // fast routine to shove out 8 columns into two rows via board's shift registers
- for (byte column = 0; column < 8; column++) {
- byte index = column + (row << 3);
- for (byte i = 0; i < 8; i++) {
- PORTB &= ~(3 << (data_R1 - 8)); // data_R2 is LOW; data_R1 is LOW;
- PORTB &= ~(1 << (clockPin - 8)); // digitalWrite(clockPin,LOW);
- PORTB |= !((buffer[index] >> (7 - i)) & 0x01) << (data_R1 - 8); // top set of rows
- PORTB |= !((buffer[index + 128] >> (7 - i)) & 0x01) << (data_R2 - 8); // bottom set of rows
- PORTB |= 1 << (clockPin - 8); // digitalWrite(clockPin,HIGH);
- };
- };
- };
- // Scan a pair of rows on to the display from "buffer" via the interrupt
- ISR(TIMER2_COMPA_vect) {
- cli();
- digitalWrite(en_74138, HIGH); // Turn off display
- shiftOut(ScanRow); // Shift out 8 columns
- digitalWrite(latchPin, LOW);
- digitalWrite(latchPin, HIGH);
- PORTD = (ScanRow << 3) | (PORTD & 0X87); // Highlight row: pins 3 4 5 6 (la_74138 lb_74138 lc_74138 ld_74138)
- digitalWrite(en_74138, LOW); // Turn on display
- ScanRow++; // Do the next pair of rows next time this routine is called
- if (ScanRow == 16) ScanRow = 0;
- sei();
- };
- void setup() {
- // Set up Timer2 as the scanning interrupt timer
- cli(); // clear interrupts
- TCCR2A = 0; TCCR2B = 0; TCNT2 = 0;
- TCCR2B |= (1 << CS12) | (1 << CS10); // Set 1024 prescaler
- // 160Hz scan rate = 10 frames/second (16 pairs of rows)
- OCR2A = 97; // 97 = (16,000,000 / (1024*160)) - 1
- TCCR2A |= (1 << WGM21); TIMSK2 |= (1 << OCIE2A);
- pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT);
- pinMode(data_R1, OUTPUT); pinMode(data_R2, OUTPUT);
- pinMode(en_74138, OUTPUT);
- pinMode(la_74138, OUTPUT); pinMode(lb_74138, OUTPUT);
- pinMode(lc_74138, OUTPUT); pinMode(ld_74138, OUTPUT);
- digitalWrite(en_74138, LOW);
- digitalWrite(data_R1, HIGH); digitalWrite(data_R2, HIGH);
- counter = millis();
- sei(); //allow interrupts
- };
- // Note that there's no need to do anything with the screen in the main loop.
- // Whatever's in "buffer" is constantly scanned out.
- void loop() {
- cm5();
- };
- long long array[2][16];
- byte getPixel(byte x, byte y, byte whichArray) {
- unsigned long long temp = (1ULL << y);
- if (array[whichArray][x] & temp) {
- return 1; //the yth bit was set, so return 1.
- }
- else {
- return 0; //the yth bit was clear, so return 0;
- }
- }
- void setPixel(byte x, byte y, byte whichArray, byte pixel) {
- unsigned long long temp = (1ULL << y);
- if (pixel) {
- array[whichArray][x] |= temp;
- }
- else {
- array[whichArray][x] &= ~temp;
- }
- }
- void clearArray(byte no) {
- byte i, j; for (j = 0; j < HEIGHT; j++) {
- for (i = 0; i < WIDTH; i++ ) {
- setPixel(i, j, no, 0);
- }
- }
- }
- #define RNUM_SEED 0xBAD
- static uint16_t rnum = RNUM_SEED;
- void paintCM5() {
- int i, j; bool pixel;
- for (i = 0; i < WIDTHR; i++ ) {
- for (j = 0; j < HEIGHTR; j++) {
- pixel = getPixel(i, j, 0);
- if (j & ROWCHANGE) {
- if (pixel == 1 ) {
- HardwarePlot(j, i, 0);
- }
- else {
- HardwarePlot(j, i, 1);
- }
- }
- else if (pixel == 1 ) {
- HardwarePlot(j, (WIDTHR - 1) - i, 0);
- }
- else {
- HardwarePlot(j, (WIDTHR - 1) - i, 1);
- }
- }
- }
- }
- static uint16_t get_random_bit(void)
- {
- #define X rnum
- uint16_t lfsr_bit = ((X >> 0) ^ (X >> 1) ^ (X >> 3) ^ (X >> 12)) & 1;
- uint16_t rand_bit = (X | (X >> 2)) & 1;
- #undef X
- rnum = (lfsr_bit << 15) | (rnum >> 1);
- return rand_bit;
- }
- void cm5() {
- int pixel, i, j;
- int count = 0;
- clearArray(0);
- //cm5 mode 7
- uint16_t gen_bit;
- uint16_t rnum = 1;
- while (count < 3080) {
- for (j = 63; j >= 0; j-- ) {
- uint16_t bit = get_random_bit();
- if (bit == 0) {
- setPixel(16, j, 0, 1);
- }
- }
- for (j = 0; j < 64; j++) {
- for (i = 0; i < 16 + 1; i++) {
- pixel = getPixel(i + 1, j, 0); if (pixel == 1) setPixel(i, j, 0, 1); else setPixel(i, j, 0, 0);
- }
- }
- count++;
- if (count > 0) {
- paintCM5();
- delay(MOVEDELAY); //131
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement