Go Down

Topic: Arduino Lightsaber for/with LED string blade (Read 128175 times) previous topic - next topic

neskweek

#60
Jan 18, 2016, 04:22 pm Last Edit: Feb 19, 2016, 09:14 pm by neskweek
Nope, there's no shrink tube.

Only the wires holds everything in place.

Here is a close up of the upper part:

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.

First of all what modules to include and global vars to be declared:
Code: [Select]
#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():
Code: [Select]
// 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).

Code: [Select]
  // 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):
Code: [Select]
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.

ryang

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! :)

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..

MegaCorsair

There's a Scheme Connection for the 4 codes?


Protonerd

#64
Jan 21, 2016, 06:02 pm Last Edit: Jan 22, 2016, 04:33 pm by 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

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 :)

Cheers!


CrossRoads

#65
Jan 21, 2016, 06:20 pm Last Edit: Jan 21, 2016, 06:20 pm by 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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

ryang

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!! :D

JakeSoft

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.  ;)

Protonerd

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:
https://www.arduino.cc/en/uploads/Main/ArduinoNano30Schematic.pdf
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.
https://github.com/NashMicro/NashDuino/blob/master/Nano/ArduinoNano3_0schematic.pdf

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.



CrossRoads

#69
Jan 22, 2016, 04:33 pm Last Edit: Jan 22, 2016, 04:35 pm by CrossRoads
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

DJWing79

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

what is SuppressCounter?

Protonerd

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

http://www.hobbyking.com/hobbyking/store/__64417__Atmel_Atmega_Socket_Firmware_Flashing_Tool_AR_Warehouse_.html?strSearch=atmega
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.

Protonerd

I made a sketch of how the placement on the PCB and the pin-out are going to look like. Any comments are welcome!!!

At this stage I know that the width of the PCB shall be between 20mm and 23mm (so a bit under 1"), approximately the same as the DFPlayer, which also have a standard pin header connectors (8 contact holes 0.1" apart).
The length is not fixed yet, it depends on the layout. There are 2 scenarios:
- pad/pin limited size: if the pins on the sides are too many and make the PCB much longer, then I will put only the most needed signals on the side, all the other pre-assigned signals (i.e. those which have a connection on the board, like the A4/A5 to the MPU or D8 to the YX5200-24SS) will be placed somewhere on the PCB, still accessible, but only on a need-to basis.
- if the placement/layout determines the size, I will try to put as many of the signals on the side rows as possible.

With regards to the pin assignment, I tried to follow the standard Arduino stile, with the MPU and DFPlayer related signals grouped at the bottom of the PCB.

Regarding the 2 big sockets (USB and micro-SD), the will be at the bottom of the PCB on the two sides respectively. I hope that is possible to mount that way.


JakeSoft

I made a sketch of how the placement on the PCB and the pin-out are going to look like. Any comments are welcome!!!

At this stage I know that the width of the PCB shall be between 20mm and 23mm (so a bit under 1"), approximately the same as the DFPlayer, which also have a standard pin header connectors (8 contact holes 0.1" apart).
The length is not fixed yet, it depends on the layout. There are 2 scenarios:
- pad/pin limited size: if the pins on the sides are too many and make the PCB much longer, then I will put only the most needed signals on the side, all the other pre-assigned signals (i.e. those which have a connection on the board, like the A4/A5 to the MPU or D8 to the YX5200-24SS) will be placed somewhere on the PCB, still accessible, but only on a need-to basis.
- if the placement/layout determines the size, I will try to put as many of the signals on the side rows as possible.

With regards to the pin assignment, I tried to follow the standard Arduino stile, with the MPU and DFPlayer related signals grouped at the bottom of the PCB.

Regarding the 2 big sockets (USB and micro-SD), the will be at the bottom of the PCB on the two sides respectively. I hope that is possible to mount that way.


Q1) What is your target power source? 3.7V? 6V? 7.4V?

Protonerd

Q1) What is your target power source? 3.7V? 6V? 7.4V?

I leave it up to the user. I use them currently mainly with 7.4V (2x3.7V) setup, but a single 3.7V cell setup is also feasible, provided that the 5V is maintained, which could be done with a small boost.

I plan to play around with 3.7V supply wo/boost, but that needs a different external connection and I do not want to commit this option as of yet.

Go Up