Objectives For This Project:
Throughout the Neopixel assignment, I learned how to create a circuit board on TinkerCAD. In the process of assembling one, I learned what a power supply, Neopixel strip, and Arduino Uno R3 board is. This also required me to be able to find them in the TinkerCAD components database. I also learned that accuracy is important in the process of building the circuit and connecting the wires. Originally, I did not connect the black wire to GND and thus my simulation did not complete. Similarly, I also learned that accuracy in my code is crucial. At first, I did not delete the prior code and added the potential code under it. That caused there to be bugs in the code and the inability for the simulation to run. After successfully simulating the circuit, I figured out how to read the power supply.
Launched by Seeed Studio, the thumb-sized board is the world's smallest RP2040 board similar to XIAO BLE NRF52840 and XIAO ESP32-C3
Pinout: There are 14 GPIO PINs on Seeed Studio XIAO RP2040, on which there are 11 digital pins, 4 analog pins, 11 PWM Pins,1 I2C interface, 1 UART interface, 1 SPI interface, and 1 SWD Bonding pad interface.
The board supports Arduino, Micropython, and CircuitPython programming
TinkerCAD Model:
↪ Testing successful code on the TinkerCAD model
Problems Encountered:
Below are three different generated codes that I created and tested. The first one did not work because I had soldered the wire to 2 as labeled on the Seeed Xiao RP2040 and not pin 2 on the pinout. The second time, I made the same mistake: instead of actually checking the pinout I assumed it to be pin 3. After trying a code with that as the pin, I realized it wasn't the right code. I finally checked the pinout and it was pin 28. When I re-generated the code with Arduino pin 28, it lit up.
Preparing the Code:
Faulty Code #1
#include <Adafruit_NeoPixel.h>
class Strip
{
public:
uint8_t effect;
uint8_t effects;
uint16_t effStep;
unsigned long effStart;
Adafruit_NeoPixel strip;
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) {
effect = -1;
effects = toteffects;
Reset();
}
void Reset(){
effStep = 0;
effect = (effect + 1) % effects;
effStart = millis();
}
};
struct Loop
{
uint8_t currentChild;
uint8_t childs;
bool timeBased;
uint16_t cycles;
uint16_t currentTime;
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};
Strip strip_0(36, 3, 36, NEO_GRB + NEO_KHZ800);
struct Loop strip0loop0(1, false, 1);
//[GLOBAL_VARIABLES]
void setup() {
//Your setup here:
strip_0.strip.begin();
}
void loop() {
//Your code here:
strips_loop();
}
void strips_loop() {
if(strip0_loop0() & 0x01)
strip_0.strip.show();
}
uint8_t strip0_loop0() {
uint8_t ret = 0x00;
switch(strip0loop0.currentChild) {
case 0:
ret = strip0_loop0_eff0();break;
}
if(ret & 0x02) {
ret &= 0xfd;
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
strip0loop0.currentChild = 0;
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
}
else {
strip0loop0.currentChild++;
}
};
return ret;
}
uint8_t strip0_loop0_eff0() {
// Strip ID: 0 - Effect: Rainbow - LEDS: 36
// Steps: 224 - Delay: 42
// Colors: 6 (183.255.255, 76.150.255, 186.130.239, 188.179.240, 241.176.161, 137.247.156)
// Options: rainbowlen=183, toLeft=true,
if(millis() - strip_0.effStart < 42 * (strip_0.effStep)) return 0x00;
float factor1, factor2;
uint16_t ind;
for(uint16_t j=0;j<36;j++) {
ind = strip_0.effStep + j * 1.2240437158469946;
switch((int)((ind % 224) / 37.333333333333336)) {
case 0: factor1 = 1.0 - ((float)(ind % 224 - 0 * 37.333333333333336) / 37.333333333333336);
factor2 = (float)((int)(ind - 0) % 224) / 37.333333333333336;
strip_0.strip.setPixelColor(j, 183 * factor1 + 76 * factor2, 255 * factor1 + 150 * factor2, 255 * factor1 + 255 * factor2);
break;
case 1: factor1 = 1.0 - ((float)(ind % 224 - 1 * 37.333333333333336) / 37.333333333333336);
factor2 = (float)((int)(ind - 37.333333333333336) % 224) / 37.333333333333336;
strip_0.strip.setPixelColor(j, 76 * factor1 + 186 * factor2, 150 * factor1 + 130 * factor2, 255 * factor1 + 239 * factor2);
break;
case 2: factor1 = 1.0 - ((float)(ind % 224 - 2 * 37.333333333333336) / 37.333333333333336);
factor2 = (float)((int)(ind - 74.66666666666667) % 224) / 37.333333333333336;
strip_0.strip.setPixelColor(j, 186 * factor1 + 188 * factor2, 130 * factor1 + 179 * factor2, 239 * factor1 + 240 * factor2);
break;
case 3: factor1 = 1.0 - ((float)(ind % 224 - 3 * 37.333333333333336) / 37.333333333333336);
factor2 = (float)((int)(ind - 112) % 224) / 37.333333333333336;
strip_0.strip.setPixelColor(j, 188 * factor1 + 241 * factor2, 179 * factor1 + 176 * factor2, 240 * factor1 + 161 * factor2);
break;
case 4: factor1 = 1.0 - ((float)(ind % 224 - 4 * 37.333333333333336) / 37.333333333333336);
factor2 = (float)((int)(ind - 149.33333333333334) % 224) / 37.333333333333336;
strip_0.strip.setPixelColor(j, 241 * factor1 + 137 * factor2, 176 * factor1 + 247 * factor2, 161 * factor1 + 156 * factor2);
break;
case 5: factor1 = 1.0 - ((float)(ind % 224 - 5 * 37.333333333333336) / 37.333333333333336);
factor2 = (float)((int)(ind - 186.66666666666669) % 224) / 37.333333333333336;
strip_0.strip.setPixelColor(j, 137 * factor1 + 183 * factor2, 247 * factor1 + 255 * factor2, 156 * factor1 + 255 * factor2);
break;
}
}
if(strip_0.effStep >= 224) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}
Faulty Code #2
#include <Adafruit_NeoPixel.h>
class Strip
{
public:
uint8_t effect;
uint8_t effects;
uint16_t effStep;
unsigned long effStart;
Adafruit_NeoPixel strip;
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) {
effect = -1;
effects = toteffects;
Reset();
}
void Reset(){
effStep = 0;
effect = (effect + 1) % effects;
effStart = millis();
}
};
struct Loop
{
uint8_t currentChild;
uint8_t childs;
bool timeBased;
uint16_t cycles;
uint16_t currentTime;
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};
Strip strip_0(36, 3, 36, NEO_GRB + NEO_KHZ800);
struct Loop strip0loop0(1, false, 1);
//[GLOBAL_VARIABLES]
void setup() {
//Your setup here:
strip_0.strip.begin();
}
void loop() {
//Your code here:
strips_loop();
}
void strips_loop() {
if(strip0_loop0() & 0x01)
strip_0.strip.show();
}
uint8_t strip0_loop0() {
uint8_t ret = 0x00;
switch(strip0loop0.currentChild) {
case 0:
ret = strip0_loop0_eff0();break;
}
if(ret & 0x02) {
ret &= 0xfd;
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
strip0loop0.currentChild = 0;
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
}
else {
strip0loop0.currentChild++;
}
};
return ret;
}
uint8_t strip0_loop0_eff0() {
// Strip ID: 0 - Effect: Rainbow - LEDS: 36
// Steps: 125 - Delay: 25
// Colors: 8 (226.147.212, 189.69.133, 162.0.220, 137.114.221, 88.142.174, 168.206.197, 255.233.178, 255.192.144)
// Options: rainbowlen=124, toLeft=true,
if(millis() - strip_0.effStart < 25 * (strip_0.effStep)) return 0x00;
float factor1, factor2;
uint16_t ind;
for(uint16_t j=0;j<36;j++) {
ind = strip_0.effStep + j * 1.0080645161290323;
switch((int)((ind % 125) / 15.625)) {
case 0: factor1 = 1.0 - ((float)(ind % 125 - 0 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 0) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 226 * factor1 + 189 * factor2, 147 * factor1 + 69 * factor2, 212 * factor1 + 133 * factor2);
break;
case 1: factor1 = 1.0 - ((float)(ind % 125 - 1 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 15.625) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 189 * factor1 + 162 * factor2, 69 * factor1 + 0 * factor2, 133 * factor1 + 220 * factor2);
break;
case 2: factor1 = 1.0 - ((float)(ind % 125 - 2 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 31.25) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 162 * factor1 + 137 * factor2, 0 * factor1 + 114 * factor2, 220 * factor1 + 221 * factor2);
break;
case 3: factor1 = 1.0 - ((float)(ind % 125 - 3 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 46.875) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 137 * factor1 + 88 * factor2, 114 * factor1 + 142 * factor2, 221 * factor1 + 174 * factor2);
break;
case 4: factor1 = 1.0 - ((float)(ind % 125 - 4 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 62.5) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 88 * factor1 + 168 * factor2, 142 * factor1 + 206 * factor2, 174 * factor1 + 197 * factor2);
break;
case 5: factor1 = 1.0 - ((float)(ind % 125 - 5 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 78.125) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 168 * factor1 + 255 * factor2, 206 * factor1 + 233 * factor2, 197 * factor1 + 178 * factor2);
break;
case 6: factor1 = 1.0 - ((float)(ind % 125 - 6 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 93.75) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 233 * factor1 + 192 * factor2, 178 * factor1 + 144 * factor2);
break;
case 7: factor1 = 1.0 - ((float)(ind % 125 - 7 * 15.625) / 15.625);
factor2 = (float)((int)(ind - 109.375) % 125) / 15.625;
strip_0.strip.setPixelColor(j, 255 * factor1 + 226 * factor2, 192 * factor1 + 147 * factor2, 144 * factor1 + 212 * factor2);
break;
}
}
if(strip_0.effStep >= 125) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}
Successful Code!!!
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
class Strip
{
public:
uint8_t effect;
uint8_t effects;
uint16_t effStep;
unsigned long effStart;
Adafruit_NeoPixel strip;
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) {
effect = -1;
effects = toteffects;
Reset();
}
void Reset(){
effStep = 0;
effect = (effect + 1) % effects;
effStart = millis();
}
};
struct Loop
{
uint8_t currentChild;
uint8_t childs;
bool timeBased;
uint16_t cycles;
uint16_t currentTime;
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};
Strip strip_0(36, 28, 36, NEO_GRB + NEO_KHZ800);
struct Loop strip0loop0(1, false, 1);
//[GLOBAL_VARIABLES]
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 8000000)
clock_prescale_set(clock_div_1);
#endif
//Your setup here:
strip_0.strip.begin();
}
void loop() {
//Your code here:
strips_loop();
}
void strips_loop() {
if(strip0_loop0() & 0x01)
strip_0.strip.show();
}
uint8_t strip0_loop0() {
uint8_t ret = 0x00;
switch(strip0loop0.currentChild) {
case 0:
ret = strip0_loop0_eff0();break;
}
if(ret & 0x02) {
ret &= 0xfd;
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
strip0loop0.currentChild = 0;
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
}
else {
strip0loop0.currentChild++;
}
};
return ret;
}
uint8_t strip0_loop0_eff0() {
// Strip ID: 0 - Effect: Rainbow - LEDS: 36
// Steps: 85 - Delay: 61
// Colors: 7 (161.112.193, 95.99.246, 0.18.244, 83.129.185, 121.163.150, 240.176.146, 230.133.144)
// Options: rainbowlen=63, toLeft=true,
if(millis() - strip_0.effStart < 61 * (strip_0.effStep)) return 0x00;
float factor1, factor2;
uint16_t ind;
for(uint16_t j=0;j<36;j++) {
ind = strip_0.effStep + j * 1.3492063492063493;
switch((int)((ind % 85) / 12.142857142857142)) {
case 0: factor1 = 1.0 - ((float)(ind % 85 - 0 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 0) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 161 * factor1 + 95 * factor2, 112 * factor1 + 99 * factor2, 193 * factor1 + 246 * factor2);
break;
case 1: factor1 = 1.0 - ((float)(ind % 85 - 1 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 12.142857142857142) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 95 * factor1 + 0 * factor2, 99 * factor1 + 18 * factor2, 246 * factor1 + 244 * factor2);
break;
case 2: factor1 = 1.0 - ((float)(ind % 85 - 2 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 24.285714285714285) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 0 * factor1 + 83 * factor2, 18 * factor1 + 129 * factor2, 244 * factor1 + 185 * factor2);
break;
case 3: factor1 = 1.0 - ((float)(ind % 85 - 3 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 36.42857142857143) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 83 * factor1 + 121 * factor2, 129 * factor1 + 163 * factor2, 185 * factor1 + 150 * factor2);
break;
case 4: factor1 = 1.0 - ((float)(ind % 85 - 4 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 48.57142857142857) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 121 * factor1 + 240 * factor2, 163 * factor1 + 176 * factor2, 150 * factor1 + 146 * factor2);
break;
case 5: factor1 = 1.0 - ((float)(ind % 85 - 5 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 60.71428571428571) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 240 * factor1 + 230 * factor2, 176 * factor1 + 133 * factor2, 146 * factor1 + 144 * factor2);
break;
case 6: factor1 = 1.0 - ((float)(ind % 85 - 6 * 12.142857142857142) / 12.142857142857142);
factor2 = (float)((int)(ind - 72.85714285714286) % 85) / 12.142857142857142;
strip_0.strip.setPixelColor(j, 230 * factor1 + 161 * factor2, 133 * factor1 + 112 * factor2, 144 * factor1 + 193 * factor2);
break;
}
}
if(strip_0.effStep >= 85) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}
Preparing the LED:
↪ Soldering wires onto the Seeed
↪ Wires soldered onto the LED strip
↪ Connecting the wires onto Female 5V Barrel Jack
From the LED roll, I cut 36 LED's and from the wire rolls I cut one red, yellow, and black wire. After stripping the ends of the wires, I soldered the black wire onto GND, the red one on SV, and the yellow one on P28. I then cut one more red and black wire and, along with the original yellow wire, soldered them to the LED strip with black and red at GND and +5V, respectively, and yellow at Din. I loosened the screw of the Female 5V Barrel Jack and, taking both the red wires, secured them on the positive (left) hole, doing the same for black on the negative (right) side. Connecting the Female 5V Barrel Jack to the rest of the cord and plugging the Seeed into the computer, I uploaded the code into the Seeed. At this point I could remove the red and black wires from the Female 5V Barrel Jack and solder them onto their paired colors. To do so, I first slipped heat shrink tubing off to the side. After connecting the ends of the wires with solder, I slid the tubing over the metal areas and used a head gun to shrink the tubing
Woodworking: Cutting
DAY 1: We cut the long piece of wood into smaller, more manageable portions
DAY 2: We cut the smaller pieces such that the sides are 45°
DAY 3: Part I: Cut grooves for the acrylic board and mirror into the flat side of the wood using a router
DAY 3: Part II: Cut wider grooves for the LED strip to be placed also using a router
DAY 3: Part III: I drilled a hole into the side of once piece of wood where the electronics and wires will exit. On the left video, I accidentally let the wood go up, which led to the hole being broken. In the second video, Mrs. Morrow fixes it.
Woodworking: Assembling
↪ Some gluing done off camera
↪ I used too much glue and it peeked through
↪ Video of the line-up and gluing of the second side piece (used less glue this time)
↪ Video of taping the corners of the wood frame
Laser Cutting: Acrylic Squares
First working on the clear acrylic, I peeled off both sides of protective paper and cut out a rough estimate from a roll of film paper. Then, using a cutting knife, we trimmed the excess film off. After spraying water on the surface of the acrylic, I placed the film sheet onto one side, using a scraper tool to remove any air pockets and excess water. With the black acrylic, I peeled off one side of the protective paper (unlike both sides with the clear acrylic) as well as one side of the metallic blue film. With the aim to center it perfectly, I placed the side I just exposed onto the black acrylic. With that put in place, I peeled off the remaining side of the metallic blue film, revealing a reflective, mirror-esque, surface beneath.
↪ CorelDraw 6 in square plan
↪ First time going under the laser (too small)
↪ Made the length of the squares 6.25 in
↪ Clear Acrylic square
↪ This is the black acrylic board that was just laser cut
↪ Attaching the mirror and peeling off the blue film
↪ Attaching the LED strip to the wooden frame
↪ Attaching with double-sided tape for more stick
↪ Using hot glue so the LED strip does not detatch
↪ Hot gluing the acrylic board onto the wood frame so it does not slide
↪ Final completed infinity mirror!
Overall Problems Encountered
In chronological order, the first issue I encountered was, as explained previously, with the Arduino pins. It was an error of indolence and not checking the pin out, relying on guesswork. The next obstacle I encountered was during the laser cutting of the acrylic boards. It was only after cutting out a full set that we realized 6" would not be secure in the confines of the frame and would be loose and possible fall out. To fix this, we re-cut the entire set, this time creating squares with 6.25" sides. Finally, during the assembly process of the wood pieces as well as the LED's I found that I could not get the respective pieces to adhere. With the wood it was for the most part my fault. After gluing down the piece, I realized it was not as perfect as I would like it to be and attempted to forcefully shift it. Of course, with the glue not being fully dried, it led to the piece to break off. To resolve this, I used hot glue, this time ensuring it was just the angle I desired. As for the LED's it required much more facility and precision. After setting the LED's up using the original tape, I realized it continued to fall apart. Thus, my first attempt to fix this was using double sided tape and adding that extra layer of adhesion, or so I thought. The double sided tape was no more effective than the original sticky backing. Again, I had to use hot glue, which worked. After using hot glue, the LEDs stayed fastened and did not detach.