blogy logo
login PRIHLÁS SA
BLOG deadawp
ČLÁNKY
DISKUSIE
3
SLEDUJETE BLOG
PHP, Arduino programátor
deadawp



Hasičské stopky cez Arduino s displejom
pridal deadawp 8.12. 2018 o 4:07



Dnes vám predstavím v krátosti hasičské stopky, respektíve časomieru, ktorú som vytváral ako fanúšiť hasičského športu. Súťažné hasičské družstvo má hádam každá dedina, či časť mesta. Každý týždeň najmä letnom období sa konajú súťaže po dedinách a mužstvá si pripisujú cenné body, úspechy i neúspechy, o ktorých rozhodujú stotiny, či tisíciny sekundy.

Vytvoril som teda jednoduché stopky, ktoré mi do istej miery dovolili použiteľne merať čas, napríklad pri tréningoch domácich požiarníkov.
Využil som millis, čo je funkcia interného časovača Arduina, ktorá vracia počet milisekúnd od štartu procesora. Vieme teda merať čas na 3 desatinné miesta (1000 ms = 1 sekunda). Presnosť vieme teda určiť na 1 tisícinu (obrazne povedané :) ).

Prostredníctvom tejto funkcie vieme teda merať čas. Potrebujeme nejaký prvotný impulz - niečo, čím si odmeriame štartovací čas a spustíme celú logiku systému. Použil som teda fyzické tlačidlo, ktoré je nutné manuálne stlačiť. Tento čas sa uloží a časy sa začnú počítať. Refresh-rate je každú sekundu a dáta by bolo možné posielať aj do displeja každú milisekundu, čo by znamenalo 1000Hz refreshrate, ale to by samozrejme displej nezvládol. Arduino to zvláda vďaka vysokorýchlostnej zbernici, ktorou je prepojené s LCD znakovým displejom. Sú to údaje o veľkosti len pár bajtov.
(Časť logiky systému pracujúcej s časom)

V programe bežia 2 podprogramy, jeden pre ľavý, druhý pre pravý prúd, kde sa skúma, či bol čas zastavený a v premenných sa nachádzajú jednotlivé údaje (minúty, sekundy, desatiny, stotiny, tisíciny), tie sa odosielajú na displej.
(Odosielané dáta na displej do riadku)

Pre impulz spadnutého terča som využil kontakt, ktorý zopne terč pre spadnutí. Rovnako pre oba terče. Čas sa zastaví prakticky okamžite (oneskorenie na vedení a pod.).

V prípade, že mužstvo zle odštartuje, je možné stopky ihneď vynulovať druhým tlačidlom a ihneď ich pripraviť na štart. Funkčnosť je veľmi jednoduchá, taktiež aj program.
Čo teda po technickej (hardvérovej) stránke potrebujeme k projektu?

  • Arduino, alebo samostatný AtMega čip
  • LCD displej 16x2 alebo 20x4 s I2C prevodníkom
  • 2 tlačidlá
  • 2 spínacie kontakty

Aby som minimalizoval použité elektrotechnické súčiastky, využil som interné pullup rezistory Arduina, prostredníctvom ktorých je možné spínať kontakt proti zemi a jednoducho zaznamenať zmenu. Štandardne sa používa 10kohm rezistor, ak sa kontakt spína proti 5V Arduina.

Prečo som na začiatku rozprával o obraznej presnosti na 1 tisícinu?

Takmer každý, kto si plánuje kúpiť Arduino pozerá na cenu. Dať 30€ za originálne Arduino, alebo 3€ za čínsky klon, odpoveď je myslím jasná..
Čínske klony sú hardvérovo totožné s originálmi. Je to ale istý rozdiel a to v kvalite oscilátora, ktorý dáva Arduinu takt. V originálnych Arduinách sa využíva presný 16MHz oscilátor. Pri klonoch sa používa rovnaký, ale nie až taký presný, dá sa predstaviť ako 15.9998MHz.
Z toho vyplýva, že sa po určitom čase presnosť zmenšuje na tisícinách, pri dlhšom meraní i na stotinách, desatinách, sekundách. Ďalší útlm predstavuje aj vedenie, po ktorom signály prichádzajú. Arduino stopky nikdy nenahradia certifikovanú časomieru, ktorá sa používa pre hasičské športy! 
Schéma zapojenia pre hasičské stopky:

Program pre hasičské stopky (na desatiny) ako ukážkové demo:

/*|------------------------------------------------------------------------------------------|*/
/*|VYHOTOVIL: MARTIN CHLEBOVEC                                                               |*/
/*|HASICSKE STOPKY - VERZIA ZDARMA - NA DESATINY SEKUNDY S CASOM PRE DVA UTOKY - LAVY/PRAVY  |*/
/*|FUNGUJE NA PRINCIPE FUNKCIE MILLIS() A VYKONAVANI KRATKYCH PROGRAMOVYCH CYKLOV            |*/
/*|INPUT PULLUP ZAPOJENIE S 50kohm INTERNAMY REZISTOROM (PODLA SCHEMY)                       |*/
/*|PROGRAM FUNGUJE PRE ZASTAVENIE A SPUSTENIE OBOCH CASOV JEDNYM TLACIDLOM                   |*/
/*|PROGRAMOVU LOGIKU SI MOZETE UPRAVIT PRE OVLADANIE CASOV SAMOSTATNYMI KONTAKTMI NA TERCOCH |*/
/*|PRI ZAUJME O PLATENU VERZIU PROGRAMU NA TISICINY KONTAKTOVAT NA MAILE!                    |*/
/*|EMAIL: martinius96@gmail.com                                                              |*/
/*|Doska: Arduino Uno, Nano, Mega, AtMega328P (Hardware I2C)                                 |*/
/*|WEB: https://arduino.php5.sk/hasicske-stopky.php                                          |*/
/*|PODPORA PROJEKTU PRE UVOLNENIE PLNEJ VERZIE ZDARMA: https://www.paypal.me/chlebovec       |*/
/*|------------------------------------------------------------------------------------------|*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//I2C adresa, stlpce, riadky, pouziva sa i 0x3F pre displej 20x4, 0x27 pre 16x2, skontruj cez I2C scanner https://playground.arduino.cc/Main/I2cScanner/
LiquidCrystal_I2C lcd(0x3F, 20, 4);

//DEKLARACIA DIGITALNYCH PINOV NA KTORE SU NAPOJENE TLACIDLA
const int start_tlacidlo = 12;
const int lavy_terc_kontakt = 11;
const int pravy_terc_kontakt = 10;
const int vynulovat_cas_tlacidlo = 9;

boolean run = false;         //bezi cas pre LAVY UTOK?
boolean run2 = false;         //bezi cas pre PRAVY UTOK?

//STAVY NACITANYCH LOGICKYCH HODNOT TLACIDIEL
int start_tlacidlo_stav = HIGH;
int lavy_terc_kontakt_stav = HIGH;
int pravy_terc_kontakt_stav = HIGH;
int vynulovat_cas_tlacidlo_stav = HIGH;

unsigned long timer = 0; //timer

//PREMENNE PRE PRVY CAS - LAVY UTOK
int second = 0;
int minute = 0;
int tenth = 0;

//PREMENNE PRE DRUHY CAS - PRAVY UTOK
int second2 = 0;
int minute2 = 0;
int tenth2 = 0;

void setup() {
  lcd.begin(); //incializacia displeja na I2C zbernici
  lcd.backlight(); //zapnutie podsvietenia
  pinMode(start_tlacidlo, INPUT_PULLUP); //nastav ako vstup proti internemu 50kohm pullup rezistoru
  pinMode(lavy_terc_kontakt, INPUT_PULLUP);
  pinMode(pravy_terc_kontakt, INPUT_PULLUP);
  pinMode(vynulovat_cas_tlacidlo, INPUT_PULLUP);
  lcd.setCursor(0, 0); //nastav kurzor pre zapis na 1. riadok, 1. stlpec
  lcd.print("00:00:0 L. PRUD");
  lcd.setCursor(0, 1); //nastav kurzor pre zapis na 2. riadok, 1. stlpec
  lcd.print("00:00:0 P. PRUD");
}

void tickClock() {
  Serial.println(millis() / 10);
  if ((timer - millis() / 100) >= 100 || timer == 0) {
    tick();
    timer = millis() / 100;
  }
}

void loop() {
  tickClock();
  start_tlacidlo_stav = digitalRead(start_tlacidlo);
  lavy_terc_kontakt_stav = digitalRead(lavy_terc_kontakt);
  pravy_terc_kontakt_stav = digitalRead(pravy_terc_kontakt);
  vynulovat_cas_tlacidlo_stav = digitalRead(vynulovat_cas_tlacidlo);
  checkStart();
}

void checkStart() {
  if (start_tlacidlo_stav == LOW ) {
    run = true; //aktivuj cas pre lavy prud
    run2 = true; //aktivuj cas pre pravy prud
  }
  if (lavy_terc_kontakt_stav == LOW ) {
    run = false;
  }
  if (pravy_terc_kontakt_stav == LOW ) {
    run2 = false;
  }
  if (vynulovat_cas_tlacidlo_stav == LOW ) {
    run = false;
    run2 = false;
    second = 0;
    minute = 0;
    tenth = 0;
    second2 = 0;
    minute2 = 0;
    tenth2 = 0;
    updateLCD();
    updateLCD2();
  }
}


void tick() { //tick sa vykonava kazdych 100 miliseund, teda kazdu desatinu sekundy
  //LOGIKA BEZIACEHO CASU PRVEHO UTOKU (UTOK LAVY)
  if (run) {
    updateLCD();
    if (tenth == 9) {
      tenth = 0;
      if (second == 59) {
        second = 0;
        minute++;
      } else {
        second++;
      }
    } else {
      tenth++;
    }
  }

  //LOGIKA BEZIACEHO CASU DRUHEHO UTOKU (UTOK PRAVY)
  if (run2) {
    updateLCD2();
    if (tenth2 == 9) {
      tenth2 = 0;
      if (second2 == 59) {
        second2 = 0;
        minute2++;
      } else {
        second2++;
      }
    } else {
      tenth2++;
    }
  }
}

//VYPIS PRVEHO UTOKU NA DISPLEJ (UTOK LAVY)
void updateLCD() {
  lcd.setCursor(0, 0);
  if (minute < 10) {
    lcd.print("0");
  }
  lcd.print(minute, DEC);
  lcd.print(":");
  if (second < 10) {
    lcd.print("0");
  }
  lcd.print(second, DEC);
  lcd.print(":");
  lcd.print(tenth, DEC);
}

//VYPIS DRUHEHO UTOKU NA DISPLEJ (UTOK PRAVY)
void updateLCD2() {
  lcd.setCursor(0, 1);
  if (minute2 < 10) {
    lcd.print("0");
  }
  lcd.print(minute2, DEC);
  lcd.print(":");
  if (second2 < 10) {
    lcd.print("0");
  }
  lcd.print(second2, DEC);
  lcd.print(":");
  lcd.print(tenth2, DEC);
}

Knižnice pre Arduino: https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
Celý systém je možné napájať i na batérie či powerbanku, jeho celkový odber je do 60mA pri 5V.
Viac o podobných projektoch môžete nájsť aj na mojich stránkach: https:/arduino.php5.sk







Prístupov 2058
Kvalita článku
hlasov 0

PRÍSPEVKY
SLEDUJETE
Prosím prihláste sa pre možnosť pridania komentáru.
Prihláste sa, alebo použite facebook login facebook login
ĎALŠIE ČLÁNKY V BLOGU
Mastermind - Logik - cez Arduino a LCD
[ 22.8.2019] (príspevkov 0)
Bicyklovanie po Google mapách - Arduino ...
[ 23.6.2019] (príspevkov 0)
Nerov (v)zostup v Caldárii
[ 3.6.2019] (príspevkov 0)
Prepočet atmosférického tlaku na hladinu...
[ 17.5.2019] (príspevkov 0)
Včelárska váha - Arduino + HX711
[ 6.5.2019] (príspevkov 0)
Hladinomer - Arduino, ESP32, ESP8266 + u...
[ 29.4.2019] (príspevkov 0)
Meteostanica - ESP32 - Webclient
[ 19.4.2019] (príspevkov 0)
Webportál - Vykurovanie cez internet - o...
[ 24.3.2019] (príspevkov 0)
Capture points (DOMINATION) - Arduino + ...
[ 23.2.2019] (príspevkov 0)
Notifikátor udalostí cez mikrokontróler
[ 22.2.2019] (príspevkov 0)