Arduino Vehicle Traffic Counter
From MakerCave
I wanted a method of counting the number of vehicle that passed through the Sleep Country Amphitheater entrance gate during events.
Air Differential Pressure Sensor EnclosuresI needed to position the air differential pressure sensors for the outer lanes at the edges of those lanes and then run wire back to the Arduino. Originally I was envisioning enclosing a sensor inside 2" PCV pipe fittings, with wiring coming out one end and the rubber tubing out the other. Then I realized I own a MakerBot Replicator Dual 3D Printer. Make an enclosure. Single Lane// include the library code: #include <SD.h> #include <Wire.h> #include "RTClib.h" #include <Adafruit_MCP23017.h> #include <Adafruit_RGBLCDShield.h> // The shield uses the I2C SCL and SDA pins. On classic Arduinos // this is Analog 4 and 5 so you can't use those for analogRead() anymore // However, you can connect other I2C sensors to the I2C bus and share // the I2C bus. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); RTC_DS1307 rtc; // define the Real Time Clock object // These #defines make it easy to set the backlight color #define RED 0x1 #define YELLOW 0x3 #define GREEN 0x2 #define TEAL 0x6 #define BLUE 0x4 #define VIOLET 0x5 #define WHITE 0x7 #define ECHO_TO_SERIAL 1 // echo data to serial port #define WAIT_TO_START 0 // Wait for serial input in setup() // these constants won't change: const int ledPin = 13; // led connected to digital pin 13 const int airSensorLane1 = A0; // the Lane 1 air pressure differential sensor is connected to analog pin 0 const int chipSelect = 10; // for the data logging shield, we use digital pin 10 for the SD cs line File logfile; // the logging file String timestamp; // these variables will change: int sensorReadingLane1 = 0; // variable to store the value read from the sensor pin A0 int ledState = LOW; // variable used to store the last LED status, to toggle the light int initialLane1 = 0; int countLane1 = 0; void setup() { pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT Serial.begin(9600); // use the serial port Serial.println("Starting setup..."); delay(5000); initialLane1 = analogRead(airSensorLane1); // set up the LCD's number of columns and rows: lcd.begin(16, 2); lcd.setBacklight(RED); // initialize the SD card Serial.print("Initializing SD card..."); // 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("Card failed, or not present"); lcd.clear(); lcd.setCursor(0,0); lcd.print("CARD FAILURE!"); // don't do anything more: return; } Serial.println("Card initialized."); Serial.print("Logging to: "); Serial.println("TRAFFIC.CSV"); lcd.clear(); lcd.setCursor(0,0); lcd.print("Card initialized"); lcd.setCursor(0,1); lcd.print("TRAFFIC.CSV"); logfile = SD.open("TRAFFIC.CSV", FILE_WRITE); logfile.println(""); logfile.println("NEW SESSION"); //#if ECHO_TO_SERIAL //Serial.println("Creating header: milliseconds,time,lane,pressure,initialPressure"); //#endif Wire.begin(); if (!rtc.begin()) { if (logfile) { logfile.println("RTC failed"); lcd.clear(); lcd.setCursor(0,0); lcd.print("RTC FAILURE!"); } Serial.println("RTC failed"); } logfile.close(); Serial.println("Setup complete"); Serial.print("Initial Lane 1 Pressure Reading:"); Serial.println(initialLane1); } void loop() { DateTime currentTimeDate = rtc.now(); // get current timestamp // read the sensor and store it in the variable sensorReading: sensorReadingLane1 = analogRead(airSensorLane1); uint8_t buttons = lcd.readButtons(); if (buttons & BUTTON_UP) { lcd.clear(); lcd.setCursor(0,0); lcd.print("RESETTING COUNT"); delay(5000); countLane1 = 0; } if (buttons & BUTTON_DOWN) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Lane1 Count:"); lcd.print(countLane1); } // if the sensor reading is greater than the threshold: if (sensorReadingLane1 > initialLane1 + 2) { ledState = !ledState; // toggle the status of the ledPin: digitalWrite(ledPin, ledState); // update the LED pin itself: // log milliseconds since starting uint32_t m = millis(); // log time timestamp = String(currentTimeDate.year()); timestamp += "/"; timestamp += String(currentTimeDate.month()); timestamp += "/"; timestamp += String(currentTimeDate.day()); timestamp += " "; timestamp += String(currentTimeDate.hour()); timestamp += ":"; timestamp += String(currentTimeDate.minute()); timestamp += ":"; timestamp += String(currentTimeDate.second()); Serial.println(timestamp); ++countLane1; // increase the Lane 1 Count if (!SD.begin(chipSelect)) {logfile = SD.open("TRAFFIC.CSV", FILE_WRITE);} // open TRAFFIC.CSV file on SD Card if (logfile) { logfile.print(m); logfile.print(", "); logfile.print(timestamp); logfile.print(", 1, "); logfile.print(sensorReadingLane1); logfile.print(", "); logfile.println(initialLane1); } //else { //lcd.clear(); //lcd.setCursor(0,0); //lcd.print("UNABLE TO WRITE"); //lcd.setCursor(0,1); //lcd.print("TO SD CARD!"); //} // write data to TRAFFIC.CSV if (!SD.begin(chipSelect)) {logfile.close();} #if ECHO_TO_SERIAL Serial.print(m); Serial.print(", "); Serial.print(timestamp); Serial.print(", 1, "); Serial.print(sensorReadingLane1); Serial.print(", "); Serial.println(initialLane1); Serial.print("Lane 1 Air Differential Pressure Sensor Reading: "); Serial.print(sensorReadingLane1); Serial.print(" of "); Serial.println(initialLane1); #endif // echo to serial monitor // update LCD screen lcd.clear(); lcd.setCursor(0,0); lcd.print("Lane 1:"); lcd.print(countLane1); lcd.setCursor(0,1); lcd.print("Reading:"); lcd.print(sensorReadingLane1); lcd.print(" ["); lcd.print(initialLane1); lcd.print("]"); } delay(100); // delay to avoid overloading the serial port buffer } Two Lanes
/* Vehicle Traffic Counter This sketch reads a Freescale MPX5500DP Air Pressure Sensors to detect when a vehicle rolls over rubber tub. It reads an analog pin and compares the result to a the initial readings of the sensors. If the result is greater than the initial readings, it tallies the trigger, displays it on a LCD display and records the triggered event to a SD card. */ // include the library code: #include <SD.h> #include <Wire.h> #include "RTClib.h" #include <Adafruit_MCP23017.h> #include <Adafruit_RGBLCDShield.h> // The shield uses the I2C SCL and SDA pins. On classic Arduinos // this is Analog 4 and 5 so you can't use those for analogRead() anymore // However, you can connect other I2C sensors to the I2C bus and share // the I2C bus. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield(); RTC_DS1307 rtc; // define the Real Time Clock object // These #defines make it easy to set the backlight color #define RED 0x1 //#define YELLOW 0x3 //#define GREEN 0x2 //#define TEAL 0x6 //#define BLUE 0x4 //#define VIOLET 0x5 //#define WHITE 0x7 #define ECHO_TO_SERIAL 0 // echo data to serial port #define WAIT_TO_START 0 // Wait for serial input in setup() // these constants won't change: //const int ledPin = 13; // led connected to digital pin 13 const int airSensorLane1 = A0; // the Lane 1 air pressure differential sensor is connected to analog pin 0 const int airSensorLane2 = A1; // the Lane 1 air pressure differential sensor is connected to analog pin 0 const int chipSelect = 10; // for the data logging shield, we use digital pin 10 for the SD cs line File logfile; // the logging file // these variables will change: int sensorReadingLane1 = 0; // variable to store the value read from the sensor pin A0 int sensorReadingLane2 = 0; // variable to store the value read from the sensor pin A0 //int ledState = LOW; // variable used to store the last LED status, to toggle the light int initialLane1 = 0; int initialLane2 = 0; int countLane1 = 0; int countLane2 = 0; char temp_date_and_time[22]; void setup() { // pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT #if ECHO_TO_SERIAL Serial.begin(9600); // use the serial port Serial.println("Starting setup..."); #endif // set up the LCD's number of columns and rows: lcd.begin(16, 2); lcd.setBacklight(RED); lcd.clear(); lcd.setCursor(0,0); lcd.print("Starting..."); delay(5000); initialLane1 = analogRead(airSensorLane1); initialLane2 = analogRead(airSensorLane2); // initialize the SD card #if ECHO_TO_SERIAL Serial.print("Initializing SD card..."); #endif // 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("Card failed, or not present"); lcd.clear(); lcd.setCursor(0,0); lcd.print("CARD FAILURE!"); // don't do anything more: return; } #if ECHO_TO_SERIAL Serial.println("Card initialized."); Serial.print("Logging to:TRAFFIC.CSV"); #endif lcd.clear(); lcd.setCursor(0,0); lcd.print("Card initialized"); lcd.setCursor(0,1); lcd.print("TRAFFIC.CSV->GO!"); date_and_time(temp_date_and_time); //get current timestamp logfile = SD.open("TRAFFIC.CSV", FILE_WRITE); logfile.println(""); logfile.print("NEW SESSION:"); logfile.println(temp_date_and_time); Wire.begin(); if (!rtc.begin()) { if (logfile) { logfile.println("RTC failed"); lcd.clear(); lcd.setCursor(0,0); lcd.print("RTC FAILURE!"); } #if ECHO_TO_SERIAL Serial.println("RTC failed"); #endif } logfile.close(); #if ECHO_TO_SERIAL Serial.println("Setup complete"); Serial.print("Initial Lane 1 Pressure Reading:"); Serial.println(initialLane1); Serial.print("Initial Lane 2 Pressure Reading:"); Serial.println(initialLane2); #endif } void loop() { // read the sensor and store it in the variable sensorReading: sensorReadingLane1 = analogRead(airSensorLane1); sensorReadingLane2 = analogRead(airSensorLane2); uint8_t buttons = lcd.readButtons(); if (buttons & BUTTON_UP) { lcd.clear(); lcd.setCursor(0,0); lcd.print("RESETTING COUNT"); delay(5000); countLane1 = 0; countLane2 = 0; lcd.clear(); lcd.setCursor(0,0); lcd.print("COUNT RESET"); } if (buttons & BUTTON_DOWN) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Lane1 Count:"); lcd.print(countLane1); lcd.setCursor(0,1); lcd.print("Lane2 Count:"); lcd.print(countLane2); } uint32_t m = millis(); // log milliseconds since starting // Lane1 Trigger: if (sensorReadingLane1 > initialLane1 + 2) { // ledState = !ledState; // toggle the status of the ledPin: // digitalWrite(ledPin, ledState); // update the LED pin itself: date_and_time(temp_date_and_time); // log time ++countLane1; // increase the Lane 1 Count if (!SD.begin(chipSelect)) { logfile = SD.open("TRAFFIC.CSV", FILE_WRITE); } // open TRAFFIC.CSV file on SD Card if (logfile) { logResults(m, temp_date_and_time, 1, sensorReadingLane1, initialLane1); // write data to TRAFFIC.CSV } else { cardError(); } if (!SD.begin(chipSelect)) { logfile.close(); } #if ECHO_TO_SERIAL updateSerial(m, temp_date_and_time, 1, sensorReadingLane1, initialLane1); // echo to serial monitor #endif updateLCD(1,countLane1,sensorReadingLane1,initialLane1); // update LCD screen } // Lane2 Trigger: if (sensorReadingLane2 > initialLane2 + 6) { // ledState = !ledState; // toggle the status of the ledPin: // digitalWrite(ledPin, ledState); // update the LED pin itself: date_and_time(temp_date_and_time); // log time ++countLane2; // increase the Lane 2 Count if (!SD.begin(chipSelect)) { logfile = SD.open("TRAFFIC.CSV", FILE_WRITE); } // open TRAFFIC.CSV file on SD Card if (logfile) { logResults(m, temp_date_and_time, 2, sensorReadingLane2, initialLane2); // write data to TRAFFIC.CSV } else { cardError(); } if (!SD.begin(chipSelect)) { logfile.close(); } #if ECHO_TO_SERIAL updateSerial(m, temp_date_and_time, 2, sensorReadingLane2, initialLane2); // echo to serial monitor #endif updateLCD(2,countLane2,sensorReadingLane2,initialLane2); // update LCD screen } #if ECHO_TO_SERIAL delay(100); // delay to avoid overloading the serial port buffer; however, will cause issues with the device being able to recognize actual vehicle traffic. #endif } void date_and_time(char *buffer) { DateTime now = rtc.now(); sprintf(buffer, "%02d/%02d/%d %02d:%02d:%02d", now.month(), now.day(), now.year(), now.hour(), now.minute(), now.second()); } void updateLCD(int lane, int count, int reading, int initial) { lcd.clear(); lcd.setCursor(0,0); lcd.print("Lane "); lcd.print(lane); lcd.print(":"); lcd.print(count); lcd.setCursor(0,1); lcd.print("Reading:"); lcd.print(reading); lcd.print(" ["); lcd.print(initial); lcd.print("]"); } void updateSerial(uint32_t ms, char *cts, int lane, int reading, int initial) { Serial.print(ms); Serial.print(", "); Serial.print(cts); Serial.print(", "); Serial.print(lane); Serial.print(", "); Serial.print(reading); Serial.print(", "); Serial.println(initial); Serial.print("Lane "); Serial.print(lane); Serial.print(" Air Differential Pressure Sensor Reading: "); Serial.print(reading); Serial.print(" of "); Serial.println(initial); } void logResults(uint32_t ms, char *cts, int lane, int reading, int initial) { logfile.print(ms); logfile.print(", "); logfile.print(cts); logfile.print(", "); logfile.print(lane); logfile.print(", "); logfile.print(reading); logfile.print(", "); logfile.println(initial); } void cardError() { lcd.clear(); lcd.setCursor(0,0); lcd.print("UNABLE TO WRITE"); lcd.setCursor(0,1); lcd.print("TO SD CARD!"); } |