Project showcase
So I Fixed a Broken Hasbro Lightsaber

So I Fixed a Broken Hasbro Lightsaber © CC BY-NC-SA

Refit a 2004 Hasbro lightsaber toy with Arduino Nano, NeoPixel, ADXL335 and a DFPlayer Mini.

  • 1,496 views
  • 3 comments
  • 1 respect

Components and supplies

Apps and online services

About this project

A while ago I was sorting some old Star Wars toys that my brothers and I got during SW fan years (before and during the prequel trilogy). I found this 2004 lightsaber in a box and load batteries in it. Nope - it was broken. Sad.

I thought about throwing it away, then I got an idea.

Since this lightsaber is a "color changing" version, the blade is white (or transparent). You can make it light up as any kind of colors with RGB LEDs. So I tear it open, break down some inner wall structures and put it various components:

  • Arduino Nano
  • 9 NeoPixel (WS2812b) LEDs (8 in a ring and an additional one in the center - I linked them together)
  • ADXL335 3-axis acceleration analog sensor
  • DFPlayer Mini MP3 Player (see docs)

I downloaded a bunch of lightsaber sound effects and put them into a mini SD card in the MP3 player. I added a few movie quotes and soundtrack music as well.

Also, two parts in the lightsaber are kept as part of the system (I cut and soldered their wires to jumper wires):

  • The side button
  • The speaker

As it happens, a small 5V power bank (which I used for my first project here) can be fitted into the original battery compartment.

Right now the saber functions as follows:

  • When you press the side button, the saber would "activate" with a random activation sound and a random color (red, green, blue, yellow, cyan, purple, white).
  • Play a random humming sound.
  • When the saber is activated, pressing the button and release quickly would shut it down (also playing a random shut down sound).
  • However, if you press the button a bit longer or long enough, it would play a random movie quote or soundtrack music,
  • While playing a quote or music, pressing it again quickly would return it to the humming mode.
  • While in humming mode, moving the saber fast enough would make it play a random whooshing sound.

I decided not to put in clashing sounds and the corresponding motion detection, since it would be tricky to detect different motions, and I don't want to smash this thing around and break it again.

I also don't want to use rainbow colors...it's meaningless here and the effect looks less effective in the plastic tube.

Probably someday I'll make it a Spaceball parody version, just maybe.

Code

Refitted Hasbro lightsaberC/C++
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h" // https://github.com/DFRobot/DFRobotDFPlayerMini
#include <Adafruit_NeoPixel.h> // https://github.com/adafruit/Adafruit_NeoPixel
#include "ADXL335.h" // https://github.com/Seeed-Studio/Accelerometer_ADXL335

#define BUTTON_PIN 2
#define NEOPIXEL_PIN 3
#define MP3_BUSY_PIN 4
#define MP3_RX_PIN 5
#define MP3_TX_PIN 6

#define ACCEL_TRIGGER_RATIO 0.06

#define NEOPIXEL_NUM 9
#define BUTTON_LONGPRESS_1 750
#define BUTTON_LONGPRESS_2 1500

#define SABER_ON 1
#define SABER_HUM 2
#define SABER_MOVE 3
#define SABER_OFF 4
#define SABER_QUOTE 5
#define SABER_MUSIC 6

#define SABER_ON_START 1
#define SABER_ON_END 15
#define SABER_HUM_START 16
#define SABER_HUM_END 25
#define SABER_MOVE_START 26
#define SABER_MOVE_END 50
#define SABER_OFF_START 51
#define SABER_OFF_END 58
#define SABER_QUOTE_START 59
#define SABER_QUOTE_END 72
#define SABER_MUSIC_START 73
#define SABER_MUSIC_END 81

#define SABER_ON_VOLUME 25
#define SABER_HUM_VOLUME 20
#define SABER_MOVE_VOLUME 22
#define SABER_OFF_VOLUME 25
#define SABER_QUOTE_VOLUME 20
#define SABER_MUSIC_VOLUME 22

SoftwareSerial softSerial(MP3_RX_PIN, MP3_TX_PIN);
DFRobotDFPlayerMini mp3;

ADXL335 accel;
int x, y, z, button_start, button_end, hum_index;
float last_accel_data, current_accel_data, accel_diff;
bool r, g, b, musicMode;

Adafruit_NeoPixel leds(NEOPIXEL_NUM, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  Serial.begin(9600);
  softSerial.begin(9600);

  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(MP3_BUSY_PIN, INPUT_PULLUP);

  leds.begin();
  accel.begin();

  mp3.begin(softSerial);
  delay(50);
  mp3.EQ(DFPLAYER_EQ_ROCK);
  musicMode = false;
  delay(200);

  clearLEDs();

}

void loop() {

  randomSeed(analogRead(A5) + analogRead(A6) + analogRead(A7));

  while (!buttonPressed());
  clearLEDs();
  chooseRGB();
  playMp3(SABER_ON);
  delay(50);
  for (int i = 0; i < 255; i++) {
    setLEDs(r * i, g * i, b * i);
    delay(1);
  }
  while (mp3IsBusy());
  while (buttonPressed());
  delay(200);
  chooseHum();
  getAccel();

  while (true) {

    last_accel_data = current_accel_data;
    getAccel();
    accel_diff = (current_accel_data - last_accel_data) / last_accel_data;

    if (!mp3IsBusy()) {
      musicMode = false;
      loopHum();
    }

    if (!musicMode && accel_diff >= ACCEL_TRIGGER_RATIO) {
      playMp3(SABER_MOVE);
      while (!mp3IsBusy());
      while (mp3IsBusy());
      delay(200);
    }

    if (buttonPressed()) {
      button_start = millis();
      while (buttonPressed());
      button_end = millis();
      if (button_end - button_start >= BUTTON_LONGPRESS_2) {
        musicMode = true;
        playMp3(SABER_MUSIC);
      } else if (button_end - button_start >= BUTTON_LONGPRESS_1) {
        musicMode = true;
        playMp3(SABER_QUOTE);
      } else {
        if (musicMode) {
          musicMode = false;
          mp3.pause();
          delay(200);
        } else {
          break;
        }
      }
    }
    delay(50);
  }

  delay(50);
  playMp3(SABER_OFF);
  delay(150);
  for (int i = 255; i >= 0; i--) {
    setLEDs(r * i, g * i, b * i);
    delay(2);
  }
  while (mp3IsBusy());
  while (!buttonPressed());
  delay(200);

}

bool buttonPressed() {
  return !digitalRead(BUTTON_PIN);
}

bool mp3IsBusy() {
  return !digitalRead(MP3_BUSY_PIN);
}

void playMp3(int soundType) {
  int startIndex, endIndex, selectedVolume;
  switch (soundType) {
    case SABER_ON:
      startIndex = SABER_ON_START;
      endIndex = SABER_ON_END;
      selectedVolume = SABER_ON_VOLUME;
      break;
    case SABER_HUM:
      startIndex = SABER_HUM_START;
      endIndex = SABER_HUM_END;
      selectedVolume = SABER_HUM_VOLUME;
      break;
    case SABER_MOVE:
      startIndex = SABER_MOVE_START;
      endIndex = SABER_MOVE_END;
      selectedVolume = SABER_MOVE_VOLUME;
      break;
    case SABER_OFF:
      startIndex = SABER_OFF_START;
      endIndex = SABER_OFF_END;
      selectedVolume = SABER_OFF_VOLUME;
      break;
    case SABER_QUOTE:
      startIndex = SABER_QUOTE_START;
      endIndex = SABER_QUOTE_END;
      selectedVolume = SABER_QUOTE_VOLUME;
      break;
    case SABER_MUSIC:
      startIndex = SABER_MUSIC_START;
      endIndex = SABER_MUSIC_END;
      selectedVolume = SABER_MUSIC_VOLUME;
      break;
    default:
      startIndex = 0;
      endIndex = 0;
      selectedVolume = SABER_HUM_VOLUME;
  }
  mp3.volume(selectedVolume);
  delay(50);
  mp3.play(random(startIndex, endIndex + 1));
  delay(200);
}

void chooseHum() {
  hum_index = random(SABER_HUM_START, SABER_HUM_END + 1);
}

void loopHum() {
  mp3.volume(SABER_HUM_VOLUME);
  delay(50);
  mp3.play(hum_index);
  delay(200);
}

void chooseRGB() {
  r = random(0, 2);
  g = random(0, 2);
  b = (r || g) ? random(0, 2) : true;
}

void clearLEDs() {
  leds.clear();
  leds.show();
}

void setLEDs(int rc, int gc, int bc) {
  for (int i = 0; i < NEOPIXEL_NUM; i++) {
    leds.setPixelColor(i, leds.Color(rc, gc, bc));
  }
  leds.show();
}

void getAccel() {
  accel.getXYZ(&x, &y, &z);
  current_accel_data = x + y + z;
}

Comments

Similar projects you might like

Sound Effects for Dok-Ondar's Lightsaber Box

Project showcase by Daniel_Haro

  • 1,538 views
  • 0 comments
  • 2 respects

RGB Lightsaber | Arduino Project

Project tutorial by Michael Darby - 314Reactor

  • 6,850 views
  • 2 comments
  • 19 respects

Air Quality Monitor

Project showcase by Mustafa Hesham

  • 18,781 views
  • 10 comments
  • 50 respects

Arduino Lightsaber

Project tutorial by Michael Darby - 314Reactor

  • 18,320 views
  • 2 comments
  • 28 respects

Digital Windmill "Digindmill"

Project tutorial by HomeMadeGarbage

  • 10,789 views
  • 2 comments
  • 26 respects

Arduino Clock with Neopixel Ring Animation

Project tutorial by Alexander

  • 70,273 views
  • 46 comments
  • 106 respects
Add projectSign up / Login