Arduino Lightsaber

Thanks for all the tips and help your giving us @JakeSoft :slight_smile:

One thing I need some clarification on is pin output voltages.

If an arduino is running at 5v, does it output 5v to its pins (assuming they're set to output).

I'd like to run the flicker LED from pin 5 so will need to add a resistor for it if it does.

Hi Jakesoft,

Thanks for the reply about the delay. I suspected the timing diagram was wrong. Interestingly I only get 24mS and haven't seen longer delays but I will look out for that.

Thanks for clarifying about the repeat function.

Have you found it to be reliable? The reason I ask is that I have two parts of my code that repeat the idle hum sound. One when it goes from powerup to idle. The second when it goes to clash and then drops back to idle.

The first one works fine. The second one does not repeat yet the code is identical! I started to wonder if it was a toggle (so first turned it on and second was turning off) hence the reason for my question. But you confirming that I need to issue the repeat command during playback of the sound I want repeated means no toggle.

Now I am wondering if I have a longer delay sometimes so the repeat is issued before the sound has started playing so the repeat command is not enabled.

Hi Canobi,

With respect to your flickering circuit. Looking at it you may have trouble with the MOSFET. The VGSon may not be satisfied and it may not turn on properly or at all. That may be helped by having the resistor and the LED both on the drain side. You still could have a voltage drop across the flicker LED that might make still cause grief.

In any case, while the flickering LED is an ingenious idea, I would suggest it is better to do it in the software. It gives you more flexibility as having it done in hardware locks you in to it always flickering the way the chip wants.

Related to that, has anyone tried these to drive the LEDs? ( http://www.ebay.com/itm/161807194247 )
You can parallel them (two for 700mA) and they are more efficient than a resistor MOSFET combination. They are specifically designed for driving LEDs from an 18650 working efficiently to hold brightness as the voltage drops from a fully charged 4.2V. Nice and small space saving solution. I understand that you just need to PWM the power pin directly from a port pin. Mine have just arrived and I am yet to try them.

Canobi:
Thanks for all the tips and help your giving us @JakeSoft :slight_smile:

One thing I need some clarification on is pin output voltages.

If an arduino is running at 5v, does it output 5v to its pins (assuming they're set to output).

I'd like to run the flicker LED from pin 5 so will need to add a resistor for it if it does.

No problem. I just hope I get to see some YouTube videos of all of your creations. I'll consider that a fine reward. :slight_smile:

I'm not sure how you're planning to run it, but if you're doing the standard Luxeon/Cree high-powered LED route, you won't power that directly from an Arduino pin anyway. Not enough current will be available to drive the LED. You'll need a MOSFET or a PEX from TCSS.

Ah well, PWM it is then. Thanks for the info RTPfan.

@JakeSoft

Was inquiring about voltages for the flicker LED, the blade LED is powered directly from the battery.

finally. i had like 2 a ha moment. one is,. that i HATE coding,.. i thought Flash Action script and MEL was bad,.. I get an F- i C++
But, alas,.. my parents said i can do anything,. and my 5 year old pat me on the back last night and siad,. "But Dad, you told me Pealer's never give up."
i cracked it.

i dont know how i did it,. but i turned the sound module 180 degrees when moving it from one bread board to another. looked good on the board,. 100% broken. Do'h!

Illuis's code used a different SCL naming convention, that i did not catch,.. arduino did tho.

this works,.. anyone can use it,.. make sure you configure the sound uploading module to edge trigger.

videos to come... if you don't know how to make buttons trigger functions,.. billpealer at yahoo dont com. either way i will upload the final,.the updated button code,.. the line diagram, and full video in 2-3 weeks. i also want to add, that a $15 sound module in a star wars walmart light saber is dang near the same thing as this... just add the mosfet/2w LED and better 2w speaker to that and the Custom Saber Shop Sabers are good to go.

#define WT588D_SCL 9 //Module pin "P03" or pin # 10
#define WT588D_BUSY 10 //Module pin "LED/BUSY" or pin # 15

byte file_count = 1;

void setup() {

  
 pinMode(WT588D_SCL, OUTPUT);  
 pinMode(WT588D_BUSY, INPUT);  
 

}


void loop()
{
 WT588D_Send_Command(0x02);  //blade on with looped hum for 80 seconds. if you dont swing for 80 seconds, why is it on?
 delay(1500); //delay for testing  waiting for buttons from china. 

 WT588D_Send_Command(0x01); //swing sound with 80 seconds of hum
 delay(1000);
 WT588D_Send_Command(0x01); //one more swing sound 'cause it sounds cool
 delay(1000);
 WT588D_Send_Command(0x00); //powerdown sound, no hum loop. der.. its off.
 delay(4500);

 delay(200); 

}


void WT588D_Send_Command(byte addr) {
   digitalWrite(WT588D_SCL, LOW);
   delay(5);

   for(int i = 0; i < 8; i++)  {
       digitalWrite(WT588D_SCL, HIGH);
       if(bitRead(addr, i)) {
           delayMicroseconds(600);
           digitalWrite(WT588D_SCL, LOW);
           delayMicroseconds(200);
       } else {
           delayMicroseconds(200);
           digitalWrite(WT588D_SCL, LOW);
           delayMicroseconds(600);
       }
   }

   digitalWrite(WT588D_SCL, HIGH);
   delay(100);
} //END

I still don't know how Sugarbombs and Illuis got what they got,.. when the documentation of the Wt588Du has this to say about one/three line serial C code.

Send_oneline(unsigned char addr) 
{      unsigned char i;      SDA=0;       
delay1ms(5);         /* delay 5ms */       
for(i=0;i<8;i++)          {SDA=1;           
if(addr & 1)             {delay100us(6);      
/* 600us */              SDA=0;             
delay100us(2);       /* 200us */        }               
else {              delay100us(2);     /* 200us */             
SDA=0;              delay100us(6);       /* 600us */  }    
addr>>=1; 

}           SDA=1; }



they took the above and translated it into,..

void WT588D_Send1(byte addr) {
   digitalWrite(wt_scl, LOW);
   delay(5);

   for(int i = 0; i < 8; i++)  {
       digitalWrite(wt_scl, HIGH);
       if(bitRead(addr, i)) {
           delayMicroseconds(600);
           digitalWrite(wt_scl, LOW);
           delayMicroseconds(200);
       } else {
           delayMicroseconds(200);
           digitalWrite(wt_scl, LOW);
           delayMicroseconds(600);
       }
   }

   digitalWrite(wt_scl, HIGH);
   delay(100);
}

WHAT THE @#$%^

is the an online gibberish translator you guys are holding out on here?

@Canobi

An arduino output should be able to drive a flicker LED. I would imagine it would be < 20ma but you should look on the LED data sheet.

A problem may be that the MOSFET gate is a voltage driven element and there may be insufficient current to operate. You make be relying on leakage currents.

I would guess you would might need a (1K??) resistor between the gate and the source (ie to Vbat) of the (P channel??) MOSFET. Then reverse the flicker LED and drive it active low.

Whether this might work depends upon a couple of things like the voltage drop of the flicker LED, value of VBat and VGSon for the MOSFET. You haven't given that information so it is hard to say .......

Still if it works well as you have it drawn then the answer is that, subject to the flicker LED data sheet that the current is <20ma an arduino pin should be fine.

Ah yes, sorry about the lack of info, it's a slight failing of mine so I'll shed some light on things.

The mosfet is an FDN327N which is rated for 2A. The gate threshold is .4v ~ 1.5v (max saturation is 8v) and according to the datasheet it only draws 250uA. This last bit might be a misunderstanding on my part, but that was all I could find regarding how much current the gate sources.

The flicker LEDs I went for are the red ones which have a Vf of 2.2v @25mA. I chose them as they had the closest working Vf to the gate threshold.

My thoery is that since the arduino is 5v and the pins sink 20mA it should work as I'd only need to drop a few Vs for the LED and it would pass enough current through to the gate for it to operate.

I have a bunch of those fets so I can use one as a guinea pig to test the theory out when the flicker LEDs arrive.

I can also use the experiment to help nail the pad design for the LED as I need to turn it into an SMT component. It'll sit right under the arduino so it can't go through hole like it was meant to and necessity is the mother of invention as they say.....

It has occured to me that the flickering will effect the fade in/out function, which just wouldn't look right.

My first thought on how to get round this problem is to use a second pin that bypasses the flicker LED:

All well and good, but how does one name a second led pin when declaring its function?

For the flicker LED I have:

int ledPin = 5; // flicker led to mosfet gate

Is it as simple as naming another pin as a led pin (eg. int ledPin = 6; )and then just call that number when it's wanted?

I just read the comments. And did my best to digest them. Thanks JakeSoft. I don't think in code. as it probably is clear.
I am having replay stutter. I think it is because the button playback is in void loop and it is cycling like mad.

I do have 2.2 questions?

I do not have this in my code "digitalWrite(WT588D_SCL, HIGH);"

1a. does it matter what pin number i use on the arduino for the SDA / SCL pin? and the comment that the "WT588D_SCL" need be changed to "...SDA" in my code? I don't have SCL set to HIGH in the setup. As is your SDA. and Illuis's code uses SCL as a name, you use SDA,.. would a rose by any other name, not smell as sweet? So it is not a critical change, just for standard naming right? i like to use the word button, i see a lot of "switchPin" in code or outPin, where as i use "LED".

If i need pinMode(WT588D_SCL, HIGH); in set up,..
1b. Why?

//my code
#define LED 13
#define LED2 12
#define WT588D_SCL 9 //Module pin "P03" or pin # 10
#define WT588D_BUSY 10 //Module pin "LED/BUSY" or pin # 15
#define button 7             //the on-off button
byte file_count = 1;

void setup() {

 
pinMode(WT588D_SCL, OUTPUT);  
pinMode(WT588D_BUSY, INPUT); 
pinMode (button, INPUT_PULLUP);


}
// end my code

when i run a void loop with the WT588d's function

example: all the above plus this below.

void loop()
{
WT588D_Send_Command(0x02);
delay (1234);
}

it plays, and delays. and repeats.

also,
when i use a standard button command.
void loop()
{
if(button == HIGH)
{WT588D_Send_Command(0x02); //blade on

} //end

It works when i press the button, but just plays rapidly. it is akin to me rapid tapping the button if it was in key mode. But i only hit the toggle button once. I know it is cycling thru the void loop. If i use the switch Boolean code,. it wouldn't let me treat the send_command as it does an LED state.

// Boolean
void loop()
{
reading = digitalRead(button);

// if the input just went from LOW and HIGH and we've waited long enough
// to ignore any noise on the circuit, toggle the output pin and remember
// the time
if (reading == HIGH && previous == LOW && millis() - time > debounce) {
  if (state == HIGH)
    state = LOW;
  else
    state = HIGH;

  time = millis();    
}

digitalWrite(LED, state); // turns off LED2, and on LED pin 13 and signal to mosfet 

digitalWrite(LED2, !state);  // turns off LED and on LED pin 12 just to show the toggle works

previous = reading;

if (state)
WT588D_Send_Command(0x02); // on sound
else (!state)
WT588D_Send_Command(0x00); // off sound
}
}  //end

i can make buttons trigger LED pins using the Boolean and debounce, but i can't seem to ge tit to jive with making a button trigger the statement or function of what ever the thing is that "WT588D_Send_Command(0x02);" is. i was under the impression that it was a function, but after hours of reading and now dreaming in gibberish arduino code, i am now leaning toward that it is a statement.

googling "buttons run functions or statements arduino"

has born no fruit. gets me to the same 3 tutes that do not apply to this.

billpealer:
I do not have this in my code "digitalWrite(WT588D_SCL, HIGH);"

1a. does it matter what pin number i use on the arduino for the SDA / SCL pin? and the comment that the "WT588D_SCL" need be changed to "...SDA" in my code? I don't have SCL set to HIGH in the setup. As is your SDA. and Illuis's code uses SCL as a name, you use SDA,.. would a rose by any other name, not smell as sweet? So it is not a critical change, just for standard naming right? i like to use the word button, i see a lot of "switchPin" in code or outPin, where as i use "LED".

The name change is not critical, it's just that it's generally a good idea to name variables something meaningful that reflects what the really are. As your projects start to grow in complexity this becomes important otherwise it's hard to understand what is going on when you read your code and especially difficult for anyone else to understand. That makes it hard for anyone to help you. For example, if I had a motor wired to open a door on pin 5, what makes more sense "DoorMotorPin" or "WindowArmPit"?

SCL means "serial clock" in 3-line serial mode however it has no meaning in one-line serial mode for the WT588D. The SDA is "serial data", which is what the pin is really doing.

It doesn't matter what Arduino pin you use for SDA so long as the other end is plugged into the right pin on the WT588D module.

billpealer:
If i need pinMode(WT588D_SCL, HIGH); in set up,..
1b. Why?

This guarantees that the pin is an a known state when the loop starts.

youtube video on its way. i am in better shape than yesterday. i know i am still doing it wrong.

anyone have some insight on how to make the sounds trigger with buttons and not sound like max headrom, or act wonky?

Also, there needs to be a way that after the main and only button is pressed the second time, it locks up the sound module, so the swing and clash buttons don't trigger their noises. I am not there yet in my code.

maybe have the arduino get a feedback loop from the LED pin, if the LED pin is LOW, send the Stop Command(0xFE)

if (digitalRead(LED == LOW) {
WT588D_Send_Command(0xFE)
}
{
else
}

that's wrong im sure.,

tonight's flavor

#define WT588D_SDA 9 //Module pin "P03" or pin # 10
#define WT588D_BUSY 10 //Module pin "LED/BUSY" or pin # 15
int LED = 13;
int LEDa = 12;
int button = 2;         // the button
int state = LOW;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin
byte file_count = 1;
long time = 0;         // the last time the output pin was toggled
long debounce = 100;   // the debounce time, increase if the output flickers


void setup() {

   
  pinMode(WT588D_SDA, OUTPUT);  
  pinMode(WT588D_BUSY, INPUT);  
  pinMode(button, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  pinMode(LEDa, OUTPUT);
  digitalWrite(button, HIGH);
  
  digitalWrite(WT588D_SDA, HIGH);

 
}

void loop() 
{
    reading = digitalRead(button);
    digitalWrite(WT588D_SDA, HIGH);
    

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
  else
      state = HIGH;
      WT588D_Send_Command(0x02); //on sound
      delay(5);
      digitalWrite(WT588D_SDA, LOW);
     
      time = millis();    
  }
 digitalWrite(LED, state);
 digitalWrite(LEDa, !state);

if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    if (state == HIGH)
    
      state = LOW;
  else
      state = HIGH;
     WT588D_Send_Command(0x00);
      time = millis();    
}
previous = reading; 
}
void WT588D_Send_Command(byte addr) {
    digitalWrite(WT588D_SDA, LOW);
    delay(5);

    for(int i = 0; i < 8; i++)  {
        digitalWrite(WT588D_SDA, HIGH);
        if(bitRead(addr, i)) {
            delayMicroseconds(600);
            digitalWrite(WT588D_SDA, LOW);
            delayMicroseconds(200);
        } else {
            delayMicroseconds(200);
            digitalWrite(WT588D_SDA, LOW);
            delayMicroseconds(600);
        }
    }

    digitalWrite(WT588D_SDA, HIGH);
    delay(100);
} //end WT588D_Send_Command

billpealer:
youtube video on its way. i am in better shape than yesterday. i know i am still doing it wrong.
first crack at Arduino and the WT588Du audio chip - YouTube

anyone have some insight on how to make the sounds trigger with buttons and not sound like max headrom, or act wonky?

Also, there needs to be a way that after the main and only button is pressed the second time, it locks up the sound module, so the swing and clash buttons don't trigger their noises. I am not there yet in my code.

maybe have the arduino get a feedback loop from the LED pin, if the LED pin is LOW, send the Stop Command(0xFE)

if (digitalRead(LED == LOW) {
WT588D_Send_Command(0xFE)
}
{
else
}

that's wrong im sure.,

tonight's flavor

#define WT588D_SDA 9 //Module pin "P03" or pin # 10

#define WT588D_BUSY 10 //Module pin "LED/BUSY" or pin # 15
int LED = 13;
int LEDa = 12;
int button = 2;        // the button
int state = LOW;      // the current state of the output pin
int reading;          // the current reading from the input pin
int previous = HIGH;    // the previous reading from the input pin
byte file_count = 1;
long time = 0;        // the last time the output pin was toggled
long debounce = 100;  // the debounce time, increase if the output flickers

void setup() {

pinMode(WT588D_SDA, OUTPUT); 
  pinMode(WT588D_BUSY, INPUT); 
  pinMode(button, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  pinMode(LEDa, OUTPUT);
  digitalWrite(button, HIGH);
 
  digitalWrite(WT588D_SDA, HIGH);

}

void loop()
{
    reading = digitalRead(button);
    digitalWrite(WT588D_SDA, HIGH);

// if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
  else
      state = HIGH;
      WT588D_Send_Command(0x02); //on sound
      delay(5);
      digitalWrite(WT588D_SDA, LOW);
   
      time = millis();   
  }
digitalWrite(LED, state);
digitalWrite(LEDa, !state);

if (reading == LOW && previous == HIGH && millis() - time > debounce) {
    if (state == HIGH)
   
      state = LOW;
  else
      state = HIGH;
    WT588D_Send_Command(0x00);
      time = millis();   
}
previous = reading;
}
void WT588D_Send_Command(byte addr) {
    digitalWrite(WT588D_SDA, LOW);
    delay(5);

for(int i = 0; i < 8; i++)  {
        digitalWrite(WT588D_SDA, HIGH);
        if(bitRead(addr, i)) {
            delayMicroseconds(600);
            digitalWrite(WT588D_SDA, LOW);
            delayMicroseconds(200);
        } else {
            delayMicroseconds(200);
            digitalWrite(WT588D_SDA, LOW);
            delayMicroseconds(600);
        }
    }

digitalWrite(WT588D_SDA, HIGH);
    delay(100);
} //end WT588D_Send_Command

Finally, somebody posts a video! Thank you, Bill!

I took a look at your code. You aren't terribly far off. Believe it or not, I think you have too much code.

  1. All of that stuff you are doing with millis() to try and debounce the button signal is not necessary. The cheap and dirty way to avoid all of that is to simply add 20 or 30 ms delay in your loop() function. That way, the button is only read every 20 milliseconds or so and jittery signal should be mitigated.

  2. Add a global bool variable to keep track of your lightsaber state.

bool saber_is_on;
...
setup()
{
...
saber_is_on = false;
...
}
  1. Then make your loop() function look something like this:
loop()
{
   if(digitalRead(button) == LOW) //button is pressed
   {
      if(saber_is_on) //Saber is on, so turn it off
      {
         //ADD CODE HERE TO TURN OFF THE LED AND PLAY OFF SOUND
         saber_is_on = false;
      }
      else //Saber is off, so turn it on
      {
         //ADD CODE HERE TO TURN ON LED AND PLAY ON SOUND
         saber_is_on = true;
      }
   }
}
  1. Take out those digitalWrite(WT588D_SDA...) lines in your loop() function. You don't need those there; they aren't doing anything useful.

i'll give it a try. can i rinse and repeat and do that for the swing sensor too? a different bool?

bool saber_is_on; ?

er...

does that go in the

int bool saber_is_on; portion above setup?

and why the 3 closed curly brackets? i see that from time to time, not quite sure wtf that is all about.
}
}
}

billpealer:
i'll give it a try. can i rinse and repeat and do that for the swing sensor too? a different bool?

bool saber_is_on; ?

er...

does that go in the

int bool saber_is_on; portion above setup?

The "bool" key word declares a variable that can only have two values: "true" and "false". It's just like when you are declaring "int" variables that can hold integer values. In this case, you just want to know if the saber is on or not, so that can be used to keep track of it.

If that's too confusing, you can use "int" instead and just use the values 0 and 1 to mean false and true and do checks on that.

billpealer:
and why the 3 closed curly brackets? i see that from time to time, not quite sure wtf that is all about.
}
}
}

That has to do with defining blocks of code. For each "{", there must be a corresponding "}". This pattern is used all over the place in C and C++. For example, your if blocks will look like this:

if(saber_is_on)
{
//DO SOMETHING HERE
//DO SOMETHING ELSE HERE
//CODE, CODE, AND MORE CODE, etc.
}

But what if you want to check something else before you worry about if the saber is on? Well, then you'd create another if block around your first block. This is called "nesting", meaning one block is contained within another.

if(button_is_pressed)
{
if(saber_is_on)
{
//DO SOMETHING HERE
//DO SOMETHING ELSE HERE
//CODE, CODE, AND MORE CODE, etc.
} //This ends the saber_is_on list of actions
} //This ends the button_is_pressed list of actions

The "{" brackets allow you to define a list of actions to be performed without having to do the check again. The language lets you get away with not using them in the case that you only have one action to perform, but I always use the brackets even then because it makes the code more readable.

Hi,

First of all thank you so much for share this project with us.

I want to do this projet and replace the speaker by a bluetooth shield (HM-10)

I used 1x Arduino pro mini 3.3V-8mHz // 1x WT588D // 3x N-Channel MOSFET 60V 30A // 1x Voltage Regulator - 5V // 1x SW18020P // 1x SW200D // 1x 9W high power LED RGB // 1 Module bluetooth Hm-10

I have a problem with the sound module, I use PL2303HX Convertisseur USB à TTL for programming the WT588D. He doesn't work and i don't know why ( i'm a begginer but i learn quickly ^^ )

( that is the downloader and the wt588d )

I you can help me that will be great and after I'll share my code. I think the sound would be better with an home cinema or something like that.

Hi Niarue

There are actually three types of WT module:

WT588D-16p (16 pin with a basic set of trigger pins)

WT588D-28p (28 pin with expanded trigger pin set and matrix capability)

WT588D-U (28 pin with same specs as above but includes an on board programmer circuit and USB port).

The first two need a separate programmer board to install the sounds and change the internal settings.

The prices can vary a bit depending on which site/distributer your looking at so have a look around.

I got mine on ebay, though I've seen them other places too.

the WT588D setterupper thing you should be using is this guy. all the youtube posts and stuff use this model.

http://www.ebay.com/itm/1PC-WT588D-USB-Sound-Module-Programmer-Downloader-Testing-Board-Tester-/261748549043?hash=item3cf16de5b3:g:rnYAAOSwm8VUxf33

i would just go with the USB version of the chip. I am a complete noob and i figured it out. it is 2cm longer, but only $2 more than the non usb version. Save a ton of time, you can leave the module in the bread board and wired the whole time instead of taking it out of the programmer everytime (just make sure to disconnect the power of the arduino before you replug in the USB for the sound doo-dad. and unless you plan to be making a dozen of these things,. the $12 cost of the programmer just aint worth it.

I'll echo what the others have said. If you can make an extra inch of room in your saber then the WT588D-U is much easier to work with. Otherwise, the only way I know to program them is to buy the $15 programmer from Ebay or an electronics supply site.

In my YouTube videos I showcase the 16-pin version, but when I'm doing development work on my bread I often use a WT588D-U with USB built in just because it's so much easier. When you are operating in serial mode, the 16 and 28 pin versions should all work exactly the same.

Changes made
made some real ground tonight.
i'm tired.