// Create a string of NeoPixels with DIN/DOUT/VSS/VDD connected
// See INSTRUCTIONS at BOTTOM of sketch.
// https://wokwi.com/projects/370606975258496001

int number = 30; // number of NeoPixels in string
int spacing = 20; // space between NeoPixels (20 is best)
int mcu = 100; // places mcu at DIN end of NeoPixel string. (number * spacing) is "far" end

#include <Adafruit_NeoPixel.h>
#define PIN            2          // Arduino PWM pin
#define NUMPIXELS     60          // NeoPixel ring size
#define pixDELAY      50          // Delay for pixel persistence
int i = 0;                        // A counter

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

void setup() {
  Serial.begin(115200);
  pix.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pix.clear(); // Set pixel colors to 'off'

  parts();
  connections();
}

void loop() {
  collide();
  // redgrnfade();
}

void collide()
{
  // RED pixel follows the counter (at the bottom of this function)
  int RED = i;
  pix.setPixelColor (RED, 255, 000, 000);

  // GREEN pixel starts at 1/4 (.25) position on the ring
  int GRN = int(trunc(NUMPIXELS * .25)) - i;
  if (GRN < 0)
    GRN = NUMPIXELS + GRN;
  pix.setPixelColor (GRN, 000, 255, 000);

  // BLUE pixels starts at 1/2 (.5) position on the ring
  int BLU = int(trunc(NUMPIXELS * .5)) + i;
  if (BLU > NUMPIXELS - 1)
    BLU = BLU - NUMPIXELS;
  pix.setPixelColor (BLU, 000, 000, 255);

  // YELLOW pixel starts at 3/4 (.75) position on the ring
  int YEL = int(trunc(NUMPIXELS * .75)) - i;
  if (YEL < 0)
    YEL = abs(NUMPIXELS + YEL);
  pix.setPixelColor (YEL, 255, 255, 0);

  pix.show();
  delay(pixDELAY);

  // BLACK-out the colored pixels
  pix.setPixelColor (RED, 0, 0, 0);
  pix.setPixelColor (GRN, 0, 0, 0);
  pix.setPixelColor (BLU, 0, 0, 0);
  pix.setPixelColor (YEL, 0, 0, 0);

  pix.show(); // show the black-out

  if (i++ == NUMPIXELS - 1)
    i = 0;

  // remove comments to see the values sent to setPixelColor()
  // char buffer[40];
  // sprintf(buffer, "RED %5d | GRN %5d | BLU %5d | YEL %5d", RED, GRN, BLU, YEL);
  // Serial.println(buffer);
}

void redgrnfade()
{
#define pixPIN         2
#define pixCOUNT      NUMPIXELS
#define pixMIN        32
#define pixMAX       255
#define pixSPRK       32
#define pixDELAY       1

  random(analogRead(0));    // random seed

  for (int i = pixMIN; i < pixMAX; i+=10)
  {
    int j = pixMAX - i;
    pix.fill(pix.Color(i, 0, 0),  0, 4);
    pix.fill(pix.Color(0, j, 0),  4, 4);
    pix.fill(pix.Color(i, 0, 0),  8, 4);
    pix.fill(pix.Color(0, j, 0),  12, 4);
    pix.fill(pix.Color(i, 0, 0),  16, 4);
    pix.fill(pix.Color(0, j, 0),  20, 4);
    pix.fill(pix.Color(i, 0, 0),  24, 4);
    pix.fill(pix.Color(0, j, 0),  28, 4);

    if (random(pixSPRK) < 1)
      pix.setPixelColor(random(NUMPIXELS), pixMAX, pixMAX, pixMAX);

    pix.show();
    delay (pixDELAY);
  }

  for (int i = pixMAX; i > pixMIN; i-=10)
  {
    int j = pixMAX - i;
    pix.fill(pix.Color(i, 0, 0),  0, 4);
    pix.fill(pix.Color(0, j, 0),  4, 4);
    pix.fill(pix.Color(i, 0, 0),  8, 4);
    pix.fill(pix.Color(0, j, 0),  12, 4);
    pix.fill(pix.Color(i, 0, 0),  16, 4);
    pix.fill(pix.Color(0, j, 0),  20, 4);
    pix.fill(pix.Color(i, 0, 0),  24, 4);
    pix.fill(pix.Color(0, j, 0),  28, 4);

    if (random(pixSPRK) < 1)
      pix.setPixelColor(random(NUMPIXELS), pixMAX, pixMAX, pixMAX);

    pix.show();
    delay (pixDELAY);
  }
}

void parts() {
  Serial.print("  \"parts\": [ { \"type\": \"wokwi-arduino-nano\", \"id\": \"nano\", \"top\": -100, \"left\": ");
  Serial.print(mcu); // put the mcu at the DIN end of the NeoPixel string
  Serial.println(", \"rotate\": 0, \"attrs\": {} },"); // orient VSS and VDD for clean connection

  for (int i = 1; i < number + 1; i++ ) {
    Serial.print("    { \"type\": \"wokwi-neopixel\", \"id\": \"rgb");
    Serial.print(i);
    Serial.print("\", \"top\": 0, \"left\": ");
    Serial.print(i * spacing + 100);
    Serial.print(", \"rotate\": 270, \"attrs\": {} }"); // remove final comma

    if (i < number)
      Serial.print(","); // add final comma
    Serial.println();
  }
  Serial.println("  ],");
}

void connections() {
  Serial.println("  \"connections\": [");
  for (int i = 1; i < number ; i++ ) { // one less connection than number of neopixels
    Serial.print("  [\"rgb");
    Serial.print(i);
    Serial.print(":DOUT\",\"rgb");
    Serial.print(i + 1);
    Serial.print(":DIN\",\"green\",[\"h5\",\"v-20\"]],");

    Serial.print("[\"rgb");
    Serial.print(i);
    Serial.print(":VSS\",\"rgb");
    Serial.print(i + 1);
    Serial.print(":VSS\",\"black\",[\"h0\"]],");

    Serial.print("[\"rgb");
    Serial.print(i);
    Serial.print(":VDD\",\"rgb");
    Serial.print(i + 1);
    Serial.print(":VDD\",\"red\",[\"v0\"]]");

    if (i < number - 1) // one less connection than number of neopixels
      Serial.print(","); // add final comma when not final line
    Serial.println();
  }
  Serial.println("  ],");
}

/*
  Original diagram.json NOTE: without added NeoPixels and connections:
  {
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [ { "type": "wokwi-arduino-nano", "id": "nano", "top": -100, "left": 100, "attrs": {} } ],
  "connections": [],
  "dependencies": {}
  }

  1. RUN the sketch
  2. COPY the serial monitor output to clipboard
  3. SELECT the diagram.json tab
  4. SELECT the two empty lines: "parts" and "connections" in the diagram.json tab
  5. PASTE from clipboard
  6. CONNECT DIN, VSS or VDD from Arduino to remove extra LineFeed from serial monitor

  EXAMPLE: Modified diagram.json with NeoPixels and connections:
    "parts": [ { "type": "wokwi-arduino-nano", "id": "nano", "top": -90.69, "left": 111.85, "attrs": {} },
    { "type": "wokwi-neopixel", "id": "rgb1", "top": 0, "left": 25, "attrs": {} },
    { "type": "wokwi-neopixel", "id": "rgb2", "top": 0, "left": 50, "attrs": {} },
    { "type": "wokwi-neopixel", "id": "rgb3", "top": 0, "left": 75, "attrs": {} },
    { "type": "wokwi-neopixel", "id": "rgb4", "top": 0, "left": 100, "attrs": {} },
    { "type": "wokwi-neopixel", "id": "rgb5", "top": 0, "left": 125, "attrs": {} }
  ],
  "connections": [
    [ "rgb2:DOUT", "rgb1:DIN", "green", [ "h0" ] ],
    [ "rgb3:DOUT", "rgb2:DIN", "green", [ "h0" ] ],
    [ "rgb4:DOUT", "rgb3:DIN", "green", [ "h0" ] ],
    [ "rgb5:DOUT", "rgb4:DIN", "green", [ "h0" ] ]
  ],
*/