Advertisement
Al_Ninyo

LED cube 4x4x4

Jan 10th, 2015
3,163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.01 KB | None | 0 0
  1. #include <Wire.h>
  2. #include <LiquidCrystal_I2C.h>
  3.  
  4. LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
  5.  
  6. const int latchPin = 8;        // Пин подключен к ST_CP входу 74HC595
  7. const int clockPin = 12;       // Пин подключен к SH_CP входу 74HC595
  8. const int dataPin = 11;        // Пин подключен к DS входу 74HC595
  9. int LayerPin[] = {4,5,6,7};    // указываем пины, к которым подключены слои кубика
  10. int ButPin = 2;               // подключаем кнопку к выходу 10
  11.  
  12. int layer = 0;                 // слой
  13. int count = 0;                 // счётчик
  14. int flag = 0;                  // флаг состояния
  15. volatile int rejim = 0;        // Переключалка
  16.  
  17. int DATA1[] = {37929,16770,10260,37449,16770,10260}; //вертолёт от левого нижнего угла к правому верхнему и потов сверху вниз
  18. //int DATA2[] = {36873,16770,10260};
  19. //int DATA3[] = {1632,38505,1632,38505,38505,1632}; // центральный квадрат + угловые
  20.  
  21. unsigned int DATA = 0;
  22.  
  23. void setup() {
  24.   Serial.begin(9600);
  25.  
  26.   lcd.init();
  27.   lcd.backlight();
  28.   lcd.print("Hello, world!");
  29.  
  30.   pinMode(latchPin, OUTPUT);
  31.   pinMode(dataPin, OUTPUT);
  32.   pinMode(clockPin, OUTPUT);
  33.   pinMode(ButPin, INPUT);
  34.  
  35.   // гасим все слои на всякий случай
  36.   for(layer = 0; layer < 4; layer++){
  37.     pinMode(LayerPin[layer], OUTPUT);
  38.     digitalWrite(LayerPin[layer], LOW);
  39.   }
  40.  
  41.   attachInterrupt(INT0, ChangeRejim, CHANGE);
  42. }
  43.  
  44. // функция смены режима по кнопке
  45. void ChangeRejim() {
  46.   if(digitalRead(ButPin) == LOW && flag == 0)      
  47.     {                                              
  48.       rejim ++;
  49.       flag = 1;
  50.       if(rejim > 9)            // Если номер режима превышает количество эффектов,
  51.         {  rejim = 0; }        // то отсчет начинается с нуля
  52.     }
  53.     if(digitalRead(ButPin) == HIGH && flag == 1)
  54.     {
  55.       flag = 0;
  56.     }
  57. }
  58.  
  59. // функция передачи данных в сдвиговый регистр для зажигания светодиодов
  60. void doMagicWithRegisters(int whatToPush) {
  61.   digitalWrite(latchPin, LOW);
  62.  
  63.   shiftOut(dataPin, clockPin, MSBFIRST, (whatToPush>> 8));
  64.   shiftOut(dataPin, clockPin, MSBFIRST, whatToPush);
  65.  
  66.   // "защелкиваем" регистр, чтобы биты появились на выходах регистра
  67.   digitalWrite(latchPin, HIGH);
  68. }
  69.  
  70. void LayersOff() { // функция для выключения всех слоёв
  71.   for(layer = 0; layer < 4; layer++){
  72.     digitalWrite(LayerPin[layer], LOW);
  73.   }
  74. }
  75.  
  76. void LayersOn() { // функция для включения всех слоёв
  77.   for(int layer = 0; layer < 4; layer++){
  78.     digitalWrite(LayerPin[layer], HIGH);
  79.   }
  80. }
  81.  
  82. // функция для работы с вертикальными слоями
  83. // where = 1 - от нас, -1 - к нам
  84. void vLayer(int where, unsigned int start, int mask, int time) {
  85.   LayersOn();
  86.    DATA = start;
  87.    if (where > 0) {
  88.    for (int n = 0; n < 4; n++) {
  89.        DATA ^= mask<< (n*4);
  90.        DATA ^= mask<< ((n-1)*4);
  91.        doMagicWithRegisters(DATA);
  92.    delay(time);
  93.      }
  94.    } else {
  95.      for (int n = 2; n >= 0; n--) {
  96.        DATA ^= mask<< ((n+1)*4);
  97.        DATA ^= mask<< (n*4);
  98.        doMagicWithRegisters(DATA);
  99.    delay(time);
  100.        }
  101.    }
  102.   LayersOff();
  103. }
  104.  
  105. // функция для работы с горизонтальными слоями
  106. // where = 1 - снизу вверх, -1 - сверху вниз, 0 - только указанный/все слои
  107. // data - какие светодиоды горят, например: 1 - горит только первый, 15 - горят первых 4, 65535 - горят все
  108. // time - сколько мс горят светодиоды
  109. // NumLayer - какой слой горит (работает только при where = 0!), при 4 - все слои горят
  110. void hLayer(int where, int data, int time, int NumLayer) {
  111.   if (where > 0) {                          // снизу вверх
  112.     for (layer = 0; layer < 4; layer++) {
  113.       digitalWrite(LayerPin[layer], HIGH);
  114.       doMagicWithRegisters(data);
  115.       delay(time);
  116.       digitalWrite(LayerPin[layer], LOW);
  117.     }
  118.   }
  119.   else if (where < 0) {                      // сверху вниз
  120.     for (layer = 2; layer >= 0; layer--) {
  121.       digitalWrite(LayerPin[layer], HIGH);
  122.       doMagicWithRegisters(data);
  123.       delay(time);
  124.       digitalWrite(LayerPin[layer], LOW);
  125.     }
  126.   }
  127.   else {
  128.    if (NumLayer == 4) {                    // все слои горят
  129.       LayersOn();
  130.         doMagicWithRegisters(data);
  131.         delay(time);
  132.       LayersOff();
  133.         delay(time);
  134.     }
  135.   else {
  136.       digitalWrite(LayerPin[NumLayer], HIGH);
  137.       doMagicWithRegisters(data);
  138.       delay(time);
  139.       digitalWrite(LayerPin[NumLayer], LOW);
  140.    }
  141.   }
  142.   LayersOff();
  143. }
  144.  
  145. void LCDtext(char Rname[]) // функция вывода на LCD 16x2 экран
  146.   {
  147.     lcd.setCursor(0,0);
  148.     lcd.print(Rname);     // выводится название режима
  149.     lcd.setCursor(0,1);
  150.     lcd.print("Rejim: ");
  151.     lcd.setCursor(8,1);
  152.     lcd.print(rejim);     // выводится номер режима
  153.   }
  154.  
  155. void loop() {
  156.  
  157.     Serial.println(digitalRead(ButPin));
  158.     if(rejim == 0)
  159.     {
  160.       LayersOff();
  161.       LCDtext("Press button!   ");
  162.   }
  163.    
  164.     if(rejim == 1)
  165.     {    
  166.   //вертолёт от левого нижнего угла к правому верхнему и потов сверху вниз
  167.   LCDtext("Helicopter  *..*");
  168.   count = 0;
  169.   while (count < 5) { // повторяем count раз
  170.       layer = 0;
  171.         for (int i = 0; i < 6; i++) {
  172.           digitalWrite(LayerPin[layer], HIGH);
  173.           doMagicWithRegisters(DATA1[i]);
  174.           delay(150);
  175.           digitalWrite(LayerPin[layer], LOW);
  176.             if (i < 3) {
  177.               layer++;
  178.             }
  179.             else {
  180.               layer--;
  181.             }
  182.         }
  183.      count++;
  184.   }
  185.   LayersOff();
  186.     }
  187.  
  188.     if(rejim == 2)
  189.     {
  190.       LCDtext("hLayers+vLayers ");
  191.       count = 0;
  192.       while (count < 3) { // повторяем count раз  
  193.           hLayer(1, 65535, 70, 4); // горизонтальные слои сверху вниз
  194.           hLayer(-1, 65535, 70, 4); // горизонтальные слои снизу вверх
  195.           vLayer(1, 15, 15, 70); // вертикальные слои от нас
  196.           vLayer(-1, 61440, 15, 70); // вертикальные слои к нам
  197.           count++;
  198.        }
  199.     }
  200.    
  201.     if(rejim == 3)
  202.     {
  203.       LCDtext("ALL IS UP!      ");
  204.       count = 0;
  205.       while (count < 3) { // повторяем count раз
  206.           hLayer(0, 65535, 300, 4); // весь кубик
  207.           count++;
  208.        }
  209.     }
  210.    
  211.     if(rejim == 4)
  212.     {
  213.       LCDtext("vLayers         ");
  214.       count = 0;
  215.       while (count < 3) { // повторяем count раз
  216.           vLayer(1, 9, 9, 200); // угловые столбцы от нас
  217.           vLayer(-1, 24576, 6, 200); // центральные столбцы к нам
  218.           count++;
  219.         }
  220.     }
  221.    
  222.     if(rejim == 5)
  223.     {
  224.       LCDtext("hLayers 1       ");
  225.       count = 0;
  226.       while (count < 5) { // повторяем count раз
  227.           hLayer(0, 36873, 200, 0);
  228.           hLayer(0, 1632, 200, 1);
  229.           hLayer(0, 1632, 200, 2);
  230.           hLayer(0, 36873, 200, 3);
  231.           count++;
  232.         }
  233.     }
  234.    
  235.     if(rejim == 6)
  236.     {
  237.       LCDtext("hLayers 2       ");
  238.       count = 0;
  239.       while (count < 5) { // повторяем count раз  
  240.           hLayer(1, 38505, 100, 4);
  241.           hLayer(-1, 38505, 100, 4);
  242.           count++;
  243.         }
  244.     }
  245.    
  246.     if(rejim == 7)
  247.     {
  248.       LCDtext("hLayers 3       ");
  249.       count = 0;
  250.       while (count < 5) { // повторяем count раз
  251.           hLayer(1, 28662, 100, 4);
  252.           hLayer(-1, 28662, 100, 4);
  253.           count++;
  254.         }
  255.     }
  256.    
  257.     if(rejim == 8)
  258.     {    
  259.       LCDtext("hLayers 4       ");
  260.       count = 0;
  261.       while (count < 5) { // повторяем count раз
  262.           hLayer(1, 63903, 150, 4); // горизонтальные слои сверху вниз
  263.           hLayer(-1, 1632, 150, 4); // горизонтальные слои снизу вверх
  264.           count++;
  265.       }
  266.     }
  267.    
  268.     if(rejim == 9)
  269.     {    
  270.       LCDtext("hLayers 5       ");
  271.       count = 0;
  272.       while (count < 5) { // повторяем count раз
  273.           hLayer(1, 1632, 150, 4); // горизонтальные слои сверху вниз
  274.           hLayer(-1, 63903, 150, 4); // горизонтальные слои снизу вверх
  275.           count++;
  276.       }
  277.     }
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement