// Obsluha displeje pres TM1637 //============================================= #ifdef signal_LED // kdyz neni pouzity displej, podprogramy jsou definované,ale nic se nezobrazuje void graf_natazeni(unsigned long vstupni_cislo , unsigned long delitel) { vstupni_cislo++; delitel++; } void zobraz_cislo(long cislo, byte styl) { styl++; cislo++; } void zobraz_text(byte polozka) { polozka++; } void aktualizuj_displej(void) { } void aktualizuj_displej(byte vstup_jas) { vstup_jas++; } #endif #ifdef displej_TM1637_5 //---------------------------------------------- // zobrazi na displeji text z pole dis_popisy[] void zobraz_text(byte polozka) { D_pamet[0] = dis_popisy[polozka][4]; // pretoceni nejvyssich a nejnizsich radu pro spravne zobrazeni na spravnych jednotkych D_pamet[1] = dis_popisy[polozka][3]; D_pamet[2] = dis_popisy[polozka][2]; D_pamet[3] = dis_popisy[polozka][1]; D_pamet[4] = dis_popisy[polozka][0]; aktualizuj_displej(); } //---------------------------------------------- //---------------------------------------------- // odesle do datoveho pinu 8 bitu se soucasnym kmitanim pinu CLK. // Na zaver posle jeste jeden hodinovy impulz pro prijem ACK bitu - ten ale netestuji. void zapis_data(byte data) { for(byte i = 0; i < 8; i++) { digitalWrite(pin_dis_CLK, LOW); delayMicroseconds(2); if(bitRead(data , i) == true) digitalWrite(pin_dis_DIN , HIGH); else digitalWrite(pin_dis_DIN , LOW); delayMicroseconds(2); digitalWrite(pin_dis_CLK, HIGH); delayMicroseconds(2); } digitalWrite(pin_dis_CLK, LOW); delayMicroseconds(10); // (tady by se mel testovat signal ACK, ale kaslu na to) digitalWrite(pin_dis_CLK, HIGH); delayMicroseconds(2); digitalWrite(pin_dis_DIN, LOW); // ukonceni odesilani bajtu prepnutim obou pinu do LOW delayMicroseconds(2); digitalWrite(pin_dis_CLK, LOW); delayMicroseconds(2); } //---------------------------------------------- //---------------------------------------------- // zapise do displeje obsah pole promennych D_pamet[] // kdyz neni zadany parametr funkce, vezme se jas z globalni promenne 'jas_displeje' void aktualizuj_displej() { aktualizuj_displej(jas_displeje); } //---------------------------------------------- //---------------------------------------------- // zapise do displeje obsah pole promennych D_pamet[] // pokud bude zadany parametr funkce, nastavi se podle nej jas displeje void aktualizuj_displej(byte vstup_jas) { digitalWrite(pin_dis_CLK,LOW); digitalWrite(pin_dis_DIN,LOW); // start_kom delayMicroseconds(2); zapis_data(0b01000000); // automaticke zvetsovani adresy (pozice sedmisegmentovky) digitalWrite(pin_dis_CLK, HIGH); // stop_kom delayMicroseconds(2); digitalWrite(pin_dis_DIN, HIGH); delayMicroseconds(2); digitalWrite(pin_dis_DIN, LOW); // start_kom delayMicroseconds(2); zapis_data(0b11000000); // bit2 az bit0 = startovni pozice na nulte segmentovce (nejvic vlevo) zapis_data(D_pamet[0]); zapis_data(D_pamet[1]); zapis_data(D_pamet[2]); zapis_data(D_pamet[3]); zapis_data(D_pamet[4]); digitalWrite(pin_dis_CLK, HIGH); // stop_kom delayMicroseconds(2); digitalWrite(pin_dis_DIN, HIGH); delayMicroseconds(2); digitalWrite(pin_dis_DIN, LOW); // start_kom delayMicroseconds(2); zapis_data(0b10001000 + vstup_jas); // bit2 az bit0 nastaveni jasu (bit3 = 0/1 = zhasnout/rosvitit displej) digitalWrite(pin_dis_CLK, HIGH); // stop_kom delayMicroseconds(2); digitalWrite(pin_dis_DIN, HIGH); delayMicroseconds(2); } //---------------------------------------------- //---------------------------------------------- // Zobrazeni cisla na 5-znakovem displeji // Uvodni nuly se nezobrazuji. (cislo 56 se zobrazi jako " 56") // Jedna nula pred desetinnou teckou se zobrazuje. Pri nastaveni napriklad 3 desetinnych mist a zobrazovanem cisle 6 ukaze displej " 0.006" // Nula pred desetinnou teckou se nezobrazi pouze v pripade zaporneho cisla se 4 desetinnymi misty: napriklad "-0,1234" se zobrazi jako "-.1234" ). // Znamenko minus se zobrazuje vzdycky na nejvyssi pozici (leva sedmisegmentovka). (-7 = "- 7") // Pri zobrazeni cisla bez desetinnych mist se desetinna tecka vpravo nezobrazuje. (78 = " 78") // Parametr 'styl' udava zpusob zobrazeni: // 0 = zobrazi cislo pres cely displej (prepisuje nebo maze i 1. sedmisegmentovku zleva) // 1 = zachova zobrazeny znak na prvni jednotce. Cislo pak musi byt v rozsahu 0 az 9999 (nesmi byt zaporne a nesmi byt moc velke). // 2 = specialni pripad, kdy se zobrazuje napis "L 0" az "L -99" (pri listovani v ulozenych hodnotach) // 3 = zobrazeni odpoctu pri mereni svetla ve formatu "-20- " az "-0- " (nahrada puvodniho sloupcoveho grafu) // 4 = rezerva (puvodne tam bylo neco hodne podobne stylu 0 ale uz to nemuzu najit. Pro jistotu nechavam neobsazene.) // 5 = styl zobrazeni odpoctu pri Hard Formatu (H.F.123) // 6 = styl zobrazeni odpoctu pri dlouhych vypisech EEPROM (rd.123) // 7 = styl zobrazeni odpoctu pri Soft Formatu (S.F.123) // 8 = podobne jako styl 1, akorat se zachovavaji 2 leve sedmisegmentovky a cislo musi byt v rozsahu 0 az 999 // 9 = styl pro zobrazeni uhlu natoceni - prvni segmentovka zobrazuje stupne, nekdy muze obsahovat i znamenko '-', druha je vzdycky volna, pak nasleduji dva znaky pro celou cast cisla (uvodni nula se nezobrazuje), desetinna tecka a jedno desetinne cislo. Ocekava vstup cislo v rozsahu -999 az 999. Desetinne cislo z toho dela automaticky // 10 = styl pro zobrazeni Elevace Slunce - prvni dva znaky jsou "SE.", treti je prazdny nebo minus, zbyle 2 znaky zobrazuji cele cislo v rozsahu 0 az 99 bez uvodnich nul) // 11 = styl pro zobrazeni Elevace Mesice - prvni dva znaky jsou "ME.", treti je prazdny nebo minus, zbyle 2 znaky zobrazuji cele cislo v rozsahu 0 az 99 bez uvodnich nul) // 12 = styl pro zobrazeni osvetleni Mesice - prvni dva znaky jsou "Mo.", treti je prazdny, zbyle 2 znaky zobrazuji cele cislo v rozsahu 0 az 99 bez uvodnich nul) // 13 = styl pro zobrazeni azimutu Slunce - prvni dva znaky jsou "SA." a pak hned nasleduje cislo mezi 0 a 359 // 14 = styl pro zobrazeni azimutu Mesice - prvni dva znaky jsou "MA." a pak hned nasleduje cislo mezi 0 a 359 // 15 = styl pro zobrazeni azimutu krabicky - prvni dva znaky jsou " A." a pak hned nasleduje cislo mezi 0 a 359 // 16 = styl pro zobrazeni odpoctu pri kalibraci kompasu - prvni tri znaky jsou "CAL." a pak hned nasleduje cislo mezi 0 a 10 // 17 = styl pro zobrazeni zadavane rektascenze - prvni dva znaky jsou "rA." a pak hned nasleduje cislo mezi 0 a 23.9 // 18 = styl pro zobrazeni zadavane deklinace - prvni dva znaky jsou "dE." a pak hned nasleduje cislo mezi -90 a 90 // 19 = styl pro zobrazeni zadavaneho intervalu 10 az 250s, 5M, 7M, 10M, 20M, 30M void zobraz_cislo(long cislo, byte styl) { byte predtext = 0; // pro styly, ktere zobrazuji nejaky dlouhy odpocet (formatovani a vypisy) se pred cislem zobrazuji jeste nejake texty posledni_n = cislo; // Pamet posledniho zadaneho cisla kvuli aktualizaci zobrazeni pri zmene polohy desetinne tecky if (styl == 5) { styl = 0; predtext = 1; // na prvnich sedmisegmentovkach se zobrazi znaky "H.F." jako Hard Format pozice_tecky = 0; // tecka se v tomto pripade nezobrazuje } if (styl == 6) { styl = 0; predtext = 2; // na prvnich sedmisegmentovkach se zobrazi znaky "rd." jako Read (vypis dlouhych dat z EEPROM) pozice_tecky = 0; // tecka se v tomto pripade nezobrazuje } if (styl == 7) { styl = 0; predtext = 3; // na prvnich sedmisegmentovkach se zobrazi znaky "S.F." jako Soft Format pozice_tecky = 0; // tecka se v tomto pripade nezobrazuje } if (styl == 8) { styl = 0; pozice_tecky = 0; // tecka se v tomto pripade nezobrazuje } if (styl == 9) { styl = 0; predtext = 4; // na prvnich sedmisegmentovkach se zobrazi stupen, nebo stupen a minus pozice_tecky = 1; } if (styl == 10) { styl = 0; predtext = 5; // na prvnich trech sedmisegmentovkach se zobrazi "S " nebo "S -" pozice_tecky = 0; } if (styl == 11) { styl = 0; predtext = 6; // na prvnich trech sedmisegmentovkach se zobrazi "M " nebo "M -" pozice_tecky = 0; } if (styl == 12) { styl = 0; predtext = 7; // na prvnich trech sedmisegmentovkach se zobrazi "o " pozice_tecky = 0; } if (styl == 13) { styl = 0; predtext = 8; // na prvnich dvou sedmisegmentovkach se zobrazi "SA." pozice_tecky = 0; } if (styl == 14) { styl = 0; predtext = 9; // na prvnich dvou sedmisegmentovkach se zobrazi "MA." pozice_tecky = 0; } if (styl == 15) { styl = 0; predtext = 10; // na prvnich dvou sedmisegmentovkach se zobrazi " A." pozice_tecky = 0; } if (styl == 16) { styl = 0; predtext = 11; // na prvnich trech sedmisegmentovkach se zobrazi "CAL." pozice_tecky = 0; } if (styl == 17) { styl = 0; predtext = 12; // na prvnich dvou sedmisegmentovkach se zobrazi "rA." pozice_tecky = 1; } if (styl == 18) { styl = 0; predtext = 13; // na prvnich dvou sedmisegmentovkach se zobrazi "dE." pozice_tecky = 0; } if (styl == 19) { styl = 0; predtext = 14; // na prvnich dvou sedmisegmentovkach se zobrazi "I.=" pozice_tecky = 0; } boolean znamenko = false; // Zapamatovat si znamenko, ktere se pak zobrazi na 1. segmentovce zleva (index 4) if (cislo < 0) // Zaporna cisla ... { znamenko = true; // ... se prevedou na kladna, ale zapamatuje se znamenko cislo=abs(cislo); } boolean zobraz_nuly = false; // Nuly pred cislem se normalne nezobrazuji // Prepnutim na true se zacnou zobrazovat uz od 1.pozice zleva na displeji if (styl == 3) // zobrazeni cisla ve formatu "-nn- " { cislo = cislo * 100; // cislo se posune o 2 mista vlevo (priklad: z puvodniho cisla 15 se stane " 1500" a na displeji se zobrazi jen pozice tisicu a stovek) zobraz_nuly = true; // budou se zobrazovat nuly pred cislem, takze napriklad z puvodniho 8 se stane "00800" a na displeji se v zaveru zobrazi "-08- " pozice_tecky = 0; // tecka se v tomto pripade nezobrazuje } if (styl == 0) { // ------------------ rad desetitisicu - tohle se pouzije jen pri mereni kladneho svetla na 3 desetinna mista ---------------------- if (cislo > 9999) { D_pamet[4] = graf_def[cislo / 10000]; cislo = cislo % 10000; zobraz_nuly = true; } else { if (zobraz_nuly == true) D_pamet[4] = graf_def[0]; // Znak '0' else D_pamet[4] = 0; // nebo prazdny znak } } // pripadne zaporne znamenko se zapise na levou segmentovku (index 4) if (znamenko == true) D_pamet[4] = D_pamet[4] | 0b01000000; // k puvodnimu znaku se prida znamenko "-" (napriklad pri prubeznem mereni teploty se nemaze levy horni segment) if (styl != 8 ) { // ------------------ rad tisicu ---------------------- if (pozice_tecky == 3) zobraz_nuly = true; if (cislo > 999) { D_pamet[3] = graf_def[cislo / 1000]; cislo = cislo % 1000; zobraz_nuly = true; } else { if (zobraz_nuly == true) D_pamet[3] = graf_def[0]; // Znak '0' else D_pamet[3] = 0; // nebo prazdny znak } } // ------------------- rad stovek ---------------------- if (pozice_tecky == 2) zobraz_nuly = true; if (cislo > 99) { D_pamet[2] = graf_def[cislo / 100]; cislo = cislo % 100; zobraz_nuly = true; } else { if (zobraz_nuly == true) D_pamet[2] = graf_def[0]; // Znak '0' else D_pamet[2] = 0; // nebo prazdny znak } // -------------------- rad desitek -------------------- if (pozice_tecky == 1) zobraz_nuly = true; if (cislo > 9) { D_pamet[1] = graf_def[cislo / 10]; cislo = cislo % 10; } else { if (zobraz_nuly == true) D_pamet[1] = graf_def[0]; // Znak '0' else D_pamet[1] = 0; // nebo prazdny znak } // ------- rad jednotek (prava sedmisegmentovka) ------- D_pamet[0] = graf_def[cislo]; if (styl == 2) // zobrazeni "L 0" az "L -99" pro kladne cislo 0 az 99 { if (posledni_n > 0) D_pamet[2] = 64; // minus na prostredni sedmisegmentovku else D_pamet[2] = 0; // na prostredni sedmisegmentovku nic pozice_tecky = 0; // tecka se v tomto pripade nezobrazuje } pripoj_tecku(); if (styl == 3) // zobrazeni cisla ve formatu "-nn- " { D_pamet[4] = 64; // na prvni sedmisegmentovku zleva (rad desetitisicu) se zapise pomlcka D_pamet[1] = 64; // na druhou sedmisegmentovku zprava (rad desitek) se zapise pomlcka D_pamet[0] = 0; // prvni sedmisegmentovka zprava (rad jednotek) se smaze } if (predtext == 1) { D_pamet[4] = 246; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak 'H.' D_pamet[3] = 241; // na druhou sedmisegmentovku zleva (rad tisicu) znak 'F.' } if (predtext == 2) { D_pamet[4] = 80; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak 'r' D_pamet[3] = 222; // na druhou sedmisegmentovku zleva (rad tisicu) znak 'd.' } if (predtext == 3) { D_pamet[4] = 237; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak 'S.' D_pamet[3] = 241; // na druhou sedmisegmentovku zleva (rad tisicu) znak 'F.' } if (predtext == 4) { if (znamenko == true) D_pamet[4] = 0b01100000; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak pro stupen a minus else D_pamet[4] = 0b00100000; // na prvni sedmisegmentovku zleva (rad desetitisicu) jen znak pro stupen if (stabilni_naklon == false) D_pamet[4] = D_pamet[4] | 128 ; // nestabilni naklon rozsviti tecku na prvnim displeji } if (predtext == 5) { D_pamet[4] = znak_eS; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak "S" (Slunce) D_pamet[3] = znak_Etecka; // druha sedmisegmentovka je znak "E." s teckou jako "Elevace" if (znamenko == true) D_pamet[2] = 64; // zaporne hodnoty maji znamenko na treti sedmisegmentovce zleva else D_pamet[2] = 0; // kladne hodnoty maji praznou sedmisegmentovku } if (predtext == 6) { D_pamet[4] = znak_eM; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak "M" (Mesic) D_pamet[3] = znak_Etecka; // druha sedmisegmentovka je znak "E." s teckou jako "Elevace" if (znamenko == true) D_pamet[2] = 64; // zaporne hodnoty maji znamenko na treti sedmisegmentovce zleva else D_pamet[2] = 0; // kladne hodnoty maji praznou sedmisegmentovku } if (predtext == 7) { D_pamet[4] = znak_eM; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak "M" (jako Mesic) D_pamet[3] = znak_oM; // druha sedmisegmentovka je znak "o." s teckou (jako osvetleni) D_pamet[2] = 0; // treti sedmisegmentovka je prazdna (vzdycky, protoze zaporne osvetleni neni mozne) } if (predtext == 8) { D_pamet[4] = znak_eS; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak "S" (Slunce) D_pamet[3] = znak_Atecka; // druha sedmisegmentovka zobrazuje znak A s teckou (Azimut) } if (predtext == 9) { D_pamet[4] = znak_eM; // na prvni sedmisegmentovku zleva (rad desetitisicu) znak "M" (Mesic) D_pamet[3] = znak_Atecka; // druha sedmisegmentovka zobrazuje znak A s teckou (Azimut) } if (predtext == 10) { D_pamet[4] = 0; // prvni segmentovka zleva bude prazdna D_pamet[3] = znak_Atecka; // druha sedmisegmentovka zobrazuje znak A s teckou (Azimut) } if (predtext == 11) { D_pamet[4] = znak_C; // prvni sedmisegmentovka zobrazuje znak "C" D_pamet[3] = znak_A; // druha sedmisegmentovka zobrazuje znak "A" D_pamet[2] = znak_Ltecka; // treti sedmisegmentovka zobrazuje znak "L." } if (predtext == 12) { D_pamet[4] = znak_R1; // prvni segmentovka zleva zobrazuje znak "r" D_pamet[3] = znak_R2; // druha sedmisegmentovka zobrazuje znak "A." } if (predtext == 13) { D_pamet[4] = znak_D1; // prvni segmentovka zleva zobrazuje znak "d" D_pamet[3] = znak_D2; // druha sedmisegmentovka zobrazuje znak "E." if (znamenko == true) D_pamet[2] = 64; // zaporne hodnoty maji znamenko na treti sedmisegmentovce zleva else D_pamet[2] = 0; // kladne hodnoty maji praznou sedmisegmentovku } if (predtext == 14) { D_pamet[4] = 134; // prvni segmentovka zleva zobrazuje znak "I." D_pamet[3] = 72; // druha sedmisegmentovka zobrazuje znak "=" switch (posledni_n) { case 251: // specialita "i= 5M" D_pamet[2] = 0; // prostredni segmentovka zobrazuje mezeru " " D_pamet[1] = 109; // ctvrta segmentovka zleva zobrazuje znak "5" D_pamet[0] = 55; // posledni segmentovka zobrazuje znak "M" break; case 252: // specialita "i= 5M" D_pamet[2] = 0; // prostredni segmentovka zobrazuje mezeru " " D_pamet[1] = 7; // ctvrta segmentovka zleva zobrazuje znak "7" D_pamet[0] = 55; // posledni segmentovka zobrazuje znak "M" break; case 253: // specialita "i=10M" D_pamet[2] = 6; // prostredni segmentovka zobrazuje mezeru "1" D_pamet[1] = 63; // ctvrta segmentovka zleva zobrazuje znak "0" D_pamet[0] = 55; // posledni segmentovka zobrazuje znak "M" break; case 254: // specialita "i=20M" D_pamet[2] = 91; // prostredni segmentovka zobrazuje mezeru "2" D_pamet[1] = 63; // ctvrta segmentovka zleva zobrazuje znak "0" D_pamet[0] = 55; // posledni segmentovka zobrazuje znak "M" break; case 255: // specialita "i=20M" D_pamet[2] = 79; // prostredni segmentovka zobrazuje mezeru "2" D_pamet[1] = 63; // ctvrta segmentovka zleva zobrazuje znak "0" D_pamet[0] = 55; // posledni segmentovka zobrazuje znak "M" break; } } aktualizuj_displej(); // Presype cele pole 'D_pamet[]' po seriove komunikaci do displeje } //---------------------- konec obsluhy displeje 5x7 znaku ------------------- //---------------------------------------------- // K jedne sedmisegmentovce prida jeste desetinnou tecku, ostatni tecky smaze void pripoj_tecku(void) { for (byte i = 1; i < 4 ; i++) // (na nulte pozici tecka nikdy nesviti, proto zacina smycka od 1) { if (pozice_tecky == i) D_pamet[i] = D_pamet[i] | 0b10000000; // rozsvit nejvyssi bit else D_pamet[i] = D_pamet[i] & 0b01111111; // zhasni nejvyssi bit } } //---------------------------------------------- //---------------------------------------------- // Na 5 mistnem displeji provede postupne rozsviceni vodorovnych segmentu // Zaplnuje se od leveho horniho rohu do praveho horniho rohu // pak se ve stejnem smeru prida stredni rada // a na zaver spodni rada (dohromady se tedy muze rozsvitit az 15 segmentu) // Pouziva se pro operace, kde je nutne nejakou dobu drzet tlacitko pred tim, nez se aktivuje nejaka "nebezpecna" akce (napriklad kalibrace magnetometru). // Behem drzeni je mozne tlacitko uvolnit a akce se nespusti. // Prvni parametr je cislo 0 az .... // Druhy parametr udava, kolik cisel pripada na jeden z 15 segmentu // priklad: vstupni_cislo je pocet milisekund od stisku tlacitka, a delitel je 133. Kazdy nasledujici segment se tedy rozsviti po 133ms. Vsech 15 vodorovnych segmentu bude svitit po 2 sekundach void graf_natazeni(unsigned long vstupni_cislo , unsigned long delitel) { byte krok_grafu = vstupni_cislo / delitel; byte segmentova_radka; byte podklad; if (krok_grafu < 5) { podklad = 0; // vsechny zobrazovaci jednotky se smazou segmentova_radka = 1; // horni segmenty } if (krok_grafu >= 5 and krok_grafu < 10) { podklad = 1; // vsechny zobrazovaci jednotky budou mit rozsviceny horni segment segmentova_radka = 64; // prostredni segmenty } if (krok_grafu >= 10 and krok_grafu <= 15) { podklad = 65; // vsechny zobrazovaci jednotky budou mit rozsviceny horni a prosredni segment segmentova_radka = 8; // spodni segmenty } for (byte i = 0; i < 5 ; i++) { if (krok_grafu < 15) { if ((krok_grafu % 5) > i) D_pamet[4-i] = podklad | segmentova_radka; else D_pamet[4-i] = podklad; } else { D_pamet[4-i] = 73; } } aktualizuj_displej(); } //---------------------------------------------- #endif