Axiometa
Round 289x NeoPixel Display
Round 289x NeoPixel Display
SKU:DSP0002
Regular price
$25.39
Regular price
Sale price
$25.39
Unit price
per
Taxes included.
Shipping calculated at checkout.
Couldn't load pickup availability




-
Pinout
-
Interface
PCB Design
-
Top
-
Bottom
Arduino Example Code
/*
* Circular 289-pixel matrix demo – v2
* — brightness capped & multi-animation playlist —
* Hardware: WS2812 / SK6812 on pin 6
*/
#include <FastLED.h>
// ---------- layout tables ----------
#define NUM_ROWS 21
const uint8_t rowCount[NUM_ROWS] = { 5, 9, 11, 13, 15, 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 15, 15, 13, 11, 9, 5 };
const uint8_t rowOffset[NUM_ROWS] = { 6, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 6 };
const uint16_t prefix[NUM_ROWS] PROGMEM = {
0, 5, 14, 25, 38, 53, 68, 85, 102, 119, 136,
153, 170, 187, 204, 221, 236, 251, 264, 275, 284
};
#define INVALID 0xFFFF
uint16_t XY(uint8_t x, uint8_t y) {
if (y >= NUM_ROWS || x < rowOffset[y] || x >= rowOffset[y] + rowCount[y]) return INVALID;
return pgm_read_word_near(prefix + y) + (x - rowOffset[y]);
}
// ---------- FastLED setup ----------
#define DATA_PIN 6
#define NUM_LEDS 289
#define BRIGHTNESS 20 // *your* requested cap
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
FastLED.show();
}
// ---------- tiny drawing helpers ----------
inline void setPixel(int x, int y, const CRGB& c) {
uint16_t i = XY(x, y);
if (i != INVALID) leds[i] = c;
}
void drawFilledCircle(int cx, int cy, int r, const CRGB& c) {
for (int y = -r; y <= r; y++)
for (int x = -r; x <= r; x++)
if (x * x + y * y <= r * r) setPixel(cx + x, cy + y, c);
}
void drawLine(int x0, int y0, int x1, int y1, const CRGB& c) {
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1, err = dx + dy, e2;
while (true) {
setPixel(x0, y0, c);
if (x0 == x1 && y0 == y1) break;
e2 = 2 * err;
if (e2 >= dy) {
err += dy;
x0 += sx;
}
if (e2 <= dx) {
err += dx;
y0 += sy;
}
}
}
// ----- BIGGER, smoother heart outline -----
void drawHeart(int cx, int cy, float scale, const CRGB& c) {
const float K = 0.50f * scale; // 0.50 maps 32-unit maths → 16 px LEDs
for (float t = 0; t < TWO_PI; t += 0.02) // finer step = smoother curve
{
float x = 16 * pow(sin(t), 3);
float y = 13 * cos(t) - 5 * cos(2 * t)
- 2 * cos(3 * t) - cos(4 * t);
setPixel(cx + int(x * K + 0.5f),
cy - int(y * K + 0.5f), c);
}
}
// ------------- individual animations --------------
void drawSad() {
drawFilledCircle(8, 10, 8, CRGB::Yellow);
// eyes
drawFilledCircle(6, 7, 1, CRGB::Black);
drawFilledCircle(10, 7, 1, CRGB::Black);
// upside-down mouth
for (int x = -5; x <= 5; x++) {
int y = int(sqrt(25 - x * x));
setPixel(8 + x, 12 + y / 2, CRGB::Black);
}
}
void drawHappy(uint32_t now) {
static bool blink = false; // blink state toggles each second
static uint32_t last = 0;
if (now - last > 1000) {
blink = !blink;
last = now;
}
drawFilledCircle(8, 10, 8, CRGB::Yellow);
if (blink) {
// closed eyelids
drawLine(5, 7, 7, 7, CRGB::Black);
drawLine(9, 7, 11, 7, CRGB::Black);
} else {
drawFilledCircle(6, 7, 1, CRGB::White);
drawFilledCircle(10, 7, 1, CRGB::White);
setPixel(6, 7, CRGB::Black);
setPixel(10, 7, CRGB::Black);
}
// smile
for (int x = -5; x <= 5; x++) {
int y = int(sqrt(25 - x * x));
setPixel(8 + x, 14 - y / 2, CRGB::Black);
}
}
void drawHeartPulse(uint32_t now) {
uint8_t bri = beatsin8(30, 40, 255, 0, now >> 2); // gentle breathing
CRGB col = CRGB(bri, 0, 0);
drawHeart(8, 10, 1.0, col);
}
void drawSwirl(uint32_t now) {
static uint8_t base = 0;
base += 1; // hue shift
for (uint8_t y = 0; y < NUM_ROWS; y++) {
for (uint8_t x = rowOffset[y]; x < rowOffset[y] + rowCount[y]; x++) {
uint16_t idx = XY(x, y);
if (idx == INVALID) continue;
uint8_t hue = (base + (x * 6) + (y * 10)) & 0xFF;
leds[idx] = CHSV(hue, 255, 255);
}
}
}
// ------------- playlist machinery ----------------
typedef void (*AnimFunc)(uint32_t);
const AnimFunc animations[] = {
[](uint32_t) {
drawSad();
},
drawHappy,
drawHeartPulse,
drawSwirl
};
const uint8_t NUM_ANIMS = sizeof(animations) / sizeof(animations[0]);
constexpr uint32_t ANIM_DURATION_MS = 5000;
uint8_t currentAnim = 0;
uint32_t animStart = 0;
void loop() {
uint32_t now = millis();
// time to switch animation?
if (now - animStart > ANIM_DURATION_MS) {
animStart = now;
currentAnim = (currentAnim + 1) % NUM_ANIMS;
FastLED.clear();
}
// draw the current frame
animations[currentAnim](now);
FastLED.show();
FastLED.clear(); // clear for next frame
}
Guides and Blogs
-
First time setup
Pair text with an image to focus on your chosen product, collection, or blog post. Add details on availability, style, or even provide a review.
-
Automatic Street Lights
Pair text with an image to focus on your chosen product, collection, or blog post. Add details on availability, style, or even provide a review.
-
How Does an LDR work ?
Pair text with an image to focus on your chosen product, collection, or blog post. Add details on availability, style, or even provide a review.