Automatic parking lot

Hello
I am making an Automatic parking lot, where if the PIR sensor detects the car then the servo will open
and the LCD will display how much space is left, and when you want to leave will be done by entering values through a keypad and typing "paid" in the serial monitor.
the issue I am facing is

  • The time spent inside the parking lot should be calculated between the keypad entries of (*n#)

and (#n*), where n represents the car number (1-5) based on the order of entry.

  • I am facing an issue with millis() I tried to convert it minutes but whenever it goes above 0.60 it continues as (0.61....0.7) it doesn't convert to (1.00....1.12). the reason I need this is so I can calculate the cost as mentioned in the point above (Parking Fee (fils) = time(sec) x fare, are= 0.29 fils/sec)

I would like your help to understand how to implement those two points.

// C++ code
//
#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Servo.h>

Servo myservo;
int pos;
int led = 3;
int count = 0;
int pir = A4;
int value = 0;
int Slot = 5;      //Enter Total number of parking Slots
int flag1 = 0;
int flag2 = 0;

double i = 0;
double a = millis();
double c ;

const int rs = 8, e = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13;
LiquidCrystal lcd(rs, e, d4, d5, d6, d7);

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'},
};
byte rowPins[ROWS] = {7, 6, 5, 4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A3, A2, A1, A0}; //connect to the column pinouts of the keypad

Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() {
  pinMode(led, OUTPUT);
  pinMode(pir, INPUT);
  lcd.begin(16, 2);
  myservo.attach(2);
  myservo.write(0);
  lcd.setCursor (0, 0);
  lcd.print("PARKING SYSTEM");
  lcd.setCursor (0, 1);
  lcd.print("PROJECT");
  delay (2000);
  lcd.clear();
  Serial.begin(9600);
  Serial.println("");
}

void loop() {
  char key = myKeypad.getKey();

  if (digitalRead (pir) == HIGH && flag1 == 0) { //pir sensor
    if (Slot > 0) {
      flag1 = 1;
      if (flag2 == 0) {
        myservo.write(0);
        Slot = Slot - 1;
        digitalWrite(led, HIGH);
        delay(500);
        digitalWrite(led, LOW);
      }
    } else {
      lcd.setCursor (0, 0);
      lcd.print("Parking Full");
      delay (3000);
      lcd.clear();
    }
  }
  
  if (key != NO_KEY) //time
  {
    if (isdigit(key))
    {
      //Serial.print(key);
      value = value * 10 + key - '0';
          
    }
    else if(){
      /*
       a = millis();
      while (true)
      {
        c = millis();
        s = ((c - a) / 1000) / 60;
        i = s * (1.00 / 0.60);
        Serial.println(i);
        delay(600);
      }
       */  
    }
  }
  
    if (Serial.available()) { // serial 
      String cmd = "paid";
      if (cmd == "paid") {
        flag2 = 1;
        if (flag1 == 0) {
          myservo.write(0);
          Slot = Slot + 1;
        }
      }
      if (flag1 == 1 && flag2 == 1) {
        delay (1000);
        myservo.write(90);
        flag1 = 0, flag2 = 0;
      }
      lcd.setCursor (0, 0);
      lcd.print("Available");
      lcd.setCursor (0, 1);
      lcd.print("Slot: ");
      lcd.print(Slot);
    }
  }

millis() returns unsigned long, not double.

is this some sort of school assignment? Car Parking lot simulation

I wrote the code separately to check but it still goes above 0.61 and doesn't convert to 1.01 or is it normal?

void setup()
{
  Serial.begin(9600);

}
long a = millis();
double c ;
double s = 0;

void loop()
{
  if (Serial.available()) {
    String cmd = "start";
    if (cmd == "start") {
      while (true)
      {

        c = millis();
        s = ((c-a)/1000)/60;
        Serial.println(s);
        delay(600);
      }
      }
    }
  }

millis returns an unsigned long, not a double.

yes, but I am using different components, and I believe I only have an issue with the keypad and time to calculate

I made both of them long

long a = millis();
long c ;
double s = 0;

but it gives me the result '0.00'

You could help yourself by using variable names longer than a single character. It would also help others understand the program better

so s is the number of minutes - seems like an odd name

yes, I was going seconds that is why s.

millis() return unsigned long, this is not JavaScript

so like this?

unsigned long a = millis();
unsigned long c ;
double s = 0;

You tell me, do you know the difference between signed and unsigned?

actually no
I just found out about it now and reading about it

edit: just understood about it now

(milliseconds - milliseconds) / 1000 / 60 ==> minutes, not seconds

apart from that unsigned holding 2x positive value than signed, it is ok and legal to overflow, when signed overflow will cause undefined behaviour in c++. millis() will wrap around after some time so you must use unsigned

yes it was seconds, before changing into minutes I'll fix it with the final code

understood, so is that the reason why I am getting zeroes when using it separately?

yes, your division result is an int, so anything from 0 and 1 will be 0, from 1 to 2 will be 1…etc.

make 1000 a 1000.0f and s a float, you don’t need extra precision there

some questions.
is it okay to have 's' as double or do I need to make it float?
also, I just remembered that you can't multiply 1.0 minute to the cost while dealing with seconds. so should I keep it as it is? or make it as a whole number?

TBH i’m not even sure what you are trying to do. 0.6 of the minute is 36 seconds not 60 seconds