toneroulette/russian_code_comments/toneroulette_ru.ino

188 lines
17 KiB
Arduino
Raw Normal View History

2022-06-28 11:40:08 +00:00
#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 миллисекунд
}