A few things first.
-
I do have tubing to restrict the vision of the sensor which seems to work (about an inch over the sensor itself)
-
I am using one digital and one analog PIR sensor, mainly to prove a point that it can be done with both so my code will be a little more complex than if (sensor == HIGH) do blah blah but thats not the hard, I have figured that out. I thought initally this would conflict as each sensor would be off and cause error but only about 75% of the time do I get a crazy value so most of the time it says I walked by going 3 mph, pretty standard, then couple times later, BOOM, I'm moving at 50 mph, a little suspicious.
-
I am constantly polling each sensor in my main loop, my code above is what I have in one of my state machines (even though I am not using switch case like you suggested, it still works nonetheless). I will post whole code for anyone that is confused.
-
I do like you switch case and I wish I had more time to go back through and clean my code up (as you can tell I'm not the best at it) however I am closing in on the project due date.
Again, I can't fathom why multiple outputs are working perfectly then all of sudden an extreme value appears.
/*
*/
#include <LiquidCrystal.h>
#include <SD.h>
const int chipSelect = 17;
String message1, message2, message3;
int digitalVal, analogVal, newDigital, newAnalog, newAnalogVal;
int digitalPin = 2;
int analogPin = A0;
int calibrationTime = 60;
int counter, counterLeft, counterRight = 0;
float t1, t0, countTime, concentration;
float speed_0, trueSpeed;
float time0, time1, delayTime ;
float timeout1, timeout0;
LiquidCrystal lcd(0, 13, 9, 4, 5, 6, 7);
void setup() {
delay(2000);
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
Serial.begin(9600);
while(!Serial) {
;
}
// Wait for sensors to calibrate (60s)
Serial.print("calibrating sensor ");
lcd.print("Calibrating");
lcd.setCursor(0,1);
lcd.print("Sensor");
lcd.setCursor(0,0);
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
lcd.print("done");
lcd.setCursor(0,1);
Serial.println("SENSOR ACTIVE");
lcd.print("SENSOR ACTIVE");
lcd.setCursor(0,0);
delay(50);
Serial.print("Initializing SD card...");
lcd.print("Initializing SD");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("SD card failed, or not present");
lcd.setCursor(0,1);
lcd.print("SD card failed");
// don't do anything more:
return;
}
Serial.println("SD card initialized.");
lcd.setCursor(0,0);
lcd.print("SD card initialized.");
delay(1000);
lcd.clear();
pinMode(analogPin, INPUT); // Analog Pin (A0) - PIR Sensor
pinMode(digitalPin, INPUT); // Digital Pin (D2) - PIR Sensor
File dataFile = SD.open("ricelake.txt", FILE_WRITE);
if (dataFile)
{
dataFile.println(", , , ,"); //Just a leading blank line, incase there was previous data
String header = "Speed | From Left | From Right | Concentration";
dataFile.println(header);
dataFile.close();
Serial.println(header);
}
else
{
Serial.println("Couldn't open log file");
}
}
void computeData_0() // calculates speed, direction and concentration
{
t0 = millis(); // timestamp for calculating data
timeout0 = millis();
while(digitalVal == LOW){ // wait for digital sensor to go HIGH
digitalVal = digitalRead(digitalPin);
if ((float)millis() - timeout0 > 800) return; // timeout after 800ms (0.8 s)
}
time0 = ((float)millis() - t0) / 1000; // time between sensor dections (secs)
delay(5000); // delay long time to ensure sensor is stable
delayTime = millis();
if (((float)millis() - delayTime) > 300){ // wait 300ms until Digital Pin is LOW
newDigital = digitalRead(digitalPin); // Check digital sensor
if (newDigital == LOW ){ //check case to see if digitalRead is LOW
}
}
speed_0 = (4 / time0) * 0.681818; // calculates speed (mph), distance of 4 ft
if (speed_0 > 60 || speed_0 < 1) return; // Check for crazy values and omit if so
else if (speed_0 < 60 || speed_0 > 1){
countTime = ((t0)/1000) / 60; // minutes since program started
counter++; // Add 1 to counter
counterLeft++; // Add 1 to counterLeft
trueSpeed = speed_0; // redeclare speed variable
concentration = counter / countTime; // calculates concentration (vehicles/min)
displayData(); // displays data
}
}
void computeData_1() // calculates speed, direction and concentration
{
t1 = millis(); // timestamp for calculating data
timeout1 = millis();
while(!(analogVal <= 400 || analogVal >= 600)){
analogVal = analogRead(analogPin);
if ((float)millis() - timeout1 > 800) return; // timeout after 800ms (0.8 s)
}
time1 = ((float)millis() - t1) / 1000; // time between sensor dections (secs)
delay(5000); // delay long time to ensure sensor is stable
delayTime = millis();
if (((float)millis() - delayTime) > 300){ // wait 300ms until Digital Pin is LOW
newAnalog = analogRead(analogPin); // check to see motion is done
newAnalogVal = newAnalog + 500; // absolute value idea
if (newAnalogVal > 600 ){ //check case to see if digitalRead is LOW
}
}
speed_0 = (4 / time1) * 0.681818; // calculates speed (mph)
if (speed_0 > 60 || speed_0 < 1) { // If speed is crazy small or large, omit it
return;
}
else if (speed_0 < 60 || speed_0 > 1) {
countTime = ((t1)/1000) / 60; // minutes since program started
counter++; // Add 1 to counter
counterRight++; // Add 1 to counterLeft
trueSpeed = speed_0; // redeclare speed variable
concentration = counter / countTime; // calculates concentration (vehicles/min)
displayData(); // display data
}
}
void displayData(){ // displays/saves data to Serial, LCD, and SD file
// Displays Speed
lcd.print("Speed=");
lcd.print(trueSpeed);
lcd.print(" MPH");
lcd.setCursor(0,1);
lcd.print("R = ");
lcd.print(counterRight);
lcd.print(", L = ");
lcd.print(counterLeft);
// open the file, note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("ricelake.txt", FILE_WRITE);
if (dataFile) {
dataFile.print(trueSpeed);
dataFile.print(" ");
dataFile.print(counterLeft);
dataFile.print(" ");
dataFile.print(counterRight);
dataFile.print(" ");
dataFile.println(concentration);
//dataFile.println(trafficData);
dataFile.close();
// print to the serial port too:
Serial.print(trueSpeed);
Serial.print(" ");
Serial.print(counterLeft);
Serial.print(" ");
Serial.print(counterRight);
Serial.print(" ");
Serial.println(concentration);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening ricelake.txt");
}
}
void loop() {
lcd.setCursor(0,0); // set cursor to Row 1, Col 1
analogVal = analogRead(analogPin);
digitalVal = digitalRead(digitalPin);
if (analogVal <= 400 || analogVal >= 600) {
computeData_0();
}
else if (digitalVal == HIGH) {
computeData_1();
}
else if (analogVal <= 400 || analogVal >= 600 && digitalVal == HIGH) {
}
}
Again I apologize for the code as it is everywhere but in general it has been working so far minus this little hiccup of random outputs.