Simplifying the design and expanding commands for the ATtiny

A project log for Lightsaber prop with sound effects

An Arduino-based lightsaber with sound effects and an accelerometer

matthias-nigmannMatthias Nigmann 05/18/2024 at 04:080 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