
Процесс сборки аппарата описал в блоге на drive2
Ниже код скетча. Для регулировки длины импульса использовал энкодер. Осталось прикрутить дисплей, чтобы видеть значение импульса, а не считать в уме количество щелчков энкодера :).
Часть кода не моя, но я, к сожалению, не помню, откуда брал. Использован код (не мой) для программного устранения дребезга (функция debounce()). Также функция encoder() не моя. Эти функции, возможно, слегка переработаны относительно авторских вариантов.
Алгоритм следующий.
1. Короткое нажатие на кнопку вызывает импульс запрограммированной длины (arduino кратковременно включает реле на нужное количество миллисекунд). После этого в течение двух секунд повторный импульс невозможен.
2. Длинное нажатие (более 2х секунд) вызывает долговременное включение реле (реле остается включенным до отпускания кнопки)
/*
impulse with soft debounce
11/06/2018 Char0day
*/
// Константы
const int ledPin = LED_BUILTIN;// номер пина со светоиодом (встроенный)
const int impulsePin=10;
const int buttonPin=A3; // пин А3 подключаем к кнопке без фиксации
const int pin_DT = 7; // пин 7 подключаем к DT енкодера
const int pin_CLK = 8; // пин 8 подключаем к CLK енкодера
// Переменные
int pos_encoder = 0; // Первоначальная позиция енкодера равна 0
int Last; // Тут всегда будет лежать предыдущие значение положения енкодера
int DT;
boolean left;
int impulse=100; // длина импульса в миллисекундах
int ledState = LOW; // ledState используется для упрвления светодиодом. Когда нажата кнопка - светодиод горит
bool longpressButton=false; // Отслеживаем долгое нажатие кнопки
void setup()
{
pinMode (pin_DT,INPUT);
pinMode (pin_CLK,INPUT);
Last = digitalRead(pin_DT); // Считываем значение на выходе DT и запоминаем его
Serial.begin (9600);
pinMode(ledPin, OUTPUT);
pinMode(impulsePin, OUTPUT);
pinMode(buttonPin, INPUT);
}
bool debounce(int pin)
{
bool current = digitalRead(pin);
if (current != LOW)
{ // Старое значение отличается от полученного
delay(10); // Ждем пока состояние стабилизируется - игнорируем дребезг
}
current = digitalRead(pin); // Считываем стабилизированное значение
return current;
}
int encoder()
{
DT = digitalRead(pin_DT);
if (DT != Last)
{ // Сравниваем фактическое положение с предыдущим, если они не равны то енкодер изменил положение
if (digitalRead(pin_CLK) != DT)
{ // Если значение с pin_CLK не равно значению с pin_DT, то значит вращение было НАПРАВО ->
pos_encoder++;
left = false;
}
else
{ // Если значение с pin_CLK равно значению с pin_DT, то значит вращение было НАЛЕВО <-
left = true;
pos_encoder--;
}
Serial.print ("Napravlenie vrashcheniya: ");
if (!left)
{
Serial.println("NAPRAVO ->");
}
else
{
Serial.println("NALEVO <-");
}
Serial.print("Polozhenie: ");
Serial.println(pos_encoder);
}
Last = DT;
if (pos_encoder >190) pos_encoder=185;
if (pos_encoder< -16) pos_encoder= -13;
return pos_encoder;
}
void loop()
{
unsigned long currentMillis = millis();
int imp=encoder();
bool pressButton = debounce(buttonPin);
if (pressButton==false) longpressButton=false;
if (pressButton && longpressButton==false)
{
ledState = HIGH;
digitalWrite(ledPin, ledState);
digitalWrite(impulsePin, HIGH);
delay (impulse+imp*5);
digitalWrite(impulsePin, LOW);
ledState = LOW;
digitalWrite(ledPin, ledState);
delay(2000);
longpressButton=debounce(buttonPin);
if (longpressButton)
{
ledState = HIGH;
digitalWrite(ledPin, ledState);
digitalWrite(impulsePin, HIGH);
}
}
else
{
if (pressButton==false && longpressButton==false)
{
ledState = LOW;
digitalWrite(ledPin, ledState);
digitalWrite(impulsePin, LOW);
}
}
}
Оставить комментарий