Hey all, this is my first time posting to the community. I am a mechanical engineer with a little bit of college training in microcontrollers, so I apologize in advance if I make silly mistakes. Please let me know if this is the wrong board, or if I make any faux pas. On to the project!
This project is for a cosplay wizard's staff. I have a high intensity RGB LED that I am controlling with a Nano and an accelerometer. The idea is that at rest, the LED will show low intensity white, then on change in acceleration (jerk) in the x, y, or z direction, the strength of the red, blue, or green will increase respectively, then slowly fall back to rest value. I have some code written (follows) that works, and I can currently get the desired effect with a cheapo RGB LED.
The questions:
- The code I wrote works, but I don't delude myself in to thinking I'm a coding wiz; do you see anything in there that I can change to make it more efficient/elegant?
- I would like to use a higher intensity RGB LED (parts to follow). Do I need to do anything to protect the mosfet or the LED from burning out? I have attached an illustration of my prototype layout to this post.
The parts:
Microcontroller: Arduino Nano
Accelerometer: LSM9DS1
RGB LED: SMT LED 5050
MOSFET: N-channel power MOSFET 30V/60A
Power: 2200mAh 5V/1A
The Code:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LSM9DS1.h>
#include <Adafruit_Sensor.h> // not used in this demo but required!
// i2c
Adafruit_LSM9DS1 lsm = Adafruit_LSM9DS1();
#define LSM9DS1_SCK A5
#define LSM9DS1_MISO 12
#define LSM9DS1_MOSI A4
#define LSM9DS1_XGCS 6
#define LSM9DS1_MCS 5
// You can also use software SPI
//Adafruit_LSM9DS1 lsm = Adafruit_LSM9DS1(LSM9DS1_SCK, LSM9DS1_MISO, LSM9DS1_MOSI, LSM9DS1_XGCS, LSM9DS1_MCS);
// Or hardware SPI! In this case, only CS pins are passed in
//Adafruit_LSM9DS1 lsm = Adafruit_LSM9DS1(LSM9DS1_XGCS, LSM9DS1_MCS);
//Define LED Pins
int redPin = 9;
int greenPin = 10;
int bluePin = 11;
//Set Resting Value for colors
int redRest = 240;
int blueRest = 240;
int greenRest = 240;
//Value to be written to LED Pins
int redVal = 0;
int blueVal = 0;
int greenVal = 0;
//Modifier for LED Values
float redAccel = 0;
float blueAccel = 0;
float greenAccel = 0;
void setupSensor()
{
// 1.) Set the accelerometer range
lsm.setupAccel(lsm.LSM9DS1_ACCELRANGE_2G);
}
void setup()
{
//Required for Sensor
lsm.begin();
setupSensor();
//Initialize LED PINS as OUTPUT
pinMode(redPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(greenPin, OUTPUT);
//Start at LED REST value
analogWrite(redPin, redRest);
analogWrite(bluePin, blueRest);
analogWrite(greenPin, greenRest);
}
void loop()
{
//Call function to calculate average Jerk
jerk(&redAccel, &blueAccel, &greenAccel);
//Attenuate Red rest noise, change the value to be written (brightens LED)
if (redAccel > 1)
redVal -=redAccel;
//Don't let the value go negative
if (redVal <= 0)
redVal = 0;
//Repeat for Blue and Green
if (blueAccel > 2)
blueVal -=blueAccel;
if (blueVal <= 0)
blueVal = 0;
if (greenAccel > 2)
greenVal -=greenAccel;
if (greenVal <= 0)
greenVal = 0;
//Write the new value to the LED
analogWrite(redPin, redVal);
analogWrite(bluePin, blueVal);
analogWrite(greenPin, greenVal);
//Fade the LED back to Rest state
if (redVal < redRest)
redVal +=10;
if (blueVal < blueRest)
blueVal +=10;
if (greenVal < greenRest)
greenVal +=10;
}
The Function:
void jerk(float* xAve, float* yAve, float* zAve)
{
//6 value array for holding acceleration readings
float xAccel[7];
float yAccel[7];
float zAccel[7];
//Initalize the values that will be passed back as 0
float xAverage = 0;
float yAverage = 0;
float zAverage = 0;
//Get the new values for 6 acceleration events
for (int i = 0; i < 6; i++)
{
lsm.read(); /* ask it to read in the data */
/* Get a new sensor event */
sensors_event_t a, m, g, temp;
lsm.getEvent(&a, &m, &g, &temp);
xAccel[i] = a.acceleration.x;
yAccel[i] = a.acceleration.y;
zAccel[i] = a.acceleration.z;
delay(5);
}
//Calculate the jerk
for (int n = 0; n < 5; n++)
{
xAverage += (xAccel[n]-xAccel[n+1])/.1;
yAverage += (yAccel[n]-yAccel[n+1])/.1;
zAverage += (zAccel[n]-zAccel[n+1])/.1;
}
//Take the average of the jerk and pass it back to Loop
*xAve = (xAverage/6);
if (xAverage < 0 )
*xAve = xAverage*-1;
*yAve = (yAverage/6);
if (yAverage < 0 )
*yAve = yAverage*-1;
*zAve = (zAverage/6);
if (zAverage < 0 )
*zAve = zAverage*-1;
}
Thanks again for any help/suggestions/insight!