The accelerometer and the GlowSaber

This page is in response of a question posted by Dennis Waschik on GlowSaber Physics Facebook page:

Hello Mr. Vadillo, I am a german student and want to make an Arduino lightsaber. Now I found your homepage and I am very impressed of your project. I would be very thankful if you could give me a little help with my project. I use a BMA020 accelerometer to control the change of color, but if the sensor is moved fast, the light is flickering, and that looks not very nice. Which sensor do you use exactly? Would it be possible to share your code? It would be a big help to compare the arduino code.

Thank you, Dennis Waschik

Dennis, I am very flattered that you reach me to find some tips on your light saber project. In the early stages of development of mine I used an accelerator, the MMA7361, and pair the values of X, Y and Z to the Red, Green and Blue LED’s. The accelerometer returned values from 0 to 1023 for each axis and I used the Arduino map function to get a PWM value for the LED. The problem with this technique was that most of the time the values for all axis were around 512 and since the PWM values were similar I got mostly a white light out of the light saber. The MMA7361 had many problems, one of them was cost. At the time, 2013, they were about $11 a piece, good enough for one prototype but certainly too expensive for running a class, as was my intention. Another problem was the form factor and the way the pins were exposed in the PCB. I switched to another accelerometer, the ADXL335-5V from Adafruit. It had a better form factor, with all the pinouts on the same side of the board, but still was too expensive. As the MMA7361 it required three analog ports to read the values for the X, Y and Z axis.

5175GD8JbHL 163-02 2019iso_lrg

In the design that I used for my class I changed again to the MMA8451 accelerometer breakout from Adafruit. The price was very reasonable at S7.95. Another advantage is that the MMA8451 has its own D/A converter and transmit the value over only two analog ports. The library for the MMA8451 that Adafruit provides reports not only the acceleration on each axis, but the position. Using the position as a way to change colors what I did was to map each position to a different hex value for the LED’s. These are the colors I am using:

#define GS_COLOR_BLACK      0
#define GS_COLOR_BLUE       0x0000ff
#define GS_COLOR_GREEN      0x00ff00
#define GS_COLOR_CYAN       0x00ffff
#define GS_COLOR_RED        0xff0000
#define GS_COLOR_MAGENTA    0xff00ff
#define GS_COLOR_YELLOW     0xffff00
#define GS_COLOR_ORANGE     0x7fff00
#define GS_COLOR_PURPLE     0x7f00ff
GS_COLOR_BLACK of course means that no LED is lighted. The values are then used to create a table that can be accessed by index. The accelerometer reports a value from 0 to 7 based on the position of the accelerometer. An example is Portrait, Up, Front. Another is Lanscape, Right, Front. See the code for the accelerometer.
I added to the GlowSaber control unit a potentiometer that allow me to change some of the behavior. I read the potentiometer every 300 milliseconds, and use the map function to map the value from 0 to 8. If the value from the potentiometer is zero, then I use the accelerometer, otherwise I use the value from 1 to 8 to a fixed color. Using this technique the user can choose the color, or choose to change colors as s/he moves the GlowSaber
color_t colors[] = {
    GS_COLOR_BLACK,
    GS_COLOR_BLUE,
    GS_COLOR_GREEN,
    GS_COLOR_CYAN,
    GS_COLOR_RED,
    GS_COLOR_MAGENTA,
    GS_COLOR_YELLOW,
    GS_COLOR_ORANGE,
    GS_COLOR_PURPLE
};
void GS_Color_Controller::pwmColor(int index) {
    color_t color;
    if (index < 0) {
        index = 0;
    }
    if (index > 8) {
        index = 8;
    }
    color = colors[index];
    analogWrite(mRedPin, (int)((color >> 0x10) & 0xff));
    analogWrite(mGrnPin, (int)((color >> 0x08) & 0xff));
    analogWrite(mBluPin, (int)(color & 0xff));
}

void GS_Color_Controller::showColors() {
    if (0 == mDominant) {
        pwmColor(getOrientation() + 1);
    } else {
        pwmColor(mDominant);
    }
}

This is only a fraction of the code. I have plans on posting all the code in Git at a later date. I still use the acceleration reported to determine if the GlowSaber is moving and to produce a distinctive sound when it moves.

Leave a Reply