Hello everybody,
The coding is finally accomplished. & by using the INTERRUPT feature the lamp can be operated in all 3 modes... ON mode, OFF mode & SMART mode.
#include <NewPing.h>
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 600 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
// the 5 states of the LED
#define STATE_OFF 0 // led == off
#define STATE_INCREASE 1 // increase the brightness
#define STATE_ON 2 // led = 100%
#define STATE_HOLD 3 // LED goes on 255 for 30 seconds
#define STATE_DECREASE 4 // led goes from 100% to 0% -> 30 seconds
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
int led = 3; //PWM pin 3 fro LAMP LED output
int pot = A5; // set the A5 pin as potmeter's output
int potValue = 0; // potmeter value will be stored here
int bookDistance = 0; //ultrasonic sensor reading
int thresholdDistance = 0; // potmeter value is mapped to determine the threshold distance
int brightness = 0; // var to hold the brightness of the LED
int state = STATE_OFF; // var to hold the state, initialise with off state
int button = 0; // pin 2 for INTERRUPT 0 to select the MODE
int onLed = 5; // pin 5 for ON MODE status
int smartLed = 6; // pin 6 for SMART MODE status
int offLed = 7; //pin 7 for OFF MODE status
volatile int sysMode = 1; // volatile integer for holding the surrent state of the system, 1= ON mode, 2= SMART mode, 3= OFF mode
// ISR for selecting the mode
void mode(){
if (sysMode == 1){ //if system is in ON MODE then switch to SMART MODE
brightness = 0; // Initialize SMART MODE with STATE OFF
analogWrite(led, brightness); // apply brightness to the LED.
state = STATE_OFF;
sysMode = 2;
}
else if (sysMode == 2){ //if system is in SMART MODE then switch to OFF MODE
analogWrite(led, 0); // apply "no brightness" to the LED. OFF MODE.
digitalWrite (onLed, LOW);
digitalWrite (offLed, HIGH); //activate only the OFF MODE status led
digitalWrite (smartLed, LOW);
state = STATE_OFF;
sysMode = 3;
}
else if (sysMode == 3){ //if system is in OFF MODE then switch to ON MODE
digitalWrite (onLed, HIGH); //activate only the ON MODE status led
digitalWrite (offLed, LOW);
digitalWrite (smartLed, LOW);
analogWrite(led, 255); // apply full brightness to the LED. ON MODE.
brightness = 0;
sysMode = 1;
}
}
// gets the book distance
void getDistance(){
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("BookDistance: ");
bookDistance = uS / US_ROUNDTRIP_CM; //the function uS / US_ROUNDTRIP_CM returns the ultrasonic reading in cm
Serial.print(bookDistance); // Convert ping time to distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
}
// gets the threshold distance by mapping the potmeter value
void getThreshold(){
potValue = analogRead(pot); // Read & store the potmeter value
Serial.print("PotValue: ");
Serial.println(potValue);
thresholdDistance = map(potValue, 0, 1023, 10, 50);
Serial.print("ThresholdDistance: ");
Serial.println(thresholdDistance);
}
void setup() {
Serial.begin(19200); // Open serial monitor at 115200 baud to see ping results.
pinMode(led, OUTPUT); // Declare the LAMP LED & Status LEDs as UOTPUT
pinMode (onLed, OUTPUT);
pinMode (offLed, OUTPUT);
pinMode (smartLed, OUTPUT);
pinMode(pot, INPUT); //DEclare the ANALOG input via POT
attachInterrupt(button, mode, RISING); // ISR for change the MODE
digitalWrite (onLed, HIGH); //activate only the ON MODE status led
digitalWrite (offLed, LOW);
digitalWrite (smartLed, LOW);
analogWrite(led, 255); // apply full brightness to the LED. ON MODE.
}
void loop() {
if (sysMode == 1) analogWrite (led, 255) ; // ON MODE
else if (sysMode == 2){ // SMART MODE
digitalWrite (onLed,LOW );
digitalWrite (offLed, LOW);
digitalWrite (smartLed, HIGH); //activate only the SMART MODE status led
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
// getDistance(); // chcks & stores the value of book distance
// getThreshold(); // chcks & stores the threshold value
switch(state) // state transitions code
{
case STATE_OFF: // This will be the initial state of the system after powering it up.
delay(10);
brightness = 0; // brightness will be 0 at OFF STATE
analogWrite(led, brightness); // apply brightness to the LED.
getDistance(); // chcks & stores the value of book distance
getThreshold(); // chcks & stores the threshold value
if (bookDistance < thresholdDistance) state = STATE_INCREASE; // if there is no book state stays the same.
break;
case STATE_INCREASE: // This is the transition period from OFF to ON state
for (int a = 0; a <3; a++ ){ // increase the brightness slowly in 3 steps
brightness = brightness + 85;
analogWrite(led, brightness); // apply brightness to the LED.
delay(500);
}
state = STATE_ON; // Switch to BOOK reading state (STATE_ON)
break;
case STATE_ON: // This is the state while reading the book
brightness = 255;
analogWrite(led, brightness); // apply brightness to the LED.
getDistance(); // chcks & stores the value of book distance
getThreshold(); // chcks & stores the threshold value
if (bookDistance >= thresholdDistance) state = STATE_HOLD;
break;
case STATE_HOLD: // This is the 30 seconds time in which the LED will hold the full brightness state even if there is no book.
for (int b = 0; b < 60; b++){ //dimming of light & simultaneously checking for the book
analogWrite(led, brightness); // apply brightness to the LED.
delay (500); // 60 times 1 second = total 1 minute time for fetching the book
getDistance(); // chcks & stores the value of book distance
getThreshold(); // chcks & stores the threshold value
if (sysMode != 2){
brightness = 0;
delay(10);
analogWrite(led, brightness); // apply brightness to the LED.
state = STATE_OFF;
break;
}
else if (bookDistance < thresholdDistance){
state = STATE_ON;
break;
}
}
if (bookDistance >= thresholdDistance){
state = STATE_DECREASE;
break;
}
case STATE_DECREASE: //30 seconds delay with intensity decrement of LAMP LED. Book should be within the range, otherwise the system will be OFF again
for (int b = 0; b < 120; b++){ //dimming of light & simultaneously checking for the book
brightness = brightness - 2;
analogWrite(led, brightness); // apply brightness to the LED.
delay (250); // 120 times 0.25 second = total 0.5 minute time for fetching the book
getDistance(); // chcks & stores the value of book distance
getThreshold(); // chcks & stores the threshold value
if (sysMode != 2){
brightness = 0;
delay(10);
analogWrite(led, brightness); // apply brightness to the LED.
state = STATE_OFF;
break;
}
else if (bookDistance < thresholdDistance){
state = STATE_ON;
break;
}
}
if (brightness <= 20) state = STATE_OFF; // if 60 seconds are over switch to the OFF mode. Brightness will be less than 20 after 60 seconds
break;
}
}
else if (sysMode == 3) analogWrite (led, 0) ;
}
All credit goes to Mr. Rob Tillaart & I also want to thank PaulS, PeterH , gawain7 and the entire arduino forum for their support.
Results are exactly as expected. Few logic can be implemented in short & tricky way but since I don't have any previous experience in coding, I opted to go for simple & lengthy process. Need to know if arduino is supported in ATtiny 2313 chips? Any Idea how to put this code into an ATtiny chip by using my UNO board?