Sara
Sara

Reputation: 29

How do we mirror two 8x8 Adafruit NeoPixels so that they are synced and showing the same design?

We are trying to code two Adafruit 8x8 NeoPixels, but only one of them is lighting up with our designated pattern. We want the other one to mirror the same pattern, but the code we have isn't working. We tried to make it so that Arduino understands it as one 128 grid board, but we can't figure that out.

We would appreciate any insight.

#include <Adafruit_NeoPixel.h>

#define PIN 6          // Pin where NeoPixel is connected
#define NUMPIXELS 128  // Number of pixels in 8x8 grid * 2
#define GRID_WIDTH 8   // Width of the grid

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

// Define colors
uint32_t WHITE = pixels.Color(255, 255, 255);
uint32_t YELLOW = pixels.Color(255, 236, 39);
uint32_t MUSTARD = pixels.Color(255, 163, 0);
uint32_t ORANGE = pixels.Color(171, 82, 59);
uint32_t PURPLE = pixels.Color(126, 37, 83);
uint32_t OFF = pixels.Color(0, 0, 0);

// Define an 8x8 color pattern using variables
uint32_t color_pattern[8][8] = {
    {OFF, OFF, OFF, ORANGE, OFF, OFF, OFF, OFF},
    {OFF, OFF, PURPLE, MUSTARD, PURPLE, OFF, OFF, OFF},
    {OFF, PURPLE, MUSTARD, YELLOW, MUSTARD, PURPLE, OFF, OFF},
    {ORANGE, MUSTARD, YELLOW, WHITE, YELLOW, MUSTARD, ORANGE, OFF},
    {OFF, PURPLE, MUSTARD, YELLOW, MUSTARD, PURPLE, OFF, OFF},
    {OFF, OFF, PURPLE, MUSTARD, PURPLE, OFF, OFF, OFF},
    {OFF, OFF, OFF, ORANGE, OFF, OFF, OFF, OFF},
    {OFF, OFF, OFF, OFF, OFF, OFF, OFF, OFF}
};

int posX = 0;  // Initial X position
int posY = 0;  // Initial Y position

void setup() {
  pixels.begin(); // Initialize NeoPixel library
}

void drawPattern(int offsetX, int offsetY) {
  pixels.clear();

  for (int y = 0; y < 8; y++) {
    for (int x = 0; x < 8; x++) {
      int pos1 = (y + offsetY) * GRID_WIDTH + (x + offsetX);
      int pos2 = pos1 + 64; // The second grid starts after the first 64 pixels
      if (pos1 >= 0 && pos1 < 64) {  // Ensure within first grid bounds
        pixels.setPixelColor(pos1, color_pattern[y][x]); // Set each pixel to its respective color
      }
      if (pos2 >= 64 && pos2 < 128) {  // Ensure within second grid bounds
        pixels.setPixelColor(pos2, color_pattern[y][x]); // Set each pixel to its respective color for the second grid
      }
    }
  }
  pixels.show();
}

void loop() {
  pixels.setBrightness(40);
  drawPattern(posX, posY); 
  delay(500); // Delay to see movement

  // Update position
  posX += 1; // Move right
  if (posX > GRID_WIDTH - 8) { // If at the right edge, move down and reset X
    posX = 0;
    posY += 1;
  }
  if (posY > GRID_WIDTH - 8) { // If at the bottom edge, reset Y
    posY = 0;
  }
}

enter image description here

Upvotes: 1

Views: 57

Answers (2)

Dimitre L
Dimitre L

Reputation: 3

The best way of repeating the same data for the two panels would be splitting the wire connecting the arduino to the DIN in two, and connecting to the DIN of both panels. if you want to keep in series as it is in the first picture, you should use 256 pixels and repeat the same data twice.

Upvotes: 0

Craig Estey
Craig Estey

Reputation: 33631

Caveat: All this comes from a cursory examination of the Adafruit_NeoPixel git repo: https://github.com/adafruit/Adafruit_NeoPixel.git

Instead of trying to combine both displays into one, I'd keep them separate. This is more intuitive. And, we only need to call [the slow(?)] setPixelColor once for each pixel we want to fill.

Then, we could copy the pixel data using memcpy from one instance to the other.

In the class, there are two fields of interest:

  1. pixels -- pointer to raw pixel data (access function: GetPixels)
  2. numBytes -- number of bytes in pixels (no access function)

These fields are protected, and since [AFAICT] there is no access function for numBytes, we need to create our own class that inherits from Adafruit_Neopixel to get such access.

Loosely, we can do:

  1. Create separate instances of each display
  2. Draw into one instance (the primary)
  3. Copy the pixel data from the primary to the mirror
  4. Do begin() and show() on each

Here is some [badly written] pseudo code:

// NOTE: pixels and numBytes are protected members of Adafruit_NeoPixel, so we
// must inherit from it
struct mypix : public Adafruit_NeoPixel {
    // AFAICT, there is _no_ exported public function for this
    uint16_t
    myGetBytes(void)
    {
        return numBytes;
    }

    // There _is_ a public for this: getPixels
    uint8_t *
    myGetBuf(void)
    {
#if 0
        return pixels;
#else
        return Getpixels();
#endif
    }
};

// [bad] pseudo code
mypix pix_primary(NUMPIXELS, 6, NEO_GRB + NEO_KHZ800);
mypix pix_mirror(NUMPIXELS, 7, NEO_GRB + NEO_KHZ800);

// copy_all_data -- copy pixel data from one instance/display to another
void
copy_all_data(mypix *pdst,const mypix *psrc)
{
    uint16_t bytelen = pdst->myGetBytes();

    assert(bytelen == psrc->myGetBytes());

    memcpy(pdst->myGetBuf(),psrc->myGetBuf(),bytelen);
}

// draw_all_data -- draw all desired data
void draw_all_data(mypix *pix);

void
draw_frame()
{

    pix_primary.begin();
    pix_mirror.begin();

    draw_all_data(&pix_primary);
    copy_all_data(&pix_mirror,&pix_primary);

    pix_primary.show();
    pix_mirror.show();
}

Upvotes: 1

Related Questions