I want the light in our baby's costome to have a sort of physical property where light drops to the bottom if the baby is lifted up and light rises to the top of the baby's costume if he accelerates down. This is a little harder than Becky's brake light motorcycle jacket at adafruit because a motorcycle has a relatively constant deceleration over a long distance as the brakes apply force slowing the rider and bike. When throwing an older toddler/child in the air you can get half a second of acceleration up before you stop applying force and let gravity accelerate them back down. When you rock a 3mo old you get about three up/down cycles a second. Each up and each down have an acceleration and deceleration associated with it. So you can get twelve significant acceleration and deceleration readings per second rocking a baby. Initially I had envisioned the light sloshing around like water in a bathtub. But the light has to be accurately reactive to the movement but also easy on the eyes. I sort of solved it by making an exponential relationship between the acceleration and the voltage change sent to the LEDs. I am open to suggestions if anyone has a better way to approach it. Code and boring video below.
#include <Wire.h>
#include <Adafruit_LSM303.h>
int upLed = 6;
int downLed = 5;
Adafruit_LSM303 lsm;
void setup()
{
Serial.begin(9600);
pinMode(upLed, OUTPUT);
pinMode(downLed, OUTPUT);
// Try to initialise and warn if we couldn't detect the chip
if (!lsm.begin())
{
Serial.println("Oops ... unable to initialize the LSM303. Check your wiring!");
while (1);
}
}
void loop()
{ int maxLight = 0;
int upAccelerationThreshold = 1050;
int downAccelerationThreshold = 820;
int delaytime = 18;
analogWrite(upLed, 50); //50 is perceptually to me 50% brightness for the LED
analogWrite(downLed, 50); //I use 50 as the equilibrium position
lsm.read();
int acceleration = (int)lsm.accelData.z;
//z acceleration seems to hover between 990 and 970
//fast up acceleration = ~1800
//fast down acceleration = ~50
//Serial.print((int)lsm.accelData.z);
if (acceleration > upAccelerationThreshold) //upward acceleration
{
if(acceleration > 1500){maxLight = 50;} //limit max light to 50
else{maxLight = (acceleration - 1010) / 9.8;} //max light goes from 0 to 50
Serial.println(maxLight);
for(int x = maxLight; x >= 0; x--){
int upLedStrength = 50 - (x*x)/50;
int downLedStrength = 50 + (x*x*4.1)/50;
analogWrite(upLed, upLedStrength);
analogWrite(downLed, downLedStrength);
delay(delaytime);
}
Serial.println("up equilibrated");
}
if (acceleration < downAccelerationThreshold) //downward acceleration
{
if(acceleration < 300){maxLight = 50;} //limit max light to 50
else{maxLight = (960 - acceleration) / 13.2;} //max light goes from 0 to 50
Serial.println(maxLight);
for(int x = maxLight; x >= 0; x--){
int upLedStrength = 50 + (x*x*4.1)/50;
int downLedStrength = 50 - (x*x)/50;
analogWrite(upLed, upLedStrength);
analogWrite(downLed, downLedStrength);
delay(delaytime);
}
Serial.println("down equilibrated");
}
}
Warning: Boring Video. The top LED represents LEDs on the top of a costume and the bottom LED represents LEDs on the bottom of a costume.