Знання і досвід у програмуванні у мене біля нуля: років сорок тому в університеті вивчав Фортран-4 для роботи на ЄС ЕВМ, якісь програмки писав і навіть на перфокарти набивав … Для сьогоднішнього дня - як шумерська чи арамейська мови для сучасного філолога =).
Кілька днів тому вирішив зробити нову електроніку для стенда по миттю форсунок. В принципі, NE555 вирішує проблеми, але потрібен таймер із зворотнім відліком. Ліпити його з «роз сипухи» не було бажання, готової підходящої недорогої плати в І-неті не знайшов, згадав за Ардуіно.
Новорічні вихідні дали трохи часу вникнути.
Тех. Завдання виглядало так: таймер зворотнього відліку з мінімальними налаштуваннями і спрощеним управлінням на час 1-3 хвилини із індикацією часу, що залишився, і виходом сигналу управління на оптрон. Розширене завдання – генератор імпульсів частотою 100-200-300-400 Гц і скважністю біля 0,3 (коефіцієнтом заповнення 30%) з виходом на оптрон, можна з управлінням від таймера. Втім для цього випадку є готова плата на 555.
Перше знайомство з Ардуіно.
Скачав Arduino IDE і бібліотеку LiquidCrystal_I2C.h, підготував залізо, зокрема підключив дисплей LCD1602 через модуль І2С, примудрував на макетку світлодіод і якісь кнопки.
Таймер знайшов готовий . Для початку скачав пару книг (мені «зайшла» «Проэкты с использованием Ардуино» Віктора Петіна) трохи почитав і «розібрав» роботу скетча таймера. Практичні експерименти почалися з бажання побачити потрібний напис на дисплеї, для чого ввів ще одну змінну і скоригував блок lcd. Заодно видалив звукове сповіщення і «розвернув» логіку роботи світлодіода щоб використати його для увімкнення/вимкнення генератора. Дуже допомогла функція перевірки скетчу в Arduino IDE =) , все запрацювало.
Але ж використано лише 15% ресурсу плати! Вирішено: генератор зроблю теж на ній.
Підходящої схеми імпульсного генератора я не знайшов – всі переобтяжені кнопками установки частоти і блоками індикації (частотомірами). Мені ж треба лише кілька частот із заданими параметрами ну і управління від таймера. Одне уяснив – генератор слід робити на TimerOne. Перечитав кілька статей по TimerOne, скачав бібліотеку TimerOne.h (тут виявилося купа версій, незрозуміло в чому різниця, так що взяв «середню» по порядку), додав ще одну кнопку для вибору частоти і почав «ліпити» Після купи експериментів отримав незграбний але цілком робочий скетч. Часу пішло – акурат вихідні на Новий рік та Різдво =). Залишилося оформити «залізо» у завершену конструкцію.
Скетч:
Код: Виділити все
#include <TimerOne.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C LCD(0x27, 16, 2);
boolean button1WasUp = true;
boolean button2WasUp = true;
boolean button3WasUp = true;
boolean button4WasUp = true;
boolean button5WasUp = true;
byte w = 0;
int SEC = 0;
int MIN = 0;
int FRC = 100; // frequency = 100 Hz
unsigned long timer;
unsigned long t = 10000, f, k = 320;
void setup() {
pinMode(2, INPUT_PULLUP); // timer min minus
pinMode(4, INPUT_PULLUP); // time min plus
pinMode(6, INPUT_PULLUP); // start/stop
pinMode(8, INPUT_PULLUP); // reset
pinMode(5, INPUT_PULLUP); // frequency
pinMode(9, OUTPUT); // frequency
pinMode(13, OUTPUT); // LED diode
digitalWrite(9, LOW);
digitalWrite(13, LOW);
LCD.init();
LCD.backlight();
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
}
void loop() {
Timer1.initialize(t);
boolean button1IsUp = digitalRead(2);
boolean button2IsUp = digitalRead(4);
boolean button3IsUp = digitalRead(6);
boolean button4IsUp = digitalRead(8);
boolean button5IsUp = digitalRead(5);
if (button1WasUp && !button1IsUp) {
delay(10);
button1IsUp = digitalRead(2);
if (!button1IsUp) {
MIN = MIN - 1; SEC = 0;
if (MIN < 0) {
MIN = 0;
}
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
}
}
button1WasUp = button1IsUp;
if (button2WasUp && !button2IsUp) {
delay(10);
button2IsUp = digitalRead(4);
if (!button2IsUp) {
MIN = MIN + 1; SEC = 0;
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
}
}
button2WasUp = button2IsUp;
if (button3WasUp && !button3IsUp && MIN > 0) {
delay(10);
button3IsUp = digitalRead(6);
if (!button3IsUp) {
if (SEC == 0) {
SEC = 60;
MIN = MIN - 1;
}
if (MIN < 0 ) {
MIN = 0;
}
digitalWrite(13, HIGH);
w = 1;
if (FRC == 100) {
Timer1.pwm(9, 320, 10000); // frequency = 100 Hz duty 0.31
}
if (FRC == 200) {
Timer1.pwm(9, 320, 5000); // frequency = 200 Hz duty 0.31
}
if (FRC == 300) {
Timer1.pwm(9, 320, 3330); // frequency = 300 Hz duty 0.31
}
if (FRC == 400) {
Timer1.pwm(9, 320, 2500); // frequency = 400 Hz duty 0.31
}
}
}
button3WasUp = button3IsUp;
if (button4WasUp && !button4IsUp) {
delay(10);
button4IsUp = digitalRead(8);
if (!button4IsUp) {
MIN = 0; SEC = 0;
digitalWrite(13, LOW);
digitalWrite(9, LOW);
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
}
}
button4WasUp = button4IsUp;
if (button5WasUp && !button5IsUp) {
delay(10);
button5IsUp = digitalRead(5);
if (!button5IsUp) {
FRC = FRC + 100;
if (FRC > 400) {
FRC = 100;
}
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
}
}
button5WasUp = button5IsUp;
while (w == 1 ) {
if (millis() - timer > 995) {
timer = millis();
SEC = SEC - 1;
if (SEC == 0 && MIN == 0) {
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
digitalWrite(13, LOW);
w = 0;
}
if (SEC == 0) {
SEC = 59; MIN = MIN - 1;
if (MIN < 0 ) {
MIN = 0;
}
}
if (w == 1) {
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("TIMER START");
LCD.setCursor(12, 0);
LCD.print(MIN);
LCD.print(":");
LCD.print(SEC);
LCD.setCursor(0, 1);
LCD.print("FREQUENCY ");
LCD.print(FRC);
LCD.print(" HZ");
}
}
boolean button3IsUp = digitalRead(6);
if (button3WasUp && !button3IsUp) {
delay(10);
button3IsUp = digitalRead(6);
if (!button3IsUp) {
LCD.setCursor(0, 0);
LCD.print("TIMER STOP");
w = 0;
}
}
button3WasUp = button3IsUp;
}
}