Kysymys:
Digitaalinen RGB-LED-animaatio
Rhys Edwards
2014-03-14 15:41:10 UTC
view on stackexchange narkive permalink

Olen yrittänyt saada värit haalistumaan toisiinsa projektissa, jossa työskentelen. Olen saavuttanut tämän sateenkaarivaikutuksella, jonka jotkut Adafruitin esimerkkikoodista, mutta haluan pystyä valitsemaan värit ( esim. tummansinisestä vaaleansiniseksi).

Minun värit muuttuvat ja haalistuvat, mutta häipyminen sammuttaa kaikki LEDit ja alkaa lisätä uuden värin kirkkautta. Tarvitsen värien sekoittumisen eikä haalistumista ja kirkkauden lisäämistä.

Voiko kukaan osoittaa minua oikeaan suuntaan?

  #include "LPD8806.h" #include "SPI.h" #define stripSize 64int nLEDs = 160; int dataPin = 2; int clockPin = 3; // Ensimmäinen parametri on säikeessä olevien LEDien määrä. LED-nauhat // ovat 32 LEDiä metriä kohden, mutta voit pidentää tai leikata nauhaa. Seuraavat kaksi // -parametria ovat SPI-tiedot ja kellonastat: LPD8806 strip = LPD8806 (64, dataPin, clockPin); // Voit halutessasi käyttää laitteisto-SPI: tä nopeammin kirjoittamiseen, jätä vain // tiedot ja kellonastan parametrit. Mutta tämä rajoittaa käyttöä hyvin // tiettyihin nastoihin Arduinossa. "Klassisille" Arduinosille (Uno, Duemilanove, // jne.) Data = nasta 11, kello = nasta 13. Arduino Megalle data = nasta 51, // kello = nasta 52. 32u4 Breakout Board +: n ja Teensyn osalta data = tappi B2, // kello = tappi B1. Leonardolle tämä voidaan tehdä VAIN ICSP-nastoilla .//LPD8806 strip = LPD8806 (nLEDs); void setup () {// Käynnistä LED-nauhan nauha.begin (); // Päivitä nauha, aloittaaksesi, ne kaikki ovat 'pois' strip.show ();} void loop () {//turnAllOn(strip.Color(30,30,30),4000); haalistuvat (0, 127, 0, 100); // punainen, vihreä, sininen, viive - häivyttää kaikki pikselit yksivärisenä //turnAllOn(strip.Color(30,100,30),4000); haalistuvat (50, 127, 02 100); // punainen, vihreä, sininen, viive - häivyttää kaikki pikselit yksivärisenä //turnAllOn(strip.Color(100,30,100),4000); haalistuvat (50, 127, 50, 100); // punainen, vihreä, sininen, viive - häivyttää kaikki pikselit yhtä väriä} void fade (uint32_t r, uint32_t g, uint32_t b, uint32_t wait) {int i, j; (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) )); } strip.show (); } delay (wait);} void turnAllOn (uint32_t c, uint32_t wait) {int i; for (i = 0; i < strip.numPixels (); i ++) {strip.setPixelColor (i, c); // käännä kaikki pikselit päälle} strip.show (); // kirjoita kaikki pikselien viive (odota); } uint32_t Pyörä (uint16_t WheelPos) {tavu r, g, b; kytkin (WheelPos / 128) {tapaus 0: r = 127 - WheelPos% 128; // Punainen alas g = WheelPos% 128; // Vihreää b = 0; // sininen pois tauko; tapaus 1: g = 127 - WheelPos% 128; // vihreä alas b = WheelPos% 128; // sininen ylös r = 0; // punainen pois tauko; tapaus 2: b = 127 - WheelPos% 128; // sininen alas r = WheelPos% 128; // punainen ylös g = 0; // vihreä pois tauko; } return (strip.Color (r, g, b));}  
üks vastaus:
#1
+6
Peter Bloomfield
2014-03-14 16:36:48 UTC
view on stackexchange narkive permalink

Häivytystoimintosi alkaa tällä hetkellä 0: sta ja interpoloi tehokkaasti haluttuun väriin asti. Häivyäkseen värien välillä, sinun on luonnos muistettava edellinen väri, jota se käytti, ja alkanut hiipua siitä 0: n sijasta.

Käytän lähestymistapaa aluksi laskemalla, kuinka paljon kukin komponentti on on muutettava jokaisessa vaiheessa. Esimerkiksi, jos haluat häivyttää 100: sta 200: een 50 askelta kohti, sen on muututtava +2: lla jokaisessa vaiheessa. Jos haluat tehdä saman päinvastaisessa järjestyksessä (200-100), sen on muututtava -2: llä.

Yksi ongelmista on, että kukin komponentti todennäköisesti muuttuu eri määrällä (punainen saattaa siirry 0: sta 200: een, mutta sininen saattaa mennä vain 50: stä 70: een). Jos käytät kokonaislukuja koko ajan, se voi johtaa epätasaisiin siirtymiin, joten suosittelen käyttämään liukulukua. Se on teknisesti hitaampi (vähemmän tehokas), mutta ei todennäköisesti riitä huolehtimiseen.

Näin luulen todennäköisesti kirjoittavan sen:

  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) {// Varo jakamista nollalla, jos (numSteps == 0) numSteps = 1; // Laske kuinka paljon jokaisen värin on muutettava jokaisessa vaiheessa const float stepR = (newR - oldR) / (float) numSteps, stepG = (newG - oldG) / (float) numSteps, stepB = (newB - oldB) / (float) numSteps; // Nämä arvot tallentavat värejä matkalla kellumaan r = oldR, g = oldG, b = oldB; uint8_t tavuR = vanhaR, tavuG = vanhaG, tavuB = vanhaB; // Käy läpi jokaisen haalistumisvaiheen const uint16_t numPixels = strip.numPixels (); for (uint32_t step = 0; step < numSteps; ++ step) {// Siirrä yksi askel kohti kohdeväriä r + = stepR; g + = vaihe G; b + = vaihe B; // Pyöritä värit tässä kokonaislukuiksi, joten meidän ei tarvitse tehdä sitä toistuvasti alla olevassa silmukassa tavuR = (uint8_t) (r + 0.5f);
tavu G = (uint8_t) (g + 0,5f); tavuB = (uint8_t) (b + 0,5f); // Levitä väri jokaiselle pikselille (uint16_t pikseli = 0; pikseli < numPixels; ++ pikseli) {strip.setPixelColor (pikseli, tavuR, tavuG, tavuB); } strip.show (); delay (waitPerStep); }}  

Kuten näette, välität sille vanhan värin (josta haalistat ) ja uuden värin (jonka haalistat - ). Kuten edellä mainitsin, tämä tarkoittaa, että luonnoksesi on muistettava, mitä väriä se on aiemmin käyttänyt, koska en usko, että kirjasto tarjoaa tapaa lukea nykyinen väri takaisin.

Olen sisällyttänyt joitain optimointeja siellä, jotta se toimisi nopeammin. Voit tehdä enemmän optimoidaksesi sen entisestään tarvittaessa.

Voit käyttää tätä tekemällä jotain tällaista:

  // Häivy mustasta punaiseksi ja keskeytä hetkeksi häivytys (0, 0, 0, 255, 0, 0, 100, 10); viive (500); // Häivy punaisesta purppuraan ja tauko lyhytaikaisesti (255, 0, 0, 255, 0, 255, 100 , 10); delay (500); // Häivytys violetista vihreään ja tauko lyhyt häivytys (255, 0, 255, 0, 255, 0, 100, 10); delay (500);  

Olen tehnyt muutamia muita muutoksia omaan haalistumistoimintoosi verrattuna. Ensinnäkin, olen tehnyt sen niin, että voit määrittää vaiheiden määrän, josta hiipuu. Tämä voi olla varsin hyödyllistä, koska suuremmat värimuutokset vaativat enemmän vaiheita, jotta ne näyttävät sujuvilta.

Olen myös muokannut parametria wait . Koodiin laitat viiveen koko haalistumisen jälkeen, mikä vaikuttaa oudolta. On järkevämpää sallia pieni viive jokaisen haalistumisvaiheen välillä, jotta voit hallita, kuinka nopeasti se menee.

Yllä olevassa esimerkissä näet 100, 10 -parametrit jokaisen fade () -kutsun lopussa. Tämä tarkoittaa, että se jakaa värimuutoksen 100 vaiheeseen viiveellä 10 ms jokaisen vaiheen välillä. Tuloksena on, että jokainen häipyminen kestää noin yhden sekunnin (lukematta LED-nauhan päivittämiseen kuluvaa aikaa).

Erittäin hyvin vastattu. Kiitos kaikista kooditiedoista, optimoinnista ja selityksistä. Ehkä pieni virhe: väristä alkaen ei tule näkyviin, kun aloitat silmukan ensimmäisen vaiheen lisäyksellä. Lisää vielä yksi iterointi ja lisäys vain silmukan loppuun.
@jfpoilpret Kiitos. Ensimmäisen vaiheen puuttuminen on todella tarkoituksellista. Kysymyksen perusteella oletan, että LEDit osoittavat jo `` vanhan '' värin ennen kuin `` fade () '' kutsutaan. Olet kuitenkin aivan oikeassa. Muissa olosuhteissa saatat todella haluta tuon lisäaskeleen.
Tämä on todella hienoa. Kiitos paljon yksityiskohdista!


Tämä Q & A käännettiin automaattisesti englanniksi.Alkuperäinen sisältö on saatavilla stackexchange-palvelussa, jota kiitämme cc by-sa 3.0-lisenssistä, jolla sitä jaetaan.
Loading...