Close
0%
0%

Lightsaber prop with sound effects

An Arduino-based lightsaber with sound effects and an accelerometer

Similar projects worth following
The leader of a maker club I am part of was interested in building lightsaber props for next year's club project. His vision for the project included LED light strips for the "blade", an accelerometer, and sound effects that responded to motion. However, all of the kits he found that supported these features were too expensive for a club project. I offered to help him design and program the electronics for the lightsaber, while he worked on the body of the lightsaber.

The main requirements for this project are listed below:

  1. The lightsaber should produce its characteristic buzzing or humming noise and modulate the buzzing noise as the lightsaber is moved or rotated.
  2. The lightsaber should be able to play sound effects from a memory chip, for example, when the blade is turned on or when the lightsaber collides with something.
  3. The lightsaber should be battery-powered and should be entirely self contained. This means that the electronics and batteries must fit inside the handle of the lightsaber.
  4. The project must not be too expensive. Ideally, the electronics should cost around 10 dollars per person, since the total cost will also include the LEDs, the tube for the blade, the handle, and the batteries.
  5. The project should be simple enough to be completed by kids of various ages in six 1.5-2 hour meetings. However, there must also be enough time to build the body of the lightsaber and assemble the parts, so the electronics will be limited to maybe three or four meetings. This means that the electronics may not involve any surface mount components.
  6. The project should involve some Arduino programming. However, since the kids will not be able to understand assembly code or register manipulation, all of these features must be hidden in an Arduino library.

With these requirements in mind, I began to design the electronics. First, I considered using just an Arduino Nano to implement all of the features. The Nano would write audio data to a DAC, which would feed into an amplifier. However, this would mean that the Nano must be able to continuously write to the DAC 44100 times per second while also controlling the LED strip and reading from the memory chip and accelerometer. All of these steps would have to be implemented very carefully to allow them to all fit in the allowed time, which would require a lot of assembly programming and would not leave much free time for user code.

To fix these issues, I split up these tasks between two processors: an Arduino Nano for reading from the accelerometer and controlling the LEDs, and an ATtiny85 for generating all of the sound effects and writing to the DAC. The Nano then sends commands to the ATtiny to control the volume of the buzzing, start playback, and control the volume of the playback. I also reduced the sample rate of the audio from 44100Hz to 33333Hz, which gives me 32% more time per sample. 

This "dual-core" structure offloads the majority of the timing-critical work onto the ATtiny, which can then be programmed in assembly. The Nano can then be programmed mostly using Arduino code, with only a little assembly hidden away in a library.

The audio amplifier also presented a number of challenges. The speaker must be small enough to fit inside the handle, but loud enough to generate a sound that is audible a few meters away. The club leader had ordered a small (~3cm diameter) 3 watt speaker for testing. To maximize the loudness of the sound that the speaker could produce, I used a full-bridge driver, which drives both terminals of the speaker, but with inverted signals. Thus, the voltage across the speaker is twice the amplitude of the input signal, and the produced sound is twice as loud.

Since the buzzing sound can be varied as the lightsaber is moved, it would be impractical to use and store a clip of original lightsaber audio. Thus, I simplified the buzzing sound so that it consists of a 25-millisecond clip that is played on repeat continuously. This clip is stored in the program memory of the ATtiny. At the chosen sample rate, the clip consists of 833 samples. A plot of the waveform is shown below:

The specific design of the buzzing sound will likely be modified later in the project.

The DAC used in this project will be an MCP4911 10-bit DAC, and the memory chip will be an SST25VF080B 8 megabit SPI flash chip. This chip was one of the few through-hole flash chips I could find on Digikey, and should be enough to store around 30 seconds...

Read more »

lightsaber_proto1.sch

gEDA schematic of the first prototype

sch - 21.21 kB - 05/11/2024 at 03:42

Download

buzz.wav

Lightsaber buzz

Waveform Audio File Format (WAV) - 162.74 kB - 05/05/2024 at 00:18

Download

  • Adding the accelerometer

    Matthias Nigmann4 days ago 0 comments

    The code on Github can now read the rotation data from the accelerometer and adjust the amplitude of the buzzing sound accordingly. I also changed the way the accelerometer and ATtiny connect to the Nano like I described in the previous update. The accelerometer connects to the I2C interface on pins A4 and A5 and the ATtiny connects to the hardware SPI on pins D10, D12, and D13. 

    Roughly 100 times per second, the Nano reads the gyroscope data from the accelerometer. The magnitude of the rotation is smoothed using a simple low-pass filter, and then converted to an amplitude value, which is sent to the ATtiny. The smoothing step makes sure that the amplitude does not fluctuate rapidly due to noise in the measurement

    Let be the angular velocity around the x-axis and be the angular velocity around the y-axis. The first step is to apply the low-pass filter to get the smoothed value , which is done using the formula:

    The next step is to calculate the buzz amplitude , which can range from 0 to 255. This is done with the formula:

    The constant offset of 50 ensures that even when the lightsaber is held still, some sound can still be heard. All of the calculations are done using integer arithmetic, and the divisions are implemented using bitshifts.

    When testing the program, I noticed a slight staticky noise in the buzz when I moved the accelerometer. I suspect this is caused by the signal suddenly changing from one level to another when the amplitude is changed. I will likely program the ATtiny to slowly ramp the amplitude from its current value to its new value to minimize these effects.

  • Simplifying the design and expanding commands for the ATtiny

    Matthias Nigmann6 days ago 0 comments

    When I recently tested the accelerometer with the Arduino Nano, I realized that its SPI interface was not working, but its I2C interface was. This led me to an obvious design simplification that I missed earlier: connecting the accelerometer via I2C and using the Nano's hardware SPI for interfacing with the ATtiny. This would let me do away with the assembly code that I currently need to communicate with the ATtiny, since the hardware already takes care of the synchronization and timing issues. I hope to implement this change soon.

    I also implemented some additional commands on the ATtiny for starting playback and for setting the volume of the playback. The commands I have implemented are shown below:

    0000 0000 dddd dddd       Set buzz volume to d
    0001 0000 dddd dddd       Set playback volume to d
    0100 dddd dddd dddd       Load lower 12 bits of the
                              playback address
    0101 dddd dddd dddd       Load upper 12 bits of the 
                              playback address and begin
                              playback. Starting playback 
                              needs two commands, since 
                              the address has 24 bits. 
    

    I also fixed a strange bug in the multiplication algorithm I implemented on the ATtiny. I found this bug when I realized that the playback was still audible even when I set its volume to zero. Furthermore, the playback would get quieter as I increased the volume from 0 to 7. At 8, it would be louder than at 0. This strange pattern repeated every 8 volume units. I found that this bug was caused by stray values in the AVR core's carry bit. The multiplication algorithm involves checking each bit (from LSB to MSB) in the volume register, adding the sample value to the result register if it is set, and then shifting the result register to the right. If the carry bit was set by the addition, then the shift would load it into the MSB of the result register. However, the unexpected side effect of this was that if the addition was not executed, then the carry bit would retain its value from the previous operation. Thus, the MSB of the result register was loaded with unexpected values, affecting the output of the multiplication. I fixed this by first shifting the sample value to the right before multiplying, and then skipping the final shift. Then, if the LSB of the sample value was set before the initial shift, then the volume was added to the result register.

    The most recent version of the code, which contains the fix for this bug, can be found at https://github.com/mnigmann/lightsaber

  • First prototype schematics and technical details

    Matthias Nigmann05/11/2024 at 03:48 0 comments

    I have added the gEDA schematic file for the first prototype to this project; it can be downloaded here or from the Files tab.

    Technical details on the first prototype, including explanations of the assembly code and schematic, can be found at https://mnigmann.blogspot.com/2024/05/lightsaber-prop-first-prototype.html

View all 3 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates