Fading an Led

nice and easy!

I have 6 leds, top, bottom, left, right, front back. like a dice, and an accelerometer taking constant readings.

i have the reading mapped, so if flat, top is 255 (bottom is 0), turn to the right and right is 255 (left is 0)

what i want is when i turn the dice from top to bottom (inverted), the top led fades to 0, whilst the bottom led fades in.

i currently have the led flicking on and off quite well, but am having trouble fading.

#include <Wire.h>
#include "FastLED.h"

#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)

byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
char str[512];                      //string buffer to transform data before sending it to the serial port

#define NUM_LEDS 12
#define DATA_PIN 3
#define CLOCK_PIN 13
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 255

int difficulty = 5;
int accuracy = 50;
int var = 8;  // initial sequence

int mean_xa = 224;
int mean_ya = 224;
int mean_za = 224;
int mean_xb = 224;
int mean_yb = 224;
int mean_zb = 224;

int lead_dot = 0;

int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345

int initx, inity, initz;
int x, y, z;
int xa, ya, za;
int xb, yb, zb;
int xc, yc, zc;
int xd, yd, zd;

unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 50;           // interval at which to blink (milliseconds)



void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  delay(2000);
  FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  FastLED.clear();
  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);


  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 0);
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);

  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
  //  startx = (((int)buff[1]) << 8) | buff[0];
  //  starty = (((int)buff[3])<< 8) | buff[2];
  //  startz = (((int)buff[5]) << 8) | buff[4];

}

void loop() {


  //  int x, y, z;

  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345

  //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
  //thus we are converting both bytes in to one int
  x = (((int)buff[1]) << 8) | buff[0];
  y = (((int)buff[3]) << 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];

  xa  = map(x, -255, 255, 0, 255);
  xb = map(x, -255, 255, 255, 0);
  ya  = map(y, -255, 255, 0, 255);
  yb = map(y, -255, 255, 255, 0);
  za  = map(z, -255, 255, 0, 255);
  zb = map(z, -255, 255, 255, 0);

  // the next section takes a constant average of the accelerometer
  // and subtracts it from the current reading. this means that
  // whatever orientation you put it in, it will tend towards readings of
  // zero for all axes. I found the adxl's I got to have quite varied
  // baselines, so this made sure that all of the suits would record an impulse
  // based on motion "away from however you were positioned last."
//      mean_xa = (xa + mean_xa) / 2;
//      mean_ya = (ya + mean_ya) / 2;
//      mean_za = (za + mean_za) / 2;
//      xa = abs(xa - mean_xa);
//      ya = abs(ya - mean_ya);
//      za = abs(za - mean_za);      
//      xb = mean_xa;
//      yb = mean_ya;
//      zb = mean_za;
//      
//      mean_xb = (xb + mean_xb) / 2;
//      mean_yb = (yb + mean_yb) / 2;
//      mean_zb = (zb + mean_zb) / 2;
//      xb = abs(xb - mean_xb);
//      yb = abs(yb - mean_yb);
//      zb = abs(zb - mean_zb);
//      xb = mean_xb;
//      yb = mean_yb;
//      zb = mean_zb;

  //we send the x y z values as a string to the serial port
  Serial.print(xa); Serial.print(" ");
  Serial.print(xb); Serial.print(" | ");
  Serial.print(ya); Serial.print(" ");
  Serial.print(yb); Serial.print(" | ");
  Serial.print(za); Serial.print(" ");
  Serial.print(zb); Serial.print(" | ");
  Serial.print(var);
  Serial.write(10);



  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;


  if (xa < 223) xa=xc;
  if (ya < 223) ya=yc;
  if (za < 223) za=zc;

  if (xa > 223) xa = 255;
  if (ya > 223) ya = 255;
  if (za > 223) za = 255;
  
  if (xb < 223) xb=xd;
  if (yb < 223) yb=yd;
  if (zb < 223) zb=zd;

  if (xb > 223) xb = 255;
  if (yb > 223) yb = 255;
  if (zb > 223) zb = 255;

    for (int i = 0; i < 2; i++) {
      leds[i]    =   CHSV( 255, 255, yb); // back
      leds[i+2]  =   CHSV( 255, 255, xa); // left
      leds[i+4]  =   CHSV( 255, 255, ya); // front
      leds[i+6]  =   CHSV( 255, 255, xb); // right
      leds[i+8]  =   CHSV( 255, 255, za); // top
      leds[i+10] =   CHSV( 255, 255, zb); // bottom
    FastLED.show();
  }

if (xc>0) xc--;
if (yc>0) yc--;
if (zc>0) zc--;
if (xd>0) xc--;
if (yd>0) yc--;
if (zd>0) zc--;
  
  } // end of timed loops

  //switch (var) {
  //  case 1: // bottom
  //    break;
  //  case 2: // right
  //    break;
  //  case 3: // left
  //    break;
  //  case 4: // Front
  //    break;
  //  case 5: // Back
  //    break;
  //  case 6: // Top
  //    break;
  //  case 7: // flat - bottom led on
  //    break;
  //  case 8:
  //    default:
  //    break;
  //} // end of switch



  //It appears that delay is needed in order not to clog the port
//  delay(100);
} // end of void loop

//---------------- Functions
//Writes val to address register on device
void writeTo(int device, byte address, byte val) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        // send register address
  Wire.write(val);        // send value to write
  Wire.endTransmission(); //end transmission
}

//reads num bytes starting from address register on device in to buff array
void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission

  Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device

  int i = 0;
  while (Wire.available())   //device may send less than requested (abnormal)
  {
    buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}

if it helps, i can see whats happening, i just dont know how to fix it.

the sensor takes a reading;

xa = 128, ya=128, za=255;

so za is lit (top)

so as xa and ya are less than 224 they both decrease by 1 (xa--:wink:

but then the sensor takes a reading and xa=128, ya=128, za=255

and thus it loops.

Hi,

Your description of what you want to happen is confusing. Your first post seems to say the fading happens when the cube is turned, the leds fade as the cube moves, and when it is placed on a surface, whichever side is top is lit? But your second post and parts of your code seem to be trying to fade all leds to off? Is that right?

If so, you need to be able to detect when the cube is not being moved before you start your fade.

Paul

PaulRB:
Hi,

Your description of what you want to happen is confusing. Your first post seems to say the fading happens when the cube is turned, the leds fade as the cube moves, and when it is placed on a surface, whichever side is top is lit? But your second post and parts of your code seem to be trying to fade all leds to off? Is that right?

If so, you need to be able to detect when the cube is not being moved before you start your fade.

Paul

You’ve pretty much worked out what i want to do, but alas this is where i’ve got to.

As the sensor is constantly putting out a reading, every variation of the maths i can work out just overrides the current number.

so. when x is flat, it reads 255 ( if (xa > 223) xa = 255; ) (so if the x is mostly flat, then the led is full brightness (_+20)

if i have the led directly connected to the mapped x y z reading, then i get half faded leds, but what im after is one led full brightness, and if the cube is turned, then once the led goes past a point (223) then it just fades to 0 (regardless of the sensor reading). if the sensor then detects over 223 again, the led turns on.

i cant seem to work out a way to incorporate the 2.

what i want in flow;

read sensor
if sensor is over 223, light led
if led is lit and the sensor reads less than 223, fade out

what i’m getting is;
read sensor,
if sensor is over 223, light led
if sensor is less than 223, led fade out
read sensor,
light led, fade led,
read sensor,
light led, fade led

but the fades are 255 to 254, before it has chance to read the sensor again.

slightly updated code below

#include <Wire.h>
#include "FastLED.h"

#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)

byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
char str[512];                      //string buffer to transform data before sending it to the serial port

#define NUM_LEDS 12
#define DATA_PIN 3
#define CLOCK_PIN 13
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 255

int difficulty = 5;
int accuracy = 50;
int var = 8;  // initial sequence
int idex =0;
int sensitivity = 210;

int lead_dot = 0;

int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345

int initx, inity, initz;
int x, y, z;
int xa, ya, za;
int xb, yb, zb;
int xc, yc, zc;
int xd, yd, zd;

unsigned long previousMillisLeds = 0;        // will store last time LED was updated
unsigned long previousMillisSensor = 0;        // will store last time sensor was updated
const long intervalLeds = 50;           // interval at which to operate leds
const long intervalSensor = 50;           // interval at which to check sensor



void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
  delay(2000);
  FastLED.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
  FastLED.clear();
  // set master brightness control
  FastLED.setBrightness(BRIGHTNESS);


  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 0);
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);

  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
  //  startx = (((int)buff[1]) << 8) | buff[0];
  //  starty = (((int)buff[3])<< 8) | buff[2];
  //  startz = (((int)buff[5]) << 8) | buff[4];

}

void loop() {

  unsigned long currentMillisSensor = millis();
  if (currentMillisSensor - previousMillisSensor >= intervalSensor) {
    previousMillisSensor = currentMillisSensor;
 
    readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345

  //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
  //thus we are converting both bytes in to one int
  x = (((int)buff[1]) << 8) | buff[0];
  y = (((int)buff[3]) << 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];
}
     
  xa = map(x, -255, 255, 0, 255);
  xb = map(x, -255, 255, 255, 0);
  ya = map(y, -255, 255, 0, 255);
  yb = map(y, -255, 255, 255, 0);
  za = map(z, -255, 255, 0, 255);
  zb = map(z, -255, 255, 255, 0);

  unsigned long currentMillisLeds = millis();
  if (currentMillisLeds - previousMillisLeds >= intervalLeds) {
    // save the last time you blinked the LED
    previousMillisLeds = currentMillisLeds;
    
  if (xa < sensitivity) fadeLedsxa; 
  if (ya < sensitivity) fadeLedsya;
  if (za < sensitivity) fadeLedsza;

  if (xa > sensitivity) xa = 255; 
  if (ya > sensitivity) ya = 255;
  if (za > sensitivity) za = 255;
  
  if (xb < sensitivity) fadeLedsxb; 
  if (yb < sensitivity) fadeLedsyb;
  if (zb < sensitivity) fadeLedszb;

  if (xb > sensitivity) xb = 255; 
  if (yb > sensitivity) yb = 255;
  if (zb > sensitivity) zb = 255;

showLeds();

 //   FastLED.show();
//  }

serialText();
  
  } // end of timed loops

} // end of void loop

//---------------- Functions
//Writes val to address register on device
void writeTo(int device, byte address, byte val) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        // send register address
  Wire.write(val);        // send value to write
  Wire.endTransmission(); //end transmission
}

//reads num bytes starting from address register on device in to buff array
void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(address);        //sends address to read from
  Wire.endTransmission(); //end transmission

  Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device

  int i = 0;
  while (Wire.available())   //device may send less than requested (abnormal)
  {
    buff[i] = Wire.read(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}

void serialText() {
    //we send the x y z values as a string to the serial port
  Serial.print(xa); Serial.print(" ");
  Serial.print(xb); Serial.print(" | ");
  Serial.print(ya); Serial.print(" ");
  Serial.print(yb); Serial.print(" | ");
  Serial.print(za); Serial.print(" ");
  Serial.print(zb); Serial.print(" | ");
  Serial.print(var);
  Serial.write(10);
}


void showLeds() {
      for (int i = 0; i < 2; i++) {
      leds[i]    =   CHSV( 255, 255, yb); // back
      leds[i+2]  =   CHSV( 255, 255, xa); // left
      leds[i+4]  =   CHSV( 255, 255, ya); // front
      leds[i+6]  =   CHSV( 255, 255, xb); // right
      leds[i+8]  =   CHSV( 255, 255, za); // top
      leds[i+10] =   CHSV( 255, 255, zb); // bottom
    FastLED.show();
    }
}


void fadeLedsxa() {
  while (xa < 223) {
    xa--; 
      for (int i = 0; i < 2; i++) {
      leds[i+2] = CHSV( 255, 255, xa);
//  fadeToBlackBy( leds, 1, 2);  // 10 = long trail, 1 = short trail
  FastLED.show(); 
  }
  }
  //xa=0;
}

void fadeLedsya() {
  while (ya < 223) {
    ya--; 
      for (int i = 0; i < 2; i++) {
      leds[i+4] = CHSV( 255, 255, ya);
//  fadeToBlackBy( leds, 1, 2);  // 10 = long trail, 1 = short trail
  FastLED.show(); 
  }
  }
  //xa=0;
}


void fadeLedsza() {
  while (za < 223) {
    za--; 
      for (int i = 0; i < 2; i++) {
      leds[i+8] = CHSV( 255, 255, za);
//  fadeToBlackBy( leds, 1, 2);  // 10 = long trail, 1 = short trail
  FastLED.show(); 
  }
  }
  //xa=0;
}
void fadeLedsxb() {
  while (xb < 223) {
    xb--; 
      for (int i = 0; i < 2; i++) {
      leds[i+6] = CHSV( 255, 255, xb);
//  fadeToBlackBy( leds, 1, 2);  // 10 = long trail, 1 = short trail
  FastLED.show(); 
  }
  }
  //xa=0;
}

void fadeLedsyb() {
  while (yb < 223) {
    yb--; 
      for (int i = 0; i < 2; i++) {
      leds[i] = CHSV( 255, 255, yb);
//  fadeToBlackBy( leds, 1, 2);  // 10 = long trail, 1 = short trail
  FastLED.show(); 
  }
  }
  //xa=0;
}


void fadeLedszb() {
  while (zb < 223) {
    zb--; 
      for (int i = 0; i < 2; i++) {
      leds[i+10] = CHSV( 255, 255, zb);
//  fadeToBlackBy( leds, 1, 2);  // 10 = long trail, 1 = short trail
  FastLED.show(); 
  }
  }
  //xa=0;
}

I think your problems are because you are trying to use the same variables to represent the led brightness, and to store the readings from the sensor. You need to have separate variables for those two purposes.

In general, your code is overcomplicated and needs to be simplified. How much of it did you write yourself and how much was cut & pasted from example code found on the net?

All the accelerometer code is copied to give me an x, y and z

The rest is my own handywork, and th original code had a lot of nonused code (hence the cutdown version)

can you offer me some advice on the separating of the variables, or point me in the direction of an example?

i have it in my head how it should work, but turning that into code ... meh!

int xc, yc, zc;
int xd, yd, zd;

What about those? They don't seem to be used for anythg else. Use them for the led fade levels. Just don't update them unconditionally, or you will end up back where you started again.

so something along the lines of;

if xa > midpoint, increase xc
or
if xa < midpoint, fade out xc

kelvinmead:
so something along the lines of;

if xa > midpoint, increase xc
or
if xa < midpoint, fade out xc

a quick tweak to this and i have some fading leds!

its not as smooth as id like, as to get the speed id like i have to change the led brightness by 20 a time… but at least its a minor hurdle completed!

  if (xa < sensitivity) xc -= fadeOut;