// Osvetleni kola s blinkry pomoci RGB LED pasku NEOpixel //=========================================================== // // Verze: 9.4.2020 // // Ovladani: // ------------- // // Hlavnim vypinacem se zapina napajeni pro Arduino. Bez zapnuteho napajeni nefunguje nic. // Hlavni vypinac ma 3 polohy. V krajnich polohach pripne jeden nebo druhy akumulator, uprostred je napajeni vypnute. // // Prepinac "den" / "noc" urcuje stav svetel. // Pri prepnuti na "den" se jen zapne testovani stavu akumulatoru, jinak zustavaji svetla zhasnuta. // Pri prepnuti na "noc" se svetla rozblikaji // - Vpredu budou svitit trvale 2 krajni LED na kazde strane b�le (jako obrysovky) a zbytek LED blika bile. // - Vzadu budou vsechny LED jen blikat cervene. // - I tady zustava aktivni testovani akumulatoru. // // Prepnuti prepinace na pravy blinkr rozblika pravou cast svetel: // Vzadu i vpredu se zacne prava polovina LED postupne rozsvecet oranzove (od stredu ke kraji). // Kdyz je prepinac nastaveny na "noc", leva predni polovina bude svitit trvale bile na 30% a leva zadni polovina bude svitit trvale cervene (na 30% jasu). // Kdyz je prepinac nastaveny na "den", leva predni i zadni polovina zustavaji zhasnute. // // Prepnuti prepinace na levy blinkr rozblika levou polovinu svetel. // Funkce LED je presne opacna, nez pri pravem blinkru. // // Blinkry se zhasinaji prepnutim prepinace blinkru do stredni polohy. // Podle stavu prepinace "den" / "noc" se pak bud zhasnou svetla uplne, nebo se rozblikaji vpredu bile a vzadu cervene (leva i prava polovina). // // Na riditkach je maly signalizacni panel, ktery ukazuje stav zadnich svetel (blikani cervene, nebo levy/pravy blinkr) // Predni svetla signalizaci nemaji. // Stav akumulatoru je signalizovan dalsimi dvema LED, ktere blikaji uspornym blikanim (dlouha pauza (3s) a kratky impulz (0.05s)). // Podle barvy kratkych impulzu je mozne urcit stav akumulatoru (zelena=OK; zluta=ubyva; cervena=nutno dobit) // // Tlacitko "trubka" spusti okamzite rezim stroboskopu - (rychle blikani vsech prednich LED bile (100% jas) a zadnich LED cervene). // Tuhle funkci pouzivam, kdyz treba pou�tim lidi na prechodu, nebo kdyz nechavam auta vycouvat z parkoviste. // Pri uvolneni tlacitka trubka se stroboskop ukonci a vrati se normalni rezim sviceni ( nic / blikani / smerovky ) // Dlouhym stiskem tlacitka trubky (2 sek.) se zapne rezim MAJAK (cerveno / modre rychle blikani vsech svetel). Majak je 'zamceny' a bude blika i po uvolneni tlacitka trubky. // Zamknuty majak se vypne dalsim kratkym stiskem trubky, nebo smerovkou. // // Ochrana proti nechtenemu okamzitemu prepnuti smerovek z jedne strany na druhou poskytuje casove zpozdeni 1,5 sekundy po vypnuti // jedne smerovky, behem ktere se druha smerovka nerozblika. Behem te pauzy je mozne vratit prepinac do stredni polohy. // // Program obsahuje jeste dva specialni rezimy, ktere se voli pri zapnuti napajeni. // - Usporny rezim blikani se voli pri zapnuti napajeni tak, ze je smerovka prepnuta vlevo a zaroven je nastaveny nocni rezim. // V tomto uspornem rezimu blika jen kazda druha LED (smerovky blikaji normalne). // Tento rezim slouzi k uspore akumulatoru v pripade, ze je jen sero a neni treba svitit naplno. // - Rezim trvale sviticich prednich svetel se voli pri zapnuti napajeni tak, ze je smerovka prepnuta vpravo a zaroven je nastaveny nocni rezim. // V tomto rezimu predni svetla neblikaji, ale sviti trvale. // Kazdy z techto specialnich rezimu se zrusi pri prepnuti prepinace den/noc na "den". Pri dalsim prepnuti na "noc" uz probiha blikani v normalnim rezimu. // // // //-------------------------------------------------------------------------------------------------------------------------------------------------- #include // knihovna pro ovladani LED pasku #define pinDI_LP 10 // pripojovaci pin pro 16 LED (indexy 0 az 15 = leva predni polovina) #define pinDI_PP 5 // pripojovaci pin pro 16 LED (indexy 0 az 15 = prava predni polovina) #define pinDI_LZ A3 // pripojovaci pin pro 14 LED (indexy 0 az 12 + 1 LED = leva zadni polovina + infoLED na riditkach) #define pinDI_PZ A0 // pripojovaci pin pro 14 LED (indexy 0 az 12 + 1 LED = prava zadni polovina + infoLED na riditkach) + 2 LED pro AKU #define pin_bzuk 3 // pin pro piskak, ktery prerusovane pipa pri blikani #define pin_sw_den_noc 8 // pin pro prepinac den / noc #define pin_sw_trub 7 // (tlacitko trubka) #define pin_sw_leva 9 // po sepnuti do LOW na tomto pinu se spusti rezim leveho blinkru #define pin_sw_prava 6 // po sepnuti do LOW na tomto pinu se spusti rezim praveho blinkru #define pin_aku_A A6 // pin pro mereni napeti na aktivnim akumulatoru #define pin_aku_Z A7 // pin pro mereni napeti na zaloznim akumulatoru // definice barev #define zhasnuto 0x000000 #define ruda 0xB00000 #define zelena 0x00FF00 #define modra 0x0000B0 #define oranzova 0xD06000 #define bila 0xB0B0B0 #define zluta 0xFFFF00 #define slaba_bila 0x303030 #define slaba_cervena 0x400000 #define slaba_zelena 0x003000 #define slaba_zluta 0x303000 #define superbila 0xFFFFFF #define superruda 0xFF0000 Adafruit_NeoPixel LED_LP = Adafruit_NeoPixel(16, pinDI_LP , NEO_GRB + NEO_KHZ800); // konstruktor LP vetve Adafruit_NeoPixel LED_PP = Adafruit_NeoPixel(16, pinDI_PP , NEO_GRB + NEO_KHZ800); // konstruktor PP vetve Adafruit_NeoPixel LED_LZ = Adafruit_NeoPixel(13, pinDI_LZ , NEO_GRB + NEO_KHZ800); // konstruktor LZ vetve Adafruit_NeoPixel LED_PZ = Adafruit_NeoPixel(15, pinDI_PZ , NEO_GRB + NEO_KHZ800); // konstruktor PZ vetve + 2 LED pro AKU boolean stav; // pomocna promenna pro blikani (v kazde smycce se meni a tim zpusobuje blikani) boolean noc; // stav prepinace den / noc byte funkce=0; // jaka funkce osvetleni prave probiha (normalni blikani / zhasnuto / blinkr / majak /... ) byte casovac; // testovani dlouheho stisku tlacitka trubky, ktere spousti majak byte cas_test_aku; // odpocet doby, kdy se ma testovat akumulator byte BlokBlik = 0; // blokovani okamziteho prepnuti blinkru z jedne strany na druhou byte spec_rezim; // pri zapnuti napajeni je mozne zvolit 'specialni rezim' void setup() { analogReference(INTERNAL); LED_LP.begin(); LED_PP.begin(); LED_LZ.begin(); LED_PZ.begin(); pinMode(pin_sw_den_noc ,INPUT_PULLUP); pinMode(pin_sw_trub ,INPUT_PULLUP); pinMode(pin_sw_leva ,INPUT_PULLUP); pinMode(pin_sw_prava ,INPUT_PULLUP); pinMode(pin_aku_A ,INPUT); pinMode(pin_aku_Z ,INPUT); pinMode(pin_bzuk, OUTPUT); // po zapnuti napajeni kratke pipnuti digitalWrite(pin_bzuk,HIGH); delay(20); digitalWrite(pin_bzuk,LOW); spec_rezim = 0; if ((digitalRead(pin_sw_leva) == LOW) and (digitalRead(pin_sw_den_noc) == LOW)) // zapnuti usporneho rezimu (LEVA + NOC po zapnuti napajeni) { spec_rezim = 1; for (byte i = 0; i<14 ; i=i+2) // predni LED rozsvitit ob jednu { LED_PP.setPixelColor(i, bila); LED_LP.setPixelColor(i, bila); LED_PP.setPixelColor(i+1, zhasnuto); LED_LP.setPixelColor(i+1, zhasnuto); } } if ((digitalRead(pin_sw_prava) == LOW) and (digitalRead(pin_sw_den_noc) == LOW)) // zapnuti predniho neprerusovaneho sviceni (PRAVA + NOC po zapnuti napajeni) { spec_rezim = 2; for (byte i = 0; i<14 ; i++) // vsechny predni LED rozsvitit { LED_PP.setPixelColor(i, bila); LED_LP.setPixelColor(i, bila); } } if (spec_rezim > 0) // kdyz je zapnuty nejaky ze specialnich rezimu, ceka program na prepnuti smerovek do nulove polohy { LED_LP.show(); LED_PP.show(); while ((digitalRead(pin_sw_leva) == LOW) or (digitalRead(pin_sw_prava) == LOW)) { delay(20); } } } void loop() { tlacitka(funkce); // testovani kontaktu ovladace na riditkach a stavu obou akumulatoru stav = !stav; // v kazde smycce se stridave meni stav, podle ktereho se v rezimu blikani meni rozsviceni, nebo zhasnuti LED if (funkce == 1) normalblik(stav); if (funkce == 2) vlevo(); if (funkce == 3) vpravo(); if (funkce == 4) stroboskop(stav); if (funkce == 5) majak(stav); if (funkce == 0) zhasnout(); } void tlacitka(byte stara_funkce) { // k testovani kazdeho akumulatoru dochazi jen 1x za 100 cyklu (3 sekundy) cteni tlacitek cas_test_aku ++; if (cas_test_aku == 4 or cas_test_aku == 54) // pri 4. a 54. cyklu akumulatorove LED zhasinaji (sviti tedy 0.12 sekundy z kazdych 3 sekund) { aku_zhasni(); } if (cas_test_aku == 50) // pri 50. cyklu se testuje stav aktivniho akumulatoru a LED se rozsveci prislusnou barvou (zelena, zluta, cervena) { test_aku(1); } if (cas_test_aku > 99) // pri 0. (resp. poslednim) cyklu se testuje stav zalozniho akumulatoru a LED se rozsveci prislusnou barvou (zelena, zluta, cervena) { test_aku(2); cas_test_aku = 0; } if (BlokBlik > 0) { funkce = stara_funkce; } if (digitalRead(pin_sw_leva) == LOW and BlokBlik == 0) // kdyz vyprsi cas blokovani smerovky a je prepnuto vlevo { funkce = 2; // nastavi se funkce na levy blinkr } if (digitalRead(pin_sw_prava)== LOW and BlokBlik == 0) // kdyz vyprsi cas blokovani smerovky a je prepnuto vpravo { funkce = 3; // nastavi se funkce na pravy blinkr } if (digitalRead(pin_sw_leva) == HIGH and digitalRead(pin_sw_prava) == HIGH and funkce < 4) funkce = 1; // je prepnuto do mezipolohy a zaroven neni stisknuta trubka if (digitalRead(pin_sw_den_noc) == HIGH) { noc = false; // pri rozpojeni pinu se nastavi DEN spec_rezim = 0; // zaroven se rusi pripadny specialni rezim } else { noc = true; // prizemneny pin znamena NOC } if (digitalRead(pin_sw_trub) == LOW) { if (casovac < 80) // mereni delky stisku { funkce = 4; // okamzity majak casovac ++; } else // pri dlouhem stisku: { funkce = 5; // funkce zamceny majak } } if (digitalRead(pin_sw_trub) == HIGH) // uvolneni tlacitka "trubka" nuluje mereni delky stisku { casovac = 0; if (funkce == 4) funkce = 0; // pri uvolneni po kratkem stisku se meni fukkce zpatky na "NORMAL" } // (pri uvolneni po dlouhem stisku zustava nastavena funkce 5) if (stara_funkce != funkce) { zhasnout(); // pri zmene funkce se vsechny LED okamzite zhasinaji // kdyz dojde k okamzite zmene blinkru z jedne strany na druhou (chyba pri vraceni prepinace do stredni polohy) // tak se smerovky na 45 cyklu zablokuji (45 cyklu je asi 1,5 sekundy) if (stara_funkce == 2 or stara_funkce == 3) { BlokBlik = 45; } } else { delay(30); // kdyz se funkce nemeni, tak se jen chvili pocka } if ( BlokBlik > 0) BlokBlik --; // po uvolneni smerovky je na 1,5 sekundy zakazano ji znova spustit } // zhasnuti vsech LED void zhasnout(void) { for (byte i = 0; i<13 ; i++) // zadni zhasnout { LED_LZ.setPixelColor(i, zhasnuto); LED_PZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<16; i++) // predni zhasnout { LED_LP.setPixelColor(i, zhasnuto); LED_PP.setPixelColor(i, zhasnuto); } LED_LZ.show(); LED_LP.show(); LED_PZ.show(); LED_PP.show(); } void vpravo(void) { if (noc == true) // v noci se leve poloviny LED nastavi na snizeny jas { for (byte i = 0; i<13 ; i++) // celou levou zadni pulku LED rozsvitit na 50% { LED_LZ.setPixelColor(i, slaba_cervena); } for (byte i = 0; i<16 ; i++) // celou levou predni pulku LED rozsvitit na 50% { LED_LP.setPixelColor(i, slaba_bila); } LED_LZ.show(); LED_LP.show(); } else // ve dne se leve poloviny zhasnou { for (byte i = 0; i<13 ; i++) // celou levou zadni pulku LED zhasnout% { LED_LZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<16 ; i++) // celou levou predni pulku LED zhasnout { LED_LP.setPixelColor(i, zhasnuto); } LED_LZ.show(); LED_LP.show(); } for (byte i = 0; i < 16 ; i++) // predni a zadni pravou pulku postupne rozsvecet do oranzova { if (i < 13) { LED_PZ.setPixelColor(i, oranzova); LED_PZ.show(); } LED_PP.setPixelColor(i, oranzova); LED_PP.show(); tlacitka(funkce); if (i == 13 ) digitalWrite(pin_bzuk, HIGH); // kratke pipnuti na posledni 2 LED if (i == 15 ) digitalWrite(pin_bzuk, LOW); } for (byte i = 0; i<16 ; i++) // pravou predni a zadni pulku okamzite zhasnout { if (i < 13) { LED_PZ.setPixelColor(i, zhasnuto); } LED_PP.setPixelColor(i, zhasnuto); } LED_PZ.show(); LED_PP.show(); } void vlevo(void) { if (noc == true) // v noci se prave poloviny LED nastavi na snizeny jas { for (byte i = 0; i<13 ; i++) // celou pravou zadni pulku LED rozsvitit na 50% { LED_PZ.setPixelColor(i, slaba_cervena); } for (byte i = 0; i<16 ; i++) // celou pravou predni pulku LED rozsvitit na 50% { LED_PP.setPixelColor(i, slaba_bila); } LED_PZ.show(); LED_PP.show(); } else // ve dne se prave poloviny zhasnou { for (byte i = 0; i<13 ; i++) // celou pravou zadni pulku LED zhasnout% { LED_PZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<16 ; i++) // celou pravou predni pulku LED zhasnout { LED_PP.setPixelColor(i, zhasnuto); } LED_PZ.show(); LED_PP.show(); } for (byte i = 0; i < 16 ; i++) // predni a zadni levou pulku postupne rozsvecet do oranzova { if (i < 13) { LED_LZ.setPixelColor(i, oranzova); LED_LZ.show(); } LED_LP.setPixelColor(i, oranzova); LED_LP.show(); tlacitka(funkce); if (i == 13 ) digitalWrite(pin_bzuk, HIGH); // kratke pipnuti na posledni 2 LED if (i == 15 ) digitalWrite(pin_bzuk, LOW); } for (byte i = 0; i<16 ; i++) // levou predni a zadni zhasnout { if (i < 13) { LED_LZ.setPixelColor(i, zhasnuto); } LED_LP.setPixelColor(i, zhasnuto); } LED_LZ.show(); LED_LP.show(); } void normalblik(boolean stav) { if (noc == true) { if (stav == true) { if (spec_rezim > 0) // usporny rezim { for (byte i = 0; i<=12 ; i=i+2) // zadni LED rozsvitit { LED_LZ.setPixelColor(i, ruda); LED_PZ.setPixelColor(i, ruda); } LED_LZ.setPixelColor(12, slaba_cervena); // LED na prednim infopanelu sviti slabe LED_PZ.setPixelColor(12, slaba_cervena); if (spec_rezim == 1) { for (byte i = 0; i<16 ; i++) // predni LED zhasnout { LED_PP.setPixelColor(i, zhasnuto); LED_LP.setPixelColor(i, zhasnuto); } } } else // normalni rezim { for (byte i = 0; i<12 ; i++) // zadni LED rozsvitit { LED_LZ.setPixelColor(i, ruda); LED_PZ.setPixelColor(i, ruda); } LED_LZ.setPixelColor(12, slaba_cervena); // LED na prednim infopanelu sviti slabe LED_PZ.setPixelColor(12, slaba_cervena); for (byte i = 0; i<14 ; i++) // predni LED zhasnout { LED_PP.setPixelColor(i, zhasnuto); LED_LP.setPixelColor(i, zhasnuto); } LED_PP.setPixelColor(14, slaba_bila); // dve predni krajni LED na kazde strane sviti trvale LED_LP.setPixelColor(14, slaba_bila); LED_PP.setPixelColor(15, slaba_bila); LED_LP.setPixelColor(15, slaba_bila); } } else { if (spec_rezim == 1) { for (byte i = 0; i<13 ; i++) // zadni LED zhasnout { LED_LZ.setPixelColor(i, zhasnuto); LED_PZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<14 ; i=i+2) // predni LED rozsvitit { LED_PP.setPixelColor(i, bila); LED_LP.setPixelColor(i, bila); } } else { for (byte i = 0; i<13 ; i++) // zadni LED zhasnout { LED_LZ.setPixelColor(i, zhasnuto); LED_PZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<14 ; i++) // predni LED rozsvitit { LED_PP.setPixelColor(i, bila); LED_LP.setPixelColor(i, bila); } LED_PP.setPixelColor(14, slaba_bila); // dve predni krajni LED na kazde strane sviti trvale LED_LP.setPixelColor(14, slaba_bila); LED_PP.setPixelColor(15, slaba_bila); LED_LP.setPixelColor(15, slaba_bila); } } } else { for (byte i = 0; i<13 ; i++) // zadni LED zhasnout { LED_LZ.setPixelColor(i, zhasnuto); LED_PZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<16 ; i++) // predni LED zhasnout { LED_PP.setPixelColor(i, zhasnuto); LED_LP.setPixelColor(i, zhasnuto); } } LED_LZ.show(); LED_LP.show(); LED_PZ.show(); LED_PP.show(); tlacitka(funkce); tlacitka(funkce); tlacitka(funkce); tlacitka(funkce); } void stroboskop(boolean stav) { if (stav == true) { digitalWrite(pin_bzuk, HIGH); // pri blikani zaroven rychle prerusovane pipa piskak for (byte i = 0; i<13 ; i++) // zadni zhasnuto { LED_LZ.setPixelColor(i, zhasnuto); LED_PZ.setPixelColor(i, zhasnuto); } for (byte i = 0; i<16 ; i++) // predni bila { LED_LP.setPixelColor(i, superbila); LED_PP.setPixelColor(i, superbila); } } else { for (byte i = 0; i<13 ; i++) // zadni superruda { LED_LZ.setPixelColor(i, superruda); LED_PZ.setPixelColor(i, superruda); } for (byte i = 0; i<16 ; i++) // predni zhasnuto { LED_LP.setPixelColor(i, zhasnuto); LED_PP.setPixelColor(i, zhasnuto); } } LED_LZ.show(); LED_LP.show(); LED_PZ.show(); LED_PP.show(); tlacitka(funkce); digitalWrite(pin_bzuk, LOW); } void majak(boolean stav) { if (stav == true) { for (byte i = 0; i<13 ; i++) // zadni modra/cervena { LED_LZ.setPixelColor(i, modra); LED_PZ.setPixelColor(i, ruda); } for (byte i = 0; i<16 ; i++) // predni cervena/modra { LED_LP.setPixelColor(i, ruda); LED_PP.setPixelColor(i, modra); } } else { for (byte i = 0; i<13 ; i++) // zadni cervena/modra { LED_LZ.setPixelColor(i, ruda); LED_PZ.setPixelColor(i, modra); } for (byte i = 0; i<16 ; i++) // predni modra/cervena { LED_LP.setPixelColor(i, modra); LED_PP.setPixelColor(i, ruda); } } LED_LZ.show(); LED_LP.show(); LED_PZ.show(); LED_PP.show(); tlacitka(funkce); // pro zpomaleni blikani tlacitka(funkce); tlacitka(funkce); tlacitka(funkce); tlacitka(funkce); tlacitka(funkce); } void test_aku(byte cislo_AKU) { unsigned int napeti1; unsigned int napeti2; napeti1 = analogRead(pin_aku_A); napeti2 = analogRead(pin_aku_Z); if (cislo_AKU == 1) // test aktivniho akumulatoru { if (napeti1 > 850) LED_PZ.setPixelColor(13, slaba_zelena); if (napeti1 > 800 and napeti1 <= 850) LED_PZ.setPixelColor(13, slaba_zluta); if (napeti1 <= 800) LED_PZ.setPixelColor(13, ruda); LED_PZ.setPixelColor(14, zhasnuto); // LED pro zalozni akumulator zustava zhasnuta } if (cislo_AKU == 2) // test zalozniho akumulatoru { if (napeti2 > 850) LED_PZ.setPixelColor(14, slaba_zelena); if (napeti2 > 800 and napeti2 <= 850) LED_PZ.setPixelColor(14, slaba_zluta); if (napeti2 <= 800) LED_PZ.setPixelColor(14, ruda); LED_PZ.setPixelColor(13, zhasnuto); // LED pro aktivni akumulator zustava zhasnuta } LED_PZ.show(); } void aku_zhasni (void) { LED_PZ.setPixelColor(13, zhasnuto); // prvni AKU LED je na 13. pozici prave zadni vetve LED_PZ.setPixelColor(14, zhasnuto); // druha AKU LED je na 14. pozici prave zadni vetve LED_PZ.show(); }