Machines, Programs and Tools
Mac computer, screen, IPhone, GitLab, HTML site, patience.
introduction
This is the code part of the final project that will be uploaded to the XIAO-ESP32-C3 chip.
Projects
First draft was designed in week 8.
I based this project on what I learned in week 4. The only thing that didnt workout according to plan was that I put the circuts too close to each other in one spot and had to manually cut the link between them. This I will fix in the next version. I also learned that for the LED lights it should have been male pins and not female pin headers.
plexiLamp_multipleLightThemes
#include
#ifdef __AVR__
#include // Required for 16 MHz Adafruit Trinket
#endif
#define PIXEL_PIN D7
#define BUTTON_PIN D5
#define PIXEL_COUNT 10
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
bool modeChanged = false;
int mode = 0; // 0 for flame, 1 for rainbow, 2-8 for solid colors, 9 for off
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
Serial.begin(9600);
strip.begin();
strip.show();
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
// Check button state and debounce
if (reading == LOW) {
if ((millis() - lastDebounceTime) > debounceDelay) {
if (!modeChanged) {
mode++;
modeChanged = true;
if (mode > 9) { // Update the maximum mode number
mode = 0;
}
Serial.print("Mode changed to: ");
Serial.println(mode);
}
lastDebounceTime = millis(); // Reset the debouncing timer
}
} else {
modeChanged = false; // Reset mode changed flag when button is not pressed
}
switch (mode) {
case 0:
Serial.println("Fire");
fireAnimation(75);
break;
case 1:
Serial.println("Rainbow");
rainbowAnimation();
break;
default:
if (mode >= 2 && mode <= 8) {
Serial.println("Colors");
solidColor(mode - 2);
} else if (mode == 9) {
Serial.println("Off");
turnOffLights();
}
break;
}
}
void fireAnimation(int wait) {
// First loop: Set the initial color for each LED
for (int i = 0; i < strip.numPixels(); i++) {
int r = random(150, 255); // More red for a fiery color
int g = random(0, 85); // Random amount of green to vary between red and yellow
int b = 0; // No blue component for fire
strip.setPixelColor(i, r, g, b);
}
// Second loop: Apply the flicker effect
for (int i = 0; i < strip.numPixels(); i++) {
uint32_t color = strip.getPixelColor(i);
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
// Random flicker effect
int flicker = random(0, 150);
r = max(0, r - flicker);
g = max(0, g - flicker);
strip.setPixelColor(i, r, g, 0);
}
strip.show();
delay(wait);
}
void rainbowAnimation() {
static unsigned long lastUpdate = 0; // Last update time
static uint16_t j = 0; // Position in color wheel
// Update only if the appropriate interval has passed
if (millis() - lastUpdate > 20) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
j = (j + 1) % 256; // Move to the next position in the color wheel
lastUpdate = millis(); // Update the last update time
}
}
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void solidColor(int color) {
uint32_t col;
switch(color) {
case 0: col = strip.Color(255, 0, 0); break; // Red
case 1: col = strip.Color(255, 165, 0); break; // Orange
case 2: col = strip.Color(255, 255, 0); break; // Yellow
case 3: col = strip.Color(0, 255, 0); break; // Green
case 4: col = strip.Color(0, 0, 255); break; // Blue
case 5: col = strip.Color(75, 0, 130); break; // Indigo
case 6: col = strip.Color(238, 130, 238); break; // Violet
default: col = strip.Color(0, 0, 0); break; // Off
}
for(int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, col);
}
strip.show();
}
void turnOffLights() {
for(int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0)); // Turn off this LED
}
strip.show();
}
Code used in final project
programming: Board
I wrote the program from scratch using Arduino with a little help from my instructor and ChatGPT. Inititally I had fire animation in the code but I removed it for the Final Project. I did that so that the I could use rainbow function. The fire anamation was red, orange and yellow. It didnt fit my design.
Aniimatronic Wings With Lights Works
AnimatronicWingsWithLights_Works
#include
#ifdef __AVR__
#include // Required for 16 MHz Adafruit Trinket
#endif
#include
#define PIXEL_PIN 10
#define PIXEL2_PIN 2
#define BUTTON_PIN 7
#define PIXEL_COUNT 40
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2(PIXEL_COUNT, PIXEL2_PIN, NEO_GRB + NEO_KHZ800);
bool modeChanged = false;
int mode = 0; // 0 for rainbow, 1-7 for solid colors, 8 for off
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
Servo servoR;
Servo servoL;
int servoRPin = 6;
int servoLPin = 20;
void setup() {
Serial.begin(9600);
strip.begin();
strip.show();
strip2.begin();
strip2.show();
pinMode(BUTTON_PIN, INPUT_PULLUP);
servoR.attach(servoRPin, 500, 2500);
servoL.attach(servoLPin, 500, 2500);
}
void loop() {
int reading = digitalRead(BUTTON_PIN);
// Check button state and debounce
if (reading == LOW) {
if ((millis() - lastDebounceTime) > debounceDelay) {
if (!modeChanged) {
mode++;
modeChanged = true;
if (mode > 8) { // Update the maximum mode number
mode = 0;
}
Serial.print("Mode changed to: ");
Serial.println(mode);
}
lastDebounceTime = millis();
}
} else {
modeChanged = false; // Reset mode changed flag when button is not pressed
}
if (mode == 0) {
rainbowAnimation();
} else if (mode >= 1 && mode <= 7) {
solidColor(mode - 1);
} else if (mode == 8) {
turnOffLights();
}
if (mode != 8) { // Flap wings only if not in "off" mode
flapWings(getFlapSpeed(mode));
}
}
void flapWings(int speed) {
static unsigned long lastUpdate = 0;
static bool flapping = true;
static int pos = 0;
if (millis() - lastUpdate > speed) {
if (flapping) {
servoR.write(pos);
servoL.write(180 - pos);
pos++;
if (pos >= 90) {
flapping = false;
}
} else {
servoR.write(pos);
servoL.write(180 - pos);
pos--;
if (pos <= 0) {
flapping = true;
}
}
lastUpdate = millis();
}
}
int getFlapSpeed(int mode) {
switch (mode) {
case 0: return 30;
case 1: return 60;
case 2: return 50;
case 3: return 40;
case 4: return 30;
case 5: return 20;
case 6: return 15;
case 7: return 10;
default: return 30;
}
}
void rainbowAnimation() {
static unsigned long lastUpdate = 0;
static uint16_t j = 0;
if (millis() - lastUpdate > 20) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i + j) & 255));
strip2.setPixelColor(i, Wheel((i + j) & 255));
}
strip.show();
strip2.show();
j = (j + 1) % 256;
lastUpdate = millis();
}
}
void solidColor(int color) {
uint32_t col;
switch(color) {
case 0: col = strip.Color(255, 0, 0); break;
case 1: col = strip.Color(255, 165, 0); break;
case 2: col = strip.Color(255, 255, 0); break;
case 3: col = strip.Color(0, 255, 0); break;
case 4: col = strip.Color(0, 0, 255); break;
case 5: col = strip.Color(75, 0, 130); break;
case 6: col = strip.Color(238, 130, 238); break;
default: col = strip.Color(0, 0, 0); break;
}
for(int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, col);
strip2.setPixelColor(i, col);
}
strip.show();
strip2.show();
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void turnOffLights() {
for(int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, strip.Color(0, 0, 0));
strip2.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
strip2.show();
}
Summary
This code was designed over multible weeks. I will have to alter it at some point because if you put it on the fastest setting it breaks the wingclip. I will also put a conductor in the next version. The final code is based on week 8 and I tweaked it over the next weeks to get it to work perfectly.