Coding Help for a noob (G meter)

Hello all, I have recently purchased an arduino and have to set to work teaching myself some coding. The project I am working on is a G meter for my car, using an adxl 335 accelerometer, and common anode RGB LEDs. I am using only 5 RGB LEDs for my display, as I want to mount this inside my factory gauge cluster. The issue I am having is that as you corner the LEDs light up in the correct fashion (turning from green to red) : Green for .3, .5, .7, and .9 Gs. Red for .2, .4, .6, .8, and 1 G. But as you exit the corner the analog reading from my adxl 335 passes back through the threshold limits of the lower values and turns all my LEDs back to green. Here is a video(sorry it’s from a cell phone):

http://youtu.be/Aqjah4zaSgE

What I am trying to do is have the LEDs switch from green to red as the Gs increase, and once Red stay Red until the millis timer has told them all to turn off. If you have any advice and pointers of where to start Please let me know. Here is just the section of code I wrote up that tells the LEDs at what thresholds to turn on, sorry if its a mess I am learning as I go here.

 // --------G force 1g to -1g-------------
  

  
  if(X_AXIS < 408) {     //LED 1 GREEN  -.9
    triggered = true; 
    startTime = millis();
    digitalWrite(led1G, LOW);
    digitalWrite(led1R, HIGH);
 
  }
     if (triggered) {      
         // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led1G, HIGH);
        digitalWrite(led1R, HIGH);}
   }
  else {digitalWrite(led1G, HIGH);
        digitalWrite(led1R, HIGH);
  
}
    
    
    
  if (X_AXIS > 531 || X_AXIS < 397) {            // LED1 RED -1 or .2g
    triggered = true;
    startTime = millis();
    digitalWrite(led1R, LOW);
    digitalWrite(led1G, HIGH);
    
   }
     if (triggered) {
       
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led1R, HIGH);
        digitalWrite(led1G, HIGH);}
   }
  else {digitalWrite(led1R, HIGH);
        digitalWrite(led1G, HIGH);}
 
 
   if (X_AXIS > 543 || X_AXIS < 430) {          //LED 2 GREEN -.7 or .3g
    triggered = true;
    startTime = millis();
    digitalWrite(led2R, HIGH);
    digitalWrite(led2G, LOW);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led2R, HIGH);
        digitalWrite(led2G, HIGH);}
   }
  else {digitalWrite(led2R, HIGH);
        digitalWrite(led2G, HIGH);}

  
  if(X_AXIS > 555 || X_AXIS < 419) {              // LED 2 RED  -.8 or .4g
    triggered = true;
    startTime = millis();
    digitalWrite(led2R, LOW);
    digitalWrite(led2G, HIGH);
    
  }
     if (triggered) {
       
       
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led2R, HIGH);
        digitalWrite(led2G, HIGH);}
   }
  else {digitalWrite(led2R, HIGH);
        digitalWrite(led2G, HIGH);}
  
  
  
  if (X_AXIS > 567 || X_AXIS < 452) {          //LED 3 GREEN -.5 or .5g
    triggered = true;
    startTime = millis();
    digitalWrite(led3R, HIGH);
    digitalWrite(led3G, LOW);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led3R, HIGH);
        digitalWrite(led3G, HIGH);}
   }
  else {digitalWrite(led3R, HIGH);
       digitalWrite(led3G, HIGH);}



 
  if(X_AXIS > 579 || X_AXIS < 441) {            //LED 3 RED -.6 or .6g
    triggered = true;
    startTime = millis();
    digitalWrite(led3R, LOW);
    digitalWrite(led3G, HIGH);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led3R, HIGH);
        digitalWrite(led3G, HIGH);}
   }
  else {digitalWrite(led3R, HIGH);
         digitalWrite(led3G, HIGH);}
  
  
  if (X_AXIS > 591 || X_AXIS < 474) {          //LED 4 GREEN -.3 or .7g
    triggered = true;
    startTime = millis();
    digitalWrite(led4R, HIGH);
    digitalWrite(led4G, LOW);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led4R, HIGH);
        digitalWrite(led4G, HIGH);}
   }
  else {digitalWrite(led4R, HIGH);
         digitalWrite(led4G, HIGH);}
  
  
  
  if(X_AXIS > 603 || X_AXIS < 463) {            //LED 4 RED -.4 or .4g
    triggered = true;
    startTime = millis();
    digitalWrite(led4R, LOW);
    digitalWrite(led4G, HIGH);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led4R, HIGH);
        digitalWrite(led4G, HIGH);}
   }
  else {digitalWrite(led4R, HIGH);
        digitalWrite(led4G, HIGH);}
  
  
  
  if (X_AXIS > 615) {          //LED 5 GREEN -.1 or .9g
    triggered = true;
    startTime = millis();
    digitalWrite(led5R, HIGH);
    digitalWrite(led5G, LOW);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led5R, HIGH);
        digitalWrite(led5G, HIGH);}
   }
  else {digitalWrite(led5R, HIGH);
        digitalWrite(led5G, HIGH);}
  
  
 
  if(X_AXIS > 627|| X_AXIS < 485 ) {          //LED 5 RED -.2 or 1g
    triggered = true;
    startTime = millis();
    digitalWrite(led5R, LOW);
    digitalWrite(led5G, HIGH);
  }
     if (triggered) {
      // Check how much time has passed
      if ((millis() - startTime) > interval) {
        // Time to turn off
        triggered = false;
        digitalWrite(led5R, HIGH);
        digitalWrite(led5G, HIGH);}
   }
  else {digitalWrite(led5R, HIGH);
        digitalWrite(led5G, HIGH);}
  
 
}

I’ve only glanced at your code but let’s be clear on what you’re trying to do. Are you looking for a peak hold function ? That is as the G’s build the display continually updates but as the G’s fall off you want the last, highest reading to persist for some amount of time. Then the display goes back to normal.

Or are you just looking to have a display that bleeds down at a slower rate than it ramps up ?

They are subtlely different. The peak hold may persist for some “long” time and once the hold goes off, immediately jumps to the new value. You can even have a threshold on it so only peaks above X G’s are held. The other is a smoothing filter that allows a more gradual transition from high to low G indications.

Assuming you want a peak hold, my first thought is to store the Gs measured each pass through the loop. Then at the top of the loop measure the Gs and ask a question, Is this new value > the stored (old) value. If yes, then continue down the loop, lighting whatever LEDs are supposed to happen and finally storing a new G value. If no, then store the time and ask Is time - stored time > hold time. If this time difference < hold time then skip going down the loop and thus don’t change any LEDs nor store a new G value. If the time differnce > hold time then go down the loop per usual. LEDs will light according to the level and the peak hold gets reset to a new value. Thus all the LEDs will hold for whatever the hold time is set to.

bchouston:
The issue I am having is that as you corner the LEDs light up in the correct fashion (turning from green to red) : Green for .3, .5, .7, and .9 Gs. Red for .2, .4, .6, .8, and 1 G.

What I am trying to do is have the LEDs switch from green to red as the Gs increase, and once Red stay Red until the millis timer has told them all to turn off.

Not that it matters but I think if you want green to red for LED1 then green to red for LED2, etc, etc as the G’s increase, then you’ve got the numbers above swapped. :mrgreen:

I note that you seem to be “mirroring” the counts used for the various G thresholds/windows around 511/512 (as you should initially, see below) but your comments don’t always reflect the G values thusly detected. And you don’t do this for the <408 or >615 thresholds. As I said above I think your problem is that you’ve got a timer setting in every threshold crossing instead of asking is the G value (absolute) is less than the one before, and doing this only once. Each time you pass some threshold test you end up resetting the timer, so in effect it does nothing.

I also note that the ADXL335 is a +3/-3 G device running off of ~3.3V. I’m not sure if your G thresholds/windows reflect this, maybe, meybe not.

Once you get the above all straightened out, I would add in a calibration routine that can be invoked by you when sitting still on a level road. It would sample the supposedly 0 G output of the ADXL335 and store that number away as the reference center value to be used in your threshold detection logic (in place of 511/512). This would be more accurate in that it removes any offset value (DC bias voltage) from the 335 which would bias your G readings. I would take multiple readings over some period of time commensurate with whatever you’ve set the bandwidth to.

Mee_n_Mac I am aware that I do not have a value programmed for both -.1g and .1g. That reading was too small so every time I hit a bump the green LED would trigger. I have a calibration routine at the top of my loop, but I only showed the part of the coding that has issues, per the forum posting recommendation. The LEDs light from right to left as you turn Left, and left to right as you turn Right. I can post a second video if it helps.

In regards to my threshold points, I am aware that the ADXL 335 runs on 3.3v the reason my number may seem of is that I am using a 3.3v ADC reference voltage instead of the 5v.

I want the timer to reset every time the next higher value is triggered, because as you enter a corner in your car the Gs will increase and I want the highest hit to display after you exit the corner so you can see it after.

**The one thing I want to change is to simply not have the LEDs turn back to Green as you exit the corner. I want them to stay Red once they are triggered until the entire row of LEDs turns off.

I was able to solve the issue. Probably not the best, cleanest or fastest way, but it works. I simple added a bitRead function to the IF statement for each green LED so that it would check to see if the Red LED was on or off, if off would continue as normal if on statement was false and would skip.

Thanks