Pre nahratie strojového kódu do Arduina je možné využiť nástroj AVRDUDE, ktorý pre nahrávanie skompilovaného programu využíva i prostredie Arduino IDE. Nástroj je možné spúšťať priamo z príkazového riadku, ale je nutné správne nastaviť všetky konfigurovateľné údaje a tak nie je vhodný pre menej skúsených programátorov, či laikov. XLoader je Windows aplikácia (spusiteľný .exe nástroj) s jednoduchým grafickým rozhraním, ktoré umožňuje výber firmvéru - strojového kódu (.hex), cieľovej platformy a vie dynamicky ukázať COM port, na ktorom sa zariadenie nachádza. Umožňuje vypalovať firmvér do AVR platforiem t.j. Arduino Uno, Nano, Duemilanove (AtMega328 / AtMega168), Arduino Mega (AtMega1280 / AtMega2560). Jednoduchým kliknutím na Upload je možné strojový kód automatizovane nahrať (XLoader využíva podobne ako Arduino IDE nástroj AVRDUDE). Okno XLoadera informuje o úspešnom uploade formou výpisu počtu uploadovaných bajtov. Po nahratí firmvéru z Github repozitáru projektu Hasičské stopky sú stopky ihneď pripravené na prevádzku. Firmvér stopiek je rozlíšený na základe I2C adresy znakového LCD displeja - štandardne 0x27 / 0x3F. Firmvér zo strojových kódov umožňuje pre stopky s počítaním na stotiny sekundy v Shareware verzii dokáže merať max 15 sekúnd. Slúži na overenie funkčnosti, testovanie rýchlosti reakcie, odozvy systému - kompilované z kompletnej .ino aplikácie (nedostupná zdarma).
/*|------------------------------------------------------------------------------------------|*/
/*|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 |*/
/*|Doska: Arduino Uno, Nano, Mega, ATmega328P (Hardware I2C) |*/
/*|WEB: http://arduino.clanweb.eu/hasicske-stopky.php |*/
/*|------------------------------------------------------------------------------------------|*/
#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 KONŠTÁNT S NASTAVENÍM POČIATOCNÝCH HODNÔT
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(" AUTOR PROJEKTU");
lcd.setCursor(0, 1); //nastav kurzor pre zapis na 2. riadok, 1. stlpec
lcd.print(" MARTIN CHLEBOVEC");
delay(2500);
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);
}
/*|--------------------------------------------------------------------------------------------|*/
/*|VYHOTOVIL: MARTIN CHLEBOVEC |*/
/*|HASICSKE STOPKY - PLATENA VERZIA - NA STOTINY 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) - MOZNO ZNIZIT EXTERNYM |*/
/*|PROGRAM FUNGUJE PRE ZASTAVENIE A SPUSTENIE OBOCH CASOV JEDNYM TLACIDLOM |*/
/*|Doska: Arduino Uno, Nano, Mega, ATmega328P (Hardware I2C) |*/
/*|WEB: https://arduino.php5.sk/hasicske-stopky.php |*/
/*|--------------------------------------------------------------------------------------------|*/
#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() {
Serial.begin(115200);
lcd.begin(); //incializacia displeja na I2C zbernici
Wire.setClock(400000); //400 kHz clock 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:00 L. PRUD ");
lcd.setCursor(0, 1); //nastav kurzor pre zapis na 2. riadok, 1. stlpec
lcd.print("00:00:00 P. PRUD ");
}
void loop() {
checkStart();
if ((micros() - timer) >= 10000 || timer == 0) {
timer = micros();
Serial.println(micros());
tick();
}
}
void checkStart() {
if (!digitalRead(start_tlacidlo)) {
run = true; //aktivuj cas pre lavy prud
run2 = true; //aktivuj cas pre pravy prud
}
if (!digitalRead(lavy_terc_kontakt)) {
run = false;
}
if (!digitalRead(pravy_terc_kontakt)) {
run2 = false;
}
if (!digitalRead(vynulovat_cas_tlacidlo)) {
run = false;
run2 = false;
second = 0;
minute = 0;
tenth = 0;
second2 = 0;
minute2 = 0;
tenth2 = 0;
lcd.setCursor(0, 0);
lcd.print("00:00:00 L. PRUD");
lcd.setCursor(0, 1);
lcd.print("00:00:00 P. PRUD");
}
}
void tick() { //tick sa vykonava kazdych 10 miliseund, teda kazdu stotinu sekundy
//LOGIKA BEZIACEHO CASU PRVEHO UTOKU (UTOK LAVY)
if (run) {
if (tenth == 99) {
tenth = 0;
if (second == 59) {
second = 0;
lcd.setCursor(3, 0);
lcd.print("00");
minute++;
lcd.setCursor(0, 0);
if (minute < 10) {
lcd.print("0");
}
lcd.print(minute, DEC);
} else {
second++;
lcd.setCursor(3, 0);
if (second < 10) {
lcd.print("0");
}
lcd.print(second, DEC);
}
} else {
tenth++;
lcd.setCursor(6, 0);
lcd.print(tenth, DEC);
}
}
//LOGIKA BEZIACEHO CASU DRUHEHO UTOKU (UTOK PRAVY)
if (run2) {
if (tenth2 == 99) {
tenth2 = 0;
if (second2 == 59) {
second2 = 0;
lcd.setCursor(3, 1);
lcd.print("00");
minute2++;
lcd.setCursor(0, 1);
if (minute2 < 10) {
lcd.print("0");
}
lcd.print(minute2, DEC);
} else {
second2++;
lcd.setCursor(3, 1);
if (second2 < 10) {
lcd.print("0");
}
lcd.print(second2, DEC);
}
} else {
tenth2++;
lcd.setCursor(6, 1);
lcd.print(tenth2, DEC);
}
}
}