// Имена пинов для светодиодов
// задать пины, к которым подсоединен светодиод. Пины должны поддерживать функцию ШИМ
#if defined(ARDUINO_ELSOMIK) || defined(ARDUINO_START_MIK32_V1)
// для плат Elsomik и Start задать пины в формате порт_вывод
const int RED_PIN = P0_0;
const int GREEN_PIN = P0_1;
const int BLUE_PIN = P0_2;
#else
// для плат Elbear задать номера цифровых выводов
const int RED_PIN = 3;
const int GREEN_PIN = 5;
const int BLUE_PIN = 6;
#endif

/*
 * Следующая переменная контролирует, насколько быстро выполняется цикл по смене
 * цветов (в качестве эксперимента попробуйте поменять ее значение).
 */
int DISPLAY_TIME = 1000;  // в миллисекундах

// Объявление функций
void mainColors();
void showRGB(int color);
void showSpectrum();

// функция настройки запускается один раз при нажатии кнопки reset или подаче питания на плату
void setup() {
  // Настройка пинов для управления RGB светодиодом:
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

// функция цикла выполняется снова и снова бесконечно
void loop() {

  /*
   * В этом примере показаны два способа управления RGB светодиодом.
   * Первый способ состоит из включения и выключения красного, зеленого и синего
   * в различных сочетаниях. Такие сочетания дают восемь цветов, если считать
   * "черный" в качестве цвета.
   */

  /*
   * Функция mainColors() проходит через все восемь цветов.
   * Эта функция включает и выключает отдельно каждый светодиод.
   * Если Вы хотите получить больше чем восемь цветов, Вам придется изменять
   * яркость каждого светодиода. Для этого можно использовать функцию 
   * analogWrite(), - градация яркости от 0 до 255.
   */
  mainColors();
  showSpectrum();  // Функция showSpectrum() плавно проследует через каждые из 8 цветов.
}


void mainColors() {
  // Все светодиоды выключены
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
  delay(DISPLAY_TIME);

  // Красный включен
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, LOW);
  delay(DISPLAY_TIME);

  // Зеленый включен
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, LOW);
  delay(DISPLAY_TIME);

  // Синий включен
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, HIGH);
  delay(DISPLAY_TIME);

  // Желтый (красный и зеленый)
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, LOW);
  delay(DISPLAY_TIME);

  // Бирюзовый (зеленый и синий)
  digitalWrite(RED_PIN, LOW);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
  delay(DISPLAY_TIME);

  // Фиолетовый (красный и синий)
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, LOW);
  digitalWrite(BLUE_PIN, HIGH);
  delay(DISPLAY_TIME);

  // Белый (красный, зеленый и синий)
  digitalWrite(RED_PIN, HIGH);
  digitalWrite(GREEN_PIN, HIGH);
  digitalWrite(BLUE_PIN, HIGH);
  delay(DISPLAY_TIME);
}


/*
 * showRGB() - выводит один цвет на светодиод. Когда Вам необходим 
 * опережеленный цвет, вызовите showRGB() с нужным Вам цветом.
 * Эта функция переводит число от 0 до 767 в определенный цвет.
 * Если плавно пройтись по этому числовому ряду, то светодиод будет
 * плавно менять цвет через весь цветовой спектр.
 *
 * int colot - код цвета от 0 до 767.
 * Базовые цифры:
 * 0 - чистый красный
 * 255 - чистый зеленый
 * 511 - чистый синий
 * 767 - чистый красный
 *
 * Числа между вышеуказанных создают промежуточные цвета.
 * Например, 640 находится между 512 (синий) и 767 (красный).
 * Это даст смесь синего и красного, в результате чего получится фиолетовый.
 */
void showRGB(int color) {
  int redIntensity;    // Яркость красного светодиода
  int greenIntensity;  // Яркость зеленого светодиода
  int blueIntensity;   // Яркость синего светодиода

  if (color <= 255)  // зона 1
  {
    redIntensity = 255 - color;  // красный меняется из включенного на выключенный
    greenIntensity = color;      // зеленый меняется из выключенного во включенный
    blueIntensity = 0;           // голубой всегда выключен
  } else if (color <= 511)       // зона 2
  {
    redIntensity = 0;                      // красный всегда выключен
    greenIntensity = 255 - (color - 256);  // зеленый меняется от включенного в выключенный
    blueIntensity = color - 256;           // синий меняется от выключенного к включенному
  } else if (color >= 512)                 // зона 3
  {
    redIntensity = color - 512;           // красный меняется от выключенного к включенному
    greenIntensity = 0;                   // зеленый всегда выключен
    blueIntensity = 255 - (color - 512);  // синий меняется от включенного к выключенному
  }

  // Функциям передаются установленные значения яркости.
  analogWrite(RED_PIN, redIntensity);
  analogWrite(BLUE_PIN, blueIntensity);
  analogWrite(GREEN_PIN, greenIntensity);
}

/*
 * showSpectrum() - выводит все цвета по очереди. Функция циклически
 * вызывает showRGB() для смены цвета с аргументом от 0 до 768.
 */
void showSpectrum() {
  for (int x = 0; x < 768; x++) {
    showRGB(x);
    delay(10);
  }
}
