Arduino Lightsaber for/with LED string blade

Hi all and thanks for all the valuable info this thread holds, all those videos were enough to push me to try it for myself despite having lost a lot of my electronic knowledge.

I'm currently waiting for materials, and doing some research in circuit and Arduino programming, you can check my progress here (warning: very preliminar solution):

As you can see running the circuit simulation, when turning on the saber (pushing button), there are some milliseconds where all the voltage is applied only to one or two segments of LEDs, which causes these to be displayed in a state of 'burned'.

Is there any solution to this problem?

Perhaps the time in this oversaturated state is short enought to cause any problem?

One second thing I can observe is that switching off the saber seems to have two steps, dimming leds in one first step and switching all off finally, I don't know if it can be a problem with 123d.circuits.io simulation or a Mosfet incorrect operation.

Thanks and may the force be with you.

Here's my code so far, warts and all - so to speak.

I've just received another shipment of parts, so I'm going to tinker with the gyro code a heap more to try and get some clash detection out of it..

neskweek:
Sweeeeet Chivotenkai !
Sorry to read that a part of your assembly got damaged :frowning:

I'm personnaly in the process of assembling my green led string segments (seriallell II type) . I've done 4 segment so far (but ruined half a segment by being to hard when bending led pins :P).
I have a question regarding building the blade :
How do you fasten the segments between each other to get a quite stiff led string?

Still waiting for my arduinos components to be delivered.

Ohh and by the way : Happy new year to everyone !

You can look here for a build log of a LED string saber:

Only thing I would change is that the shrink tube should be used only to fasten the segments at the segment boundary for an inch or so. Putting the whole blade into the shrink tube makes it impossible to maintain and that is something you have to do on a regular basis.

Thanks for the fasten tips.

I'll finally go with the method found here :

I'll then wrap the whole string with some cellophane.

I'll post a photo of the full fisrt string (the green one) when I'll complete it.

Right now I only have half a string cause I burned some leds during my tests (stupid short cuts). I have ordered some more.

ryang:
Here's my code so far, warts and all - so to speak.

saber - Pastebin.com

I've just received another shipment of parts, so I'm going to tinker with the gyro code a heap more to try and get some clash detection out of it..

Nice :slight_smile:
And i'm also starting to receive my new part from china, my fingers are starting to itch to start working on v2 of my saber XD.
I can already start discovering my i2c DAC to see how my next iteration of doing all the sound myself rather than the mp3 module will work :p.

ryang:
Here's my code so far, warts and all - so to speak.

saber - Pastebin.com

I've just received another shipment of parts, so I'm going to tinker with the gyro code a heap more to try and get some clash detection out of it..

This is the code for the MPU6050 + DfPlayer + Minipro? How Will be connected correctly?

First led strip done !

OFF :

ON:

Tested with a lux meter app on my android phone around 5400 lux, last night.

The mounting and soldering are not quite academic but that do the trick and the string is quite stiff by only enterlacing wires trought the led pins.
Next steps are :

  • DIN soldering (still waiting for the connector)
  • wrap it in diffusor material (polyurethane foam made for flooring isolation)
  • put it in the blade and make a nice picture :slight_smile:

Still waiting the Arduino Nano board to be delivered :frowning:

Looks awesome, good luck with the build! Did you put the whole string into a shrink tube, do I see it right?

Nope, there's no shrink tube.

Only the wires holds everything in place.

Here is a close up of the upper part:

Since there is a growing demand to know how to use the MPU6050, instead of sending PM to fellow lightsaber builders, I give you here some hints how I use it in my lightsaber. If you integrate this code into your code, it's gonna work.

First of all what modules to include and global vars to be declared:

#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
// or the next one, should be equivalent
//#include "MPU6050.h"
#include <stdlib.h>
#include <SoftwareSerial.h>


// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  #include "Wire.h"
#endif


MPU6050 accelgyro;
// calibrated acc/gyro values
int16_t ax_zero, ay_zero, az_zero;
int16_t gx_zero, gy_zero, gz_zero;
// acc/gyro values of the previous cycle
int16_t ax_prev, ay_prev, az_prev;
int16_t gx_prev, gy_prev, gz_prev;
// MPU control/status vars
bool dmpReady = false;  // set true if DMP init was successful
uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high

// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

Then in the void setup():

 // initialize device
  Serial.println("Initializing I2C devices...");
  accelgyro.initialize();

  // verify connection
  Serial.println("Testing device connections...");
  Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

  // load and configure the DMP
  Serial.println(F("Initializing DMP..."));
  devStatus = accelgyro.dmpInitialize();
 
    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        accelgyro.setDMPEnabled(true);



        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        //packetSize = accelgyro.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

Here in the setup you can also experiment with some of the advanced options (use at your own risk, this section of the code is not fully verified).

  // motion engine configuration

  accelgyro.setFullScaleGyroRange(0); //0-250deg/s | 1-500deg/s | 2-1000deg/s | 3-2000deg/s
  accelgyro.setFullScaleAccelRange(1); //0-2g | 1-4g | 2-8g | 3-16g

  
  // INT_PIN_CFG register
  // in the working code of MPU6050_DMP all bits of the INT_PIN_CFG are false (0)
  accelgyro.setInterruptMode(false); // INT_PIN_CFG register INT_LEVEL (0-active high, 1-active low)
  accelgyro.setInterruptDrive(false); // INT_PIN_CFG register INT_OPEN (0-push/pull, 1-open drain)
  accelgyro.setInterruptLatch(false); // INT_PIN_CFG register LATCH_INT_EN (0 - emits 50us pulse upon trigger, 1-pin is held until int is cleared)
  accelgyro.setInterruptLatchClear(false); // INT_PIN_CFG register INT_RD_CLEAR (0-clear int only on reading int status reg, 1-any read clears int)
  accelgyro.setFSyncInterruptLevel(false);
  accelgyro.setFSyncInterruptEnabled(false);
  accelgyro.setI2CBypassEnabled(false);

  
// set up interrupt sources
  accelgyro.setIntFreefallEnabled(false);
  accelgyro.setIntMotionEnabled(true);
  accelgyro.setIntZeroMotionEnabled(false);
  accelgyro.setIntFIFOBufferOverflowEnabled(false);
  accelgyro.setIntI2CMasterEnabled(false);
  accelgyro.setIntDataReadyEnabled(false);

  accelgyro.setIntMotionEnabled(true); // INT_ENABLE register enable interrupt source  motion detection
  accelgyro.setMotionDetectionThreshold(10); // 1mg/LSB
  accelgyro.setMotionDetectionDuration(2); // number of consecutive samples above threshold to trigger int
  mpuIntStatus = accelgyro.getIntStatus();

Then finally in each loop (only MPU related code included, all the rest removed):

 int16_t ax, ay, az;
  int16_t gx, gy, gz;
  int16_t accgyro_temp[6];



    else { // motion engine actions
      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
      accgyro_temp[0]=ax;
      accgyro_temp[1]=ay;
      accgyro_temp[2]=az;
      accgyro_temp[3]=gx;
      accgyro_temp[4]=gy;
      accgyro_temp[5]=gz;
      
      ax = ax- ax_prev;
      ay = ay- ay_prev;
      az = az- az_prev;
      gx = gx- gx_prev;
      gy = gy- gy_prev;
      gz = gz- gz_prev;
      
      ax_prev=accgyro_temp[0];
      ay_prev=accgyro_temp[1];
      az_prev=accgyro_temp[2];
      gx_prev=accgyro_temp[3];
      gy_prev=accgyro_temp[4];
      gz_prev=accgyro_temp[5];
      

      // ************************* blade movement detection ************************************
      if ((abs(ax) > 1000 or abs(ay) > 1000 or (az) > 1000)) { is there any movement to trigger motion detection

        if ((abs(ax) > 4000 or abs(ay) > 4000 or (az) > 4000)) { // threshold for Clash (values depend on Acceleration Range used!!!)
          if (SupressCounter >= 3) {
            if (verboseprint) {Serial.println("Clash") ;}
            Sound_PlayClash(SoundFontIdx);
          }
        }
        else {
          if (SupressCounter >= 30) {
            if (verboseprint) {Serial.println("Swing");}
            Sound_PlaySwing(SoundFontIdx);
            
          }
        }
      }
      else {
        if (verboseprint) {Serial.println(F("\nNo activity, continue hum"));}
      }
      // ************************* blade movement detection ends************************************

I hope it helps. Good luck with coding and experimenting.

Protonerd:
Since there is a growing demand to know how to use the MPU6050, instead of sending PM to fellow lightsaber builders, I give you here some hints how I use it in my lightsaber. If you integrate this code into your code, it's gonna work.

Holy hell man, great work!! Quite a bit more detailed than mine! :slight_smile:

How is the clash detection working out? Usable?

Also, I came to the realisation the other day that the way I've mounted the gyro, the Z-access is actually going to be useful for thrust detection - and possibly only that..

There's a Scheme Connection for the 4 codes?

I decided it was time to move to the next level of Arduino based LED-string saber electronics, integrating everything discussed in this thread on one single PCB. I dubbed my future board:

DIYino

for 2 reasons:

  • it's meant for DIY projects (obviously), but with this board my intention is to provide the possibility to build either LED-string sabers or sabers with high-power LED's. On top of that, since the board provides sound, light control (and motion detection), it can be used for a multitude of other projects as well (I plan an E11 blaster electronics as well, to stay with the SW theme).
  • the Y also stays for the MP3 chipset YX5200-24SS

Here is the schematics I came up with after many weeks of research. It basically implements the same as my Arduino-based module:

  • an Arduino-Nano-clone circuit
  • a motion detection engine using the MPU-6050
  • and the circuitry of the DFPLayer mini
  • a MOSFET attached to each PWM-capable pin of the Atmega328P-AU (6pcs) to drive up to 6 strings or high-power LED's

I try to attach a PDF of the schematics, feedbacks and checks are warmly welcome, I'm now planning on starting the layouting and ordering the parts for the sample builds.

Target is to have a module size ~20mmx70mm, including mini-USB and SD card socket. So far the plans :slight_smile:

Cheers!

DIYino_1.1_LayoutSubmit.pdf (100 KB)

Suggestion: add more caps.
Atmega328: 0.1uf for each pin of VCC and AVCC - 3 total. I only see 1.
Ft232: Same, add more 0.1uF
UA78M05: "All characteristics are measured with a 0.33-μF capacitor across the input and a 0.1-μF capacitor across the output." I don't see any caps.
IC5: Same, add a 0.1F. will help with hum issues also.

Protonerd:
I decided it was time to move to the next level of Arduino based LED-string saber electronics, integrating everything discussed in this thread on one single PCB. I dubbed my future board:

DIYino

Love it!! Bring it on!! :smiley:

Protonerd:
I decided it was time to move to the next level of Arduino based LED-string saber electronics, integrating everything discussed in this thread on one single PCB. I dubbed my future board:

DIYino

OMG. I've created a monster. :wink:

CrossRoads:
Suggestion: add more caps.
Atmega328: 0.1uf for each pin of VCC and AVCC - 3 total. I only see 1.
Ft232: Same, add more 0.1uF
UA78M05: "All characteristics are measured with a 0.33-μF capacitor across the input and a 0.1-μF capacitor across the output." I don't see any caps.
IC5: Same, add a 0.1F. will help with hum issues also.

Wow CrossRoads, actually I've been fervently hoping that you would chip in! Thanks a lot for the advice, I will make the updates.

Actually I based the Arduino part on the schematics found on the Arduino page:

and realized just recently, that other than the link suggest this is the Nano v2.

I found an updated schematics for v3 on GitHub, and now I see that the v2 had some mistakes (actually I found one, the FTDI IC's Test pin must be connected to GND if unused, which is on the v3 schematics but not on the v2 on the Arduino site) and other external component values.

I added suggested 100nF caps to UA78M05 and the IC5 audio amp, one on the VCC/VCCIO of the FTDI, as well as the 2 caps for LDO. As for the Atmega328 I opted to stay with the current caps, I fear that it will be the sheer number of external components that will dominate the board and dictate the size.

We discussed the topic of bootloader burning the other day. Currently I'm reluctant to plan in an ICSP header, due to limited space on the board and the fact that everyone removes them once it fulfilled its purpose. Instead I will try to use the same SPI pins from the sides, I hope it will work.

Schematics in PDF replaced.

Can also use a press-in-place adapter to bootload and then program the 328p:

Ok, quick question about your clash and swing detect, ProtoNerd

what is SuppressCounter?

CrossRoads:
Can also use a press-in-place adapter to bootload and then program the 328p:

Radio Control Planes, Drones, Cars, FPV, Quadcopters and more - Hobbyking

Is it specified how much keepout area I have to observe around the Atmega to have a proper contact with this press-in-place adapter? I could ask the layouter to cater for this.