Basic code issues for using an IR sensor to dim an LED between states

I’m sure this is something quite simple, but I haven’t been able to figure it out by myself yet. For some weeks now, I have been researching and experimenting with a code I found online at [u]http://www.bajdi.com[/u] that lets you use a TCRT5000 infrared sensor to turn ON and OFF an LED. With this code, as soon as the infrared sensor “sees” and object nearby, it makes the LED go to full brightness and it remains like that for as long as the sensor keeps on sensing the object. Then, as soon as the sensor stops sensing it, the LED goes OFF instantly...and so on, endlessly. This part of the code works perfectly as it is right now.

MY PROBLEM: I need all of this ON and OFF switching to happen with smooth PWM fades instead of with abrupt “instant ON” and "instant OFF" changes. I need to have a 1.5 seconds PWM fade-in of the LED from 0% to 100% as soon as the TCRT5000 sensor gets activated; and then a 3.5 seconds fade-out as soon as the sensor stops sensing something nearby. As long as the sensor is activated, the LED needs to remain at full brightness. So, simply put: I need the LED to dim smoothly between the infrared sensor's state-changes, instead of changing instantly in an abrupt manner.

Also, I don’t know if something like re-activating the sensor and causing the LED to “fade-in” back to 100% while it might had been already “fading-out” to 0%, may cause the sketch to “crash”…or if it would be no big deal and the LED would just simply stop at whatever brightness level it might had been at at the moment of the sensor’s state-change back to reactivation and then just go back effortlessly to “fade-in” dimmer mode (for as long as the infrared sensor is being kept activated). I don’t think this would be an issue for my Arduino Mega ADK, but maybe it might be an issue for smaller capacity Arduinos or for “shrinkified” projects running on bootloaded ATtiny45 / ATtiny85 8-pin chips (which is my intended goal); Right?

I’m fairly new to writing arduino code and this project has been really frustrating, even thou I know it’s not that complicated. I’ve learned a lot already, but still can’t find out a way to accomplish what I’ve just described above. I can’t figure out on how to properly use the “if/else” and the “delay” functions at their proper places yet. I’m on a mental block right now, so any help would be extremely appreciated! :blush:

Here is the detailed code that I have been using, with no success for the dimming tasks:

/* Code has been modified from the one by 
the owner of the http://www.bajdi.com blog.
   
   Im using the TCRT5000 infrared sensor and an Arduino MEGA ADK
   TCRT5000 pins breakout: (see the sensor's datasheet here:
   http://www.vishay.com/docs/83760/tcrt5000.pdf )
  
  The breakout:
     C = connects to Arduino digital pin 2
     E = connects to GND
     A = connects to 100 ohm resistor and the other end of resistor to 5V
     C = connects to GND
*/

const int sensor = 2;     // connected to the TCRT5000 C pin
const int led =  13;      // the number of the LED pin

// variables will change:
int sensorState = 0;         // variable for reading the TCRT5000 status
int brightness = 0;

void setup() {
  // initialize the LED pin as an output:
  pinMode(led, OUTPUT);     
  // initialize the tcrt5000 pin as an input, and turn on the internal pullup resistors:
  pinMode(sensor, INPUT);
  digitalWrite(sensor, HIGH); 
}

void loop(){
  // read the state of the tcrt5000:
  sensorState = digitalRead(sensor);

  // check if the tcrt5000 sensor detects something.
  // if it is, the tcrtState is LOW:
  if (sensorState == LOW) {    
    // turn LED on:   
    digitalWrite(led, HIGH); 
    }
  
  if (sensorState == HIGH) {    
    // turn LED on:   
    digitalWrite(led, LOW); 
    }
  
  else {
    // turn LED off:
    digitalWrite(led, LOW);
  }
}

This is my first ever post here, so again, any help would be extremely appreciated! (just as well as feedback on how overly detailed, or lacking of, this post was). THANKS GUYS! :grin:

Depending on HOW you do the fading, any changes in the sensor state while the fading is happening may, or may not, be noticed.

  if (sensorState == LOW)
  { // Put this down here where it belongs
    // turn LED on:   
    digitalWrite(led, HIGH); // delete this
     for(byte i=0; i<=255; i++)
     {
          analogWrite(led, i); // Fade the LED
          delay(10); // Change time to define how slowly to fade up
     }
  } // Line this up properly

This code will ignore the sensor while the fading up happens. You can use similar code, decrementing in the for loop to fade down and ignore the sensor while fading.

Also, I don’t know if something like re-activating the sensor

You don’t “activate” the sensor. It’s active all the time. You may, or may not, give a shit what the sensor is saying. Ignoring it will not cause your Arduino to crash or cause the sensor to emit its magic smoke.

FYI: It looks like that sensor is rated for 15mm range!

...may not be a good match for your application?

AnalysIR, a 15mm detection range is way more than what I need, hence why I chose this specific lil’ cheap sensor. Thanks for the heads-up anyway. :)

PaulS, thank you for your fast reply! I’ve just tried your code but it is not behaving the way that I need it. Let me try and clarify what I need: I need NOT TO IGNORE the sensor’s state changes (if they happened to occur, that is) while a dimming transition was already in process. And yes, I knew that the sensor is always running in an endless loop dozens of times per second for as long as the arduino has power….but I didn’t knew how to express my need. My concerns about “crashing” the arduino are more for the ATtiny45 / ATtiny85 chips because I know that they only have a small fraction of the speed, memory and capacity of the ATmega2560 chip on my Arduino Mega ADK…but let’s not get into that just yet. I need to figure out the dimming part first. The “shrinkifying” process with the ATtiny chips can wait for now.

Ok, all of this is for an interactive/responsive lighted surface that is almost the size of a thick drink coaster. I’m planning on making a dozen of them and placing them all on a table, but behaving and operating individually from one another. Te behavior NEEDS to be like this: If something is placed over one of those “drink coasters”, the IR sensor would notice it and the surface’s LED will glow with a fade-in from 0% to 100% in 1.5 seconds. The surface will remain lit for as long as the object is over it. As soon as the object is removed from the “drink coaster”, it’s LED has to fade-out from 100% to 0% in about 3.5 seconds. If during a fade-out, the object is placed back again over the surface, the microcontroller will stop the fade-down to 0% process at whatever percentage it might had been at when interrupted, and will instantly start to fade-up back to 100% brightness. If the object is lifted away during the fade-up process, then the LED should fade-out to 0% brightness…and remain that way until something is placed over the “drink coaster” again.

This following last part is not necessary at all, but to save on battery, there could also be a “sleep function” embedded into the code on which if the “drink coaster’s” sensor remains undisturbed for let’s say more than 45 seconds, the system would then go to sleep and remain sleeping until the IR sensor detects something over him once again; therefore waking the system up and making it go to work until the next sleep phase is reached.

This first link is a video I’ve just recorded, to demonstrate the code that I posted at the start of this thread. As it can be noticed, the sensor’s range is more than enough for my needs, and the responsiveness of the system is instantaneous. When I flick my finger over the IR sensor, the LED flicks on and off just as fast.

http://youtu.be/WaritJM6vrE

This second link, shows someone else’s project that, in a super larger scale, does EXACTLY what I need my single LED and single IR sensor module to do:

http://youtu.be/OLfF4b49MLs?t=33s

I hope this helps to clarify my needs. Thanks to everyone for your time and help. It’s greatly appreciated.

Here’s a crude way to do it:

const int sensor = 2;     // connected to the TCRT5000 C pin
const int led =  13;      // the number of the LED pin

int sensorState = 0;         // variable for reading the TCRT5000 status
int Brightness = 0;
int DesiredBrightness = 0;

void setup() 
{
// initialize the LED pin as an output:
pinMode(led, OUTPUT);     
// initialize the tcrt5000 pin as an input, and turn on the internal pullup resistors:
pinMode(sensor, INPUT);
digitalWrite(sensor, HIGH); 
}

void loop()
{
sensorState = digitalRead(sensor);   // read the state of the tcrt5000: object present gives low
if (sensorState == LOW) 
  {    
  DesiredBrightness=255; 
  }
else 
  {
  DesiredBrightness=0;
  }
  
if(Brightness < DesiredBrightness)
  {
  Brightness++;  
  }
if(Brightness > DesiredBrightness)
  {
  Brightness--;  
  }
analogWrite(led, Brightness); // Fade the LED
delay(10); // Change time to define how slowly to fade  
}

Compiled, not tested.

A better solution would replace the delay with some “blink without delay” style control of the fade. As long as the delay is small though, the lack of immediate response won’t be noticeable to the user.

A better solution would replace the delay with some "blink without delay" style control of the fade

WILD BILL, THANK YOU SOOO SO MUCH!!!!! I have no idea about how to do that style of dimming, but I've just tested the code you made and it works PERFECTLY. It's even better than what I needed originally. I like it a lot because it is super simple and straightforward to understand/adjust. THANK YOU, SIR!!!! :grin: