Линк на форум.

Обсуждение проекта на форуме Arduino.ru

воскресенье, 15 июля 2012 г.

Новые эффекты

    На выходных неплохо посидел над кодом проекта, можно было и лучше но не так много времени было. На данный момент я решил проблему с заменой эффектов, и выстроил некоторую структуру кода готовую к большому количеству эффектов, также сделал автоматическую их смену через каждые 10 секунд. Дальше по коду:



#define clock 3 //синхро контакт
#define reset 4
// контакт сброса
#define data 2
// контакт данных

boolean matrix[8][8][8];
// массив который является внутренним
                         //представлением куба


byte i,j,k,x,y,z,iteration;
// переменные для циклов
byte lastX, lastY, lastZ;
// переменные для последней координаты


byte curEffect;
// номер текущего эффекта

// Переменные для работы со временемlong pause; // задержка обновления эффекта
long lastEffectChangeTime;
// время последней смены эффекта
long lastEffectCallTime;
// время последней смены эффекта

void setup()
// функция установки начальных праметров
{
 
// инициализируем переменные
  curEffect = 0;
  lastEffectChangeTime = 0;
  lastEffectCallTime = 0;
  pause = 0;
 
//переводим все контакты в режим вывода
  pinMode(clock, OUTPUT);
  pinMode(reset, OUTPUT);
  pinMode(data, OUTPUT);

  for(i = 0; i < 8; i++){
      for(j = 0; j < 8; j++){
          for(k = 0; k < 8; k++){
              matrix[i][k][j] = false;
          }
      }
  }

  lastX = 0;
  lastY = 0;
  lastZ = 0;
}

void loop()
{
/*обнаруживаем время смены эффекта
 мросто берем время с момента запуска программы и
 вычисляем временной промежуток с момента
 последней смены эффекта, если прошло больше 10 секунд
 меняем эффект на случайный
*/
  if(millis() - lastEffectChangeTime >10000){
    curEffect = random(0,4);
//меняем эффект
    lastEffectChangeTime = millis(); // запоминаем время
  }
/*
 тоже самое и для обновления эффекта
 как оказалось быстродействие ардуины больше
 чем я думал, и если делать обновление эффекта
 на каждой итерации то не будет плавности,
 и так как каждому эффекту нужно све время
 обновления(гдето больше, гдето меньше)
 добавлена пауза для эффектов
*/

  if(millis() - lastEffectCallTime > pause){
    startEffect();
// если сделана достаточная выдержка
                   // то обновляем эффект

    lastEffectCallTime = millis();
//запоминаем время
  }
  writeMatrix();
//выводим массив на куб
}

/*
  самая простая функция которая по номеру запускает нужный эффект
*/
void startEffect(){
  switch(curEffect){
    case 0: effectRandomeMagik(); break;
    case 1: effectRain(); break;
    case 2: effectStruya(); break;
    case 3: effectCircleSpiral(); break;
    default: effectCircleSpiral();
  }
}
/*
 Эфект спирального целиндра, после долгих раздумий
 решил сделать просто прописав 5 его состояний..
*/
void effectCircleSpiral(){
    pause = 70;
    moveMassToDown();
// функция- утилита которая сдвигает массив вниз
    switch(lastZ){
        case 1: matrix[7][0][2] = true;
                matrix[7][2][7] = true;
                matrix[7][7][5] = true;
                matrix[7][5][0] = true;
                lastZ = 2;
                break;

        case 2: matrix[7][0][3] = true;
                matrix[7][3][7] = true;
                matrix[7][7][4] = true;
                matrix[7][4][0] = true;
                lastZ = 3;
                break;

        case 3: matrix[7][0][4] = true;
                matrix[7][4][7] = true;
                matrix[7][7][3] = true;
                matrix[7][3][0] = true;
                lastZ = 4;
                break;

        case 4: matrix[7][0][5] = true;
                matrix[7][5][7] = true;
                matrix[7][7][2] = true;
                matrix[7][2][0] = true;
                lastZ = 0;
                break;

        default: matrix[7][1][1] = true;
                 matrix[7][1][6] = true;
                 matrix[7][6][1] = true;
                 matrix[7][6][6] = true;
                 lastZ = 1;
    }
 
}

/*
 эффект хаоса
*/
void effectRandomeMagik(){
  pause = 10;
  x = random(0,8) - 1;
  y = random(0,8) - 1;
  z = random(0,8) - 1;
  matrix[z][x][y] = !matrix[z][x][y];
}
/*
 эффект похожий на дождь
*/

void effectRain(){
    pause = 60;
    moveMassToDown();
    x = random(0,8);
    y = random(0,8);
    matrix[7][y][x] = true;
}

/*
 эффект струи которая льется сверху вних
*/

void effectStruya(){
    pause = 60;
    moveMassToDown();

    x = random(1,4) - 2 + lastX;
    if(x > 7){
      x = 0;
    }
    if(x < 0){
      x = 7;
    }
   
    y = random(1,4) - 2 + lastY;
    if(y > 7){
      y = 0;
    }
    if(y < 0){
      y = 7;
    }
   
    lastX = x;
    lastY = y;
   
    matrix[7][y][x] = true;
   
}

/*
 функция утилита которая просто сдвигает
 массив вниз.
*/

void moveMassToDown(){
    for(i = 0; i < 8; i++){
        for(j = 0; j < 8; j++){
            for(k = 0; k < 8; k++){
                if(matrix[i][j][k]){
                    matrix[i-1][j][k] = true;
                    matrix[i][j][k] = false;
                }
            }
        }
    }
}
// функция которая отображает внутренний массив на кубе
void writeMatrix(){
  digitalWrite(clock, LOW);
  for(i = 0; i < 8; i++){
// цикл по этажам  координата Z
      digitalWrite(reset, LOW);
      for(j = 0; j < 8; j++){
//цикл по рядам(координата Y)
         
// сбрасываю синхросигнал
         
// цикл по строкам(координата X)
          for(k = 0; k < 8; k++){
             
// сбрасываю сигнал на выходе данных
              digitalWrite(data, LOW);
             
//проверка на истину
              if(matrix[i][k][j] == true){
                 
// если истина то даю логическую 1 на выход
                  digitalWrite(data, HIGH);
              }
              if(matrix[i][k][j] == true){
              }else{
              }
              digitalWrite(clock, HIGH);
              digitalWrite(clock, LOW);
          }         
//сбрасываю сигнал по координате Z
      }
      for(j = 0; j < 8; j++ ){
          digitalWrite(data, LOW);
          if(i == j){
              digitalWrite(data, HIGH);
          }
          digitalWrite(clock, HIGH);
          digitalWrite(clock, LOW);
      }
      digitalWrite(reset, HIGH);
//зажигаю ряд(этаж)
      digitalWrite(reset, LOW);
//гашу ряд(этаж)
 
}
}


    Небольшое видео с демонстрацией:

    На видео "струя", "дождь", "спиральный цилиндр", и "хаос" поймал момент когда они шли один за другим без повторов.

Комментариев нет:

Отправить комментарий