Complete novice needs help coding a parking guard

So I have an arduino Uno and a Relay shield Downloads – Support – Velleman – Wholesaler and developer of electronics
And also 4 ultrasonic sensors

We have 4 bookable parkingspot at our coworking space, but people often park without booking. This again pisses of the person who actually prebooked the spot.

The goal is to have it so that if the ultrasonic sensor sense that the distance is less than say 1.5 meters (a car parked underneath it) over a periode of time of 30s it will trigger one of the relays (the relays will be connected to our locking system where I can export the incidens to a csv file)

So where do I start?
This should be straight forward with just copy paste libraries? but I have never coded before so this is worse than Latin for me (since I actually know some few latin words

Maby there is a block editor of some sort?

Well, reading a sensor value is not too difficult. Doing something with that server read data (log to a file, turn on a light, etc.) shouldn't be too difficult to figure out.

Finding a suitable all weather sensor with the range you want at a price you will pay with a data output you can access will be more difficult.

But, assuming you got everything up and running perfectly, what are you going to do with it? The system detects there is a car parked in the space Bob reserved. Well, Bob can see that. The system isn't calling the tow company, putting a boot on the offending vehicle, or reading the offending vehicle's license tag information.

What's the desired outcome? A camera and a "Smile you're on camera" sign may be more what you want.

This sensor is all weather

It just might be better to have a pi and camera automatically reading the car number plate and recording the offenders with logging of photos as proof! - not too difficult to do now, see this months Magpi magazine (Issue 79) for details on how to build such a system.

saildude:
This sensor is all weather

Ultrasonic Range Finder - HRXL-MaxSonar-WR - SEN-11724 - SparkFun Electronics

So is this one.

Well I already have the arduino ultrasonic sensor , an off brand ardunino uno and the velleman relay shield. The parkingspots are indoor so no need for weather proofing.

All I need is for the ultrasonic sensor to trigger the shield relay so that it closes a circuit for the IN port in our lockin system. I have 4 IN ports free on a door controller close by.
From here its actually quite easy to use their system to export events (car registered and who opened up the garrage door) to a google sheet where also the booking calender is exported too.

It looks like it´s possible to use both analog and digital pins on the UNO to connect to the trig and echo on the ultrasonic sensor (whats the OUT pin on the Ultrasonic sensor for btw?)

Lets say I attach the first sensor is attached like this:
TRIG - 1 digital pin on the shield (wich would be digital 2 pin on the UNO)
ECHO - 2 digital pin on the shield (wich would be the digital 3 pin on the UNO)

And lets try using Analog on the second sensor
TRIG - 1 analog pin on the shield (wich would be Analog 0 pin on the UNO)
ECHO - 2 analog pin on the shield (wich would be the analog 1 pin on the UNO)

Here is the Shield: VMA05: I/O SHIELD FOR ARDUINO® – Velleman – Wholesaler and developer of electronics
It has 6 digital and 6 analog imputs where it uses pin 8 to 13 as outputs(the relay), pin A0 to A5 as analog inputs, and pin 2 to 7 as digital inputs

HERE IS THE VELLEMANS EXAMBLE CODE from their website

void setup()
{
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

pinMode(7, INPUT);
pinMode(6, INPUT);
pinMode(5, INPUT);
pinMode(4, INPUT);
pinMode(3, INPUT);
pinMode(2, INPUT);
}

void loop()
{
digitalWrite(8, HIGH);
delay(50);
digitalWrite(9, HIGH);
delay(50);
digitalWrite(10, HIGH);
delay(50);
digitalWrite(11, HIGH);
delay(50);
digitalWrite(12, HIGH);
delay(50);
digitalWrite(13, HIGH);
delay(50);
digitalWrite(8, LOW);
delay(50);
digitalWrite(9, LOW);
delay(50);
digitalWrite(10, LOW);
delay(50);
digitalWrite(11, LOW);
delay(50);
digitalWrite(12, LOW);
delay(50);
digitalWrite(13, LOW);
delay(200);
digitalWrite(13, HIGH);
delay(50);
digitalWrite(12, HIGH);
delay(50);
digitalWrite(11, HIGH);
delay(50);
digitalWrite(10, HIGH);
delay(50);
digitalWrite(9, HIGH);
delay(50);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(13, LOW);
delay(50);
digitalWrite(12, LOW);
delay(50);
digitalWrite(11, LOW);
delay(50);
digitalWrite(10, LOW);
delay(50);
digitalWrite(9, LOW);
delay(50);
digitalWrite(8, LOW);
delay(200);
digitalWrite(13, HIGH);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(12, HIGH);
digitalWrite(9, HIGH);
delay(50);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
delay(200);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
delay(50);
digitalWrite(12, LOW);
digitalWrite(9, LOW);
delay(50);
digitalWrite(13, LOW);
digitalWrite(8, LOW);
delay(200);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(200);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(200);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(50);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(50);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(50);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(50);
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(50);
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(200);

}

I´m guessing I will have to add the code to trig each sensor (at different intervals to prevent wrong reading?)
And have the speed of sound calculation to calculate he distance from the echo pin.

Also have som IF commands so that the the distance is less than 1,5 meters it will trigger one of the relays.

Again I have absolutley no Coding Experience. So I´m kinda on deep water on this one :stuck_out_tongue:

If those analog pins are just the normal Uno analog pins passed through the shield (and they are numbered the same, so probably are) then they're fully functional digital pins anyway, so that gives you 12 pins for the sensors.

whats the OUT pin on the Ultrasonic sensor for btw

No idea; mine doesn't have one. Perhaps it's to hook up to an led to show it's active?

Also have som IF commands so that the the distance is less than 1,5 meters it will trigger one of the relays.

But it's not quite as simple as that, since earlier you said:

the distance is less than say 1.5 meters (a car parked underneath it) over a periode of time of 30s it will trigger one of the relays

Presumably that 30 second's to give someone a chance to back out if they realise their mistake, or are using the bay to turn around.

But that means you need to start a timer when the sensor distance is less than the threshold, and monitor to check it remains under the threshold for 30s continuous, and only then arm the relay.

Just for the heck of it I coded that for one relay this evening. I'll post it if you want it....

Seems about right.
Yes, I would love that :slight_smile:

That would help me alot not only to get this project up and running + learn arduino

Vassi_Solutions:
Yes, I would love that :slight_smile:

Ok here it is.

Couple of points:

  • I used the NewPing library
  • That library suggests a minimum 30ms gap between pings, and the example used delay(50). I changed that to use a millis-based approach with no delay()
  • To keep things tidy, the work is done in functions which are called from loop(). It gets the distance, then checks if the sensor has detected a car for long enough, and then arms the realy, all in separate functions.
  • My relay is active low, meaning a low signal activates it. I have a line in the code where you can change that logic if your relay works the other way
  • The values for the distance threshold and the length of time before the relay triggers are in variables, so they can be set to be more suitable for testing
// ---------------------------------------------------------------------------
// BASED ON Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------
//ping interval is now millis()-based delay()-less

#include <NewPing.h>

#define TRIGGER_PIN  19  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     18  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
//ping interval is millis()-based delay()-less
unsigned long currentMillis;
unsigned long previousMillisPing;
unsigned long previousMillisOccupied;
int occupiedThreshold = 5000; //ms, set this <<<<<<<<<<<<<<<<<<<<<<<<<<
byte pingInterval = 50; //30 minimum
bool gotNewDistance = false;

int actualDistance;
int thresholdDistance = 30; //cm <<<<<<<<<<<<<<<<<<<< set this
bool occupiedLongEnough = false;
byte relayPin = 14;

//choose one of the following lines <<<<<<<<<<<<<<<<<<<<<<<<<<<<
bool relayClosed = 0; bool relayOpen = 1;  //relay active low
//bool relayClosed=1; bool relayOpen=0;  //relay active high:

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

void setup()
{
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
  Serial.println(".... parking project ....");
  Serial.print("Created: ");
  Serial.print(__TIME__);
  Serial.print(", ");
  Serial.println(__DATE__);
  Serial.println(" ");

  digitalWrite(relayPin, relayOpen);
  pinMode(relayPin, OUTPUT);
  delay(1000);
}

void loop()
{
  currentMillis = millis();
  getDistance();
  checkIfOccupiedLongEnough();
  setRelay();  //based on time occupied
}//loop

void getDistance()
// this is from the new ping library, but mills based now, no delay
{
  if (currentMillis - previousMillisPing >= pingInterval)
  {
    previousMillisPing = currentMillis;
    //delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
    unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
    actualDistance = uS / US_ROUNDTRIP_CM;
    Serial.print("Ping: ");
    Serial.print(actualDistance); // Convert ping time to distance in cm and print result (0 = outside set distance range)
    Serial.println("cm, ");
    gotNewDistance = true;
  }
}//getDistance

void checkIfOccupiedLongEnough()
{
  if (gotNewDistance)
  {
    if (currentMillis - previousMillisOccupied >= occupiedThreshold)
    {
      // if it gets here, it's occupied long enough
      occupiedLongEnough = true;
      Serial.println(" car for long enough XXXXXXXXXXXXXXXXXXXXX");
    }
    else
    {
      occupiedLongEnough = false;
    }

    if (actualDistance > thresholdDistance)
    {
      previousMillisOccupied = currentMillis;  //no car so reset timer
    }

    gotNewDistance = false;
  }
}//checkIfOccupiedLongEnough()

void setRelay()
{
  if (occupiedLongEnough)
  {
    //Serial.println(" occupied");
    digitalWrite(relayPin, relayClosed);
  }
  else
  {
    //Serial.println(" vacant");
    digitalWrite(relayPin, relayOpen);
  }
}//setRelay()