Go Down

Topic: Arduino Lightsaber (Read 393822 times) previous topic - next topic

billpealer

#90
Nov 03, 2015, 06:56 am Last Edit: Nov 03, 2015, 03:00 pm by billpealer
youtube video on its way.  i am in better shape than yesterday.  i know i am still doing it wrong.
https://www.youtube.com/watch?v=A6grN9m3EJ4

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

Code: [Select]
#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

JakeSoft

#91
Nov 04, 2015, 04:36 am Last Edit: Nov 04, 2015, 04:37 am by JakeSoft
youtube video on its way.  i am in better shape than yesterday.  i know i am still doing it wrong.
https://www.youtube.com/watch?v=A6grN9m3EJ4

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

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

bool saber_is_on;
...
setup()
{
...
saber_is_on = false;
...
}


3. Then make your loop() function look something like this:
Code: [Select]

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;
      }
   }
}


4. Take out those digitalWrite(WT588D_SDA...) lines in your loop() function. You don't need those there; they aren't doing anything useful.

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?


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

JakeSoft

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.

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.

Niarue

#94
Nov 04, 2015, 04:56 pm Last Edit: Nov 04, 2015, 04:56 pm by Niarue
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 ^^ )

https://drive.google.com/file/d/0B4G7p1vQyogjQWtiUk5RS21vcTg/view?usp=sharing
( 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.

 

Canobi

#95
Nov 04, 2015, 06:20 pm Last Edit: Jan 25, 2016, 04:08 pm by Canobi
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.

billpealer

#96
Nov 04, 2015, 07:30 pm Last Edit: Nov 04, 2015, 07:31 pm by billpealer
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.

JakeSoft

#97
Nov 04, 2015, 08:44 pm Last Edit: Jan 25, 2016, 03:49 pm by JakeSoft
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.

billpealer

#98
Nov 05, 2015, 06:54 am Last Edit: Nov 05, 2015, 07:07 am by billpealer
Changes made
made some real ground tonight.
i'm tired.

https://youtu.be/c2b59vya0LI

Niarue

Ok Thank you for your time everyone.

I already buy the programmer on your video jakesoft, I leave in france and the time of shipment is verrrry

looong ahah. So I try to use this usb converter.

I think I'll try to work on the program for the LED wile the programmer come.

JakeSoft

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

https://youtu.be/c2b59vya0LI
It's looking pretty good!

I chuckled a little bit at the on-the-fly code updates during your demo. Sometimes stuff like that happens to me when I'm filming my videos, but I usually just take a cut and start over. If it works right the first time, you didn't learn anything, right? lol

Anyway, I think the issue with your swing sounds repeating is fixable. When I wrote my Mk. II code I had to write it such that the swing sound would only trigger if the state changed. You had some code that was kind of doing something like that before. Each cycle you just keep track of what the last state was and if it's not the same, then do the swing sound. Otherwise, do nothing.

Code: [Select]

int last_swing_state;

loop()
{
   
   int current_swing_state = digitalRead(swingSensorPin);

   if(current_swing_state != last_swing_state)
   {
      //PLAY A SWING SOUND HERE
   }

   //Save the current swing state for comparison in the next cycle
   last_swing_state = current_swing_state;
   
}


That should do it.

I'm liking your MHS hilts, BTW. I'm looking forward to seeing them all lit up.


purgedsoul

#101
Nov 06, 2015, 08:58 am Last Edit: Nov 06, 2015, 03:17 pm by purgedsoul Reason: added another video
For those who have no WT588D programmer I finally got to upload audio to the board using only the Arduino and processing. This is based on AdaFruit's audio transfer code for the Trinket. Link to the code can be found on this thread:

http://forum.arduino.cc/index.php?topic=227435.msg2466463#msg2466463

USE AT YOUR OWN RISK

For JakeSoft here's a youtube vid for you :-)

https://youtu.be/EKgHZP4UJjs

With lightsaber sounds loaded. Still needs to work on my button/sensor codes.

https://youtu.be/S7qEvnJbOLg

purgedsoul

Question: Do we need to issue a stop command (0xFE) before we play another audio group?

billpealer

#103
Nov 06, 2015, 05:19 pm Last Edit: Nov 06, 2015, 05:21 pm by billpealer
Question: Do we need to issue a stop command (0xFE) before we play another audio group?
No. Just make sure the WT is set to edge retrigger.  i suggest a delay(100);  after every WT_send_command(0x..)


Update:
I disconnected the Busy pin from the arduino to the WT and everything still works.
Frees up an arduino pin too.

and

Jake, I'll give that a try.

I over came the swing repeat with the standard debounce code.

Code: [Select]


int SW_sensor = 9  //sensor button pin
long time = 0  //time of nothing
long debounce = 200 //200ms is the margin of error to determine a press, hold, or rapid press
bool swing_sound

setup
digitalWtite(SW_sensor,HIGH);
swing_sound = false;

void loop()
{

  // if the swing sensor was toggled and not just held at a state for less than 200ms
 
 if (digitalRead(SW_sensor) == HIGH && digitalRead(SW_sensor) == LOW && millis() - time > debounce) {
   
if (swing_sound)

  // do nothing.  get coffee but be back in 100 ms
     delay(100);
   
 else
      WT_send_command(1); // swing sound
      delay(100);

    time = millis();   
  }
}


JakeSoft

#104
Nov 06, 2015, 11:14 pm Last Edit: Nov 06, 2015, 11:15 pm by JakeSoft
No. Just make sure the WT is set to edge retrigger.  i suggest a delay(100);  after every WT_send_command(0x..)


Update:
I disconnected the Busy pin from the arduino to the WT and everything still works.
Frees up an arduino pin too.

and

Jake, I'll give that a try.

I over came the swing repeat with the standard debounce code.

Code: [Select]


int SW_sensor = 9  //sensor button pin
long time = 0  //time of nothing
long debounce = 200 //200ms is the margin of error to determine a press, hold, or rapid press
bool swing_sound

setup
digitalWtite(SW_sensor,HIGH);
swing_sound = false;

void loop()
{

  // if the swing sensor was toggled and not just held at a state for less than 200ms
 
 if (digitalRead(SW_sensor) == HIGH && digitalRead(SW_sensor) == LOW && millis() - time > debounce) {
   
if (swing_sound)

  // do nothing.  get coffee but be back in 100 ms
     delay(100);
   
 else
      WT_send_command(1); // swing sound
      delay(100);

    time = millis();   
  }
}


Look at you, Bill: Answering questions complete with sample code!

"Indeed, you are powerful" --Darth Vader

Good for you!
"Pass on what you have learned" --Yoda

...I should stop now, huh? :-)

Go Up