#4896288
I've got 3 questions (as parts start to reach my doorstep).
1. What would be a good mess of wires to use on the final product?
2. Are you planning on soldering it all together, or is there another solution? (When messing with the breadboard I would prefer to not have to solder just to test, then unsolder and then resolder to final product)
3. Have you had a chance to draw a schematic for your wiring (or at least taken a picture of you breadboard for reference?)
#4896709
The jewels haven't arrived yet (yet!) but I've taken to the neopixels (for the powercell) to work on my programming. Are you using the FastLED library to control your cyclotron, or the adafruit_neopixel library?

Second question, do you have each cyclotron light on it's own pin, or did you daisy them all on one pin and then control them like (0-6), (7-13),(14-20),(21-27)? (maybe in an array?)
#4896753
This post may contain an affiliate link that helps support GBFans.com when you make a purchase at no additional cost to you.

I'm going to be using a 16 wire ribbon cable for the bar graph (https://www.amazon.com/gp/product/B01EV70C78). The power wire is a 20 gauge speaker wire I got at home depot. I've got tons of that stuff. The rest of the wires are a mix of this stuff (https://www.amazon.com/gp/product/B01KOEZ29U) that I used on my PKE Meter and my other projects

For prototyping I use solderless breadboards (https://www.amazon.com/gp/product/B01EV6LJ7G) with jumper wires. (https://www.amazon.com/Solderless-Flexi ... per-100pcs)

I am planning to solder it all together. As an example you can look back up to the bargraph earlier in the thread. I have a ton of prototyping boards (https://www.amazon.com/gp/product/B01IONQQ3Y) that I'll be using to clean everything up. There will be 1 board in the thrower for the arduino and sx1509 and then another board in the pack with the buck converter, sound fx board, and speaker amp.

I don't have a full schematic yet. It has been changing quite a bit. I was originally going to go with 2 arduinos but I don't think I will need that. I'm in the process of putting back together the circuit that I took apart in the last video now :) Once I have that back together I'll post an image of it as the plan has solidified.

I'm planning to use 2 pins for the neopixels. One for the jewel in the nose of the thrower and then one for the powercell/cyclotron lights. They will all be strung together to save pins. The way I'm counting it right now is

input pins:
3 for switches in the thrower
1 for activation button

output pins
3 for the fx board
1 for neopixel in the nose
1 for neopixels in the pack

SDA/SCL to the sx1509

by my count that's 9 pins in use which leaves me a few pins to control random LED's for inside the body or on the pack. I'm wiring all of this up right now on my breadboard to finalize the code and then will figure out what the final soldered boards will look like.

for the neopixels I'm using the adafruit_neopixel lib. It works well. I didn't know about the other one but will take a look at it.
#4896757
A word of warning to those 3d printing. I just ruined a good chunk of the wand by using filler primer on it.

http://www.rustoleum.com/product-catalo ... imer-spray

If you do use it you have to go with really light coats. It heated up and warped the entire gun track part. I'll have to reprint it. I'll also have to reprint the side of the gunbox as that warped bad as well. Live and learn.
#4896759
This post may contain an affiliate link that helps support GBFans.com when you make a purchase at no additional cost to you.

Oh man, sorry about your 3D printed parts. I wish I had a 3D printer so I have the opportunity to melt the parts with primer. I wonder if there's isn't something else that wasn't such a hazard to the material...

I've got the motherboards (4 of them) made for the pack, and I'm on my third go with the programming. The first one turned to crap, the second one was OK (all Adafruit Library), but with the third one I'm planning on using FastLED for the code (cyclotron on one pin) instead of the adafruit one, and another pin for the powercell light. (But you're right; by count of pins on one nano, it might be tight).

FastLED is really easy and once you wrap your head around the syntax changing colors is a snap (especially because for this project it's like "blue", "red" maybe "green"?) You still think a breakout board is needed? (Coming from a guy who doesn't really know how to wire it up.)

I've got some wiring from my stairs project left over https://youtu.be/jM8gDLn-Woc that I can use, but I might pick up that other wiring spool you linked for the length of the tubing to the thrower and to the powercell.

Already got prototyping breadboards in the mail, :cool: I plan on using that image you have for the leds, but your video, while cool, is hard to distinguish what goes where. I did create a simple diagram of all my parts https://imgur.com/a/Ez9VQ in hopes that I or someone could draw the lines between one thing to the next for wiring purposes. (I guess I don't need that extra nano if the leds can be cut down on real estate.)

Lastly, that battery you suggested, has a few less mAh than this bad boy, https://www.amazon.com/Anker-PowerCore- ... ttery+pack. Why wouldn't you just use this and plug it right into the nano's USB? (Or maybe you don't because you have to power the speakers with it: again, I'm not the best at power usage and wiring.)

I look forward to seeing what you come up with.
#4896767
I'm in the process of wiring it all back up. I should have it in the next day or so and will be able to show detailed pics. Now that things are pretty much settled I can probably draw something up by hand pretty easy.

I'm running power directly to the neopixels, soundboard, speaker amp, and arduino from the buck converter at 5v. You don't want to power the arduino and then try to power everything else off the arduinos 5v. It will not work well. TBH I may need a second buck converter but we'll see. With a single speaker I was well below 3 amps last time I tested it with the current setup but if I go with 2 it could put me over and force me into a second buck converter.

The only thing I power off the arduino is the sx1509 as that is 3v

I updated the model on thingiverse. https://www.thingiverse.com/thing:2334883

Since I have to reprint the baseplate and gun track I went ahead and redid that part to make it look better and be more solid. I also posted the updated main with the thicker roof. I've been printing off the pack parts to start that build so I have to wait another 4 hours or so before I can print off the parts to repair the oops.
#4896770
I have the code back together into one file. This is basically what you saw in the video with a few updates. I'm about to write the code for the cyclotron as well. I think I'm pretty close to getting this all up on github.

This code has the following features:
1. Sound triggers for the various features
2. Two different bargraph animations. One for idle and one for firing
3. Two different powercell animations. Once for startup and one for idle (I might add code to speed it up while firing)
4. Play's the ghostbuster theme when the main bottom switch is thrown
5. Handles the various input switches and button
6. Does the firing animation at the nose of the wand with the neopixel

When I get all of this up on github I'll post the sound files too. I might make a few more modifications yet and maybe add a few more sayings
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 
#define SFX_RST 2
#define SFX_RX 3
#define SFX_TX 4

SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);
Adafruit_Soundboard sfx = Adafruit_Soundboard( & ss, NULL, SFX_RST);
const int ACT = 13;

// inputs
const int THEME_SWITCH = 5;
const int STARTUP_SWITCH = 6;
const int SAFETY_SWITCH = 7;
const int FIRE_BUTTON = 8;

// switch states
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 texTrack = 7;
const int choreTrack = 8;
const int toolsTrack = 9;
const int themeTrack = 10;

// dialog trigger times/states
unsigned long startDialogMillis;
const int numDialog = 3;
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

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:
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
  ss.begin(9600);

  // see if we have the soundboard 
  // if not we gotta flash lights or something
  if (!sfx.reset()) {
    while (1);
  }

  // set pin modes for the 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 lets 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'

  // handle the switches
  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);

  shutdown_leds();  
}

bool isFiring = false;

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();
}

void loop() {
  int currentMillis = millis();
  int theme_switch = digitalRead(THEME_SWITCH);
  int playing = digitalRead(ACT);
  
  if (theme_switch == 1) {
    if (theme == false) {
      playTrack(themeTrack); // send message to other board to play track
      theme = true;
    }
  } else {
    theme = false;
  }

  int startup_switch = digitalRead(STARTUP_SWITCH);
  int safety_switch = digitalRead(SAFETY_SWITCH);
  int fire_button = digitalRead(FIRE_BUTTON);
  if (startup_switch == 1) {
    if (playing == 1) {
      playTrack(idleTrack); // send message to other board to play track
    }

    if( powerBooted == true ){
      powerSequenceOne(currentMillis);
    }else{
      powerSequenceBoot(currentMillis);
    }
    
    if (startup == false) {
      startup = true;
      playTrack(startupTrack); // send message to other board to play track

      if (safety_switch == 1 && safety == false) {
        safety = true;
      }
    }

    if( safety_switch == 1 && fire_button == 0){
      if( isFiring == false ){
        shutdown_leds();
        isFiring = true;
      }
      barGraphSequenceTwo(currentMillis);
    }else{
      if( isFiring == true ){
        shutdown_leds();
        isFiring = false;
      }
      barGraphSequenceOne(currentMillis);
    }

    // fire loop 
    if (startup == true && safety_switch == 1) {
      if (safety == false) {
        safety = true;
        playTrack(clickTrack); // send message to other board to play track
      }

      if (fire_button == 0) {
        fireStrobe();
        if (fire == false) {
          fire = true;
          startDialogMillis = millis();
          playTrack(blastTrack); // send message to other board to play track
        } else {
          if (playing == 1) {
            playTrack(blastTrack); // send message to other board to play track
          }
        }
      } else {
        if (fire == true) {
          clearFireStrobe();
          fire = false;
          // see if we've been firing long enough to get the dialog
          long diff = millis() - startDialogMillis;
          if( diff > warnWaitTime){
            playTrack(warnTrack); // send message to other board to play track
          }else if( diff > dialogWaitTime){
            switch(currentDialog){
              case(1):
                playTrack(choreTrack); // send message to other board to play track
                break;
              case(2):
                playTrack(toolsTrack); // send message to other board to play track
                break;
              case(3):
                playTrack(texTrack); // send message to other board to play track
                break;
            }
            if( currentDialog >= numDialog ){
              currentDialog = 1;
            }else{
              currentDialog++;
            }
          }else{
            playTrack(endTrack); // send message to other board to play track
          }
        }
      }
    } else {
      if (safety == true) {
        safety = false;
        playTrack(clickTrack); // send message to other board to play track
      }
    }
  } else {
    clearPowerStrip();
    shutdown_leds();
    
    if (startup == true) {
      startup = false;
      safety = false;
      fire = false;

      playTrack(shutdownTrack); // send message to other board to play track
    }
  }
  delay(1);
}

/*************** Powercell Animations *********************/
unsigned long prevPwrBootMillis = 0; 
const long pwr_boot_interval = 300;     // interval at which to cycle lights (milliseconds).
unsigned long prevPwrMillis = 0; 
const long pwr_interval = 40;     // interval at which to cycle lights (milliseconds).

int powerSeqTotal = 16; // total number of led's for power
int powerBootSeqNum = 16;
int powerSeqNum = 0;

void clearPowerStrip(){
  powerBooted = false;
  for( int i=0; i< powerSeqTotal; i++) {
     powerStick.setPixelColor(i, 0);
  }
  powerStick.show();
  powerSeqNum = 0;
  powerBootSeqNum = 16;
}

void powerSequenceBoot(int currentMillis){
  // normal sync animation on the bar graph
  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;
      }
  }
}

void powerSequenceOne(int currentMillis){
  powerBootSeqNum = 16;
  // normal sync animation on the bar graph
  if (currentMillis - prevPwrMillis > pwr_interval) {
      // 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 = 3;

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(0,0,255));
      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;
  }

  noseJewel.show();

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

/*************** Bar Graph Animations *********************/
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;
        }
    }
  }
}

unsigned long prevBarMillis_fire = 0; // bargraph firing tracker
const long firing_interval = 40;    // interval at which to cycle firing lights (milliseconds).
int fireSequenceNum = 1;
void barGraphSequenceTwo(int currentMillis){
  // normal sync animation on the bar graph
  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;

  clearPowerStrip();
  
  // shut all led's off
  switch_graph_led(1, LOW); 
  switch_graph_led(2, LOW); 
  switch_graph_led(3, LOW); 
  switch_graph_led(4, LOW); 
  switch_graph_led(5, LOW); 
  switch_graph_led(6, LOW); 
  switch_graph_led(7, LOW); 
  switch_graph_led(8, LOW); 
  switch_graph_led(9, LOW); 
  switch_graph_led(10, LOW); 
  switch_graph_led(11, LOW); 
  switch_graph_led(12, LOW); 
  switch_graph_led(13, LOW); 
  switch_graph_led(14, LOW);
  switch_graph_led(15, 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;
    }
  }
#4896815
Which 3D printer do you have? I've seen some as low as $200 on Amazon (da vinci) but just for funzies I was looking online at the different ones (no money for one, though).

So you basically got the battery wired to the buck converter and then have a splitter (or just a wire nut on a bunch of wires to the various components? I'm very interested to see how you have that wired up!

There's a few questions I have about your code (but A. there's a lot I DON'T know what's going on there and B. each person's code is a bit different) but I would love to play with it! Since I'm transitioning all my code over to FastLEDs I'll share it with you when I get confident that it's on point. One question is when I see stuff like:
Code: Select all
  // shut all led's off
  switch_graph_led(1, LOW); 
  switch_graph_led(2, LOW); 
  switch_graph_led(3, LOW); 
  switch_graph_led(4, LOW); 
  switch_graph_led(5, LOW); 
  switch_graph_led(6, LOW); 
  switch_graph_led(7, LOW); 
  switch_graph_led(8, LOW); 
  switch_graph_led(9, LOW); 
  switch_graph_led(10, LOW); 
  switch_graph_led(11, LOW); 
  switch_graph_led(12, LOW); 
  switch_graph_led(13, LOW); 
  switch_graph_led(14, LOW);
  switch_graph_led(15, LOW);
what is your decision for not throwing it in a for loop?
Code: Select all
  // shut all led's off
  for(int i=1;i<=15;i++){
      switch_graph_led(i, LOW); 
  }
I wish I knew how to wire it all together. I'm using a finite state machine and just getting the switches to do various things (and sound would be so COOL!) would be such a morale booster! To flip a switch and get that sound: oh my God!

I'm excited to see your progress, cause it both fascinates me and inspires me to learn and build more myself!
#4896822
I have 2 printers. I have the Davinci Mini which is a great first printer as it's easy to get started and get good quality prints out. It is however expensive when it comes to filament. You are paying for the ease of use. My other printer is the Monoprice Maker Select v2. It's the one I use the most now but it did take quite a bit of work to get printing nicely. Luckily a lot of the upgrade parts can be printed from thingiverse for it. I did have to buy the upgrade mosfet board for the bed heater and get some Z braces. There is also a substantial learning curve with the slicer software.

You can get the idea on the wiring by looking at the init area. That is where the pins are specified and what they hook up to.
Code: Select all
// neopixel pins
#define NEO_NOSE 9 // data pin for nose of wand
#define NEO_POWER 10 // data pin for powercell

// soundboard 
#define SFX_RST 2
#define SFX_RX 3
#define SFX_TX 4
const int ACT = 13; // this pin is optional but lets you read if the sfx board is currently playing or not. I found it useful

// inputs
const int THEME_SWITCH = 5;
const int STARTUP_SWITCH = 6;
const int SAFETY_SWITCH = 7;
const int FIRE_BUTTON = 8;

the SX1509 is hooked up to the i2c bus which is A4 and A5

// SX1509 pin definitions:
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; 
You are correct that I could optimize that code by using a loop there. :)

For the power I'm planning to have a power/ground rail on the mounting boards I create for all of the components to connect to. That power rail will come right from the buck converter.
#4896954
Ran into another issue today. This time it has nothing to do with the models or the electronics. A new proton pack was released on thingiverse over the past week or so and I've been looking at it in detail. I really like the printability of the pack itself. DancinFool's, while very good and detailed, is proving a bit difficult to print in areas. I started doing a mixture of the two models as I want and to add in the channels and stuff for the electronics when my wife started asking me questions about size. I've been planning on keeping the thrower full size while scaling down the pack to about 85-90%. I showed my wife the dimensions and she just said no. Way to big for our 7 year old. I started to look at it in more detail and if I take the pack down to 70% where I was originally looking the thrower has to drop in size as well otherwise it looks completely out of proportion.

I'm not sure what I'm going to do yet. My son has to have a pack for halloween so I may just need to scale everything down to 75% or so and then look at doing really minimal electronics for it. I guess I can look at doing a full pack for myself at some point as I have enough parts printed to nearly put one together.
#4896956
Well having to scale it down more means just more printing? (I hope you can get it done in time!)

I don't think finding another pattern to print online is an issue. While time consuming, it can be fun to explore someone else's vision of the pack.

Here's what I have so far. Don't have Millis() put in yet (kinda still learning it) but I'm pretty confident in my cyclotron code (the powercell will be cake). So, I'm going to try and focus on the sound and the switches. I keep going back and forth between your setup and an example to get it wired up and testing.

One thing (maybe you can chime in) that I'm having a snag is I'll plug in the 5V from the uno to the soundcard, the ground, then I'll plug in my Omaker M4 bluetooth speaker to the audio out and touch the GND + 1, 2, 3 or whatever. I see the light flash as it's repeating the sound, but I'm not getting anything out of the speakers. When I plug in my PC speakers, however, I get sound. Does it need more power than the 5V from the nano?

And then I've still gotta find a speaker. :sigh: When I plug in my PC speakers, it's got a nice big sub, and that's the sound I'm looking for, but I can't fit that in the motherboard.
Code: Select all
// for the sound board
#include <SoftwareSerial.h>
#include "Adafruit_Soundboard.h"

// for the leds
#include <Adafruit_NeoPixel.h>

#define PIN2 2                          // cyclotron upper left light
//#define PIN3 3                          // cyclotron upper right light
//#define PIN4 4                          // cyclotron lower left light
//#define PIN5 5                          // cyclotron lower left light


#define CYC_LED_NUM 28                  // # of LEDS on each cyclotron gem (7)
int rotatenum = 0;                      // rotates between cyclotron lights
int i = 0;                              // counter for initalizing gems in setup()
const float fadeIncr = .5;              // how slow/fast to fade before going to next gem (lower number = slower cyclotron/faster number = faster cyclotron)
const int LED_PER_GEM = 7;              // how many leds on each cyclotron gem?
int oh = 10;                      // overheat timer (how long to flash overheat)

#define CYC_STARTUP   1           // DSM state: (kick on sound, all lights on then fade up and down a bit)
#define CYC_AT_REST   2           // DSM state: (lights cycle, sound hums)
#define CYC_FIRING    3           // DSM state: (lights flash faster & faster, fire sound, counter ticks up to overheat)
#define CYC_COOLDOWN  4           // DSM state: (finger off the trigger & cyclotron light slow to normal, power down sound)
#define CYC_OVERHEAT  5           // DSM state: (counter counts down, alarm blares, all cyclotron light flash)
#define CYC_SHUTDOWN  6           // DSM state: (after overheat, all 4 lights fade down, then to startup)
char packState = CYC_OVERHEAT;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;   // will store last time LED was updated
const long interval = 1000;         // interval at which to blink (milliseconds)

// switches
boolean canFire = false;

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// Adafruit_NeoPixel(Parameter1, Parameter2, NEO_GRB + NEO_KHZ800)
Adafruit_NeoPixel cycloPins = Adafruit_NeoPixel(CYC_LED_NUM, PIN2, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);             // for serial print (testing)
  
  cycloPins.begin();            // prepare the data pin for NeoPixel output
  cycloPins.show();             // this initializes all the NeoPixels to an initial “off” state in case some were left lit by a prior program

  //Serial.print(" show#: ");
  //Serial.print(i);
}

void loop() {

  switch (packState) {
    case CYC_STARTUP:                 // initial turn on sound, cyclotron lights flash on like a hard start
      canFire = false;
      break;    
    case CYC_AT_REST:                 // each gem lights up and fades repeating sequence
      canFire = true;
      cycRotateLED();                 
      break;
    case CYC_FIRING:                  // while the button is held down, lights continue to flash in succession
      break;  
    case CYC_COOLDOWN:                // for later (maybe smoke?)
      break;  
    case CYC_OVERHEAT:                // all 4 gems flash red for a specified amount of time
      canFire = false;
      while(oh >= 0){
      cycOverheat();                   
      oh--;
      }
      packState = CYC_SHUTDOWN;
      break;  
    case CYC_SHUTDOWN:                // all 4 gems light up then slowly die out
      cycShutdown();                  
      delay(1000);
      packState = CYC_AT_REST;
      break;
    default: 
      // if nothing else matches, do the default
      // default is optional
    break;
  }
  
  // code here to check for firing button pressed
  
  nextLED();                        // iterates to the next gem
}

void nextLED(){
  if(rotatenum < 3){
    rotatenum++;
  } else {
    rotatenum=0;
  }
  Serial.print(" rotatenum#: ");
  Serial.print(rotatenum);
}

void cycRotateLED() {
  // light leds in sequense (increments of LED_PER_GEM (or 7)
  cycloPins.setBrightness(255);
  for(int i = LED_PER_GEM * rotatenum; i <= 6 + LED_PER_GEM * rotatenum; i++){
    cycloPins.setPixelColor(i, 255,0,0);        // RED // setPixelColor(n, red, green, blue)
    cycloPins.show();
  }
  // fade those leds that lit up
  for(float y=255;y>=0;y=y-fadeIncr){
    cycloPins.setBrightness(y);                 // change the brightness for next time through the loop:
    cycloPins.show();
    delay(2);
  }
    cycloPins.setBrightness(0);                 // make sure that it's black before moving on
} 

void cycOverheat(){

  for(int oh=0;oh<=3;oh++){                     // all LEDs on
    cycloPins.setBrightness(255); 
    for(int i=0; i<CYC_LED_NUM; i++){
      cycloPins.setPixelColor(i, 255,0,0);  // RED // setPixelColor(n, red, green, blue)
    }
  cycloPins.show();       
  }
  delay(300);

  for(int oh=0;oh<=3;oh++){                     // all LEDs off (blinking)
    cycloPins.setBrightness(0); 
    for(int i=0; i<CYC_LED_NUM; i++){
      cycloPins.setPixelColor(i, 255,0,0);  // RED // setPixelColor(n, red, green, blue)
    }
  cycloPins.show();       
  }
  delay(300);
}

void cycShutdown(){
  
  for(int sd=0;sd<=3;sd++){                     // all LEDs on
    cycloPins.setBrightness(255); 
    for(int i=0; i<CYC_LED_NUM; i++){
      cycloPins.setPixelColor(i, 255,0,0);  // RED // setPixelColor(n, red, green, blue)
    }
  cycloPins.show();       
  }
  delay(300);
  
  for(int y=255;y>=0;y--){                      // all dip into black
      for(int sd=0;sd<=3;sd++){
      cycloPins.setBrightness(y);           // change the brightness for next time through the loop:
      cycloPins.show();
      }
      delay(3);
    }
  delay(2000);
}
#4896960
It is likely that the sound board and the amp need more juice than the arduino can provide. If you turn the volume down on the arduino it should eventually play if you have a small enough speaker. It just won't be very loud off the arduino 5v. I have mine wired similarly to this:

https://learn.adafruit.com/assets/23313

where the fx board and the amp are powered separately. The difference in my wiring is instead of the power coming off the 5v from the arduino I power everything on the breadboard directly from the buck converter. I have the 5v on the arduino connected to the buck converter, the 5v on the fx board to the buck converter, and the 5v on the amp to the buck converter. The only out I use from the arduino is the 3v for the sx1509.

I've already started printing everything out. I'm going to target 82% and see if I can get away with that size. As long as I can keep the weight down it should be ok for him. Everything has to be reprinted though so these printers are going to be printing non stop for the next few weeks. Luckily I can print a lot of the small stuff on the davinci.

One thing that will be lost on the smaller version is the bar graph. Just going to have to be that way as there is not enough space for it. I've made modifications to the models to accommodate the electronics I want to put in at 82%. I'll be printing those parts first to quadruple check tho

I've not done the cyclotron code yet. Thanks for sharing. :)
#4897001
Here's what I have for wiring? I'm kinda going off of your init that you posted. Does it look good so far? (albeit messy)

I've only gone as far as I know; I'm still not sure how to wire up the breakout board, switch, or the leds once I get them attached to the prototyping board.

And how to I connect he battery to the 20 gauge wire? It's got a strange plug I've never seen before.

https://imgur.com/a/gyWo9
#4897002
Tebasaki wrote:The jewels haven't arrived yet (yet!) but I've taken to the neopixels (for the powercell) to work on my programming. Are you using the FastLED library to control your cyclotron, or the adafruit_neopixel library?

Second question, do you have each cyclotron light on it's own pin, or did you daisy them all on one pin and then control them like (0-6), (7-13),(14-20),(21-27)? (maybe in an array?)
My build (which is similar CountDeMonet's in many ways, we tag-teamed a lot of development in this thread) uses the FastLED library, which I like better than the Adafruit one. I'm using a single "array" Neopixels for all four of the cyclotron lights, as you described (0-6, 7-13, etc.)

My powercell is a separate 144pixel/m Neopixel strip.
#4897003
Tebasaki wrote:Here's what I have for wiring? I'm kinda going off of your init that you posted. Does it look good so far? (albeit messy)

I've only gone as far as I know; I'm still not sure how to wire up the breakout board, switch, or the leds once I get them attached to the prototyping board.

And how to I connect he battery to the 20 gauge wire? It's got a strange plug I've never seen before.

https://imgur.com/a/gyWo9
I switched to silicon wire of a couple of gauges...man, is it flexible! Highly recommend it!

Pack to Wand is a networking cable, which has 8 wires, which is plenty for my needs (5v/GND, 3v3/GND, I2C control SDA/SCL, two extra.)

For your power supply, that's a standard connector, just google around and you'll find what it's called and can buy some to attack to your board.
#4897004
Tebasaki wrote:Well having to scale it down more means just more printing? (I hope you can get it done in time!)

I don't think finding another pattern to print online is an issue. While time consuming, it can be fun to explore someone else's vision of the pack.

Here's what I have so far. Don't have Millis() put in yet (kinda still learning it) but I'm pretty confident in my cyclotron code (the powercell will be cake). So, I'm going to try and focus on the sound and the switches. I keep going back and forth between your setup and an example to get it wired up and testing.

One thing (maybe you can chime in) that I'm having a snag is I'll plug in the 5V from the uno to the soundcard, the ground, then I'll plug in my Omaker M4 bluetooth speaker to the audio out and touch the GND + 1, 2, 3 or whatever. I see the light flash as it's repeating the sound, but I'm not getting anything out of the speakers. When I plug in my PC speakers, however, I get sound. Does it need more power than the 5V from the nano?

And then I've still gotta find a speaker. :sigh: When I plug in my PC speakers, it's got a nice big sub, and that's the sound I'm looking for, but I can't fit that in the motherboard.
For me, I have a 12v supply and individual feeds to my speaker (which is a huge awesome secret I hope works...), the Arduino, and the Neopixels using individual Battery Elimination Circuits (BECs.) Like the Count, the only thing running off the Arduino is the SX1509 (and, therefore, the Wand's bargraph.)
#4897013
This was where I got to with the wand. It was getting really close :)

Image
Image
Image

Here are some closeups of the wiring of the sx1509.

First the buck converter powers the top rails on the breadboard

Image

Image

The sx1509 power is plugged into the arduino 3v out and the ground. It can be the arduino or the buck ground. In this case you can see a little jumper where I connected the ground from the buck converter into the bottom ground rail. The SDA/SLC are then connected to the A4/A5 pins. Other than that all of the inputs and the led outputs are on the top left of the arduino. This setup is all for the wand. I have the other board ready to hook up to this one for the sound module/power/cyclotron hooked up on a separate breadboard since that's how it will be in the pack.

Image

All of the outs are then, for this setup, put in order so I can connect the ribbon cable

Image

And finally the ribbon is connected along with the ground to the buck ground and the circuit is complete for that one

Image

My battery uses old Deans style connectors. The RC world moved on from those a while ago but I still like them. Very high current support. You can clip that connector off and put a new one on. Just make sure to cut each lead individually and not allow them to touch while soldering a new one on. A shorted lipo is not a fun thing to see.

Image
#4897040
xoff00 wrote: I switched to silicon wire of a couple of gauges...man, is it flexible! Highly recommend it!
where did you find this wire? I've been having trouble finding really flexible wire between 22 and 28 gauge. For next year I'm planning to redo the pke meter with a nicer finish and paint job and want to redo the wiring. The wires I have are really tough to bend causing the servo a lot of stress and power spikes. I was thinking servo wire but have yet to find a good source for it. I don't like to use ebay if I can help it.
#4897058
This post may contain an affiliate link that helps support GBFans.com when you make a purchase at no additional cost to you.

CountDeMonet wrote:
xoff00 wrote: I switched to silicon wire of a couple of gauges...man, is it flexible! Highly recommend it!
where did you find this wire? I've been having trouble finding really flexible wire between 22 and 28 gauge. For next year I'm planning to redo the pke meter with a nicer finish and paint job and want to redo the wiring. The wires I have are really tough to bend causing the servo a lot of stress and power spikes. I was thinking servo wire but have yet to find a good source for it. I don't like to use ebay if I can help it.
Amazon, of course!

22g: https://smile.amazon.com/gp/product/B01LH1FR6M
30g: https://smile.amazon.com/gp/product/B01KQ2JNLI

The 30g is *really* thin but works fine everywhere I tried, I just wanted thicker for power leads -- the 22g seems better. The 22g is rated for around 900mA and 30g for 140mA according to https://www.powerstream.com/Wire_Size.htm

BTW, you can remove the silicon insulation with you fingernails, especially on the 30g!
#4897059
This post may contain an affiliate link that helps support GBFans.com when you make a purchase at no additional cost to you.

Tebasaki wrote:Where'd you get the prototyping board for the wand gauge? (unless you just chopped a 2cmx8cm?

Maybe this for the silicone?? But what awg?

https://www.amazon.com/StrivedayTMFlexi ... icone+wire
That would be ideal. I got 22 and 30, they didn't have 24 in stock when I looked. Same brand I got. It's ultra flexible and thin! As I said to Count, you can also remove the insulation with you fingernails. :)
#4897066
This post may contain an affiliate link that helps support GBFans.com when you make a purchase at no additional cost to you.

Tebasaki wrote:Where'd you get the prototyping board for the wand gauge? (unless you just chopped a 2cmx8cm?
I cut one of the long skinny boards with a small tooth hand saw

I must have missed their flexible version of that wire. The 28 gaugeI bought is not flexible at all. I'll have to order some of that.
#4897074
I'm looking at your front and back for the thrower led.
Are the leds they connected through the bar resistors? It looks like you've got A6 tied to A5, Q6 to Q5 (front view)?
You've got ground connected to A1?
And then on the back side you have this strip of wire going from L5 (or L4) to B5 and one of those side tabs?
#4897076
In this post I have closeups of that board

viewtopic.php?p=4894680#p4894680

find the negative lead side on the bar graph to attach the resistor network and solder the wire from the led to a resistor on the network. On the ones I bought it's the side without markings. Make sure the negative leads on the resistor network are on the outside and not connected to a pin of the bar graph. They are the ones with the dot or text on them.

I set the bargraph through the board and bent the LED leads into the resistor network leads and soldered each one.

The ribbon cable that goes to the sx1509 goes on the opposite side connected to the other lead on the resistor. I then tied the grounds together on the resistor networks (since we have to use 2) using the green wire. The negative black lead on the ribbon cable is connected to the pad on the end where the other ones are.

Does that make sense?
#4897097
Ok. I had to take my heat gun and desolder the whole thing (the resistor dots were messed up).

I got the dots of the resistors to the outside rows, and it looks like on the back side you soldered them together (get the ground all connected) but on the top view I see your ground is tied into A1 (on the left there) next to the whole row of colorful wires, and not to the back where the resistors are grounded.

And how did you attach the colored leads to the leds? I see on the resistors you might've just gobbed some solder on there (that's what I did) but it looks like there's actually a wire connecting (maybe from the colored wire?)
#4897098
Does this help?

Image

Sometimes I am successful bridging with the solder but in this case I took a small wire and used that to bridge it.

For the ribbon cable I removed the insulation on each wire, fed it one by one in bending it over towards the pin from the LED, then carefully soldered them together and filled the hole with solder where the wire came through to solidify the connection. For through hole components I always use the feed/bend/solder/cut technique. In this case since I am basically bridging after feeding I don't need to cut.
Tebasaki liked this
#4897101
The only thing I don't understand is how the ground from the ribbon is connected to the ground(s) on the other side of the board.
It looks like there's that black wire connected on the right to L and it stretches across to B and that oval guy? (right?) That's the grounds for the resistor connecting, but how does that little white circle connect to that?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 25

While waiting impatiently for Frozen Empire to rel[…]

Make it that pack, sell it for $599. (While I […]

Good morning everyone! I have a local toy collect[…]

Yeah, we've been building this thing for ten[…]