#include #define pin_vstup 8 // vstup pro komunikaci s ATtiny #define pin_DEC A3 // prepinac pro prepsani typu zobrazeni #define pin_HEX A2 // prepinac pro prepsani typu zobrazeni #define pin_CHR A1 // prepinac pro prepsani typu zobrazeni #define pin_BIN A0 // prepinac pro prepsani typu zobrazeni #define pin_LED 9 // LED pro signalizaci problemu unsigned long prijata_hodnota; // promenne pro prepocitavani delky prijatych impulzu na cislo unsigned int cislo; float jednotka; byte pasmo; int korekce; byte soustava = 0; // v jake soustave se maji zobrazovat hodnoty na displeji (DEC/BIN/HEX/CHR) byte typ_zobrazeni[8]; // pro kazdou z 8 pozic na displeji se kvuli mazani musi zapamatovat, v jake soustave je prave zobrazovane cislo byte dis_x, dis_y; // souradnce na displeji byte index_pozice; // displej je rozdeleny na 8 pozic, do kterych se vypisuji cisla // ( RS , E , D4 , D5 , D6 , D7 ) // vyvody na displeji LiquidCrystal lcd( 2 , 3 , 4 , 5 , 6 , 7 ); // konstruktor pro displej s nastavenim vyvodu na Arduinu // ============================================================================= void setup(void) { Serial.begin(19200); pinMode(pin_vstup , INPUT); pinMode(pin_DEC , INPUT_PULLUP); pinMode(pin_BIN , INPUT_PULLUP); pinMode(pin_HEX , INPUT_PULLUP); pinMode(pin_CHR , INPUT_PULLUP); pinMode(pin_LED , OUTPUT); lcd.begin(16, 2); lcd.setCursor(2,0); lcd.print("Attiny DEBUG"); delay(2000); lcd.clear(); } // ============================================================================= void loop(void) { // prvni impulz by mel byt kalibracni (5 az 9 ms s krokem 1 ms). prijata_hodnota = pulseIn(pin_vstup , HIGH , 4000000); // maximalni mozny timeout (4 sekundy) pasmo = 99; // znacka, ktera bude signalizovat, jestli prisel kalibracni impulz if (prijata_hodnota < 5500 and prijata_hodnota > 0) // prvni pasmo kolem 5ms { jednotka = prijata_hodnota / 100.0; // 5ms odpovida 100 jednotkam pasmo = 0; } if (prijata_hodnota < 6500 and prijata_hodnota >= 5500) // druhe pasmo kolem 6ms { jednotka = prijata_hodnota / 120.0; // 6ms odpovida 120 jednotkam pasmo = 1; } if (prijata_hodnota < 7500 and prijata_hodnota >= 6500) // treti pasmo kolem 7ms { jednotka = prijata_hodnota / 140.0; // 7ms odpovida 140 jednotkam pasmo = 2; } if (prijata_hodnota < 8500 and prijata_hodnota >= 7500) // ctvrte pasmo kolem 8ms { jednotka = prijata_hodnota / 160.0; // 8ms odpovida 160 jednotkam pasmo = 3; } if (prijata_hodnota < 9500 and prijata_hodnota >= 8500) // pate pasmo kolem 9ms { jednotka = prijata_hodnota / 180.0; // 9ms odpovida cislu 180 jednotkam pasmo = 4; } if (pasmo < 5) // nejaky impulz se objevil, tak cekej jeste na druhy impulz { delay(6); //druhy impulz uz prenasi konkretni cislo prijata_hodnota = pulseIn(pin_vstup , HIGH , 50000); if(prijata_hodnota > 10000) prijata_hodnota = prijata_hodnota + 30; // specialni nesystemova korekce pro velka cisla if (prijata_hodnota > 0) { cislo = (prijata_hodnota - 25) / jednotka; // prepocet z delky impulzu na cislo // TABULKA KOREKCI //============================================= // zbytek po deleni // || 0 | 1 | 2 | 3 | 4 | // ===||==============================| // p 0 || 0 | -1 | -2 | +2 | +1 | // a ---||------------------------------| // s 1 || +1 | 0 | -1 | -2 | +2 | // m ---||------------------------------| // o 2 || +2 | +1 | 0 | -1 | -2 | // ---||------------------------------| // 3 || -2 | +2 | +1 | 0 | -1 | // ---||------------------------------| // 4 || -1 | -2 | +2 | +1 | 0 | // ---||------------------------------| byte zbytek = cislo % 5; if (zbytek == pasmo) korekce = 0; if (pasmo == 0 and zbytek == 1) korekce = - 1; if (pasmo == 0 and zbytek == 2) korekce = - 2; if (pasmo == 0 and zbytek == 3) korekce = + 2; if (pasmo == 0 and zbytek == 4) korekce = + 1; if (pasmo == 1 and zbytek == 0) korekce = + 1; if (pasmo == 1 and zbytek == 2) korekce = - 1; if (pasmo == 1 and zbytek == 3) korekce = - 2; if (pasmo == 1 and zbytek == 4) korekce = + 2; if (pasmo == 2 and zbytek == 0) korekce = + 2; if (pasmo == 2 and zbytek == 1) korekce = + 1; if (pasmo == 2 and zbytek == 3) korekce = - 1; if (pasmo == 2 and zbytek == 4) korekce = - 2; if (pasmo == 3 and zbytek == 0) korekce = - 2; if (pasmo == 3 and zbytek == 1) korekce = + 2; if (pasmo == 3 and zbytek == 2) korekce = + 1; if (pasmo == 3 and zbytek == 4) korekce = - 1; if (pasmo == 4 and zbytek == 0) korekce = - 1; if (pasmo == 4 and zbytek == 1) korekce = - 2; if (pasmo == 4 and zbytek == 2) korekce = + 2; if (pasmo == 4 and zbytek == 3) korekce = + 1; cislo = cislo + korekce; // korekce prijateho cisla tak, aby zapadlo do prislusneho pasma Serial.println(cislo); // logovani prijatych cisel do seriove linky //-------------------------------------------------------------------------------------------------------------------- // Moznost rucniho prepsani typu zobrazeni pomoci prepinace. // Kdyz neni sepnuty zadny kontakt na prepinaci, urcuje zobrazeni ATtiny. if (digitalRead(pin_DEC) == LOW) soustava = 0; // prepinac prepnuty na desitkove zobrazeni if (digitalRead(pin_HEX) == LOW) soustava = 1; // prepinac prepnuty na hexadecimalni zobrazeni if (digitalRead(pin_CHR) == LOW) soustava = 2; // prepinac prepnuty na znakove zobrazeni if (digitalRead(pin_BIN) == LOW) soustava = 3; // prepinac prepnuty na binarni zobrazeni // specialni kody switch (cislo) { // ----------------- specialni kody pro zmenu polohy pro tisk na displeji ----------------- case 256: dis_x = 0; dis_y = 0; index_pozice = 0; break; case 257: dis_x = 4; dis_y = 0; index_pozice = 1; break; case 258: dis_x = 8; dis_y = 0; index_pozice = 2; break; case 259: dis_x = 12; dis_y = 0; index_pozice = 3; break; case 260: dis_x = 0; dis_y = 1; index_pozice = 4; break; case 261: dis_x = 4; dis_y = 1; index_pozice = 5; break; case 262: dis_x = 8; dis_y = 1; index_pozice = 6; break; case 263: dis_x = 12; dis_y = 1; index_pozice = 7; break; // ----------------- specialni kody pro zmenu zobrazeni cisel ----------------- case 264: // ATtiny chce zobrazovat desitkova cisla (je mozne, ze tento pozadavek bude prepsan polohou prepinace) soustava = 0; break; case 265: // ATtiny chce zobrazovat hexadecimalni cisla (je mozne, ze tento pozadavek bude prepsan polohou prepinace) soustava = 1; break; case 266: // ATtiny chce zobrazovat znaky (CHR) (je mozne, ze tento pozadavek bude prepsan polohou prepinace) soustava = 2; break; case 267: // ATtiny chce zobrazovat binarni cisla (je mozne, ze tento pozadavek bude prepsan polohou prepinace) soustava = 3; break; // ----------------- specialni kod pro smazani posledni pouzite oblasti na displeji ----------------- case 268: // smazat blok nekolika bunek na displeji od pozice [dis_x, dis_x] podle nastavene soustavy cisel if (soustava == 3) // pro binarni soustavu se maze 8 bunek na displeji { lcd.setCursor(dis_x,dis_y); lcd.print(" "); } else //pro jine soustavy, nebo CHR se mazou 4 znaky { lcd.setCursor(dis_x,dis_y); lcd.print(" "); } typ_zobrazeni[index_pozice] = 0; // pri mazani bloku se navic jeste nastavi jeho typ zobrazeni na desitkovou soustavu break; // ----------------- specialni kod pro smazani celeho displeje ----------------- case 269: lcd.clear(); for (byte i = 0; i < 8 ; i++) { typ_zobrazeni[i] = 0; // pri mazani celeho displeje se jeste nastavi vsechny typy zobrazeni na desitkovou soustavu } break; // ----------------- vsechny ostatni cisla (obvykle 0 az 255) se zobrazi na displeji podle pozadovaneho typu soustavy (DEC/BIN/HEX/CHR) ------------------ default: if (typ_zobrazeni[index_pozice] != soustava) // prave doslo ke zmene typu zobrazeni na aktualni pozici { if (typ_zobrazeni[index_pozice] == 3) // pokud byla predchozi soustava nastavena na binarni, { lcd.setCursor(dis_x,dis_y); // maze se 8 znaku na displeji lcd.print(" "); } else // pokud byla predchozi soustava jina nez binarni, { lcd.setCursor(dis_x,dis_y); // mazou se 4 znaky na displeji lcd.print(" "); } } lcd.setCursor(dis_x,dis_y); if (soustava == 0) { dopln_mezery10(); lcd.print(cislo); // zobrazeni cisla v desitkove soustave } if (soustava == 1) { dopln_mezery16(); lcd.print(cislo,HEX); // zobrazeni cisla v sestnactkove soustave } if (soustava == 2) { lcd.print(" \""); lcd.write(cislo); // zobrazeni cisla jako CHR lcd.print('\"'); } if (soustava == 3) { dopln_mezery2(); lcd.print(cislo,BIN); // zobrazeni cisla ve dvojkove soustave } typ_zobrazeni[index_pozice] = soustava; // zapamatuje si, jaky byl skutecny typ zobrazeni na prislusne pozici displeje } // konec SWITCHe digitalWrite(pin_LED, LOW); } else { Serial.println("Druhy impulz: ERR"); digitalWrite(pin_LED, HIGH); } } } // ============================================================================= //------------------------------------------------------------------------------------------- // podprogramy pro doplneni potrebneho poctu mezer (nebo nul v pripade binarniho zobrazeni) pred zobrazovane cislo void dopln_mezery10(void) { lcd.print(' '); // oddelovaci mezera je na zacatku bloku if (cislo < 100) lcd.print(' '); // pro desitkova cisla se misto uvodnich nul zapisuji mezery. Priklad: " 45" if (cislo < 10) lcd.print(' '); } void dopln_mezery16(void) { lcd.print(" x"); // hexadecimalni cisla zacinaji znakem 'x'. Priklad " x0F" if (cislo < 16) lcd.print('0'); } void dopln_mezery2(void) // binarni cisla obsahuji uvodni nuly, ale jinak nemaji zadne specialni o znaceni. Priklad: "00101101" { // narozdil od ostatnich typu zobrazeni ani nezacinaji mezerou if (cislo < 128) lcd.print('0'); if (cislo < 64) lcd.print('0'); if (cislo < 32) lcd.print('0'); if (cislo < 16) lcd.print('0'); if (cislo < 8) lcd.print('0'); if (cislo < 4) lcd.print('0'); if (cislo < 2) lcd.print('0'); }