/*
* Набор для экспериментов ArduinoKit
* Код программы для опыта №4: sketch 04
*
* Написано для сайта http://arduinokit.ru
*
*
* Помощь сообщества Arduino.
* Посетите сайт http://www.arduino.cc
*
* МНОЖЕСТВО СВЕТОДИОДОВ
*
* Заставьте танцевать восемь светодиодов. Танец светодиодов!
*
* Аппаратные соединения:
*
* Вам понадобится 8 светодиодов, и восемь резисторов на 200- 560 Ом
* (Цветовая маркировка 200 Ом — оранжевый, оранжевый, коричневый).
*
* Отрицательный вывод светодиода (более короткая нога) присоедините
* к резистору на 330 Ом.
*
* Присоедините другой вывод резисторов к GND.
*
* Присоедините положительные выводы (длинная нога) светодиодов
* к Arduino, цифровые контакты (pin) 2 — 9.
*

* Комменарий к программе написан
* 22 января 2014
* специально для http://arduinokit.ru и HelpSet.Ru
*/

// Чтобы иметь возможность обратиться к любому светодиоду, мы будем
// использовать «массив». Массивы позволяют хранить группу переменных,
// и обращаться к ним по «индексу». Здесь мы создаем массив из восьми целых
// чисел, и инициализируем их:

int ledPins[] = {2,3,4,5,6,7,8,9};

// Первый элемент массива имеет индекс 0.
// Мы поместили значение «2» (pin2) в индекс 0, «3» (pin3) в индекс 1 и т.д.
// Последний индекс в массиве «7», содержит значение «9» (pin9).

// Значения в нашем массиве, как бы определяет число контактов
// восьми светодиодов. Светодиод 0 соединяется с Pin2,
// cветодиод 1 соединяется с Pin3, cветодиод 2 соединяется с Pin4 и т.д.

void setup()
{
int index;

// В этом скетче мы будем использовать цикл «for()», чтобы изменять
//  значения переменных от одного к другого, и выполнить ряд инструкций
// для каждого шага. Циклы for() являются очень удобным способом,
// чтобы заставить число уменьшаться или увеличиваться.

// У каждого цикла for() есть три оператора, разделенные точками с запятой (;):

// 1. Первый заставляет что-то сделать перед запуском
// 2. Во втором производится проверка во время выполнения, с заданным условием,
//    если условие ИСТИНА, выполнять цикл далее
// 3. В третьем, что-то сделать после каждого цикла (например увеличить переменную)

// Вот эти три условия для цикла for() идущего ниже:

//   1. index = 0;    Инициализация index = 0.
//   2. index <= 7;   Если индекс меньше, или равен 7,
//                    выполнить следующий код.
//            (Когда index станет равным 8, цикл завершается.)
//   3. index++    взять значение индекс и увеличить на единицу
//            (Также это можно записать «index = index + 1».)

// Каждый раз когда условие будет ИСТИНА, цикл будет повторяться снова и снова
// Когда тест станет FALSE (ложь), цикл закончится, и перейдет к следующему
// шагу программы

// Здесь мы используем цикл for() для инициализации всех светодиодов,
// Это на много удобнее, чем писать восемь отдельных операторов для
// каждого светодиода по отдельности.

// Цикл for() возьмет из массива индекс 0 (значение 2), затем выполнит функцию pinMode(),
// возьмет из массива index 1, со значением 3, затем следующий — 4, и т.д.,
// пока полностью не дойдет до конца массива, т.е. не переберет все светодиоды.

for(index = 0; index <= 7; index++)
{
pinMode(ledPins[index],OUTPUT);
// ledPins[index] заменяется ЗНАЧЕНИЕМ в массиве.
// Для примера, ledPins[0] теперь будет 2
}
}

void loop()
{
// Далее идут шесть функций, пять из которых закомментированны,
// т.е. в данный момент не активны, а активна oneAfterAnotherNoLoop();
// Комментарием является строка начинающаяся с «//».
// Чтобы попробовать ту или иную функцию в действии, вы должны
// раскомментировать нужную, и закомментировать не нужную.

oneAfterAnotherNoLoop();  // Зажечь поочередно все светодиоды

//oneAfterAnotherLoop();  // Тоже что и oneAfterAnotherNoLoop,
// но с меньшим значением печати

//oneOnAtATime();         // Зажигать светодиоды по очереди

//pingPong();             // Зажечь от центра к краям

//marquee();              // преследование, как на знаках

//randomLED();            // Случайны светодиод
}
/*
oneAfterAnotherNoLoop()

Эта функция включит один светодиод, затем последует небольшая пауза,
затем включится следующий светодиод, и так пока не загорятся все. Затем
она их выключит в обратном порядке.

Эта функция не использует цикл for(). Здесь мы выбрали сложный путь
чтобы показать вам на сколько проще использовать цикл for().
Смотрите на функцию oneAfterAnotherLoop(), далее, которая делает
тоже самое, но с меньшим количеством кода.
*/

void oneAfterAnotherNoLoop()
{
int delayTime = 100; // время в миллисекундах для паузы
// можете попробовать изменить значения
// для более быстрого переключения

// выключить все, на:

digitalWrite(ledPins[0], HIGH);  //Включить светодиод индекс #0 (pin 2)
delay(delayTime);                //пауза delayTime, миллисек.
digitalWrite(ledPins[1], HIGH);  //Включить LED #1 (pin 3)
delay(delayTime);                //пауза delayTime
digitalWrite(ledPins[2], HIGH);  //Включить LED #2 (pin 4)
delay(delayTime);                //пауза
digitalWrite(ledPins[3], HIGH);  //Включить LED #3 (pin 5)
delay(delayTime);                //пауза
digitalWrite(ledPins[4], HIGH);  //Включить LED #4 (pin 6)
delay(delayTime);                //пауза
digitalWrite(ledPins[5], HIGH);  //Включить LED #5 (pin 7)
delay(delayTime);                //пауза
digitalWrite(ledPins[6], HIGH);  //Включить LED #6 (pin 8)
delay(delayTime);                //пауза
digitalWrite(ledPins[7], HIGH);  //Включить LED #7 (pin 9)
delay(delayTime);                //пауза

// выключить все, на:

digitalWrite(ledPins[7], LOW);   //Выключить светодиод LED индекс #7 (pin 9)
delay(delayTime);                //пауза delayTime, миллисек.
digitalWrite(ledPins[6], LOW);   //Выключить LED #6 (pin 8)
delay(delayTime);                //пауза delayTime
digitalWrite(ledPins[5], LOW);   //Выключить LED #5 (pin 7)
delay(delayTime);                //пауза
digitalWrite(ledPins[4], LOW);   //Выключить LED #4 (pin 6)
delay(delayTime);                //пауза
digitalWrite(ledPins[3], LOW);   //Выключить LED #3 (pin 5)
delay(delayTime);                //пауза
digitalWrite(ledPins[2], LOW);   //Выключить LED #2 (pin 4)
delay(delayTime);                //пауза
digitalWrite(ledPins[1], LOW);   //Выключить LED #1 (pin 3)
delay(delayTime);                //пауза
digitalWrite(ledPins[0], LOW);   //Выключить LED #0 (pin 2)
delay(delayTime);                //пауза
}
/*
oneAfterAnotherLoop()

Эта функция делает тоже самое что и oneAfterAnotherNoLoop(),
но используя цикл for() и массив, от этого код на много короче и проще.
*/

void oneAfterAnotherLoop()
{
int index;
int delayTime = 100; // пауза delayTime, миллисек.
// можно изменить, чтобы замедлить и наоборот

// выключить все, на:

// Этот цикл for() перебирает значение индекса от 0 до 7
// (увеличивает «++» затем использует полученное значение в digitalWrite()
// затем переключает светодиод на Вкл.

for(index = 0; index <= 7; index++)
{
digitalWrite(ledPins[index], HIGH);
delay(delayTime);
}

// Переключить все на Выкл:

// Этот цикл for() перебирает значение индекса от 7 к 0
// (уменьшает «—» уменьшает на единицу, использует полученное в
// функции digitalWrite() затем выключает светодиод.

for(index = 7; index >= 0; index—)
{
digitalWrite(ledPins[index], LOW);
delay(delayTime);
}
}
/*
oneOnAtATime()

Эта функция включат светодиоды, по одному.
*/

void oneOnAtATime()
{
int index;
int delayTime = 100; // пауза delayTime, миллисек.
// можно изменить, чтобы замедлить и наоборот

// перебирается индекс от 0 к 7

for(index = 0; index <= 7; index++)
{
digitalWrite(ledPins[index], HIGH);  // Вкл. светодиод
delay(delayTime);                    // пауза перед выкл.
digitalWrite(ledPins[index], LOW);   // Выкл. светодиод
}
}
/*
pingPong()

Эта функция гоняет светодиод от стенки до стенки.
*/

void pingPong()
{
int index;
int delayTime = 100; // пауза delayTime, миллисек.
// можно изменить, чтобы замедлить и наоборот

// перебирается индекс от 0 к 7

for(index = 0; index <= 7; index++)
{
digitalWrite(ledPins[index], HIGH);  // Вкл. светодиод
delay(delayTime);                    // пауза перед выкл.
digitalWrite(ledPins[index], LOW);   // Выкл. светодиод
}

// step through the LEDs, from 7 to 0

for(index = 7; index >= 0; index—)
{
digitalWrite(ledPins[index], HIGH);  // Вкл. светодиод
delay(delayTime);                    // пауза перед выкл.
digitalWrite(ledPins[index], LOW);   // Выкл. светодиод
}
}

/*
marquee()

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

void marquee()
{
int index;
int delayTime = 200; // пауза delayTime, миллисек.
// можно изменить, чтобы замедлить и наоборот

// Шаг 4 светодиода
// (подсветим один, и 4 вниз, 4 в верх)

for(index = 0; index <= 3; index++) // Шаг от 0 to 3
{
digitalWrite(ledPins[index], HIGH);    // Вкл. светодиод
digitalWrite(ledPins[index+4], HIGH);  // 4-ый из массива вкл.
delay(delayTime);                      // пауза
digitalWrite(ledPins[index], LOW);     // переключить светодиод на выкл.
digitalWrite(ledPins[index+4], LOW);   // 4-ый из массива выкл.
}
}

/*
randomLED()

Эта функция включает случайные светодиоды.
Вы можете попробовать изменить время включения?
*/

void randomLED()
{
int index;
int delayTime;

// Функция random() возвращает каждый раз при вызове случайное значение

index = random(8);    // случайны индекс из массива от 0 and 7
delayTime = 100;

digitalWrite(ledPins[index], HIGH);  // Вкл. светодиод
delay(delayTime);                    // пауза перед выкл.
digitalWrite(ledPins[index], LOW);   // Выкл. светодиод
}