Pinewood Derby Car - Triggering LED strip loop with accelerometer

I am wiring up some LED light strips to attach to a pinewood derby car. I want them to turn on and run a rainbow light run when acceleration is detected.

so far, I have code that runs the rainbow light sequence when it is run in isolation, and i have code that turns the LED strips on when it senses acceleration in the y axis. However, i have not had luck getting the two parts to play nice with each other. When running the code below, the LED's turn on, but it does not run the strips loop effect.

Thank you for your time,

Joey

[code]
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Adafruit_NeoPixel.h>


Adafruit_MPU6050 mpu;

class Strip
{
  public:
    uint8_t   effect;
    uint8_t   effects;
    uint16_t  effStep;
    unsigned long effStart;
    Adafruit_NeoPixel strip;
    Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) {
      effect = -1;
      effects = toteffects;
      Reset();
    }
    void Reset() {
      effStep = 0;
      effect = (effect + 1) % effects;
      effStart = millis();
    }
};

struct Loop
{
  uint8_t currentChild;
  uint8_t childs;
  bool timeBased;
  uint16_t cycles;
  uint16_t currentTime;
  Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {
    currentTime = 0;
    currentChild = 0;
    childs = totchilds;
    timeBased = timebased;
    cycles = tottime;
  }
};

Strip strip_0(8, 2, 8, NEO_GRB + NEO_KHZ800);
struct Loop strip0loop0(1, false, 1);

void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens


  strip_0.strip.begin();

  Serial.println("Adafruit MPU6050 test!");

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
  }

  Serial.println("");
  delay(100);
}
void loop() {
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");
  Serial.println("");
  if (a.acceleration.y <= -4) {
    strips_loop();
    delay(10000)
  }
  else {
    for (uint16_t j = 0; j < 8; j++) {
      strip_0.strip.setPixelColor(j, 0, 0, 0);
    }
    strip_0.strip.show();
  }
  delay(500);
}

void strips_loop() {
  if (strip0_loop0() & 0x01)
    strip_0.strip.show();
}

uint8_t strip0_loop0() {
  uint8_t ret = 0x00;
  switch (strip0loop0.currentChild) {
    case 0:
      ret = strip0_loop0_eff0(); break;
  }
  if (ret & 0x02) {
    ret &= 0xfd;
    if (strip0loop0.currentChild + 1 >= strip0loop0.childs) {
      strip0loop0.currentChild = 0;
      if (++strip0loop0.currentTime >= strip0loop0.cycles) {
        strip0loop0.currentTime = 0;
        ret |= 0x02;
      }
    }
    else {
      strip0loop0.currentChild++;
    }
  };
  return ret;
}

uint8_t strip0_loop0_eff0() {
  // Strip ID: 0 - Effect: Rainbow - LEDS: 8
  // Steps: 3 - Delay: 20
  // Colors: 3 (255.0.0, 0.255.0, 0.0.255)
  // Options: rainbowlen=8, toLeft=true,
  if (millis() - strip_0.effStart < 20 * (strip_0.effStep)) return 0x00;
  float factor1, factor2;
  uint16_t ind;
  for (uint16_t j = 0; j < 8; j++) {
    ind = strip_0.effStep + j * 0.375;
    switch ((int)((ind % 3) / 1)) {
      case 0: factor1 = 1.0 - ((float)(ind % 3 - 0 * 1) / 1);
        factor2 = (float)((int)(ind - 0) % 3) / 1;
        strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2);
        break;
      case 1: factor1 = 1.0 - ((float)(ind % 3 - 1 * 1) / 1);
        factor2 = (float)((int)(ind - 1) % 3) / 1;
        strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2);
        break;
      case 2: factor1 = 1.0 - ((float)(ind % 3 - 2 * 1) / 1);
        factor2 = (float)((int)(ind - 2) % 3) / 1;
        strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2);
        break;
    }
  }
  if (strip_0.effStep >= 3) {
    strip_0.Reset();
    return 0x03;
  }
  else strip_0.effStep++;
  return 0x01;
}


[/code]

I realize now that it is likely because im using delay around the loop. I am working now to understand and integrate the ideas from the blink without delay example code.

1 Like

This is your problem. The program can't run any effects while it's sitting there doing nothing for 10 seconds.

We didnt necessarily figure it out, but we got the code into a state that it meets the requirements of our build. We took out the delays so it runs the effect when the condition is met. once the car is no longer accelerating the strips goes to a constant on. if we accelerate again it runs the effect again. we reset by disconnecting power to the system to turn off the LEDS.

so although it isnt perfect, it meets our objectives and is a really cool effect.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.