3 мая 2012 г.

Arduino: управляем цветом RGB светодиода с помощью джойстика

Достался мне внезапно джойстик для Arduino, поэтому сегодня время повеселиться с ним! Объектом нашего издевательства избирается трехцветный светодиод, как раз вспомним ШИМ.


Подключение джойстика

Джойстик такой обычный, двухкоординатный:



Подключать его удобно к Sensor Shield тремя кабелями:



Почему тремя, если координат две? На самом деле у него условно еще есть третья координата, которая реализуется кнопкой. Я подключил проводки от оси x к A1, от оси y к A2, от z - к A3. A0-A5 - это аналоговые входы.

Для проверки работы девайса напишем простенькую программу, которая будет передавать 3 числа по параллельному интерфейсу в комп:

//переменные для значений с джойстика
int xValue, yValue, zValue; 



void setup(){
  Serial.begin(9600); //инициируем последовательное соединение
}


void loop(){
    //читаем значения с джойстика и ремапим их от 0 до 252
  xValue = map(analogRead(A1), 0, 1024, 0, 252);
  yValue = map(analogRead(A2), 0, 1024, 0, 252);
  zValue = map(analogRead(A3), 0, 1024, 0, 252);


  Serial.print(xValue);    //выводим значение x
  Serial.print("\t");      //отступ 
  Serial.print(yValue);    //выводим значение y
  Serial.print("\t");      //отступ
  Serial.println(zValue);  //выводим значение z

}
Результат вот такой:



Итак, мы видим, что при движении джойстика меняются цифры по x и y, а при нажатии на джойстик компонента z получает максимальное значение.

Цветовая гамма

Как бы реализовать цветовую гамму и переходы от одного цвета к другому при передвижении джойстика по одной координате? Давайте спросим графический редактор GIMP (можете спросить Paint - там то же самое). Открываем его палитру:


Самая верхняя его строка под названием "H" означает тон. Если мы подвигаем ползунок туда-сюда, то увидим, как меняются красная, зеленая и синяя составляющие цвета. Можно заметить следующую интересную особенность: полоса как бы разделяется на 6 частей, в которых интенсивность одного цвета нулевая, другого - максимальная, а третьего - линейно изменяется. Схематически это можно изобразить так:


Глядя на схему и, одновременно, на палитру GIMP, понимаем, что наша догадка верна: самым левым должен быть чисто красный цвет, самым правым - лиловый (много красного и чуть-чуть синего), по серединке - голубенький (много синего и зеленого, нет красного), синий правее центра, зеленый - левее. Все сходится. Можем применить нашу модель для управления цветом с джойстика.

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

Подключение светодиода

Подключение трехцветного светодиода у нас уже было, я приведу картинку оттуда еще раз:


Пожалуйста, не забывайте про резисторы, не подключайте ноги светодиода напрямую к выходам Arduino! Светодиод сгорает и неприятно пахнет, я проверял.

Кодинг

Как я уже говорил, мы разобьем ось x на 6 частей.. Именно потому я выше взял максимальное значение не 256, а 252. В этом случае один отрезок будет длиной 42. Без лишних слов приступаем к кодингу:



int REDpin = 9;
int GREENpin = 10;
int BLUEpin = 11;



void setup() {
  Serial.begin(9600);
}



void loop() {
  int xValue = map(analogRead(A1), 0, 1024, 0, 251);
  int yValue = map(analogRead(A2), 0, 1024, 0, 251);
  int zValue = map(analogRead(A3), 0, 1024, 0, 251);

//1 отрезок
  if(xValue<=41){
    analogWrite(REDpin, 0);
    analogWrite(GREENpin, 251-6*xValue);
    analogWrite(BLUEpin, 251);
  }
//2
 отрезок 
  if (xValue>=42 && xValue<=83){
    analogWrite(REDpin, 6*(xValue-42));
    analogWrite(GREENpin, 0);
    analogWrite(BLUEpin, 251);
  }
//3
 отрезок 
  if (xValue>=84 && xValue<=125){
    analogWrite(REDpin, 251);
    analogWrite(GREENpin, 0);
    analogWrite(BLUEpin, 251-6*(xValue-84));
  }
//4
 отрезок 
  if (xValue>=126 && xValue<=167){
    analogWrite(REDpin, 253);
    analogWrite(GREENpin, 6*(xValue-126));
    analogWrite(BLUEpin, 0);
  }
//5
 отрезок 
  if (xValue>=168 && xValue<=209){
    analogWrite(REDpin, 251-6*(xValue-168));
    analogWrite(GREENpin, 251);
    analogWrite(BLUEpin, 0);
  }
//6
 отрезок 
  if (xValue>=210 && xValue<=251){
    analogWrite(REDpin, 0);
    analogWrite(GREENpin, 251);
    analogWrite(BLUEpin, 6*(xValue-210));
  } 

  delay(10);
}

Обратите внимание, что светодиод у нас с общим анодом, а это значит, что при подаче на "цветовую" ногу пяти вольт ничего не горит, а при подаче нуля - все горит с максимальной интенсивностью. Поэтому участки роста на схеме интенсивностей соответствуют линейным функциям с отрицательной производной и наоборот.

Получаем такое веселье:




Больше веселья!

Теперь задействуем ось у джойстика. Подключим второй светодиод к ногам 3, 5 и 6 и заставим его светиться разными цветами. В программе это сделаем тупой копипастой с соответствующими корректировками:

int REDpin1 = 9;
int GREENpin1 = 10;
int BLUEpin1 = 11;




int REDpin2 = 3;
int GREENpin2 = 5;
int BLUEpin2 = 6;



void setup() {
  Serial.begin(9600);
}



void loop() {
  int xValue = map(analogRead(A1), 0, 1024, 0, 251);
  int yValue = map(analogRead(A2), 0, 1024, 0, 251);
  int zValue = map(analogRead(A3), 0, 1024, 0, 251);

//Первый светодиод
//1 отрезок
  if(xValue<=41){
    analogWrite(REDpin1, 0);
    analogWrite(GREENpin1, 251-6*xValue);
    analogWrite(BLUEpin1, 251);
  }
//2
 отрезок 
  if (xValue>=42 && xValue<=83){
    analogWrite(REDpin1, 6*(xValue-42));
    analogWrite(GREENpin1, 0);
    analogWrite(BLUEpin1, 251);
  }
//3
 отрезок 
  if (xValue>=84 && xValue<=125){
    analogWrite(REDpin1, 251);
    analogWrite(GREENpin1, 0);
    analogWrite(BLUEpin1, 251-6*(xValue-84));
  }
//4
 отрезок 
  if (xValue>=126 && xValue<=167){
    analogWrite(REDpin1, 253);
    analogWrite(GREENpin1, 6*(xValue-126));
    analogWrite(BLUEpin1, 0);
  }
//5
 отрезок 
  if (xValue>=168 && xValue<=209){
    analogWrite(REDpin1, 251-6*(xValue-168));
    analogWrite(GREENpin1, 251);
    analogWrite(BLUEpin1, 0);
  }
//6
 отрезок 
  if (xValue>=210 && xValue<=251){
    analogWrite(REDpin1, 0);
    analogWrite(GREENpin1, 251);
    analogWrite(BLUEpin1, 6*(xValue-210));
  } 

//Второй светодиод

//1 отрезок
  if(yValue<=41){
    analogWrite(REDpin2, 0);
    
analogWrite(GREENpin2, 251-6*xValue);
    
analogWrite(BLUEpin2, 251);
  }
//2
 отрезок
  if (yValue>=42 && yValue<=83){
    analogWrite(REDpin2, 6*(xValue-42));
    analogWrite(GREENpin2, 0);
    analogWrite(BLUEpin2, 251);
  }
//3
 отрезок
  if (yValue>=84 && yValue<=125){
    analogWrite(REDpin2, 251);
    analogWrite(GREENpin2, 0);
    analogWrite(BLUEpin2, 251-6*(xValue-84));
  }
//4
 отрезок
  if (yValue>=126 && yValue<=167){
    analogWrite(REDpin2, 253);
    analogWrite(GREENpin2, 6*(xValue-126));
    analogWrite(BLUEpin2, 0);
  }
//5
 отрезок
  if (yValue>=168 && yValue<=209){
    analogWrite(REDpin2, 251-6*(xValue-168));
    analogWrite(GREENpin2, 251);
    analogWrite(BLUEpin2, 0);
  }
//6
 отрезок
  if (yValue>=210 && yValue<=251){
    analogWrite(REDpin2, 0);
    analogWrite(GREENpin2, 251);
    analogWrite(BLUEpin2, 6*(xValue-210));
  } 

  delay(10);
}

Получаем вот такое веселье:


Еще больше веселья!

Наконец, задействуем ось z. Там есть только кнопочка, по нажатию этой кнопочки мы будем рандомно включать и выключать светодиоды. Для этого конечно же надо оторвать анодные ноги светодиодов от Vcc и приляпать их на управляемые пины, например 7 и 8. По нажатию кнопки на этих пинах будет происходить некая магия, меняющая состояние светодиодов.

Чтобы не показывать вам один и тот же листинг, я просто приведу список строк, которые необходимо добавить в предыдущую версию (с указанием таргетируемых частей проги):



int anodePin1 = 7;
int anodePin2 = 8;

int timer=0, timerPrev=0;
void setup() {
  pinMode(anodePin1, OUTPUT);
  pinMode(anodePin2, OUTPUT);
}

void loop() {
  timer=millis();

  if (zValue>200){
    if (timer-timerPrev > 100){ 
 //это такое веселое подавление дребезга 
      digitalWrite(anodePin1, random(2));
      digitalWrite(anodePin2, random(2));
      timerPrev=timer;
    }

}
Самое веселое веселье:


Надеюсь, вы здорово повеселились и нашли идеи для своих проектов ан Arduino. Всем удачи!

Далее по теме Arduino и ШИМ

Осиливаем ШИМ в темпой компании Arduino и RGB светодиода
Визуализация ШИМ на осциллографе