В гараж. Генератор імпульсів для стенда промивки форсунок.

Конструкції та програмування ARDUINO UNO
Відповісти
Мирослав
Повідомлень: 4
З нами з: 16 березня 2021, 17:51
Дякував (ла): 5 разів
Подякували: 3 рази

В гараж. Генератор імпульсів для стенда промивки форсунок.

Повідомлення Мирослав »

Добратися до Ардуіно я збирався років з два. Придбав плату «Уно», блок живлення, макетку з проводами, кілька датчиків і дисплеїв… І дав тому всьому добре вилежатися. =)
Знання і досвід у програмуванні у мене біля нуля: років сорок тому в університеті вивчав Фортран-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;
  }
}

Відповісти