XRAD'S WISH UPON A STAR DESTROYER

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
XRAD
 
Posts: 753
Joined: Sat Nov 19, 2016 3:28 pm

XRAD'S WISH UPON A STAR DESTROYER

Post by XRAD »

creating a star destroyer with pixies, neopixel strips, adafruit sound board, teensy 3.2, hundreds of fiber optics, 3d prints, adafruit 315mhz controller .....more to come...
IMG_0663.JPG
IMG_0663.JPG (168.43 KiB) Viewed 286 times
IMG_0665.JPG
IMG_0665.JPG (163.34 KiB) Viewed 286 times

User avatar
adafruit_support_mike
 
Posts: 67391
Joined: Thu Feb 11, 2010 2:51 pm

Re: XRAD'S WISH UPON A STAR DESTROYER

Post by adafruit_support_mike »

Whoof.. looks ambitious. We’ll love to see progress shots!

User avatar
XRAD
 
Posts: 753
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S WISH UPON A STAR DESTROYER

Post by XRAD »

Yes, Mike.....tediously relaxing! Mounted most hardware to one small board. finished the code. everything works. had some noise from pixies and neopixels but solved it. Using the 4 button RF fob, and 'one click on/one click off' for both switches A and B, i can remotely turn on power(using pololu 2808), and turn lights on and off (but I could have written a multiple press counter++ code to cycle through many different hull neopixle displays...but not necessary. mostly will be just white lights with a twinkle of blue here and there, and some fade in/out red lights). Music play is only a one press 'ON' function( switches C and D)....so once the track starts, it doesn't stop till finished. all engine lights react to sound, the main engines are obviously brightest and react the most, but not flashy due to amplitude averaging of biased input.... will post code and final pics/vid soon...

see short action vid:
https://www.youtube.com/watch?v=53FH7dcg604
IMG_0666.JPG
IMG_0666.JPG (158.77 KiB) Viewed 272 times

User avatar
adafruit_support_mike
 
Posts: 67391
Joined: Thu Feb 11, 2010 2:51 pm

Re: XRAD'S WISH UPON A STAR DESTROYER

Post by adafruit_support_mike »

Looks good! The imperial theme is a nice touch. ;-)

User avatar
XRAD
 
Posts: 753
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S WISH UPON A STAR DESTROYER

Post by XRAD »

Thx Mike! oh boy...what a time running fiber....hull done....still have the superstructure to finish. Final code nearly complete and works great.
IMG_0678.JPG
IMG_0678.JPG (174.31 KiB) Viewed 237 times

User avatar
XRAD
 
Posts: 753
Joined: Sat Nov 19, 2016 3:28 pm

Re: XRAD'S WISH UPON A STAR DESTROYER

Post by XRAD »

Here is my star destroyer code. Plenty of array usage, and using Pixies with simple fastLed code. Also, great for learning how to use the adafruit Tx Rx transmitter/receiver and how to incorporate it into your project with on/off button presses. Analog biasing and running volume averaging can come in handy for any sensor project. feel free to modify for your use. I have not finished the fiber runs as my ADD took over and i'm on to something new. Cheers, Xrad

Code: Select all

/////XRAD'S WISH UPON A STAR DESTROYER CODE////
/* 11/30/21 This uses an adafruit FX sound board, teensy 3.2, pam8403 stereo
   amplifier with x2 3watt speakers. Control by R02A RF receiver,
   and adafruit 4 button RF transmitter. main engines are x3 3watt
   pixies ontrolled with fastLed array. You still need to use
   SoftwareSerial.h !first! when compiling (maintain lib order!) There are a few
   code bits I modified nicely for RF receiver interface control, and debouncing
   of the M4 type RF reciever output. Also, I inverted fastLED 'fadeLightBy'
   so that the engine lights increase brightness with increased
   amplitude. simple biasing circuit to create usable input values
   from the line level sound board output Left channel only.  I
   'kinda eyeballed' the input/biasing relationship to get
   the lighting effect I needed for -1dB max sound level. There are many averaging code
   snippets out there, but this one worked well because of its adjustability:
   https://forum.arduino.cc/t/dance-party-light-adressable-led-strip-controlled-by-software-soundwave-analyser/547091/2
   Fob button A triggers the pololu latching power switch. Other fob buttons
   triggered in the code. The RF receiver is always powered, otherwise
   it could not be triggered! There is a hardwired on off bat switch in the base.
  RF receiver outputs 5v signal. Teensy 3.2 I/O pins  are 5v digital tolerant. 
  This was a super fun project. Hope you enjoy!
*/


#include <SoftwareSerial.h> //needs to compile first for pixies!
#include "Adafruit_Pixie.h"
#include <FastLED.h>


// neopixel/pixie #'s and pin definitions
#define NUMLEDSMAINENGINE 3
#define PIXIEPIN 3 //serial 1 tx not needed

#define NUMLEDSEMERGENGINE 4
#define DATAPINEMERGENGINE 5

#define NUMLEDSHULL 40
#define DATAPINHULL 7


#define IMPERIALMARCH 23 // imperial march trigger pin out to sound board 0
#define MAINENGINESTART 22 // engine start trigger pin out to sound board 1

#define RF_D0 21 // read this pin from RF transmitter/button B to trigger imperial march
#define RF_D1 20 // read this pin from RF transmitter/button C to trigger engine start
#define RF_D2 19 // read this pin from RF transmitter/button D to trigger hull lighting 
//note: RF_D3 is only to directly trigger the latching main power switch on off.....


CRGB ledsE[NUMLEDSMAINENGINE];
CRGBArray<NUMLEDSEMERGENGINE> ledsB;
CRGBArray<NUMLEDSHULL> ledsH;


CRGBSet emergEngines(ledsB (0, 3)); //array of 4 emergency engines single neopixels

//5 neopixel arrays of 8 pixel sticks for hull lighting
CRGBSet pix1(ledsH (0, 7)); //pixel series 1 hull lighting
CRGBSet pix2(ledsH (8, 15));  //pixel series 2 hull lighting
CRGBSet pix3(ledsH (16, 23)); //pixel series 3 hull lighting
CRGBSet pix4(ledsH (24, 31));  //pixel series 4 hull lighting
CRGBSet pix5(ledsH (32, 39)); //pixel series 5 hull lighting

//neopixel/pixie variables
int fadeAmount = 7;//Set the amount to fade, 1-255 possible...I like 7
int brightness = 0;
int brightnessFade = 0;
int Ebrightness = 0;//global for main and emergency engine brightness, mapped from Max analog read

//analog read LEFT channel line level pin to create moving average Max value
int Bias = 512;                           //Nominally half of the 1023 range = 512.  Adjust as necessary
int NoiseThreshold = 25;                  //Increase to minimize false triggers with silence or background noise
int Analog;                               //The analog reading (with the bias subtracted-out)
int Max;                                  //The waveform peak over a short period of time
int Average;                              //"sampled" moving average of Max values(not the true-average).

unsigned long ReadStartTime;             //millis() used to set time
int SampleTime = 40;                     //Sample for short time to find waveform peak
unsigned long ArrayStartTime;            //millis() again
int ArrayTime = 500;                     //Update array at x millis

const int ArraySize = 20;                // 20 values in the moving-average array
int ArrayIndex = 0;                      // Index/pointer
int AverageArray[ArraySize];             // Saves a sample of 20 Max values for averaging

int UpdateAverage(int Max);               //UpdateAverage() function prototype


//RF input ontrol variables for three buttons B,C,D
int triggerStateD0 = LOW;
int buttonStateD0;
int lastButtonStateD0 = LOW;
unsigned long lastDebounceTimeD0 = 0;
unsigned long debounceDelayD0 = 250;//create a delay timer so no bouncing!

int triggerStateD1 = LOW;
int buttonStateD1;
int lastButtonStateD1 = LOW;
unsigned long lastDebounceTimeD1 = 0;
unsigned long debounceDelayD1 = 250;

int triggerStateD2 = LOW;
int buttonStateD2;
int lastButtonStateD2 = LOW;
unsigned long lastDebounceTimeD2 = 0;
unsigned long debounceDelayD2 = 250;

bool stateHullLights = false;


//---------------------------------------------------------------
void setup() {
  Serial.begin(115200);
  delay(1000);

  FastLED.addLeds<PIXIE, PIXIEPIN, RGB>(ledsE, NUMLEDSMAINENGINE);
  FastLED.addLeds<NEOPIXEL, DATAPINEMERGENGINE  >(ledsB, NUMLEDSEMERGENGINE);
  FastLED.addLeds<NEOPIXEL, DATAPINHULL  >(ledsH, NUMLEDSHULL);

  FastLED.setBrightness(100); //0-255 initial brightness
  FastLED.clear();
  FastLED.show();


  pinMode(LED_BUILTIN, OUTPUT); // for debugging only

  pinMode(21, INPUT);// RF input, imperial march
  pinMode(20, INPUT);// RF input, engine start
  pinMode(19, INPUT);// RF input, hull lighting

  pinMode(22, OUTPUT); // trigger to sound board
  pinMode(23, OUTPUT); // trigger to sound board
  pinMode(18, OUTPUT); // trigger to sound board


  digitalWrite(18, HIGH);

  for (int i = 0; i < 20; i++) { //fill average array elements, set all to zero
    AverageArray[i] = 0;
  }

  delay(500);
  digitalWrite(18, LOW);
  delay(500);
  digitalWrite(18, HIGH);
  delay(2500);//to play the 2.2 sec intro audio track
}

//------------------------LOOP--------------------------------
void loop() {
  Max = 0;

  ReadStartTime = millis();

  while (millis() - ReadStartTime < SampleTime) {
    Analog = abs(analogRead(A0) - Bias);
    if (Analog > Max) {
      Max = Analog;
    }
  }

  if (Average < NoiseThreshold) {
    Average = NoiseThreshold;
  }

  if (millis() - ArrayStartTime > ArrayTime) {
    Average = UpdateAverage(Max);
  }

  Ebrightness = map(Max, 300, 330, 100, 255);//map audio Max to neopixel brightness

  MEngines(); //always running waiting for audio input to trigger leds

  EEngines(); //always running waiting for audio input to trigger leds

  FastLED.show();


  /////trigger the imperial march audio,fob button D
  int readingD0 = digitalRead(RF_D0);
  if (readingD0 != lastButtonStateD0) {
    lastDebounceTimeD0 = millis();
  }
  if ((millis() - lastDebounceTimeD0) > debounceDelayD0) {
    if (readingD0 != buttonStateD0) {
      buttonStateD0 = readingD0;
      if (buttonStateD0 == HIGH) {
        triggerStateD0 = !triggerStateD0;
        digitalWrite(23, triggerStateD0);
        digitalWrite(13, HIGH);//on board LED
        delay (250);//long enough to trigger sound board
        digitalWrite(13, LOW);
        //Serial.println(buttonStateD0);
        digitalWrite(23, LOW);
      }
    }
  }
  lastButtonStateD0 = readingD0;


  //////trigger the engine start audio, fob button C
  int readingD1 = digitalRead(RF_D1);
  if (readingD1 != lastButtonStateD1) {
    lastDebounceTimeD1 = millis();
  }
  if ((millis() - lastDebounceTimeD1) > debounceDelayD1) {
    if (readingD1 != buttonStateD1) {
      buttonStateD1 = readingD1;
      if (buttonStateD1 == HIGH) {
        triggerStateD1 = !triggerStateD1;
        digitalWrite(22, triggerStateD1);
        digitalWrite(13, HIGH);
        delay (250);//long enough to trigger sound board
        digitalWrite(13, LOW);
        //Serial.println(buttonStateD1);
        digitalWrite(22, LOW);
      }
    }
  }
  lastButtonStateD1 = readingD1;


  /////////trigger the hull lights, fob button B
  int readingD2 = digitalRead(RF_D2);
  if (readingD2 != lastButtonStateD2) {
    lastDebounceTimeD2 = millis();
  }
  if ((millis() - lastDebounceTimeD2) > debounceDelayD2) {
    if (readingD2 != buttonStateD2) {
      buttonStateD2 = readingD2;
      //turn on/off hull lights
      if (buttonStateD2 == HIGH   ) {
        triggerStateD2 = !triggerStateD2;
        stateHullLights = ( stateHullLights == true) ? false : true;//neat line of code!
        //digitalWrite(13, HIGH);
        //delay (100);
        //digitalWrite(13, LOW);
      }
    }
  }
  lastButtonStateD2 = readingD2;

  if (stateHullLights == true) {
    hullLights();
    addGlitter(20);//it's actually dimming! rather than full brightness white
  }

  if (stateHullLights == false) {
    hullLightsOFF();
  }
}

///////////////////////////////////////////////////////////

int UpdateAverage(int Max) {

  int Sum = 0;    // Inialize/reset Sum before calculating average
  AverageArray[ArrayIndex] = Max;                //Update one array element with the latest Max

  for (int i = 0; i < 20; i++)                   //Sum-up the data in the array
  {
    Sum = Sum + AverageArray[i];
  }

  Average = Sum / 20;                            // Find average of the saved Max values

  ArrayIndex++;                                  //Next index for next time
  if (ArrayIndex > 19)
    ArrayIndex = 0;                              //Back to the beginning of the circuar buffer

  //Print information (Optional, once per x millis for testing/debugging)
  //Serial.print (" Ebrightness = ");
  //Serial.println (Ebrightness);
  //Serial.print (" Average = ");
  //Serial.println (Average);
  //Serial.print (" Max = ");
  //Serial.println (Max);

  ArrayStartTime = millis(); //New Array Start Time

  return Average;
}



//glitter/twinkle: dimming effect just for hull lights pix1 - pix5
void addGlitter( fract8 chanceOfGlitter) {
  if ( random8() < chanceOfGlitter) {
    ledsH[ random16(NUMLEDSHULL) ].setRGB( 50, 150, 200);//dim LEDs a bit here for that little twinkle!
  }
}

void hullLightsOFF() {//when 'off' do this
  for (int i = 0; i < 8; i++) {
    pix1[i]  = CRGB::Black ;
    pix2[i]  = CRGB::Black;
    pix3[i]  = CRGB::Black;
    pix4[i]  = CRGB::Black;
    pix5[i]  = CRGB::Black;
  }
}



void hullLights() {//when 'on' do this

  for (int i = 0; i < 7; i++) {
    pix1[i]  = CRGB::White ;
  }
  //pix1 [7]  = CRGB::Purple;


  for (int i = 0; i < 7; i++) {
    pix2[i]  = CRGB::White;
  }

  //pix2 [7]  = CRGB::Red;
  CoolFadeRed();// pixel 8 on strip 1 and 2 as need for red fibers

  for (int i = 0; i < 7; i++) {
    pix3[i]  = CRGB::White;
  }

  pix3 [7]  = CRGB::Orange;//more like yellow...

  for (int i = 0; i < 8; i++) {
    pix4[i]  = CRGB::White;
  }

  for (int i = 0; i < 8; i++) {
    pix5[i]  = CRGB::White;
  }
}



void CoolFadeRed() {//single color w/fade in and out as need for red fibers
  EVERY_N_MILLISECONDS(20) { //update at 'x' millis
    pix1[7]  = CRGB::Red;
    pix2[7]  = CRGB::Red;
    pix1[7].fadeLightBy(brightnessFade);
    pix2[7].fadeLightBy(brightnessFade);

    FastLED.show();

    brightnessFade = brightnessFade + fadeAmount;
    if (brightnessFade <= 0 || brightnessFade >= 255)
    {
      if (brightnessFade <= 0) {
        brightnessFade = 0;
      }
      if (brightnessFade >= 255) {
        brightnessFade = 255;
      }
      fadeAmount = -fadeAmount ;
    }
    //Serial.println(brightnessFade);
  }
}



void MEngines() {
  EVERY_N_MILLISECONDS(30) { //update at 'x' millis
    for (int i = 0; i < NUMLEDSMAINENGINE; i++ )
    {
      ledsE[i].setRGB(0, 255, 255); //bluish
      if (Ebrightness <= 0) {
        Ebrightness = 0;
        ledsE[i].setRGB(0, 0, 0);
      }
      if (Ebrightness > 255) {
        Ebrightness = 255;
      }
      ledsE[i].fadeLightBy(-Ebrightness);// (-Ebrightness) creates a 'fade in' effect matching audio peaks
      FastLED.show();
      //Serial.println(Ebrightness);
    }
  }
}



void EEngines() {
  if (Ebrightness > 30) {
    for (int i = 0; i < 4; i++) {
      // emergEngines[i].addToRGB(100);
      emergEngines[i]  = CRGB::Teal;
      // FastLED.show();
    }
  }
  else {
    for (int i = 0; i < 4; i++) {
      // emergEngines[i].addToRGB(100);
      emergEngines[i].setRGB(0, 0, 0);
    }
  }
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”