Using multiple ultrasonic sensors to give readings to a counter

Hello everyone I hope you are doing well.

I am coding my own smart car park utilising the following components:

  • Arduino Mega
  • 4 x Ultrasonic sensors
  • 1 x OLED
  • 1x servo motor

The idea behind this is that 1 ultrasonic sensor is used to open the gate to the car park (servo motor) whilst the other three sensors are used to display the parking slots in the park.

My problem is that I wish to use the ultrasonic sensors to display a space being taken up in the car park and this information being displayed on an OLED.
I cannot seem to count the number of slots available, and if one frees up, also display this on the OLED.

I would like to display the number of car slots available, and when one is used up, this is displayed on the OLED showing "2 slots available"; if another one is used up, deduct this value from the other car slot taken up and displaying "1 slot available".

Here is the current copy of my code below:

// This project uses an Arduino MEGA to house more ultrasonic sensors

// Define ultrasonic sensor parameters

int trigPin = 5;
int echoPin = 6;
long duration;
int distance;

int trigPin2 = 8;
int echoPin2 = 9;
long duration2;
int distance2;

int trigPin3 = 19;
int echoPin3 = 18;
long duration3;
int distance3;

int DelayTime = 1000;
int OLEDTime = 500;
int C1 = 3;
int C2 = 2;
int C3 = 1;
int C4 = 0;
int currentVal;
int x = 1;
int y = -1;

String currentState = "CLOSED";

// Define OLED parameters //
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Define Servo Motor //
#include <Servo.h>
Servo myservo;
int pos = 0;

// Define Ultrasonic function //
long Ultrasonic() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);

digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034/2;
}

long Ultrasonic2() {
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);

digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2, LOW);

duration2 = pulseIn(echoPin2, HIGH);
distance2 = duration2 * 0.034/2;
}

long Ultrasonic3() {
digitalWrite(trigPin3, LOW);
delayMicroseconds(2);

digitalWrite(trigPin3, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin3, LOW);

duration3 = pulseIn(echoPin3, HIGH);
distance3 = duration3 * 0.034/2;
}

void clearOLED() {
oled.clearDisplay();
oled.setTextSize(8);
oled.setTextColor(WHITE);
oled.setCursor(1,20);
oled.println("");
delay(1000);
oled.display();
}

String open_gate_OLED() {
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(40,30);
oled.println("GATE OPEN");
oled.display();
return "OPEN";
}

String close_gate_OLED() {
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(30,30);
oled.println("GATE CLOSED");
oled.display();
return "CLOSED";
}

int slots_used() {
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(19,30);
oled.print("SLOTS AVAILABLE: ");
oled.setCursor(62,40);
oled.println(C1-1);
oled.display();
delay(OLEDTime);
return currentVal;
}

int slots_available() {
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(19,30);
oled.print("SLOTS AVAILABLE: ");
oled.setCursor(62,40);
oled.println();
oled.display();
delay(OLEDTime);
return currentVal;
}

//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------

void setup() {

Serial.begin(9600);

if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
delay(1000);

pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(trigPin3, OUTPUT);
pinMode(echoPin3, INPUT);
myservo.attach(3);

}

//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------

void loop() {

Ultrasonic();
Ultrasonic2();
Ultrasonic3();
Serial.print(distance3);
Serial.println(" cm");

if (currentState == "CLOSED" && distance <= 10) { // This part of code will open the gate to 180 if the distance is less that 10cm for one of the ultrasonic sensors
delay(DelayTime); // This will be displayed on the OLED saying GATE OPEN
distance = Ultrasonic();
if (distance <= 10) {
myservo.write(180);
delay(OLEDTime);
currentState = open_gate_OLED();
}
}

else if (distance >= 10) { // And if the distance is more than 10 cm for the DelayTime of 1s, then the gate will shut
delay(DelayTime); // It will be displayed on the OLED saying GATE CLOSED
distance = Ultrasonic();
if (distance >= 10) {
myservo.write(pos);
delay(OLEDTime);
currentState = close_gate_OLED();
}
}

if (distance2 <= 3) {
delay(DelayTime);
distance2 = Ultrasonic2();
if (distance2 <= 3) {
slots_used();
}
}

if (distance3 <= 3) {
delay(DelayTime);
distance3 = Ultrasonic3();
if (distance3 <= 3) {
slots_used();
}
}
else if (currentVal == C2) {
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(WHITE);
oled.setCursor(19,30);
oled.print("SLOTS AVAILABLE: ");
oled.setCursor(62,40);
oled.println(C1-1);
oled.display();
delay(OLEDTime);
}

}

You tell us what the code should do and that it doesn't work,but you do not tell us what the code actually does and how that is different from what you want.

Post a schematic of the project. Hand drawn, photographed and posted is fine. How is the servo powered?

Did you not see a warning asking you to post the code properly?

Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

You can go back and fix your original post by highlighting the code and clicking the </> in the menu bar.
code tags new

Post a schematic. How to make a schematic to post.

Have you noticed how the functions Ultrasonic, Ultrasonic2 and Ultrasonic3 look very similar?
(And wrong - they promise to return values, but don't)

You can fix that.

Please remember to use code tags when posting code

Here is the updated code:

// This project uses an Arduino MEGA to house more ultrasonic sensors

// Define ultrasonic sensor parameters

int trigPin = 5;
int echoPin = 6;
long duration;
int distance;

int trigPin2 = 8;
int echoPin2 = 9;
long duration2;
int distance2;

int trigPin3 = 19;
int echoPin3 = 18;
long duration3;
int distance3;

int DelayTime = 1000;
int OLEDTime = 500;
int C1 = 3;
int C2 = 2;
int C3 = 1;
int C4 = 0;
int currentVal;
int x = 1;
int y = -1;

String currentState = "CLOSED";
 

// Define OLED parameters //
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Define Servo Motor //
#include <Servo.h>
Servo myservo;
int pos = 0;

// Define Ultrasonic function //
long Ultrasonic() {  
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034/2;
} 

long Ultrasonic2() {
  digitalWrite(trigPin2, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin2, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin2, LOW);

  duration2 = pulseIn(echoPin2, HIGH);
  distance2 = duration2 * 0.034/2;
}

long Ultrasonic3() {  
  digitalWrite(trigPin3, LOW);
  delayMicroseconds(2);

  digitalWrite(trigPin3, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin3, LOW);

  duration3 = pulseIn(echoPin3, HIGH);
  distance3 = duration3 * 0.034/2;
} 

void clearOLED() {
  oled.clearDisplay();           
  oled.setTextSize(8);           
  oled.setTextColor(WHITE);     
  oled.setCursor(1,20);
  oled.println("");               
  delay(1000);
  oled.display();
}

String open_gate_OLED() {
  oled.clearDisplay();           
  oled.setTextSize(1);           
  oled.setTextColor(WHITE);     
  oled.setCursor(40,30);
  oled.println("GATE OPEN");               
  oled.display();
  return "OPEN";
}

String close_gate_OLED() {
  oled.clearDisplay();           
  oled.setTextSize(1);           
  oled.setTextColor(WHITE);     
  oled.setCursor(30,30);
  oled.println("GATE CLOSED");               
  oled.display();
  return "CLOSED";
}

int slots_used() {
   oled.clearDisplay(); 
   oled.setTextSize(1);           
   oled.setTextColor(WHITE);     
   oled.setCursor(19,30);
   oled.print("SLOTS AVAILABLE: ");
   oled.setCursor(62,40);
   oled.println(C1-1);
   oled.display(); 
   delay(OLEDTime);
   return currentVal; 
}

int slots_available() {
   oled.clearDisplay(); 
   oled.setTextSize(1);           
   oled.setTextColor(WHITE);     
   oled.setCursor(19,30);
   oled.print("SLOTS AVAILABLE: ");
   oled.setCursor(62,40);
   oled.println();
   oled.display(); 
   delay(OLEDTime);
   return currentVal;
}

//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------

void setup() {
  
  Serial.begin(9600);
   
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {       
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
  delay(1000);
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(trigPin3, OUTPUT);
  pinMode(echoPin3, INPUT);
  myservo.attach(3);   

}

//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------

void loop() {

  Ultrasonic();
  Ultrasonic2();
  Ultrasonic3();
  Serial.print(distance3);
  Serial.println(" cm");
  
  if (currentState == "CLOSED" && distance <= 10) {               // This part of code will open the gate to 180 if the distance is less that 10cm for one of the ultrasonic sensors
    delay(DelayTime);                                             // This will be displayed on the OLED saying GATE OPEN
    distance = Ultrasonic();
    if (distance <= 10) {
     myservo.write(180);
     delay(OLEDTime);
     currentState = open_gate_OLED();
    }
  }
   
  else if (distance >= 10) {                                      // And if the distance is more than 10 cm for the DelayTime of 1s, then the gate will shut
    delay(DelayTime);                                             // It will be displayed on the OLED saying GATE CLOSED
    distance = Ultrasonic();
    if (distance >= 10) {
      myservo.write(pos);
      delay(OLEDTime);
      currentState = close_gate_OLED();
    }
  }

  if (distance2 <= 3) {
    delay(DelayTime);
    distance2 = Ultrasonic2();
    if (distance2 <= 3) {    
      slots_used();
    }
  }

  if (distance3 <= 3) {
    delay(DelayTime);
    distance3 = Ultrasonic3();
    if (distance3 <= 3) {    
      slots_used();       
    }
  }
    else if (currentVal == C2) {
      oled.clearDisplay(); 
      oled.setTextSize(1);           
      oled.setTextColor(WHITE);     
      oled.setCursor(19,30);
      oled.print("SLOTS AVAILABLE: ");
      oled.setCursor(62,40);
      oled.println(C1-1);
      oled.display(); 
      delay(OLEDTime);
    }

}

So far the things that are working in the code:

  1. The OLED displays Gate OPEN and CLOSED when the first ultrasonic sensor detects an object close to it.

Right now it cannot count the number of cars that are in the slots and if there is one available if the car decides to leave the park.

Here is the diagram of the circuit:

Have you noticed how the functions Ultrasonic, Ultrasonic2 and Ultrasonic3 look very similar?
(And wrong - they promise to return values, but don't)

You can fix that.

I kept the values of Ultrasonic, Ultrasonic2 and 3 the same because each ultrasonic code in the void loop() is essentially the same.

Could you let me know what bit of code I should have written?

Of course.

long Ultrasonic (byte trigPin, byte echoPin) 
{
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  unsigned long duration = pulseIn(echoPin, HIGH);
  return duration * 0.034/2;
} 

Is this code the one I can use for all of the Ultrasonic sensors?

No, it's the code you should use for all the ultrasonic sensors.

How would I go about writing the code for the counter in the car park?

More carefully than thus far, and with due caution about late returns from adjacent transmitters.

Would you be able to write the code for it?

I think I already did (mostly)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.