Next on the block – adding LEDs to the foot wells and glove box.   (Prev mods: LED Tails and Rear Passenger LED mods)

This mod can be especially useful this time of year up here on the 49th parallel since we are pretty much in darkness @ 5PM during November. All to often I drop something down near my feet and have to go looking for it.  The light that casts from the map lights does not reach the areas down near the front driver/passenger foot wells, so I decided to add a few tiny LEDs to shed some love in the area when needed.  In addition to this, the Juke comes with a MASSIVE glove box and no light.  So, it was natural to throw a small LED strip in there as well.  Both sets of LEDs are hooked up to a custom controller that uses an ATTiny85 and touch sensitive pins to control on/off states (I’m not one to go with status-quo, so the standard on/off switch would not cut it for me).

The switching unit (below) has 2 pairs of pins and 1 switch.  The switch is used to control the rear passenger LED and is discussed here.   Each pin pair make up a galvanic touch sensor that use the conductive abilities of skin to bridge the connection (reads – won’t work with gloves).  Touch them once and the LEDs ramp up (on), touch them again to power them off.  The top pair control the foot well LEDs, the bottom controls the glove box LED.

The switch controller installed – top left. Nissan was nice enough to leave us a blank, so naturally, I had to find a use for it!

LEDs:

I’ve replaced the original LEDs with a set of Optek ones.  Details here.

New:

[ad name=”GoogleAS728x90ImgOnly”]

Old LEDs:

Below are the first run LEDs I used for each foot well.    Yes, that is LEGO you see..  Have a look around this site to see why..   I can always rely on my LEGO inventory for parts when I need to do some sort of off hook-up, or mount.  In this case, the pivot connectors allow me to swivel the LEDs to different positions – yet they are strong enough to hold their set position. They also allow me to quickly disconnect the LEDs in the event I have to remove something, such as the glove box. Some Goop glue and it’s all good.

Another pic showing the left and right foot well LEDs (old) .

Right footwell illuminiated (old):

Controller:

I did not take any pics of the controller, but it is loosely based on this. The idea being that the natural galvanic response of your skin acts to complete the circuit when touching the two touch pads/pins.  This triggers a state change that the micro controller can interpret and act on.  In this case, I have it watch the pin inputs for a voltage change and trigger the LEDs on (when the state is off) and vice-versa.

The code is pretty straight forward – monitor the 2 sets of touch pins for a change in voltage, when this happens to either, trigger the related LED output pin to ramp up to full brightness. Touch a pin set again, turn the related LED output pin off. A timer has also been used to automatically turn off either light after 5 minutes.

Code:


//uses button to dim LEDs in steps.  Coded toward ATTiny85
 //v6 updates to v5 include adding timer capabilities to allow LEDs to auto shut off after an elapsed time.  Will prevent from leaving lights on if not hooked up on accessory mode in car.

#include       // important note - MS2Timer2 affects PWM of PIN 3 and 11, so don't use them for PWM output.
 #include 
 #include

//***********************
 //CONFIGURABLE VALUES

int tchValSens = 990;                      //val 1023 is open circuit.  0 is closed.  Dry fingers use 900, humid, damp, use 100

//************************

#ifndef cbi
 #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= -_BV(bit))
 #endif
 #ifndef sbi
 #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
 #endif

#define statusLED PB2                        //Digital In D1 - used to show timer countdown.
 #define ledCtrlrA PB0                       //Digital In Pin 1  MUST BE A PWM PIN (oddly my PWM pin#11 does not work) - controls IRF530 transistor > LED lights
 #define ledCtrlrB PB1                       //Digital In Pin 0  MUST BE A PWM PIN (oddly my PWM pin#11 does not work) - controls IRF530 transistor > LED lights
 int tchPadA = 3;                            //defined as Pin 3 (analog input 3) - physical pin ? on ATT85
 int tchPadB = 2;                            //defined as Pin 4 (analog input 2) - physical pin 2 on ATT85

int i = 0;
 int counterA = 0;                             //Counter used for dimming feature
 int counterB = 0;                             //Counter used for dimming feature
 int dlyTime = 20;                            //delay timer (for overall loop) in MS.
 int statCounter = 0;                         //counter for the status LED.
 int tchValA = 0;                            //Holder for tchValA
 int tchValB = 0;                            //Holder for tchValB

int ledStateA = LOW;                          //Holds the current state of the LED lights (HIGH=on LOW=off)
 int ledStateB = LOW;                          //Holds the current state of the LED lights (HIGH=on LOW=off)

int brightnessA = 0;                        //Brightness value for dimming the LED  0-255
 int brightnessB = 0;                        //Brightness value for dimming the LED  0-255
 int startBrightness = 0;                   //Initial brightness of the LED  0-255
 int statusLEDFlashDur = 100;                 //In Milliseconds - Flash period for MSTimer2 to flash the LED in ms.  100ms

long previousMillis = 0;                      //Store last time LED was updated
 long shutoffStartMillis = 0;                  //Store the value to start the shutoff timer from in Milliseconds.
 long shutOffDelayMS = 300000;                  //In Milliseconds - Determines how long to keep LED system on (after shutoff timer clicked) in Milliseconds  10000 (10sec), 60000 (1min) 300000 (5min)

//boolean sleepEnable = 1;

void setup ()
 {
 //Serial.begin (9600);
 pinMode(tchPadA, INPUT);                   //Setup the tchPadA as an Input
 pinMode(tchPadB, INPUT);                   //Setup the tchPadB as an Input
 pinMode(statusLED, OUTPUT);                 //Setup the statusLED as an Output
 pinMode(ledCtrlrA, OUTPUT);             //Setup the ledCtrlrA as an Output
 pinMode(ledCtrlrB, OUTPUT);             //Setup the ledCtrlrA as an Output
 }

void system_sleep()
 {
 sbi(MCUCR,PUD);                                  //Disables All Internal Pullup Resistors
 sbi(GIMSK,PCIE);                                   //Enable Pin Change Interrupts Interrups
 //add interrupt on 2 pins:
 sbi(PCMSK,PCINT3);                              //Changes Interrupt to pin 2 on physical chip (PIN 3 Analog Input 3)   (see http://hlt.media.mit.edu/wiki/pmwiki.php?n=Main.ArduinoATtiny4585)
 sbi(PCMSK,PCINT4);                              //Changes Interrupt to pin 3 on physical chip (PIN 4 Analog Input 2)
 cbi(ADCSRA,ADEN);                              //switch Analog to Digital Converter OFF
 cbi(MCUCR,SM0);                                  //Power Down Mode
 sbi(MCUCR,SM1);                                  //Power Down Mode
 sbi(MCUCR,SE);                                    //sleep Mode Power down enable (Sleep_enable(); should set this-- not tested yet)
 sleep_enable();                                      //Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
 sleep_mode();                                       //sleep begins here
 sleep_disable();                                     //Coming out of sleep
 sbi(ADCSRA,ADEN);                             //switch Analog to Digital Converter ON
 cbi(MCUCR,PUD);                                 //Enables Pullup Resistors Again (this should happen anyway, but i have it here for now just in case, haven't fully tested yet)
 }

void flash(byte howmany, byte dly) {
 for (i=0; i < howmany; i++)
 {
 digitalWrite(statusLED, HIGH);
 delay(dly);
 digitalWrite(statusLED, LOW);
 delay(dly);
 }
 }

void rampLEDDownNoff(byte ledPin, byte lval, int dly, byte ledStateWhich)
 {
 //sleepEnable = 0;
 if (dly == 0)
 {
 analogWrite(ledPin,0);
 }
 else
 {
 flash(3, 60);
 while(lval > 0)
 {
 analogWrite(ledPin,lval);
 lval--;
 delay(dly);
 }
 //make it is all the way off
 digitalWrite(ledPin, LOW);
 }

if (ledStateWhich == 1)
 {
 ledStateA = LOW;
 }
 else
 {
 ledStateB = LOW;
 }
 //sleepEnable = 1;
 }

void rampLEDupOn(byte ledPin, byte lval, byte ledNormVal, int dly, byte ledStateWhich)
 {
 //sleepEnable = 0;
 if (dly == 0)
 {
 analogWrite(ledPin,255);
 }
 else
 {
 flash(3, 60);
 while(lval < ledNormVal)
 {
 analogWrite(ledPin,lval);
 lval++;
 delay(dly);
 }
 }
 if (ledStateWhich == 1)
 {
 ledStateA = HIGH;
 }
 else
 {
 ledStateB = HIGH;
 }
 //sleepEnable = 1;
 }

void loop (){

tchValA = analogRead(tchPadA);
 tchValB = analogRead(tchPadB);

/*
 Serial.print("touchValA: ");
 Serial.print(tchValA, DEC);
 Serial.print("  touchValB: ");
 Serial.print(tchValB, DEC);
 Serial.print("  TriggerVal: ");
 Serial.print(tchValSens, DEC);
 Serial.print("\n");
 */
 /*  continue to watch the touch for a capacitance change, when this happens determine
 *  what the intent is:
 *  a) user is holding finger on sensor, ramp LEDs up until they remove their finger.
 *  b) user tapped sensor, so turn lights on full (basic on/off)
 */

//using a threshold value to determine when the touch sensor is being pressed/tapped.
 //average normal values hover around 480-490, then when tapped, are about 680.  However
 //seems to be some sort of leak or interferance in the circuit as sometimes the circuit
 //can be made to jump to higher values and trigger the below statement to execute.
 //this was noticed by simply waving hand near the transistors/touch sensor.

if (tchValA < tchValSens)        //use this if modified R3 (2.2K) and T2 Emitter grounded direct to 0V. Arduino pin to Collector out of T2 (will be HIGH)
 {
 //when the sensor is either touched or pressed for a longer perior, the below statement triggers.
 //when a finger is held to the sensor, the time difference between current and previous Millis is very small
 //(as its resetting through every cycle which is approx 50ms) so, the first statement executes which causes the
 //LED power to ramp down from high to low
 //when tapped quickly, the intent is to toggle the LED on/off.  This is triggered when the current and previous
 //Millis are further apart. Then the state of the LED is checked and toggled to determine if it needs to be switched
 //on or off.
 //flash(3, 60);

//check state and turn led on or off -  if the LED is off turn it on and vice-versa:
 if (ledStateA == LOW)
 {
 brightnessA=startBrightness;
 counterA = 0;
 shutoffStartMillis = millis();      //get a start value to start the countdown from.
 MsTimer2::start();                  //start the timer to trigger the shutoff
 rampLEDupOn(ledCtrlrA, 0, 255, 2, 1); //5
 }
 else
 {
 brightnessA=startBrightness;
 counterA = 0;
 rampLEDDownNoff(ledCtrlrA, 255, 0, 1);  //10
 MsTimer2::stop();                    //shut off is reset any time user changes something
 }
 flash(3, 60);
 }

if (tchValB < tchValSens)
 {
 //Check on the second touch sensor
 //flash(3, 60);

//check state and turn led on or off -  if the LED is off turn it on and vice-versa:
 if (ledStateB == LOW)
 {
 brightnessB=startBrightness;
 counterB = 0;
 shutoffStartMillis = millis();      //get a start value to start the countdown from.
 MsTimer2::start();                  //start the timer to trigger the shutoff
 rampLEDupOn(ledCtrlrB, 0, 255, 2, 2); //5
 }
 else
 {
 brightnessB=startBrightness;
 counterB = 0;
 rampLEDDownNoff(ledCtrlrB, 255, 0, 2);  //10
 MsTimer2::stop();                    //shut off is reset any time user changes something
 }
 flash(3, 60);
 }

//this will shut down the LED after the ellapsed time period.  Rules - if the shutoffStartMilis has been set AND the time ellapsed is greater than the delay time. Shut off the LED
 if (shutoffStartMillis != 0 && millis() - shutoffStartMillis > shutOffDelayMS)    //if shutoff time has elapsed, turn the LEDs off  1000ms = 1 second
 {
 if (ledStateA  == HIGH)
 {
 rampLEDDownNoff(ledCtrlrA, 255, 10, 1);  //10
 }
 if (ledStateB  == HIGH)
 {
 rampLEDDownNoff(ledCtrlrB, 255, 10, 2);  //10
 }

shutoffStartMillis = 0;
 MsTimer2::stop();
 }

//we dont need to be polling with every cycle, so slow things down a bit. 20 original value.
 delay(dlyTime);

//pulse the status LED every second.  Use the delay value to calculate into approx a flash every second.
 //if (statCounter * dlyTime >= 1000)
 // {
 //  flash(1, 60);
 //  statCounter = 0;
 //}
//statCounter++;
// system_sleep();                                      //Runs the system_sleep() function
}