Подключение джойстика
Джойстик такой обычный, двухкоординатный:
Подключать его удобно к Sensor Shield тремя кабелями:
Почему тремя, если координат две? На самом деле у него условно еще есть третья координата, которая реализуется кнопкой. Я подключил проводки от оси x к A1, от оси y к A2, от z - к A3. A0-A5 - это аналоговые входы.
Почему тремя, если координат две? На самом деле у него условно еще есть третья координата, которая реализуется кнопкой. Я подключил проводки от оси 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
}
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
}
Цветовая гамма
Как бы реализовать цветовую гамму и переходы от одного цвета к другому при передвижении джойстика по одной координате? Давайте спросим графический редактор 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;
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));
}
//Второй светодиод
delay(10);
}
int GREENpin1 = 10;
int BLUEpin1 = 11;
int REDpin2 = 3;
int GREENpin2 = 5;
int BLUEpin2 = 6;
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<=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 отрезок
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 отрезок
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 отрезок
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 отрезок
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));
}
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 светодиода
Визуализация ШИМ на осциллографе
Особенно забавно в этом видео - это изображение ШИМа. Когда меняется цвет диода, то на видео линия засвета прерывистой становится =)
ОтветитьУдалитьвеселая статья !
ОтветитьУдалить