toneroulette/russian_code_comments/toneroulette_ru.ino

188 lines
17 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "pitches.h" // загрузить ноты из pitches.h
#include "Servo.h" // загрузить стандартную библиотеку Servo.h
Servo myservo; // создать объект сервопривода myservo для его контроя
const int redLED = 4; // красный пин светодиода
const int greenLED = 5; // зелёный пин светодиода
const int blueLED = 6; // синий пин светодиода
const int buzzer = 7; // сигнальный пин пищалки
const int servo = 9; // контрольный пин сервопривода
const int encDT = 2; // пин правого поворота (DT) поворотного регулятора
const int encCLK = 3; // пин левого поворота (CLK) поворотного регулятора
const int encSW = 8; // пин нажатия (SW) поворотного регулятора
volatile unsigned int encPos = 32768; // счётчик позиции поворотного регулятора
unsigned int lastReportedPos = 32768; // последнее записанное значение позиции поворотного регулятора
static boolean rotating = false; // управление поворотом регулятора
boolean right_set = false; // переменная процедуры правого поворота регулятора
boolean left_set = false; // переменная процедуры левого поворота регулятора
int pos = 0; // переменная позиции сервопривода
int posnote = 0; // переменная ноты на которую указывает сервопривод
int playednote = 0; // переменная хранящая последнюю сыгранную ноту
int gamma[] = {NOTE_B3, NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5}; // си3-до5
void setup() { // функция выполняемая при запуске
Serial.begin(9600); // инициализация серийного монитора
pinMode(LED_BUILTIN, OUTPUT); // определение встроенного светодиода
digitalWrite(LED_BUILTIN, LOW); // выключить встроенный светодиод подав напряжение низкого уровня
pinMode(buzzer, OUTPUT); // определение пищалки на выходной сигнал
pinMode(encDT, INPUT_PULLUP); // определение правого поворота регулятора на вход с подтягивающим резистором
pinMode(encCLK, INPUT_PULLUP); // определение левого поворота регулятора на вход с подтягивающим резистором
pinMode(encSW, INPUT_PULLUP); // определение нажатия регулятора на вход с подтягивающим резистором
attachInterrupt(0, encRight, CHANGE); // контакт регулятора на прерывании 0 (право)
attachInterrupt(1, encLeft, CHANGE); // контакт регулятора на прерывании 1 (лево)
// randomSeed(analogRead(0)); // устновка случайного семени в зависимости от напряжения на незанетом пине
initAll(); // вызов функции иниализации пищалки, светодиода и севпривода
randomNote(); // вызов функции проигрывания случайной ноты
}
void loop() { // функция выполняемая постоянно
rotating = true; // указание состояния поворота регулятора
if (lastReportedPos != encPos) { // если последнее записанное значение поворота регулятора неравно нынешнему положению
// Serial.print("POS:"); Serial.print(pos); Serial.print("IN:"); Serial.println(encPos, DEC); // вывод значений для отладки
if (lastReportedPos < encPos) { // если последнее записанное значение поворота регулятора меньше нынешнего
if (pos > 10) rotateRight (pos, (pos-30)); // если позиция севопривода больше 10 - повернуть вправо на 30 градусов
}
if (lastReportedPos > encPos) { // если последнее записанное значение поворота регулятора больше нынешнего
if (pos < 170) rotateLeft (pos, (pos+30)); // если позиция севопривода меньше 170 - повернуть влево на 30 градусов
}
lastReportedPos = encPos; // последнему записанному значению присвоить нынешнее значение регулятора
}
if (digitalRead(encSW) == LOW ) { // если нажата кнопка
posnote = ((((pos / 30) + 1) - 8) * (-1)); // вычисление ноты на которую указывает сервопривод
// Serial.print("NOTE:"); Serial.println(posnote); // вывод значений для отладки
if (posnote == playednote) { // если сервопривод указывает на последнюю сыгранную ноту
int blinking; // объявление временной переменной мерцания светодиода
for (blinking = 0; blinking < 10; blinking += 1) { // цикл 10 шагов мерцания от 0 до 9
colourGreen(); // зелёный свет светодиода
delay(200); // задержка в 200 миллисекунд
colourBlue(); // синий свет светодиода
delay(200); // задержка в 200 миллисекунд
}
colourOff(); // выключить свечение светодиода
delay(1000); // задержка в 1000 миллисекунд
randomNote(); // вызов функции проигрывания случайной ноты
} else { // иначе
colourRed(); // красный свет светодиода
delay(1000); // задержка в 1000 миллисекунд
colourOff(); // выключить свечение светодиода
}
}
}
void colourRandom() { // функция случайного цвета светодиода
analogWrite(redLED, random(0,255)); // случайное значение красного
analogWrite(greenLED, random(0,255)); // случайное значение зелёного
analogWrite(blueLED, random(0,255)); // случайное значение синего
}
void colourRed() { // функция красного цвета светодиода
analogWrite(redLED, 255); // максимальное значение красного
analogWrite(greenLED, 0); // минимальное значение зелёного
analogWrite(blueLED, 0); // минимальное значение синего
}
void colourGreen() { // функция зелёного цвета светодиода
analogWrite(redLED, 0); // минимальное значение красного
analogWrite(greenLED, 255); // максимальное значение зелёного
analogWrite(blueLED, 0); // минимальное значение синего
}
void colourBlue() { // функция синего цвета светодиода
analogWrite(redLED, 0); // минимальное значение красного
analogWrite(greenLED, 0); // минимальное значение зелёного
analogWrite(blueLED, 255); // максимальное значение синего
}
void colourOff() { // функция отсутствия цвета светодиода
analogWrite(redLED, 0); // минимальное значение красного
analogWrite(greenLED, 0); // минимальное значение зелёного
analogWrite(blueLED, 0); // минимальное значение синего
}
void rotateLeft(int posFrom, int posTo) { // функция поворота сервопривода влево
delay(32); // подождать 32 миллисекундыы
myservo.attach(servo); // присоединиться к сервоприводу
delay(32); // подождать 32 миллисекунды
for (pos = posFrom; pos < posTo; pos += 1) { // цикл увеличения позиции с posFrom до postTo с шагом в 1 градус
myservo.write(pos); // сообщить сервоприводу переместиться в позицию pos
delay(15); // подождать 15 миллисекунд для достижения позиции
}
// Serial.print("LEFTfrom:"); Serial.print(posFrom); Serial.print("to:"); Serial.print(posTo); Serial.print("cur:"); Serial.println(pos); // вывод значений для отладки
delay(32); // подождать 32 миллисекунды
myservo.detach(); // отсоединиться от сервопривода
delay(32); // подождать 32 миллисекунды
}
void rotateRight(int posFrom, int posTo) { // функция поворота сервопривода вправо
delay(32); // подождать 32 миллисекунды
myservo.attach(servo); // присоединиться к сервоприводу
delay(32); // подождать 32 миллисекунды
for (pos = posFrom; pos > posTo; pos -= 1) { // цикл уменьшения позиции с posFrom до postTo с шагом в 1 градус
myservo.write(pos); // сообщить сервоприводу переместиться в позицию pos
delay(15); // подождать 15 миллисекунд для достижения позиции
}
// Serial.print("RIGHTfrom:"); Serial.print(posFrom); Serial.print("to:"); Serial.print(posTo); Serial.print("cur:"); Serial.println(pos); // вывод значений для отладки
delay(32); // подождать 32 миллисекунды
myservo.detach(); // отсоединиться от сервопривода
delay(32); // подождать 32 миллисекунды
}
void initAll() { // функция иниализации пищалки, светодиода и севпривода
int gammavar; // обявление временной переменной нотной гаммы
for (gammavar = 1; gammavar <= 8; gammavar += 1) { // цикл увеличение ноты от 1 до 8
colourRandom(); // случайный цвет светодиода
tone(buzzer, gamma[gammavar]); // подать на пищалку соответствующий тон гаммы
delay(200); // подождать 200 миллисекунд
noTone(buzzer); // нет больше тона на пищалке
delay(10); // подождать 10 миллисекунд
}
for (gammavar = 7; gammavar >= 1; gammavar -= 1) { // цикл уменьшения ноты от 7 до 1
colourRandom(); // случайный цвет светодиода
tone(buzzer, gamma[gammavar]); // подать на пищалку соответствующий тон гаммы
delay(200); // подождать 200 миллисекунд
noTone(buzzer); // нет больше тона на пищалке
delay(10); // подождать 10 миллисекунд
}
colourRandom(); // случайный цвет светодиода
delay(500); // подождать 500 миллисекунд
colourRandom(); // случайный цвет светодиода
rotateLeft (0, 180); // повернуть сервопривод налево на 180 градусов
colourRandom(); // случайный цвет светодиода
delay(500); // подождать 500 миллисекунд
colourRandom(); // случайный цвет светодиода
rotateRight (180, 0); // повернуть сервопривод направо на 180 градусов
colourRandom(); // случайный цвет светодиода
delay(500); // подождать 500 миллисекунд
colourRandom(); // случайный цвет светодиода
delay (1000); // подождать 1000 миллисекунд
colourOff(); // выключить свечение светодиода
}
void encRight(){ // обработка прерывния поворотного регулятора на прерывании 0 (право)
if (rotating) delay (1); // подождать миллисекунду, пока поворот не закончится
if (digitalRead(encDT) != right_set) { // если физическое значение регулятора неравно переменной процедуры правого поворота регулятора
right_set = !right_set; // изменить значение переменной процедуры правого поворота регулятора на обратное
if (right_set && !left_set) // если происходит поворот вправо и не происходит вопорота влево (для регулировки)
encPos += 1; // увеличить счётчик позиции поворотного регулятора на 1
rotating = false; // больше нет вращения до завершения постоянно выполняемой функции loop()
}
}
void encLeft(){ // обработка прерывния поворотного регулятора на прерывании 1 (лево)
if (rotating) delay (1); // подождать миллисекунду, пока поворот не закончится
if (digitalRead(encCLK) != left_set) { // если физическое значение регулятора неравно переменной процедуры левого поворота регулятора
left_set = !left_set; // изменить значение переменной процедуры левого поворота регулятора на обратное
if (left_set && !right_set) // если происходит поворот влево и не происходит вопорота вправо (для регулировки)
encPos -= 1; // уменьшить счётчик позиции поворотного регулятора на 1
rotating = false; // больше нет вращения до завершения постоянно выполняемой функции loop()
}
}
void randomNote() { // функция проигрывания случайной ноты
delay(200); // подождать 200 миллисекунд
playednote = random(1,7); // сгенерировать случайное значение от 1 до 7 для переменной хранящей последнюю сыгранную ноту
tone(buzzer, gamma[playednote]); // подать на пищалку соответствующий тон переменной хранящей последнюю сыгранную ноту
delay(2000); // подождать 2000 миллисекунд
noTone(buzzer); // нет больше тона на пищалке
delay(200); // подождать 200 миллисекунд
}