krobert35:
The red zone eg. stopped state, come to rest. Will be a distance to be determined later.
Then final position won't always be the same position varying by a few cm each time.
So <= 30 will define it adequately.
I have uploaded your patched code and the random LED no longer exist. The code works as intended
for indicating the positions, repeatedly, until the object remains in the red zone for longer than the 30 seconds . After the red LED isn't lit , movement is indicated by the distance measurement but the LED doesn't lit again.
It is restored again with a power down of the UNO.
This is interesting. I can't see an immediate reason for this (the lights staying off.) I added some serial debug messages to the state machine if you're willing to load the code up and report back what it's saying:
/*LCD circuit:
* LCD RS pin to digital pin 13
* LCD Enable pin to digital pin 12
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
* LCD R/W pin to ground
* LCD VSS pin to ground
* LCD VCC pin to 5V
* 10K resistor:
* ends to +5V and ground
* wiper to LCD VO pin (pin 3)*/
#include<LiquidCrystal.h>
LiquidCrystal lcd(12, 13, 5, 4, 3, 2); //Interface pins of the LCD
const int trig_pin=8;//ultrasonic
const int echo_pin=9;//ultrasonic
float
distance;
unsigned long
echo_time;
int redPin = 11;
int greenPin = 10;
void setup()
{
Serial.begin( 9600 );
lcd.begin(16,2);
lcd.setCursor(0,0); //set the cursor to column 0 and line 0
lcd.print("Distance is ");
pinMode( trig_pin,OUTPUT );
pinMode( echo_pin,INPUT );
pinMode( redPin,OUTPUT );//RGB LED red
pinMode( greenPin,OUTPUT );//RGB LED green
}//setup
void loop()
{
UpdateDistance();
UpdateLCD();
LEDStateMachine();
}//loop
void UpdateLCD( void )
{
static unsigned long
timeLCD = 0;
unsigned long
timeNow;
timeNow = millis();
if( timeNow - timeLCD < 300 )
return;
timeLCD = timeNow;
lcd.setCursor(0,1); //set the cursor to column 1 and line 1
lcd.print(distance);
lcd.print("cm ");
}//UpdateLCD
void UpdateDistance( void )
{
static unsigned long
timeUltrasound = 0;
unsigned long
timeNow;
timeNow = millis();
if( timeNow - timeUltrasound < 100 )
return;
timeUltrasound = timeNow;
digitalWrite(trig_pin,HIGH);
delayMicroseconds(20);
digitalWrite(trig_pin,LOW);
delayMicroseconds(20);
echo_time = pulseIn(echo_pin, HIGH); //To receive the reflected signal.
distance= (float)echo_time*0.034/2.0;
}//UpdateDistance
// LED state machine states
#define ST_INIT 0
#define ST_INDETERMINATE 1
#define ST_DIST_FAR 2
#define ST_DIST_GREEN 3
#define ST_DIST_YELLOW 4
#define ST_DIST_RED 5
#define ST_RED_TIMER 6
#define ST_STOPPED 7
//
void LEDStateMachine( void )
{
float
temp;
static float
fStopDist = 0.0;
static byte
stateLEDs = ST_INIT;
static unsigned long
timeRedLED = 0;
switch( stateLEDs )
{
case ST_INIT:
//initialize the state
stateLEDs = DistanceToState();
break;
case ST_INDETERMINATE:
case ST_DIST_FAR:
if( stateLEDs == ST_INDETERMINATE )
Serial.println( "State ST_INDETERMINATE" );
else
Serial.println( "State ST_DIST_FAR" );
//far distance or indeterminate (0.0, somewhere between 125 and 175...)
analogWrite( greenPin,0 );//both LED OFF
analogWrite( redPin,0 );
stateLEDs = DistanceToState();
break;
case ST_DIST_GREEN:
Serial.println( "State ST_DIST_GREEN" );
analogWrite( greenPin,100 );//green LED ON
analogWrite( redPin,0 );
stateLEDs = DistanceToState();
break;
case ST_DIST_YELLOW:
Serial.println( "State ST_DIST_YELLOW" );
analogWrite( redPin,250 );// yellow LED ON
analogWrite( greenPin,90 );
stateLEDs = DistanceToState();
break;
case ST_DIST_RED:
Serial.println( "State ST_DIST_RED" );
//when we enter the "red zone":
// - grab the current distance
// - set the LED red
// - grab the current millis count
// - move to the red timer state
fStopDist = distance;
analogWrite( redPin,255 );//red LED ON
analogWrite( greenPin,0 );
timeRedLED = millis();
stateLEDs = ST_RED_TIMER;
break;
case ST_RED_TIMER:
Serial.println( "State ST_RED_TIMER" );
//check to see if we're still in the "red zone"
if( distance == 0.0 || distance > 30.0 )
//if not, reset stateLEDs
stateLEDs = DistanceToState();
else
{
//has the distance changed more than 2cm from when we hit red?
if( abs( distance - fStopDist ) > 2.0 )
{
//yes...reset the "initial" distance and red timer
fStopDist = distance;
timeRedLED = millis();
}//if
//check if 30-sec has passed
if( (millis() - timeRedLED) > 30000 )
{
//if so, turn off the LED, then enter the "STOPPED" state
analogWrite( redPin,0 );//red LED OFF
analogWrite( greenPin,0 );
stateLEDs = ST_STOPPED;
}//if
}//else
break;
case ST_STOPPED:
//just wait for the distance to indicate we've moved out of the "red zone"
//then go to that state
Serial.println( "State ST_STOPPED" );
Serial.print( "Distance :" ); Serial.println( distance, 2 );
if( distance > 30.0 )
stateLEDs = DistanceToState();
Serial.print( "stateLEDs :" ); Serial.println( stateLEDs );
break;
}//switch
}//LEDStateMachine
//convert a distance to a value usable in the state machine
byte DistanceToState( void )
{
if( distance >= 175.0 )
return ST_DIST_FAR;
else if( distance <= 125.0 && distance > 60.0 )
return ST_DIST_GREEN;
else if( distance <= 60.0 && distance > 30.0 )
return ST_DIST_YELLOW;
else if( distance <= 30.0 && distance > 0.0 )
return ST_DIST_RED;
else
return ST_INDETERMINATE;
}//DistanceToState