There's a big difference from my code and your code. Your code is more of a synchronous state machine, where as mine is an asynchronous state machine. There's nothing wrong with that... but I would argue that my state machine is superior. When you change states, you're going to sub-functions and your code can't progress to another state until that function completes. This severely limits your ability to do things the "easy way". For example, what if you wanted to flash a LED 4 times a second regardless of which state you are in? You'd have to implement this code in each state or call a function in each state, taking care to ensure that the timing doesn't get thrown off. You'll likely discover that the LED blinks somewhat irratic and not what you intended. My code, on the other hand, allows me to put the flash code at the end of the main loop, and this code will get executed for every state. As long as each state doesn't take longer than 125ms, I should have very accurate flashing no matter what is going on in my state machine.
Here's the code updated showing you how to flash the LED. I've taken the "reset" logic and moved it to it's own state so that the LED will continue to flash even while waiting for the sensors to reset. Note that I've also updated the code to handle your analog sensor.
#define STATE_IDLE 0
#define STATE_DETECT_FROM_LEFT 1
#define STATE_DETECT_FROM_RIGHT 2
#define STATE_WAIT_FOR_RESET 3
int state = STATE_IDLE;
unsigned long sample_start = 0;
unsigned long sample_end = 0;
unsigned long flashtimestamp = 0;
unsigned long flashrate = 125;
boolean flipflop;
boolean leftsensor;
boolean rightsensor;
int left = 3;
int right = 4;
int minvalue = 400;
int maxvalue = 600;
void setup()
{
pinMode(13, OUTPUT);
pinMode(left, INPUT);
pinMode(right, INPUT);
}
void loop()
{
leftsensor = digitalRead(left);
//rightsensor = digitalRead(right);
int rightanalog = analogRead(right);
if (rightanalog >= minvalue && rightanalog <= maxvalue)
{
rightsensor = HIGH;
}
else
{
rightsensor = LOW;
}
switch(state)
{
case STATE_IDLE:
{
if (leftsensor == HIGH)
{
sample_start = millis();
state = STATE_DETECT_FROM_RIGHT;
}
else if (rightsensor == HIGH)
{
sample_start = millis();
state = STATE_DETECT_FROM_LEFT;
}
}
break;
case STATE_DETECT_FROM_LEFT:
{
if (rightsensor == HIGH)
{
// The right sensor just triggered, this means
// we should calculate and display the speed.
sample_end = millis();
calculateSpeed();
state = STATE_IDLE;
}
}
break;
case STATE_DETECT_FROM_RIGHT:
{
if (leftsensor == HIGH)
{
// The left sensor just triggered, this means
// we should calculate and display the speed.
sample_end = millis();
calculateSpeed();
}
}
break;
case STATE_WAIT_FOR_RESET:
{
if (leftsensor == LOW && rightsensor == LOW)
{
state = STATE_IDLE;
}
}
break;
}
// Code that will be executed regardless of which state we are in:
///////////////////////////////////////////////////////////////////
// let's make a LED flash 4 times a second.
if (millis() > flashtimestamp)
{
flipflop = !flipflop;
flashtimestamp = millis() + flashrate;
}
if (flipflop)
digitalWrite(13, HIGH);
else
digitalWrite(13, LOW);
}
void calculateSpeed()
{
unsigned long duration = sample_end - sample_start;
// do speed conversion math here using duration
// display results here
// delay until sensors reset
state = STATE_WAIT_FOR_RESET;
}
Another thing that will prove to you that my code is the better way to go... What if you wanted to monitor another set of sensors for a different road from the same Arduino? In other words, you'd have 2 sets of PIRs. Your code isn't going to work so hot... Once one of the sensors is triggered, you're going to be unable to process the speed on the other set of sensors if they should happen to be triggered while waiting for the second sensor on the first set. Try to solve that one using your code. Bet you'll have a difficult time with that! But if you used my state machine, you could detect both "lanes" simultaneously and independently of each other. All you would need to do is add another state machine after the first state machine and modify the code a little to deal with the different sets of sensors. This would be darn near impossible with your code. Just saying. ![]()
As for your problems... are you using any pullup or pulldown resistors? You may have your signals floating which would cause erratic reads on the digital & analog IO.