Arduino Lightsaber

Hi there, it looks like you've received 97 pages or so of these types of messages, but I'm new to arduino and have been working on a lightsaber for about a month. I'm trying to use the blade from the new Disney Galaxy's Edge lightsabers in my own custom made hilt.

I've been able to make the blade ramp up on, steady on, and ramp down off.

I've connected an MPU 6050 and been able to make it flash another color when moved or clashed.

But when I moved to sound it keeps playing the power on sound over and over again on loop.

I'd like to think there is a simple bug in my code that I'm missing because I'm a noob. Otherwise maybe it is a short in my soldering.

I am using:

  • Arduino Nano
  • MPU 6050 gyro sensor
  • Adafruit Audio FX SoundboardI w
  • PAM 8302 amplifier
  • Homemade PCB board with two resistors and pogo pins to interface with the Disney blade

The tutorials for how to interface with a Disney blade were found here:

One of the tutorials I was using for the Adafruit soundboard was here:

The Wiring was
Arduino 5V to Adafruit VIN and MPU VIN and Amp VIN and Blade VIN
Arduino Ground to Adafruit Ground and MPU Ground and Amp Ground and Blade Ground
Arduino D2 to blade data
Arduino D3 to Adafruit trigger 0
Arduino D4 to Adafruit trigger 1
Arduino D5 to Adafruit trigger 2
Arduino D6 to Adafruit trigger 3
Arduino D7 to Adafruit trigger 4
Arduino D8 to a switch and then switch to ground
Arduino A4 to MPU SDA
Arduino A5 to MPU SCL
Adafruit Left channel to Amp A+
Adafruit audio ground to Amp A-

The code is below, thanks in advance for any help.

//For controlling a Savi's/Legacy Blade with Arduino

//Digital out needs to be 2.5V,
//So use voltage splitting on the 5V
//Digital out line of an Arduino

int resetCycle = 174500;
int restPeriod = 653;
int duty_cycle_length = 3600;
int digitalPin = 2;

// Setup toggle switch
boolean switchOn = 0;
int switchPin = 8;

// Setup sound ports
int soundon = 3;
int soundhum = 4;
int soundoff = 5;
int soundswing = 6;
int soundclash = 7;

#include <Wire.h>

long accelX, accelY, accelZ;
float gForceX, gForceY, gForceZ;

long gyroX, gyroY, gyroZ;
float rotX, rotY, rotZ;

long accelXp, accelYp, accelZp;
float gForceXp, gForceYp, gForceZp;

long gyroXp, gyroYp, gyroZp;
float rotXp, rotYp, rotZp;

long accelXd, accelYd, accelZd;
float gForceXd, gForceYd, gForceZd;

long gyroXd, gyroYd, gyroZd;
float rotXd, rotYd, rotZd;

float gForceT;

float rotXa, rotYa, rotZa;

float rotT;

void setup() {

pinMode(switchPin, INPUT); //lightsaber switch code
pinMode(digitalPin, OUTPUT); //blade data pin
digitalWrite(digitalPin, HIGH);

pinMode (soundon, OUTPUT);
pinMode(soundhum, OUTPUT);
pinMode(soundoff, OUTPUT);
pinMode(soundswing, OUTPUT);
pinMode(soundclash, OUTPUT);

boolean switchOn = false;

Serial.begin(9600);
Wire.begin();
setupMPU();

gyroXp = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
gyroYp = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
gyroZp = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ

accelXp = Wire.read()<<8|Wire.read(); //Initializes accelerometer
accelYp = Wire.read()<<8|Wire.read(); //
accelZp = Wire.read()<<8|Wire.read(); //
}

void loop()
{
recordAccelRegisters();
recordGyroRegisters();
processAccelData();
processGyroData();
printData();
delay(125);

if (digitalRead(switchPin) == LOW && switchOn == false)
{
digitalWrite (digitalPin, LOW);
switchOn = !switchOn;
digitalWrite (soundon, LOW);
delay (125);
digitalWrite (soundon, HIGH);
perform_animation(0x26);
delay (125);
digitalWrite (soundhum, LOW);
}

if (abs(accelX) > 30000 || abs(accelY) > 30000 || abs (accelZ) > 30000)
{
digitalWrite (soundhum, HIGH);
digitalWrite (soundclash, LOW);
delay (125);
digitalWrite (soundclash, HIGH);
}

if ((abs(accelX) > 25000 && abs(accelX) <30000) || (abs(accelY) > 25000 && abs(accelY) < 30000) || (abs(accelZ) > 25000) && (abs(accelZ) < 30000))
{
digitalWrite (soundhum, HIGH);
digitalWrite (soundswing, LOW);
delay (125);
digitalWrite (soundswing, HIGH);
}

if (digitalRead (switchPin)==HIGH && switchOn ==true)
{
switchOn = !switchOn;
digitalWrite (soundhum, HIGH);
digitalWrite (soundoff, LOW);
delay (125);
digitalWrite (soundoff, HIGH);
}
else {
digitalWrite (digitalPin, HIGH);
digitalWrite (soundhum, HIGH);
}
}

void perform_animation(byte cmd){
digitalWrite (digitalPin, LOW);
delayMicroseconds(resetCycle);
digitalWrite(digitalPin, HIGH);
delayMicroseconds(resetCycle);
digitalWrite(digitalPin, LOW);
delayMicroseconds(resetCycle);

for(int i= 7; i>= 0; i--){
if(bitRead(cmd, i)){
duty_cycle(.65);
}else{
duty_cycle(.33);
}
}

digitalWrite(digitalPin, HIGH);
delay(restPeriod);
}

void duty_cycle(float percentage){
digitalWrite(digitalPin, HIGH);
delayMicroseconds(duty_cycle_length * percentage );
digitalWrite(digitalPin, LOW);
delayMicroseconds(duty_cycle_length - (duty_cycle_length * percentage));
}

void setupMPU(){
Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2)
Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
Wire.endTransmission();
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4)
Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s
Wire.endTransmission();
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5)
Wire.write(0b00000000); //Setting the accel to +/- 2g
Wire.endTransmission();
}

void recordAccelRegisters() {
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x3B); //Starting register for Accel Readings
Wire.endTransmission();
Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40)
while(Wire.available() < 6);
accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
processAccelData();
}

void processAccelData(){
gForceX = accelX / 16384.0;
gForceY = accelY / 16384.0;
gForceZ = accelZ / 16384.0;

gForceXp = accelXp /16384.0;
gForceYp = accelYp / 16384.0;
gForceZp = accelZp / 16384.0;

gForceXd = gForceX - gForceXp;
gForceYd = gForceY - gForceYp;
gForceZd = gForceZ - gForceZp;

gForceT = gForceXd + gForceYd + gForceZd;

gForceXp = gForceX;
gForceYp = gForceY;
gForceZp = gForceZ;

}

void recordGyroRegisters() {
Wire.beginTransmission(0b1101000); //I2C address of the MPU
Wire.write(0x43); //Starting register for Gyro Readings
Wire.endTransmission();
Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 - 48)
while(Wire.available() < 6);
gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
processGyroData();
}

void processGyroData() {
rotX = gyroX / 131.0;
rotY = gyroY / 131.0;
rotZ = gyroZ / 131.0;

rotXp = gyroXp / 131.0;
rotYp = gyroYp / 131.0;
rotZp = gyroZp / 131.0;

rotXd = rotX - rotXp;
rotYd = rotY - rotYp;
rotZd = rotZ - rotZp;

rotXa = fabs (rotXd);
rotYa = fabs (rotYd);
rotZa = fabs (rotZd);

rotT = rotXa + rotYa + rotZa;

rotXp = rotX;
rotYp = rotY;
rotZp = rotZ;

}

void printData() {
Serial.print("Gyro (deg)");
Serial.print(" X=");
Serial.print(rotX);
Serial.print(" Y=");
Serial.print(rotY);
Serial.print(" Z=");
Serial.print(rotZ);
Serial.print(" Accel (g)");
Serial.print(" X=");
Serial.print(gForceX);
Serial.print(" Y=");
Serial.print(gForceY);
Serial.print(" Z=");
Serial.println(gForceZ);
Serial.println("Total G's=");
Serial.println(gForceT);
Serial.println("Total degrees=");
Serial.println(rotT);
}