sunnuntai 23. lokakuuta 2016

LEDimatriisi pähkinäpuukotelossa

Pahoitteluni, en ole tänä syksynä kerennyt puuhastelemaan juurikaan harrastusten parissa, joten blogikin on jäänyt orvoksi. Perustamani yritys, perhe-elämä, muutama työn alla oleva nettisivusto, järjestötoiminta ja opiskelu ovat vieneet kaiken aikani varsin tehokkaasti. Huomennakin olisi analogia- ja tehoelektroniikan tentti, mutta jotenkin kummasti löydän itseni kirjoittamasta tätä opiskelun sijaan :D

Matriisia pitäisi saada laskettua alemmas, että hiottu pleksi taittaisi valoa kivemmin. Vähän ahdasta rasiassa on, mutta kyllä se onnistunee jos taivuttaa pinnejä 90 asteen kulmaan.




Asiaan. Nurkissani on pyörinyt monta vuotta sitten tekemäni puolivalmis pähkinäpuinen rasia, jolle en oikein ole keksinyt käyttöä. Keksin istuttaa siihen Arduino Nanon ja 8x8 pisteen LEDmatriisin suunnitellessani jonkunlaista sääasemaa kesällä. Laitoin rasiaan kannen leikkamalla sopivan palasen kirkasta pleksimuovia ja hiomalla sen mattapintaiseksi. En tiedä tuleeko tästä koskaan sääasema, mutta ainakin rasia on nyt valmis ja siinä vilkkuu nättejä valoja:

Gif-kuva ei oikein tee oikeutta ultra-smoothille sinifunktiolleni.



Koodasin FastLED-kirjaston avulla yksinkertaisen ohjelman, joka piirtää y-akselille pikselin sinifunktiolla ja siirtää x-akselin positiota sinifunktion nollakohdassa seuraavalle riville. Pikseli ei sammu saman tien seuraavaan siirryttäessä, vaan himmenee asteittain jättäen coolin jäljen tyyliin Ritari Ässän KITT.



#include "FastLED.h"

FASTLED_USING_NAMESPACE

#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif

#define DATA_PIN    3
//#define CLK_PIN   4
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB

const uint8_t kMatrixWidth  = 8; // LED-matriisin leveys
const uint8_t kMatrixHeight = 8; // LED-matriisin korkeus
const bool    kMatrixSerpentineLayout = false; // Onko LEDit järjestetty zigzag-tyyliin vai ei

#define NUM_LEDS (kMatrixWidth * kMatrixHeight) // LEDien lukumäärä (64 8x8 -matriisissa)
CRGB leds[NUM_LEDS]; // Alusta LED-oliot

#define BRIGHTNESS          30 // Kirkkaus
#define FRAMES_PER_SECOND  120 // Ruudunpäivitysnopeus

void setup() {
  delay(1500); // Anna 1,5s aikaa käynnistyä

  FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); // Lisää LEDit
  FastLED.setBrightness( BRIGHTNESS );

}

uint8_t gHue = 0; // Värisävyn alustus
int x = 0; // x-position alustus
bool siirretty = false; // Onko x-positiota jo siirretty -muuttujan alustus

void loop() {
  sini(); // Mene funktioon sini()
  FastLED.show(); // Piirrä LEDit
  FastLED.delay(1000 / FRAMES_PER_SECOND); // Odottele

  EVERY_N_MILLISECONDS( 20 ) { // Muuta värisävyä 20 ms välein
    gHue++;
  }
}

void sini() { // LEDien liikutusfunktio

  fadeToBlackBy( leds, NUM_LEDS, 20); // Jättää hienot feidaavat jäljet
  int y = beatsin16(120, 0, kMatrixHeight); // Määritä y-positio sinifunktiolla 120 beats/min välillä 0 - 8 
  leds[ XY(x, y)] += CHSV( gHue, 255, 192); // Päivitä LEDi positiossa x, y (hae indeksi funktiolla XY)

  if ( (y == (kMatrixHeight - 1) && siirretty == false) ) // Jos ollaan rivin lopussa ja x-positiota ei olla vielä siirretty
  {
    x++; // lisää 1 x-positioon
    siirretty = true; // Merkkaa että siirto on tehty
  }
  if ( y == 0 ) { siirretty = false; } // Jos on palattu takaisin rivin alkuun, nollaa x-position siirto
  if (x >= kMatrixWidth) { x = 0; } // Jos x:n arvo on isompi kuin matriisin leveys, siirrä x-positio kohtaan 0
} // sini() loppuu

uint16_t XY( uint8_t x, uint8_t y) // Muuntaa x- ja y-koordinaatit ledin indeksinumeroksi
{
  uint16_t i;

  if ( kMatrixSerpentineLayout == false) {
    i = (y * kMatrixWidth) + x;
  } else {
    if ( y & 0x01) {
      // Odd rows run backwards
      uint8_t reverseX = (kMatrixWidth - 1) - x;
      i = (y * kMatrixWidth) + reverseX;
    } else {
      // Even rows run forwards
      i = (y * kMatrixWidth) + x;
    }
  }
  return i; // Palauta indeksinumero
}

Tunnelmavalon lisäksi tällä ei tämmöisenään oikein ole käyttöä, mutta koodaamallahan saa tehtyä mitä huvittaa. Esimerkiksi uusista sähköposteista tai somekommenteista ilmoittava valo olisi aika hieno, tosin minun käytössäni se vilkkuisi koko ajan. Onni (3v) kysyi heti rasian nähdessään että "Onko se peli?". Oikeastaan tästä saisikin aika hienon pelin kun lisäisi potentiometrin ja pari nappia. Esimerkiksi Space Invader -tyylinen viritelmä voisi toimia. Plus olisi aika hienoa voida sanoa, että on rakentanut itse oman pelikonsolin ja sille pelejä :D.

3 kommenttia:

  1. Vastaukset
    1. hmm :D eikös trendi ole silläkin sektorilla kohti HD-resoluutiota?

      Poista
    2. hmm :D eikös trendi ole silläkin sektorilla kohti HD-resoluutiota?

      Poista