Küsimus:
Digitaalne RGB LED-animatsioon
Rhys Edwards
2014-03-14 15:41:10 UTC
view on stackexchange narkive permalink

Olen proovinud, et projektid, millega töötan, värvid üksteisesse tuhmuksid. Olen selle saavutanud vikerkaareefektiga, mida mõned Adafruiti näidiskoodist näevad, kuid siiski soovin, et saaksin neid värve valida ( nt tumesinine helesinine).

Mul on värvid muutumas ja tuhmumas, kuid tuhmumine lülitab kõik LED-id välja ja hakkab uue värvi heledust suurendama. Mul on vaja, et värvid seguneksid, mitte ei hajuks ega suureneks heledust.

Kas keegi suudab mind õiges suunas suunata?

  #include "LPD8806.h" #include "SPI.h" #define stripSize 64int nLEDs = 160; int dataPin = 2; int clockPin = 3; // Esimene parameeter on ahelas olevate LED-ide arv. LED-ribad // on 32 LED-i meetri kohta, kuid saate riba pikendada või lõigata. Järgmised kaks // parameetrit on SPI andmed ja kella tihvtid: LPD8806 strip = LPD8806 (64, dataPin, clockPin); // Kiirema kirjutamise jaoks saate kasutada riistvara SPI-d, lihtsalt jätke välja // andmete ja kella tihvti parameetrid. Kuid see piirab kasutamist Arduino väga spetsiifiliste tihvtidega. Klassikaliste Arduinode (Uno, Duemilanove, // jne) puhul on andmed = tihvt 11, kell = tihvt 13. Arduino Mega puhul andmed = tihvt 51, // kell = tihvt 52. 32u4 Breakout Board + ja Teensy puhul andmed = tihvt B2, // kell = tihvt B1. Leonardo puhul saab seda teha AINULT ICSP-tihvtidel .//LPD8806 strip = LPD8806 (nLEDs); void setup () {// Käivitage LED-riba riba.begin (); // Värskendage riba, alustamiseks on nad kõik välja lülitatud strip.show ();} void loop () {//turnAllOn(strip.Color(30,30,30),4000); tuhmuma (0, 127, 0, 100); // punane, roheline, sinine, viivitus - tuhmuvad kõik pikslid ühevärvilisena //turnAllOn(strip.Color(30,100,30),4000); tuhmuma (50, 127, 02,100); // punane, roheline, sinine, viivitus - tuhmuvad kõik pikslid ühevärvilisena //turnAllOn(strip.Color(100,30,100),4000); tuhmuma (50, 127, 50, 100); // punane, roheline, sinine, viivitus - tuhmuvad kõik pikslid ühte värvi} void fade (uint32_t r, uint32_t g, uint32_t b, uint32_t wait) {int i, j; jaoks (j = 0; j < 384; j ++) {
for (i = 0; i < strip.numPixels (); i ++) {strip.setPixelColor (i, strip.Color ((r * j) / 1000, (g * j) / 1000, (b * j) / 1000) )); } riba.show (); } delay (wait);} void turnAllOn (uint32_t c, uint32_t wait) {int i; for (i = 0; i < strip.numPixels (); i ++) {strip.setPixelColor (i, c); // lülita kõik pikslid sisse} strip.show (); // kirjuta kõik pikslite väljaviivitus (oota); } uint32_t ratas (uint16_t WheelPos) {bait r, g, b; lüliti (WheelPos / 128) {juhtum 0: r = 127 - WheelPos% 128; // punane värv g = WheelPos% 128; // roheline kuni b = 0; // sinine väljalülitus; juhtum 1: g = 127 - WheelPos% 128; // roheline all b = WheelPos% 128; // sinine üles r = 0; // punane väljalülitus; 2. juhtum: b = 127 - WheelPos% 128; // sinine alla r = WheelPos% 128; // punane üles g = 0; // roheline väljalülitus; } return (riba.Värv (r, g, b));}  
üks vastus:
Peter Bloomfield
2014-03-14 16:36:48 UTC
view on stackexchange narkive permalink

Praegu algab teie tuhmumisfunktsioon 0-st ja efektiivselt interpoleeritakse soovitud värvini. Värvide vahel tuhmumiseks vajate visandit, et see mäletaks eelmist värvi, mida see kasutas, ja alustaks sellest tuhmumist 0 asemel.

Kasutaksin lähenemist, et arvutada, kui palju iga komponent peab igal sammul muutuma. Näiteks kui soovite 50 sammu ulatuses tuhmuda 100-lt 200-le, peab see igal sammul muutuma +2 võrra. Kui soovite sama teha vastupidises suunas (200 kuni 100), peaks see muutuma -2 võrra.

Üks probleemidest on see, et tõenäoliselt muutub iga komponent erineva summa võrra (punane võib 0 kuni 200, kuid sinine võib minna ainult 50 kuni 70). Kui kasutate kogu aeg täisarvusid, võib see põhjustada ebaühtlaseid üleminekuid, nii et soovitaksin selle asemel kasutada ujukoma. See on tehniliselt aeglasem (vähem efektiivne), kuid tõenäoliselt pole sellest muretsemiseks piisavalt.

Ma kirjutan selle tõenäoliselt nii:

  void fade (uint8_t oldR, uint8_t oldG, uint8_t oldB, uint8_t newR, uint8_t newG, uint8_t newB, uint32_t numSteps, uint32_t waitPerStep) {// Kaitse nulliga jagamise eest, kui (numSteps == 0) numSteps = 1; // Arvutage, kui palju peab iga värv muutuma igal sammul const float stepR = (newR - oldR) / (float) numSteps, stepG = (newG - oldG) / (float) numSteps, stepB = (newB - oldB) / (ujuk) numSteps; // Need väärtused salvestavad meie värvid teel ujukile r = oldR, g = oldG, b = oldB; uint8_t baitR = vanaR, baitG = vanaG, baitB = vanaB; // Käige läbi kõik fade-sammud const uint16_t numPixels = strip.numPixels (); for (uint32_t step = 0; step < numSteps; ++ step) {// Liiguta üks samm sihtvärvi r + = stepR suunas; g + = sammG; b + = samm B; // Ümardage värvid siin täisarvudeks, nii et me ei pea seda korduvalt tegema allpool olevas silmus byteR = (uint8_t) (r + 0.5f);
baitG = (uint8_t) (g + 0,5f); baitB = (uint8_t) (b + 0,5f); // Rakendage igale pikslile värv (uint16_t pixel = 0; pixel < numPixels; ++ pixel) {strip.setPixelColor (pixel, byteR, byteG, byteB); } riba.show (); viivitus (waitPerStep); }}  

Nagu näete, edastate sellele vana värvi (mille te tuhmute ) ja uue värvi (mida te tuhmite kuni ). Nagu ma eespool mainisin, tähendab see, et teie visand peab meeles pidama, millist värvi see varem kasutas, kuna ma ei usu, et teek pakub võimalust praegust värvi tagasi lugeda.

Lisasin mõned optimeerimised seal, et see kiiremini töötaks. Vajaduse korral saate selle optimeerimiseks veelgi teha.

Selle kasutamiseks peate tegema midagi sellist:

  // tuhmuma mustast punaseks ja paus lühidalt tuhmuma (0, 0, 0, 255, 0, 0, 100, 10); viivitus (500); // Hajub punasest lillani ja paus lühiajaliselt (255, 0, 0, 255, 0, 255, 100 , 10); delay (500); // Hajub lillalt rohelisele ja paus lühidalt hajub (255, 0, 255, 0, 255, 0, 100, 10); delay (500);  

Olen võrreldes teie enda tuhmumisfunktsiooniga teinud paar muud muudatust. Esiteks olen selle teinud nii, et saaksite seada sammude arvu, mis kustuvad. See võib olla üsna kasulik, sest suuremate värvimuutuste jaoks on sujuva väljanägemise jaoks vaja rohkem samme.

Olen muutnud ka parameetrit wait . Oma koodis panite viivituse pärast kogu hääbumise lõppu, mis tundub veider lähenemine. Mõistlikum on lubada iga viivitusetapi vahel väike viivitus, et saaksite kontrollida, kui kiiresti see kulgeb.

Minu ülaltoodud näites näete iga fade () -kõne lõpus parameetreid 100, 10 . See tähendab, et see jagab värvimuutuse 100 sammuks, viivitades iga sammu vahel 10 ms. Tulemuseks on see, et iga tuhmumine võtab umbes 1 sekundi (arvestamata LED-riba reaalseks värskendamiseks kuluvat aega).

Väga hästi vastatud. Au kõik koodi üksikasjad, optimeerimised ja selgitused. Võib-olla väike viga: alates värvist ei ilmu kunagi, kui alustate oma tsüklit esimese sammuga. Ainult tsükli lõppu peaksite lisama veel ühe iteratsiooni ja juurdekasvu.
@jfpoilpret Aitäh. Esimese sammu kaotamine on tegelikult tahtlik. Küsimuse põhjal eeldan, et valgusdioodid näitavad juba "vana" värvi, enne kui nimetatakse "fade ()". Sul on siiski täiesti õigus. Muudel asjaoludel võite tõesti soovida seda täiendavat sammu.
See on tõesti suurepärane. Suur tänu üksikasjaliku kirjutamise eest!


See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...