Accelerometer and LEDs from coldsoup753 on Vimeo.
I had a great deal of trouble with the accelerometers of this project. I tried the ADXL335 and the MPU-6050 (as the MPU-6050 page says, “Reading raw values is easy, the rest is not”). Both accelerometers were good at spitting out data, but it was extremely difficult to get that data to be anything other than seemingly random numbers.
Eventually I found the ADXL345, which is simply the updated version of the ADXL335, and that turned out to be exactly the part that I needed. I combined this tutorial with my RGB LED code from my RGB Pencil project to make an LED light up a specific color when the accelerometer senses a tap, double tap, free fall, and inaction.
I tested this out by strapping a breadboard to my Arduino and dropping it a whole bunch of times, and it worked just fine. I originally planned on using the TLC5940NT to drive a whole bunch of RGB LEDs, but that did not work out. I ended up simply using the remaining pins on the Arduino.
/Arduino 1.0+ Only! //Arduino 1.0+ Only! #include #include //Accelerometer code from here: http://bildr.org/2011/03/adxl345-arduino/ ADXL345 adxl; //variable adxl is an instance of the ADXL345 library int RED_PIN = 13; //set pins for LEDs int GREEN_PIN = 12; int BLUE_PIN = 11; int RED_PIN2 = 10; //set pins for LEDs int GREEN_PIN2 = 9; int BLUE_PIN2 = 8; int RED_PIN3 = 7; //set pins for LEDs int GREEN_PIN3 = 6; int BLUE_PIN3 = 5; int RED_PIN4 = 4; //set pins for LEDs int GREEN_PIN4 = 3; int BLUE_PIN4 = 2; void setup(){ Serial.begin(9600); adxl.powerOn(); pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); pinMode(RED_PIN2, OUTPUT); pinMode(GREEN_PIN2, OUTPUT); pinMode(BLUE_PIN2, OUTPUT); pinMode(RED_PIN3, OUTPUT); pinMode(GREEN_PIN3, OUTPUT); pinMode(BLUE_PIN3, OUTPUT); pinMode(RED_PIN4, OUTPUT); pinMode(GREEN_PIN4, OUTPUT); pinMode(BLUE_PIN4, OUTPUT); //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(5); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625μs per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(5); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(20); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); } void loop(){ //Boring accelerometer stuff int x,y,z; adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Output x,y,z values - Commented out //Serial.print(x); //Serial.print(y); //Serial.println(z); //Fun Stuff! //read interrupts source and look for triggerd actions //getInterruptSource clears all triggered actions after returning value //so do not call again until you need to recheck for triggered actions byte interrupts = adxl.getInterruptSource(); // freefall if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){ Serial.println("freefall"); showRGB(200); } //inactivity if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){ Serial.println("inactivity"); showRGB(400); } //activity if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){ Serial.println("activity"); showRGB(700); } //double tap if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){ Serial.println("double tap"); showRGB(300); } //tap if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){ Serial.println("tap"); showRGB(100); } } void showRGB(int color) { int redIntensity; int greenIntensity; int blueIntensity; // Here we'll use an "if / else" statement to determine which // of the three (R,G,B) zones x falls into. Each of these zones // spans 255 because analogWrite() wants a number from 0 to 255. // In each of these zones, we'll calculate the brightness // for each of the red, green, and blue LEDs within the RGB LED. if (color <= 255) // zone 1 { redIntensity = 255 - color; // red goes from on to off greenIntensity = color; // green goes from off to on blueIntensity = 0; // blue is always off } else if (color <= 511) // zone 2 { redIntensity = 0; // red is always off greenIntensity = 255 - (color - 256); // green on to off blueIntensity = (color - 256); // blue off to on } else // color >= 512 // zone 3 { redIntensity = (color - 512); // red off to on greenIntensity = 0; // green is always off blueIntensity = 255 - (color - 512); // blue on to off } // Now that the brightness values have been set, command the LED // to those values analogWrite(RED_PIN, redIntensity); analogWrite(BLUE_PIN, blueIntensity); analogWrite(GREEN_PIN, greenIntensity); analogWrite(RED_PIN2, redIntensity); analogWrite(BLUE_PIN2, blueIntensity); analogWrite(GREEN_PIN2, greenIntensity); analogWrite(RED_PIN3, redIntensity); analogWrite(BLUE_PIN3, blueIntensity); analogWrite(GREEN_PIN3, greenIntensity); analogWrite(RED_PIN4, redIntensity); analogWrite(BLUE_PIN4, blueIntensity); analogWrite(GREEN_PIN4, greenIntensity); }