#4897585
CountDeMonet wrote:I also started in on the electronic mounts. The first being the cyclotron lights. I'm looking to find some red transparent file folders and cut those to make the lenses. Then those will be cut to fit under the lip and then the cup for the neopixel will be glued onto that. I think it'll work pretty good.
TOTALLY STEALING THOSE CYCLOTRON MOUNTS! :):love:

For my cyclotron lights, I hemmed and hawed about what to do for the lenses, because I wanted the ability to do any color lights I wanted (which is half the reason to do Neopixels!)...I finally decided on using clear plexiglass and a dark transparent vinyl for window or headlamp tinting to hide the Neopixels when they're off, but any color I use will show through when on. Still deciding if I'm using a diffuser or not.

This is the stuff (the color on the website is horrible, it's really a nice dark gray): https://www.fellers.com/fellers-shoppin ... ndow-vinyl

I got a 12" square sample piece for $3 and was able to pick it up from a local distributor. I'd be more than happy to send you (both) a strip if you'd like, let me know!
#4897588
I've been going back and forth on what to use for the lens color. I originally was going to go clear and frost it somehow. Was thinking of just using sandpaper to rough up the underside of some plexiglass or something. I could still go back to that. I do want it diffused as the neopixels can be a little harsh on the eyes without something doing that. I have a dollar store trip in my future as I can usually find stuff there to use for things like this. Maybe I'll strike gold there :)

If the material is thicker than a piece of paper then my mount will need to be modified some for your use. I'm very close to having all of the printing completed and once I have and checked the fit I'll post all of the modified models to thingiverse and github.
xoff00 liked this
#4897684
I've made some more updates to the code and I've redone some of the audio files. Now when in the warning time for firing it switches to the firing sound with the warning sound attached. When the firing stops after being in warning the pack is vented and rebooted.

I've also added 2 more dialog tracks at the end of the firing sequence if you get to the second firing level.

The bar graph animation is also sped up along with the powercell as you hold down the firing button.

And finally the pack will play the full ghostbusters theme song and not just a 20 second sample. I don't want to just post the sound files so if anyone wants them PM me and I'll send you a link to the zip with the ones I am using.

still have to do the cyclotron lights. I have not had a chance to solder those up. I've been busy printing the pack and fixing models this past week mainly.
Code: Select all
// for the sound board
#include <SoftwareSerial.h>
#include "Adafruit_Soundboard.h"

#include <Wire.h> // Include the I2C library (required)
#include <SparkFunSX1509.h> // Include SX1509 library

#include <Adafruit_NeoPixel.h>

// for led triggers
#define HIGH 0x1
#define LOW  0x0

// neopixel pins
#define NEO_NOSE 9 // for nose of wand
Adafruit_NeoPixel noseJewel = Adafruit_NeoPixel(7, NEO_NOSE, NEO_GRB + NEO_KHZ800);

#define NEO_POWER 10 // for cyclotron and powercell
Adafruit_NeoPixel powerStick = Adafruit_NeoPixel(16, NEO_POWER, NEO_GRB + NEO_KHZ800);

bool powerBooted = false; // has the pack booted up

// soundboard pins
#define SFX_RST 2
#define SFX_RX 3
#define SFX_TX 4

// setup the board with the pins
SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
Adafruit_Soundboard sfx = Adafruit_Soundboard( & ss, NULL, SFX_RST);
const int ACT = 13;// this connects to the act on the board so we can know if the audio is playing

// inputs for switches and buttons
const int THEME_SWITCH = 5;
const int STARTUP_SWITCH = 6;
const int SAFETY_SWITCH = 7;
const int FIRE_BUTTON = 8;

// switch states for tracking
bool theme = false;
bool startup = false;
bool safety = false;
bool fire = false;
bool warning = false;

// audio track locations on soundboard
const int startupTrack = 0;
const int blastTrack = 1;
const int endTrack = 2;
const int idleTrack = 3;
const int shutdownTrack = 4;
const int clickTrack = 5;
const int warnTrack = 6;
const int ventTrack = 7;
const int texTrack = 8;
const int choreTrack = 9;
const int toolsTrack = 10;
const int listenTrack = 11;
const int goodTrack = 12;
const int themeTrack = 13;

// dialog trigger times/states
unsigned long startDialogMillis;
const int numDialog = 5;
int currentDialog = 1;
const int dialogWaitTime = 5000;
const int warnWaitTime = 10000;

// SX1509 I2C address (set by ADDR1 and ADDR0 (00 by default):
const byte SX1509_ADDRESS = 0x3E;  // SX1509 I2C address
SX1509 io; // Create an SX1509 object to be used throughout

// bargraph helper variables
int seq_1_current = 0;  // current led in sequence 1
const int num_led = 15; // total number of leds in bar graph

// SX1509 pin definitions for the leds on the graph:
const byte SX1509_BAR_01 = 0;
const byte SX1509_BAR_02 = 1;
const byte SX1509_BAR_03 = 2;
const byte SX1509_BAR_04 = 3;
const byte SX1509_BAR_05 = 4;
const byte SX1509_BAR_06 = 5;
const byte SX1509_BAR_07 = 6;
const byte SX1509_BAR_08 = 7;
const byte SX1509_BAR_09 = 8;
const byte SX1509_BAR_10 = 9;
const byte SX1509_BAR_11 = 10;
const byte SX1509_BAR_12 = 11;
const byte SX1509_BAR_13 = 12;
const byte SX1509_BAR_14 = 13;
const byte SX1509_BAR_15 = 14;

void setup() {
  // softwareserial at 9600 baud for the audio board
  ss.begin(9600);

  // see if we have the soundboard
  // If we fail to communicate, loop forever for now but it would be nice to warn the user somehow
  if (!sfx.reset()) {
    while (1);
  }

  // set act modes for the fx board
  pinMode(ACT, INPUT);

  // Call io.begin(<address>) to initialize the SX1509. If it
  // successfully communicates, it'll return 1.
  if (!io.begin(SX1509_ADDRESS)) {
    while (1) ; // If we fail to communicate, loop forever for now but it would be nice to warn the user somehow
  }

  // configure nose jewel
  noseJewel.begin();
  noseJewel.show(); // Initialize all pixels to 'off'

  // configure powercell/cyclotron
  powerStick.begin();
  powerStick.setBrightness(10);
  powerStick.show(); // Initialize all pixels to 'off'

  // set the modes for the switches/buttons
  pinMode(THEME_SWITCH, INPUT);
  digitalWrite(THEME_SWITCH, HIGH);
  pinMode(STARTUP_SWITCH, INPUT);
  digitalWrite(STARTUP_SWITCH, HIGH);
  pinMode(SAFETY_SWITCH, INPUT);
  digitalWrite(SAFETY_SWITCH, HIGH);
  pinMode(FIRE_BUTTON, INPUT);
  digitalWrite(FIRE_BUTTON, HIGH);

  // configuration for the bargraph
  io.pinMode(SX1509_BAR_01, OUTPUT);
  io.pinMode(SX1509_BAR_02, OUTPUT);
  io.pinMode(SX1509_BAR_03, OUTPUT);
  io.pinMode(SX1509_BAR_04, OUTPUT);
  io.pinMode(SX1509_BAR_05, OUTPUT);
  io.pinMode(SX1509_BAR_06, OUTPUT);
  io.pinMode(SX1509_BAR_07, OUTPUT);
  io.pinMode(SX1509_BAR_08, OUTPUT);
  io.pinMode(SX1509_BAR_09, OUTPUT);
  io.pinMode(SX1509_BAR_10, OUTPUT);
  io.pinMode(SX1509_BAR_11, OUTPUT);
  io.pinMode(SX1509_BAR_12, OUTPUT);
  io.pinMode(SX1509_BAR_13, OUTPUT);
  io.pinMode(SX1509_BAR_14, OUTPUT);
  io.pinMode(SX1509_BAR_15, OUTPUT);

  // set everything off initially
  shutdown_leds();
}

bool isFiring = false; // keeps track of the firing state
bool shouldWarn = false; // track the warning state for alert audio

/* ************* Audio Board Helper Functions ************* */
// helper function to play a track on the audio board
void playTrack(int num) {
  // stop track if one is going
  int playing = digitalRead(ACT);
  if (playing == 0) {
    sfx.stop();
  }

  // now go play
  if (sfx.playTrack(num)) {
    sfx.unpause();
  }
}

void stopTrack() {
  sfx.stop();
}

void resetSoundboard() {
  sfx.reset();
}

/* ************* Main Loop ************* */
int pwr_interval = 60;     // interval at which to cycle lights for the powercell. We update this in the loop to speed up the animation so must be declared here (milliseconds)
long firing_interval = 40;    // interval at which to cycle firing lights on the bargraph. We update this in the loop to speed up the animation so must be declared here (milliseconds).

void loop() {
  // get the current time
  int currentMillis = millis();

  // find out of the audio board is playing audio
  int playing = digitalRead(ACT);

  // find out the theme switch state
  int theme_switch = digitalRead(THEME_SWITCH);

  // if the theme switch has recently changed we should play the full ghostbusters theme song
  if (theme_switch == 1) {
    if (theme == false) {
      playTrack(themeTrack); 
      theme = true;
    }
  } else {
    theme = false;
  }

  // now get the other switch/button states so we can handle animations/sounds
  int startup_switch = digitalRead(STARTUP_SWITCH);
  int safety_switch = digitalRead(SAFETY_SWITCH);
  int fire_button = digitalRead(FIRE_BUTTON);

  // while the startup switch is set on
  if (startup_switch == 1) {
    // in general we always try to play the idle sound if started
    if (playing == 1 && startup == true) {
      playTrack(idleTrack); 
    }

    // choose the right powercell animation sequence for booted/on
    if ( powerBooted == true ) {
      powerSequenceOne(currentMillis, pwr_interval);
    } else {
      powerSequenceBoot(currentMillis);
    }

    // if we are not started up we should play the startup sound first
    if (startup == false) {
      startup = true;
      playTrack(startupTrack);

      // get the current safety switch state
      if (safety_switch == 1 && safety == false) {
        safety = true;
      }
    }

    // if the safety switch is set off then we can fire when the button is pressed
    if ( safety_switch == 1 && fire_button == 0) {
      // if the button is just pressed we clear all led's to start the firing animations
      if ( isFiring == false ) {
        shutdown_leds();
        isFiring = true;
      }

      // show the firing bargraph sequence
      barGraphSequenceTwo(currentMillis);
    } else { // if we were firing and are no longer reset the leds
      if ( isFiring == true ) {
        shutdown_leds();
        isFiring = false;
      }

      // and do the standard bargraph sequence
      barGraphSequenceOne(currentMillis);
    }

    // if we are started up fire loop
    if (startup == true && safety_switch == 1)
    {
      // if the safety was just changed play the click track
      if (safety == false) {
        safety = true;
        playTrack(clickTrack);
      }

      // if the fire button is pressed 
      if (fire_button == 0) {
        fireStrobe(); // strobe the nose pixels

        // if this is the first time reset some variables and play the blast track
        if (fire == false) {
          shouldWarn = false;
          fire = true;
          startDialogMillis = millis();
          playTrack(blastTrack);
        } else {
          // find out what our timing is
          long diff = millis() - startDialogMillis;
          // if we are in the warn interval
          if ( diff > warnWaitTime) {
            pwr_interval = 20; // speed up the powercell animation
            firing_interval = 20; // speed up the bar graph animation
            if (playing == 1 || shouldWarn == false ) {
              shouldWarn = true;
              playTrack(warnTrack); // play the firing track with the warning 
            }
          } else if ( diff > dialogWaitTime) { // if we are in the dialog playing interval
            pwr_interval = 40; // speed up the powercell animation
            firing_interval = 30; // speed up the bar graph animation
            if (playing == 1) {
              playTrack(blastTrack); // play the normal blast track
            }
          }
        }
      } else { // now the button is no longer pressed
        if (fire == true) { // if we were firing let's reset the animations and play the correct final firing track
          clearFireStrobe();
          pwr_interval = 60;
          firing_interval = 40;
          fire = false;
          
          // see if we've been firing long enough to get the dialog or vent sounds
          long diff = millis() - startDialogMillis;
         
          if ( diff > warnWaitTime) { // if we are past the warning let's vent the pack
            playTrack(ventTrack);
            clearPowerStrip(); // play the boot animation on the powercell
          } else if ( diff > dialogWaitTime) { // if in the dialog time play the dialog in sequence 
            switch (currentDialog) {
              case (1):
                playTrack(choreTrack);
                break;
              case (2):
                playTrack(toolsTrack);
                break;
              case (3):
                playTrack(texTrack);
                break;
              case (4):
                playTrack(listenTrack);
                break;
              case (5):
                playTrack(goodTrack);
                break;
            }
            if ( currentDialog >= numDialog ) {
              currentDialog = 1;
            } else {
              currentDialog++;
            }
          } else {
            // otherwise play the standard power down track
            playTrack(endTrack);
          }
        }
      }
    } else {
      // if the safety is switched off play the click track
      if (safety == true) {
        safety = false;
        playTrack(clickTrack);
      }
    }
  } else { // if we are powering down 
    clearPowerStrip(); // clear all led's
    shutdown_leds();

    if (startup == true) { // if started reset the variables
      startup = false;
      safety = false;
      fire = false;

      playTrack(shutdownTrack); // play the pack shutdown track
    }
  }
  delay(1);
}

/*************** Powercell Animations *********************/
unsigned long prevPwrBootMillis = 0;    // the last time we changed a light in the boot sequence
const long pwr_boot_interval = 400;     // interval at which to cycle lights (milliseconds).
unsigned long prevPwrMillis = 0;        // last time we changed a light in the idle sequence

int powerSeqTotal = 16;     // total number of led's for power
int powerBootSeqNum = 16;   // boot sequence counts down from 16
int powerSeqNum = 0;

// clears out and resets the power cell neopixel
void clearPowerStrip() {
  powerBooted = false;
  for ( int i = 0; i < powerSeqTotal; i++) {
    powerStick.setPixelColor(i, 0);
  }
  powerStick.show();
  powerSeqNum = 0;
  powerBootSeqNum = 16;
}

// boot animation on the bar graph
void powerSequenceBoot(int currentMillis) {
  if (currentMillis - prevPwrBootMillis > pwr_boot_interval) {
    // save the last time you blinked the LED
    prevPwrBootMillis = currentMillis;

    for ( int i = powerSeqTotal; i > 0; i--) {
      if ( i <= powerBootSeqNum ) {
        powerStick.setPixelColor(i, powerStick.Color(0, 0, 150));
      } else {
        powerStick.setPixelColor(i, 0);
      }
    }
    powerStick.show();
    if ( powerBootSeqNum > 0) {
      powerBootSeqNum--;
    } else {
      powerBooted = true;
      powerBootSeqNum = 16;
    }
  }
}

// normal animation on the bar graph
void powerSequenceOne(int currentMillis, int anispeed) {
  powerBootSeqNum = 16;
  if (currentMillis - prevPwrMillis > anispeed) {
    // save the last time you blinked the LED
    prevPwrMillis = currentMillis;

    for ( int i = 0; i < powerSeqTotal; i++) {
      if ( i <= powerSeqNum ) {
        powerStick.setPixelColor(i, powerStick.Color(0, 0, 150));
      } else {
        powerStick.setPixelColor(i, 0);
      }
    }
    powerStick.show();
    if ( powerSeqNum < powerSeqTotal) {
      powerSeqNum++;
    } else {
      powerSeqNum = 0;
    }
  }
}

/*************** Firing Animations *********************/
unsigned long prevFireMillis = 0;
const long fire_interval = 2;     // interval at which to cycle lights (milliseconds).
int fireSeqNum = 0;
int fireSeqTotal = 5;

void clearFireStrobe() {
  for ( int i = 0; i < 7; i++) {
    noseJewel.setPixelColor(i, 0);
  }
  noseJewel.show();
  fireSeqNum = 0;
}

void fireStrobe() {
  switch ( fireSeqNum ) {
    case 0:
      noseJewel.setPixelColor(0, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(1, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(2, 0);
      noseJewel.setPixelColor(3, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(4, 0);
      noseJewel.setPixelColor(5, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(6, 0);
      break;
    case 1:
      noseJewel.setPixelColor(0, noseJewel.Color(0, 0, 255));
      noseJewel.setPixelColor(1, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(3, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(4, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(5, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
      break;
    case 2:
      noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(1, 0);
      noseJewel.setPixelColor(2, noseJewel.Color(0, 0, 255));
      noseJewel.setPixelColor(3, 0);
      noseJewel.setPixelColor(4, noseJewel.Color(0, 0, 255));
      noseJewel.setPixelColor(5, 0);
      noseJewel.setPixelColor(6, noseJewel.Color(255, 0, 0));
      break;
    case 3:
      noseJewel.setPixelColor(0, noseJewel.Color(0, 0, 255));
      noseJewel.setPixelColor(1, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(3, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(4, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(5, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
      break;
    case 4:
      noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(1, 0);
      noseJewel.setPixelColor(2, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(3, 0);
      noseJewel.setPixelColor(4, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(5, 0);
      noseJewel.setPixelColor(6, noseJewel.Color(255, 255, 255));
      break;
    case 5:
      noseJewel.setPixelColor(0, noseJewel.Color(255, 0, 255));
      noseJewel.setPixelColor(1, noseJewel.Color(0, 255, 0));
      noseJewel.setPixelColor(2, noseJewel.Color(255, 0, 0));
      noseJewel.setPixelColor(3, noseJewel.Color(0, 0, 255));
      noseJewel.setPixelColor(4, noseJewel.Color(255, 0, 255));
      noseJewel.setPixelColor(5, noseJewel.Color(255, 255, 255));
      noseJewel.setPixelColor(6, noseJewel.Color(0, 0, 255));
      break;
  }

  noseJewel.show();

  fireSeqNum++;
  if ( fireSeqNum > fireSeqTotal ) {
    fireSeqNum = 0;
  }
}

/*************** Bar Graph Animations *********************/
// This is the idle sequence
unsigned long prevBarMillis_on = 0;   // bargraph on tracker
const long pwrcl_interval = 60;     // interval at which to cycle lights (milliseconds).
bool reverseSequenceOne = false;
void barGraphSequenceOne(int currentMillis) {
  // normal sync animation on the bar graph
  if (currentMillis - prevBarMillis_on > pwrcl_interval) {
    // save the last time you blinked the LED
    prevBarMillis_on = currentMillis;

    if ( reverseSequenceOne == false ) {
      switch_graph_led(seq_1_current, HIGH);
      seq_1_current++;
      if ( seq_1_current > num_led ) {
        reverseSequenceOne = true;
      }
    } else {
      switch_graph_led(seq_1_current, LOW);
      seq_1_current--;
      if ( seq_1_current < 0  ) {
        reverseSequenceOne = false;
      }
    }
  }
}

// This is the firing sequence
unsigned long prevBarMillis_fire = 0; // bargraph firing tracker
int fireSequenceNum = 1;
void barGraphSequenceTwo(int currentMillis) {
  if (currentMillis - prevBarMillis_fire > firing_interval) {
    // save the last time you blinked the LED
    prevBarMillis_fire = currentMillis;

    switch (fireSequenceNum) {
      case 1:
        switch_graph_led(2, LOW);
        switch_graph_led(14, LOW);
        switch_graph_led(1, HIGH);
        switch_graph_led(15, HIGH);
        fireSequenceNum++;
        break;
      case 2:
        switch_graph_led(1, LOW);
        switch_graph_led(15, LOW);
        switch_graph_led(2, HIGH);
        switch_graph_led(14, HIGH);
        fireSequenceNum++;
        break;
      case 3:
        switch_graph_led(2, LOW);
        switch_graph_led(14, LOW);
        switch_graph_led(3, HIGH);
        switch_graph_led(13, HIGH);
        fireSequenceNum++;
        break;
      case 4:
        switch_graph_led(3, LOW);
        switch_graph_led(13, LOW);
        switch_graph_led(4, HIGH);
        switch_graph_led(12, HIGH);
        fireSequenceNum++;
        break;
      case 5:
        switch_graph_led(4, LOW);
        switch_graph_led(12, LOW);
        switch_graph_led(5, HIGH);
        switch_graph_led(11, HIGH);
        fireSequenceNum++;
        break;
      case 6:
        switch_graph_led(5, LOW);
        switch_graph_led(11, LOW);
        switch_graph_led(6, HIGH);
        switch_graph_led(10, HIGH);
        fireSequenceNum++;
        break;
      case 7:
        switch_graph_led(6, LOW);
        switch_graph_led(10, LOW);
        switch_graph_led(7, HIGH);
        switch_graph_led(9, HIGH);
        fireSequenceNum++;
        break;
      case 8:
        switch_graph_led(7, LOW);
        switch_graph_led(9, LOW);
        switch_graph_led(6, HIGH);
        switch_graph_led(10, HIGH);
        fireSequenceNum++;
        break;
      case 9:
        switch_graph_led(6, LOW);
        switch_graph_led(10, LOW);
        switch_graph_led(5, HIGH);
        switch_graph_led(11, HIGH);
        fireSequenceNum++;
        break;
      case 10:
        switch_graph_led(5, LOW);
        switch_graph_led(11, LOW);
        switch_graph_led(4, HIGH);
        switch_graph_led(12, HIGH);
        fireSequenceNum++;
        break;
      case 11:
        switch_graph_led(4, LOW);
        switch_graph_led(12, LOW);
        switch_graph_led(3, HIGH);
        switch_graph_led(13, HIGH);
        fireSequenceNum++;
        break;
      case 12:
        switch_graph_led(3, LOW);
        switch_graph_led(13, LOW);
        switch_graph_led(2, HIGH);
        switch_graph_led(14, HIGH);
        fireSequenceNum = 1;
        break;
    }
  }
}

/************************* Shutdown and helper functions ****************************/
void shutdown_leds() {
  // reset the sequence
  seq_1_current = 1;
  fireSequenceNum = 1;

  // shut all led's off
  for (int i = 1; i <= 15; i++) {
    switch_graph_led(i, LOW);
  }
}

void switch_graph_led(int num, int state) {
  switch (num) {
    case 1:
      io.digitalWrite(SX1509_BAR_01, state);
      break;
    case 2:
      io.digitalWrite(SX1509_BAR_02, state);
      break;
    case 3:
      io.digitalWrite(SX1509_BAR_03, state);
      break;
    case 4:
      io.digitalWrite(SX1509_BAR_04, state);
      break;
    case 5:
      io.digitalWrite(SX1509_BAR_05, state);
      break;
    case 6:
      io.digitalWrite(SX1509_BAR_06, state);
      break;
    case 7:
      io.digitalWrite(SX1509_BAR_07, state);
      break;
    case 8:
      io.digitalWrite(SX1509_BAR_08, state);
      break;
    case 9:
      io.digitalWrite(SX1509_BAR_09, state);
      break;
    case 10:
      io.digitalWrite(SX1509_BAR_10, state);
      break;
    case 11:
      io.digitalWrite(SX1509_BAR_11, state);
      break;
    case 12:
      io.digitalWrite(SX1509_BAR_12, state);
      break;
    case 13:
      io.digitalWrite(SX1509_BAR_13, state);
      break;
    case 14:
      io.digitalWrite(SX1509_BAR_14, state);
      break;
    case 15:
      io.digitalWrite(SX1509_BAR_15, state);
      break;
  }
}
xoff00 liked this
#4897699
Updated video showing the new features. I pretty pleased with how it's coming out. Only thing that is bothering me right now is the little hiccup when it switches from normal firing sound to firing with the warning. I wanna figure out a way to make that a smoother transition. I think that will be sound file updates and not code changes.

User avatar
By xoff00
#4897709
CountDeMonet wrote:I've made some more updates to the code and I've redone some of the audio files. Now when in the warning time for firing it switches to the firing sound with the warning sound attached. When the firing stops after being in warning the pack is vented and rebooted.

I've also added 2 more dialog tracks at the end of the firing sequence if you get to the second firing level.

The bar graph animation is also sped up along with the powercell as you hold down the firing button.

And finally the pack will play the full ghostbusters theme song and not just a 20 second sample. I don't want to just post the sound files so if anyone wants them PM me and I'll send you a link to the zip with the ones I am using.

still have to do the cyclotron lights. I have not had a chance to solder those up. I've been busy printing the pack and fixing models this past week mainly.
Your code is light years better than mine, I appreciate you sharing it, I'm going to borrow large chunks of it. I haven't done any of the wand coding, but the basics for my cyclotron and powercell lights is down, but my version is just a millis() loop instead of responding to any button presses -- I was reserving that for v3 or v4 of the code, yours rocks!
Last edited by xoff00 on September 2nd, 2017, 7:37 pm, edited 1 time in total.
CountDeMonet liked this
#4897776
talem84 wrote:Thank you. Yeah I'm probably going to pick up that one to start printing the proton pack cyclotron . Thank you again
I'm still using the DancinFool's cyclotron for my son's pack build. I was able to print it in one piece at 83%. The rest of the pack is scaled width wise at 83% using this model as a base.

https://www.thingiverse.com/thing:2479141

I scaled it up, as it's already small, to near scale size then brought it back down to 83% of the real one to match the wand.

I've made a ton of other changes to the packs and even updated some of the dale resistor models to be more realistic. Once I have everything together I'll post my remix of these 2 packs to thingiverse as well. If anyone has a Spirit pack a lot of the detail parts should work nicely on that too. I have a lot of plans when mine comes in for sure.
WindDrake wrote:I have two Robo 3D R1+'s. Fantastic printers. Got one on sale and the other broken, repaired for cheap.

Big thanks to CountDeMonet - Almost finished with the wife's neutrona wand. :)

Image
That looks awesome! Very nice work. Now you are farther along than I am :) I still need to paint mine black and do all of the welds. I found some shiny silver paper that can actually take ink at michael's the other day. I'm going to try and make the clippard labels using that. I'm hoping it comes out well. I've tried a few other pieces of paper and other materials with not much luck
#4897825
Things get a lot simpler if you take the bar graph out of the mix

Image

I'm starting on how I want the boards to be setup that the arduino, sound board, bucks and audio amps are connected to. I've decided I'm going to make this a bit more professional and serviceable so ordered a ton of 2/3/4/5 Pin Male/Female connectors for breadboards. I'm thinking there will be at least 4 boards I have to make.
  1. One in the wand for the arduino with a ton of connectors. One for each switch/button, one for the static vent light, slow blow and rear lens light, one for the nose neopixel jewel, and one connector that will go to a cat5 cable to the pack. This will be a connector heavy board but should be cleaner.
  2. A connector board in the pack with the connector for the cat 5 to the wand. I'm thinking I may need to run the power and ground separately as well instead of going thru the cat5 so there would be 2 cables between the wand/pack. The cat 5 and then the power/ground 18 gauge wire.
  3. a board for the adafruit sound board with the two buck converters and the two amps with connections to the connector board and the neopixel board
  4. and finally a board for all of the neopixels to connect to for the powercell and the cyclotron lights.
I have all of the wiring in my head right now. We'll see if I can get it all to work out. If I had time I'd fabricate some boards from oshpark but I don't think I have enough time to do that before halloween. I will definitely do that when I build my full size pack next year with the board for the bargraph
grogking, xoff00 liked this
User avatar
By xoff00
#4897828
CountDeMonet wrote:Things get a lot simpler if you take the bar graph out of the mix

I'm starting on how I want the boards to be setup that the arduino, sound board, bucks and audio amps are connected to. I've decided I'm going to make this a bit more professional and serviceable so ordered a ton of 2/3/4/5 Pin Male/Female connectors for breadboards. I'm thinking there will be at least 4 boards I have to make.
  1. One in the wand for the arduino with a ton of connectors. One for each switch/button, one for the static vent light, slow blow and rear lens light, one for the nose neopixel jewel, and one connector that will go to a cat5 cable to the pack. This will be a connector heavy board but should be cleaner.
  2. A connector board in the pack with the connector for the cat 5 to the wand. I'm thinking I may need to run the power and ground separately as well instead of going thru the cat5 so there would be 2 cables between the wand/pack. The cat 5 and then the power/ground 18 gauge wire.
  3. a board for the adafruit sound board with the two buck converters and the two amps with connections to the connector board and the neopixel board
  4. and finally a board for all of the neopixels to connect to for the powercell and the cyclotron lights.
I have all of the wiring in my head right now. We'll see if I can get it all to work out. If I had time I'd fabricate some boards from oshpark but I don't think I have enough time to do that before halloween. I will definitely do that when I build my full size pack next year with the board for the bargraph
Very similar to my thoughts. I was thinking of using individual 5mm neopixels for all/most of the "regular" LEDs so I can just daisy chain them together and only need 3 pins for all of them, including the nose jewel.

Standard cat5 cable has 8 wires (4 pair) and is 24awg (which can handle about 500ma) so I was going to do:
  • 5v power
    5v GND
    3.3v power
    3.3v GND
    I2C SCL
    I2C SCA
    OPEN
    OPEN
This lets me double up on 5v power with another wire if needed. I was thinking the last wire might be for an interrupt for bringing to pack from a "standby" low-power mode or something.

I'm still deciding on how to physically mount the Arduino and Soundboard (I gave in and just ordered the soundboard so your code works instead of trying to adapter the MP3 shield) -- I've got alternating ideas of just gluing standoffs to the motherboard or making some sort of wood/plastic "daughterboard" everything attaches to.

Major +1 for OSHPark. This was a great experience making my first board!

After seeing how things fit in the Wand I'll likely be redoing my custom board to fit 2 SX1509s, the bargraph ribbon cable, the attachments for the switches/buttons/lights, and an RJ45 jack.
CountDeMonet liked this
#4897832
xoff00 wrote: Very similar to my thoughts. I was thinking of using individual 5mm neopixels for all/most of the "regular" LEDs so I can just daisy chain them together and only need 3 pins for all of them, including the nose jewel.

Standard cat5 cable has 8 wires (4 pair) and is 24awg (which can handle about 500ma) so I was going to do:
  • 5v power
    5v GND
    3.3v power
    3.3v GND
    I2C SCL
    I2C SCA
    OPEN
    OPEN
This lets me double up on 5v power with another wire if needed. I was thinking the last wire might be for an interrupt for bringing to pack from a "standby" low-power mode or something.

I'm still deciding on how to physically mount the Arduino and Soundboard (I gave in and just ordered the soundboard so your code works instead of trying to adapter the MP3 shield) -- I've got alternating ideas of just gluing standoffs to the motherboard or making some sort of wood/plastic "daughterboard" everything attaches to.

Major +1 for OSHPark. This was a great experience making my first board!

After seeing how things fit in the Wand I'll likely be redoing my custom board to fit 2 SX1509s, the bargraph ribbon cable, the attachments for the switches/buttons/lights, and an RJ45 jack.
Interesting, I thought the cat5 current was a lot lower than that per wire. I'll have to double check. If I can do the power over that too that does simplify things. Once I have the final size for the boards I make I'll be fabricating simple mounts with the printer that I can then glue into the body. Since there is no metal I could probably get away with just hot gluing the boards right in place but I want to be able to remove them if I have to. I hot glued them in the pke meter due to space and it worked well.

Oshpark is awesome and seem to be getting faster. My last boards were to my house in less than 2 weeks. I've ordered a number of things from them and the service has been awesome.
talem84 wrote:So I found out it was just the usb cable that wasn't working .I hope it's okay that I will be using your code and possibly diagrams to make my own.
It's the whole reason I shared everything. I look forward to seeing what you come up with :) For me the fun part is collaborating on all of this. The design we have now is significantly changed for the better due to all of you guys.
User avatar
By xoff00
#4897834
CountDeMonet wrote: Interesting, I thought the cat5 current was a lot lower than that per wire. I'll have to double check. If I can do the power over that too that does simplify things.
I've been using this chart: https://www.powerstream.com/Wire_Size.htm which claims it's numbers as being from The Handbook of Electronic Tables and Formulas, but Wikipedia shows a lot higher Ampacity (a word I would never have searched on!) https://en.wikipedia.org/wiki/American_ ... wire_sizes
CountDeMonet wrote:Once I have the final size for the boards I make I'll be fabricating simple mounts with the printer that I can then glue into the body. Since there is no metal I could probably get away with just hot gluing the boards right in place but I want to be able to remove them if I have to. I hot glued them in the pke meter due to space and it worked well.
In the past I've epoxied threaded standoffs to metal frames and then bolted the boards to that. It works pretty well and makes things removable...I was thinking an entire subplate doing the same thing, here.
CountDeMonet wrote: It's the whole reason I shared everything. I look forward to seeing what you come up with :) For me the fun part is collaborating on all of this. The design we have now is significantly changed for the better due to all of you guys.
Feel the same way! We've come a long way together!
#4897840
I don't have a dagram but I have detailed pictures in this post

viewtopic.php?p=4897293#p4897293

With a detailed video walk through in the post after. Using the pictures and the code you can figure out what's all connected. I've tried to use the diagram software like fritzing but not everything I use is available to make a nice diagram. Before I pull it all apart I'll probably draw everything by hand. That might be the best I can do
User avatar
By xoff00
#4897844
Try out kicad -- http://kicad-pcb.org/ -- it's free and I found it far easier to use for schematics that Fritzing, and far less confusing than Eagle (which isn't free anymore...) Kicad does PCB layout, too, and the files it produces are directly accepted by OSHPark without making gerber.
#4897858
xoff00 wrote:Ah, I'm wrong -- apparently it's still free for personal use, but everything else is pay: https://hackaday.com/2017/01/19/autodes ... y-pricing/

Still, I found Eagle a pain, and while kicad was still esoteric, it was easier for me, and the schematic portion is better than Fritzing.
Other than Eagle I've used diptrace in the past. It was ok but I actually found eagle easier with the auto layout and routing. I'll have to give kicad a try.
talem84 wrote:https://github.com/bendetat/venkman/blo ... /README.md
This github has some easy sciatica . Don't know if it will hel0 anymore
That was one of the early ones I was looking at. I tried to get the shift registers working but my knowledge of binary is severely limited and I was not able to get what I wanted out of it. I was able to get the basics working from that setup though. In the end the amount of wiring for the shift register was impressive. Utilizing the SX1509 proved simpler and more powerful in my mind. As far as I know our setup is the first to utilize it as well as neopixels for the main lighting. Lots of options for LED animations with the neopixels. Now if only they would come out with a 15 or 16 segment neopixel bargraph :)
By grogking
#4897872
I also started in on the electronic mounts. The first being the cyclotron lights. I'm looking to find some red transparent file folders and cut those to make the lenses. Then those will be cut to fit under the lip and then the cup for the neopixel will be glued onto that. I think it'll work pretty good.
Can I make a suggestion? Get a highly reflective red paint, and paint the 3d printed LED cyclotron mounts. Then you can get a piece of 1/8 clear acrylic from lowes for the lenses.

The reason is the folders are cheap and scratch and cloud up easily. The acrylic is tougher and stands up to more abuse.
  • 1
  • 4
  • 5
  • 6
  • 7
  • 8
  • 25
Positron Props GB1 Pack Build

Awesome!! Good luck on your build! Tom's shell i[…]

Trailer posted for release for the Frozen Empire u[…]

Trivia, callbacks etc I noticed so far *Cover A *[…]

Matty Trap - Replace Pedal?

Has anyone successfully transferred the pedal elec[…]