Thoughts of my program

May i know your thoughts on my program, because for me i think on case botready and case charging is kinda messy

/*

SMART MATERIAL SORTER - AUTOMATED WASTE SEGREGATION SYSTEM

Program Description:
This program automates the process of sorting waste materials (metal and non-metal) 
and rewards users with phone charging time in return. The system uses capacitive and inductive sensors 
to identify the type of waste, and IR sensors to detect if bins are full. 
Servo motors manage the waste sorting mechanism and lid control. 
A pushbutton allows users to start or stop the charging process, while an LCD provides instructions,
timer updates, and status messages. The relay module controls power delivery to the charging port.

Key Features:
- Material detection using a combination of capacitive and inductive proximity sensors.
- Automatic sorting into metal or non-metal bins via servo-controlled mechanisms
- Overflow detection for both bins using infrared sensors to prevent overfilling.
- Pushbutton-controlled charging that activates a countdown timer and can be extended with more waste input.
- User feedback via LCD, displaying instructions, sorting status, and countdown during charging.
- Relay and LED control for managing and indicating charger activity.
- Timeout mechanism resets the system if no activity is detected within a specific time.
*/

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

#include <LiquidCrystal_I2C.h>
#include <Servo.h>

// Re-named servo for clarity
LiquidCrystal_I2C lcd(0x27,16,2);
Servo servoLid;
Servo servoSeg;

// Sensor Pins
const int indSensorPin              = 2;     // Inductive
const int capSensorPin              = 3;     // Capacitive
const int overflowMetal             = 4;     // Ir-Sensor
const int overflowNon               = 5;     // Ir-Sensor

// Servo Pins
const int servoLidPin               = 6;
const int servoSegPin               = 7;

//Servo Positions
const int srvoClosed                = 0;     // Lid Closed
const int srvoOpen                  = 180;   // Lid Open
const int binCenter                 = 90;
const int binMetal                  = 135;
const int binNonMetal               = 45;

// Button Pins
const int chargeBut                 = 8;    // Start/Stop Button

// Charger Controls Pins
const int chargerRelay              = 11;   // Power Control
const int greenLED                  = 13;   // Status Light

// Charing Time Countdown
int countdown                       = 0;    
const int addTime                   = 60;
const unsigned long msecTimer       = 1000;
unsigned long msec1                 = 0;

// Inactivity Timeout
const unsigned long TimeOutInac     = 20000; // 20 seconds till timeout

bool wasteaddedprev = false;

// Delay Time
const int dt                        = 500;   // Delay for 0.5 seconds
const int dtinac                    = 2000;  // Delay for 2 seconds
const int dtdone                    = 3000;  // Delay for 3 seconds

// Switch Statement Cases
enum{Prompt,Idle,BotReady,Charging,Wait,Overflow};
int state;

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

void setup() {

  // LCD Startup
  lcd.begin(16,2);
  lcd.backlight();

  // Servo Startup
  servoLid.attach(servoLidPin);
  servoSeg.attach(servoSegPin);
  servoLid.write(srvoClosed);               // Calibration check
  servoSeg.write(90);                       // Calibration check

  // Sensor Startup
  pinMode(indSensorPin,         INPUT);     // Inductive Sensor
  pinMode(capSensorPin,         INPUT);     // Capacitive Sensor
  pinMode(overflowMetal,        INPUT);     // Ir-Sensor
  pinMode(overflowNon,          INPUT);     // Ir-Sensor

  // Charger Controls Startup
  pinMode(chargerRelay,        OUTPUT);     // Power Control
  pinMode(greenLED,            OUTPUT);     // Status Light
  digitalWrite(chargerRelay,     HIGH);     // Calibration check - Active on low
  digitalWrite(greenLED,          LOW);     // Calibration check

  // Button Startup
  pinMode(chargeBut,   INPUT_PULLUP);    // Start Button

  //Serial Monitor Startup
  Serial.begin(9600);
  Serial.println("Charging Station Initializing...");
  state = Prompt;
}

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

// LCD Function
void lcdDisp(const char *s0,const char *s1){
  lcd.clear();
  if(s0){
    lcd.setCursor(0,0);
    lcd.print(s0);
  }
  if(s1){
    lcd.setCursor(0,1);
    lcd.print(s1);
  }
}

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

// Servo Function
void sortBin(int binPos){
  servoSeg.write(binPos);
  delay(dt);
  servoLid.write(srvoOpen);
  delay(dt);
  servoLid.write(srvoClosed);
  delay(dt);
  servoSeg.write(binCenter);
}

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

void loop() {
  unsigned long msec = millis();

  //Sensor State
  bool indDetected = !digitalRead(indSensorPin);    // Active on LOW
  bool capDetected = digitalRead(capSensorPin);     // Active on HIGH
  bool Moverflow = !digitalRead(overflowMetal);     //Overflow Detection
  bool Noverflow = !digitalRead(overflowNon);       //Overflow Detection

  // Overflow Warning
  if (Moverflow || Noverflow){
    servoSeg.write(binCenter);
    servoLid.write(srvoClosed);
    lcdDisp("Trash Bin Full",nullptr);
    Serial.println("state Overflow - Trash Bin Full Please Empty");
    state = Overflow;
    return;
  }

// -----------------------------------------------------------------------------
  switch(state){
  case Prompt:// Waiting for a waste to be inserted
      Serial.println("State Idle");
      Serial.println("               Insert waste");
      lcdDisp("Please Insert A","Waste Material");
      state = Idle;
      break;
  // -----------------------------------------------------------------------------
  case Idle: // Waste inserted ready to charge phone
      // Sorting Functions
      if (capDetected && !indDetected) {            // Non-Metal Detected
        lcdDisp("Sorting:","    Non-Metal");
        Serial.println("state BotReady - Non-Metal Detected");
        sortBin(binNonMetal);                // Segway to non-metal bin
        state = BotReady;
      }
      else if (capDetected && indDetected) {        // Metal Detected
        lcdDisp("Sorting: ","      Metal");
        Serial.println("state BotReady - Metal Detected");
        sortBin(binMetal);                   // Segway to metal bin
        state = BotReady;
      }
      break;
    // -----------------------------------------------------------------------------
    case BotReady: // Station buttons
        if (digitalRead(chargeBut) == LOW){ // Charging starts
          lcdDisp("Charging Activated","Connect Phone");
          Serial.println("state Charging");
          Serial.println("Button Pressed - Start Timer");
          countdown = addTime;
          msec1 = msec;
          digitalWrite(chargerRelay,LOW);
          digitalWrite(greenLED,HIGH);
          state = Charging;
        }
        if (msec - msec1 >=TimeOutInac){ // Timeout if no actions was made
          digitalWrite(chargerRelay,HIGH);
          digitalWrite(greenLED,LOW);
          lcdDisp("   Inactivity","Restart Required");
          Serial.println ("state Prompt - Inactivity");
          delay(dtinac);
          msec1 = msec;
          state = Prompt;
        }
        break;
    // -----------------------------------------------------------------------------
    case Charging: // Charging phone
        bool wasteadded = (capDetected && indDetected) || (capDetected && !indDetected);

        if (wasteadded && !wasteaddedprev){ // Timer added when waste insert
          countdown = countdown + addTime;
          msec1 = msec;
          digitalWrite(greenLED, HIGH);
          delay(200);
          digitalWrite(greenLED, LOW);
          Serial.println("Time Added");
        }
        wasteaddedprev = wasteadded;
        if (msec - msec1 >= msecTimer){ // Timer countdown
          countdown--;
          msec1 = msec;
          lcd.clear();
          lcd.print("Timer left:");
          lcd.setCursor(0,1);
          lcd.print(countdown);
        }
        if (countdown <= 0){
          msec1 = msec;
          digitalWrite(chargerRelay,HIGH);
          digitalWrite(greenLED,LOW);
          lcdDisp(" Charging Done",nullptr);
          Serial.println("state Wait - Charging Timer Done");
          state = Wait;
        }
        if (digitalRead(chargeBut) == LOW){ // Stop button
          msec1 = msec;
          countdown = 0;
          digitalWrite(chargerRelay,HIGH);
          digitalWrite(greenLED,LOW);
          lcdDisp("Charging Stopped",nullptr);
          Serial.println("state Wait - Time stopped by user");
          state = Wait;
        }
        break;
    // -----------------------------------------------------------------------------
    case Wait:
        lcdDisp("Unplug Charger","   Thank You!");
        delay(dtdone);
        state = Prompt;
        break;
    // -----------------------------------------------------------------------------
    case Overflow: // Overflow Warning
        if (!Moverflow && !Noverflow){
          lcdDisp("Trash Bin Empty","   Thank You");
          Serial.println("State Prompt - Trash Bin Emptied");
          state = Prompt;
        }
  }
}
// -----------------------------------------------------------------------------

The main thought is a question. Does it work the way you want or does it not?

1 Like

My code complied but i haven't tried testing it with the necessary components because my batteries are out of charge

Why would you run this on a battery instead of the mains with an appropriate power supply?

2 Likes

Have you tried the inputs that are active LOW with INPUT_PULLUP?
You did not verify data sent to the LCD is limited to 16 characters.
Seems like everything is "non-metal".

That tells me your DID NOT TEST during program development! So, I do not think much of your program nor your method of program development. Test and then begin debugging and tell us how the results match your requirements.

1 Like

That problem is easy to solve.

Not quite correct.
Declaring a variable with an initializer inside a case, without limiting the scope of the variable to that particular case, will cause problems. The scope of the variable is the remainder of the switch statement, so the compiler sees the initializer being skipped for any subsequent case. The practical result of this, with the gcc compiler used by the Arduino IDE, is that no subsequent case can ever be executed.

If the Arduino IDE preferences are set to show all warning during compilation, it will display warnings:

/tmp/arduino_modified_sketch_132393/BlinkWithoutDelay.ino: In function 'void loop()':
/tmp/arduino_modified_sketch_132393/BlinkWithoutDelay.ino:247:10: warning: jump to case label [-fpermissive]
     case Wait:
          ^~~~
/tmp/arduino_modified_sketch_132393/BlinkWithoutDelay.ino:209:12: note:   crosses initialization of 'bool wasteadded'
       bool wasteadded = (capDetected && indDetected) || (capDetected && !indDetected);
            ^~~~~~~~~~
/tmp/arduino_modified_sketch_132393/BlinkWithoutDelay.ino:253:10: warning: jump to case label [-fpermissive]
     case Overflow: // Overflow Warning
          ^~~~~~~~
/tmp/arduino_modified_sketch_132393/BlinkWithoutDelay.ino:209:12: note:   crosses initialization of 'bool wasteadded'
       bool wasteadded = (capDetected && indDetected) || (capDetected && !indDetected);
            ^~~~~~~~~~

Here's the updated code that I tested(it works). I'd want to hear your opinions on my code, and just a reminder that I'll be recoding the state charging and adding comments about those funtions later on.

Note: I used an Ir-Sensor(active on LOW) as a temporary replacement for the Capacitive Sensor(active on HIGH), because the wires of the Capacitive sensor is messy
bool capActive = !digitalRead(capSensorPin); // Active on HIGH

/*
SMART MATERIAL SORTER - AUTOMATED WASTE SEGREGATION SYSTEM

Program Description:
This program automates the process of sorting waste materials (metal and non-metal) 
and rewards users with phone charging time in return. The system uses capacitive and inductive sensors 
to identify the type of waste, and IR sensors to detect if bins are full. 
Servo motors manage the waste sorting mechanism and lid control. 
A pushbutton allows users to start or stop the charging process, while an LCD provides instructions,
timer updates, and status messages. The relay module controls power delivery to the charging port.

Key Features:
- Material detection using a combination of capacitive and inductive proximity sensors.
- Automatic sorting into metal or non-metal bins via servo-controlled mechanisms
- Overflow detection for both bins using infrared sensors to prevent overfilling.
- Pushbutton-controlled charging that activates a countdown timer and can be extended with more waste input.
- User feedback via LCD, displaying instructions, sorting status, and countdown during charging.
- Relay and LED control for managing and indicating charger activity.
- Timeout mechanism resets the system if no activity is detected within a specific time.
*/

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

#include <LiquidCrystal_I2C.h>
#include <Servo.h>

// Re-named servo for clarity
LiquidCrystal_I2C lcd(0x27,16,2);
Servo servoLid;
Servo servoSeg;

// Sensor Pins
const int indSensorPin              = 2;     // Inductive
const int capSensorPin              = 3;     // Capacitive
const int overflowMetal             = 4;     // Ir-Sensor
const int overflowNon               = 5;     // Ir-Sensor

// Servo Pins
const int servoLidPin               = 6;
const int servoSegPin               = 7;

//Servo Positions
const int srvoClosed                = 0;     // Lid Closed
const int srvoOpen                  = 180;   // Lid Open
const int binCenter                 = 90;
const int binMetal                  = 135;
const int binNonMetal               = 45;

// Button Pins
const int chargeBut                 = 8;     // Start/Stop Button

// Charger Controls Pins
const int chargerRelay              = 11;    // Power Control
const int greenLED                  = 13;    // Status Light

// Charging Time Countdown
int countdown                       = 0;    
const int addTime                   = 60;
const unsigned long msecTimer       = 1000;
unsigned long msec1                 = 0;

// Inactivity Timeout
const unsigned long TimeOutInac     = 20000; // 20 seconds till timeout

// Delay Time
const int dt                        = 500;   // Delay for 0.5 seconds
const int dtover                    = 4000;
const int dtblink                   = 200;   // Delay for 0.1 seconds
const int dtinac                    = 2000;  // Delay for 2 seconds
const int dtdone                    = 3000;  // Delay for 3 seconds

// Switch Statement Cases
enum{Prompt,Idle,BotReady,Charging,Wait,Overflow};
int state;

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

void setup() {

  // LCD Startup
  lcd.begin(16,2);
  lcd.backlight();

  // Servo Startup
  servoLid.attach(servoLidPin);
  servoSeg.attach(servoSegPin);
  servoLid.write(srvoClosed);                 // Calibration check
  servoSeg.write(binCenter);                  // Calibration check

  // Sensor Startup
  pinMode(indSensorPin,         INPUT);       // Inductive Sensor
  pinMode(capSensorPin,         INPUT);       // Capacitive Sensor
  pinMode(overflowMetal,        INPUT);       // Ir-Sensor
  pinMode(overflowNon,          INPUT);       // Ir-Sensor

  // Charger Controls Startup
  pinMode(chargerRelay,        OUTPUT);       // Power Control
  pinMode(greenLED,            OUTPUT);       // Status Light
  digitalWrite(chargerRelay,     HIGH);       // Calibration check - Active on low
  digitalWrite(greenLED,          LOW);       // Calibration check

  // Button Startup
  pinMode(chargeBut,   INPUT_PULLUP);         // Start/Stop Button

  //Serial Monitor Startup
  Serial.begin(9600);
  Serial.println("Charging Station Initializing...");
  state = Prompt;
}

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

// LCD Function
void lcdDisp(const char *s0,const char *s1){
  lcd.clear();
  if(s0){
    lcd.setCursor(0,0);
    lcd.print(s0);
  }
  if(s1){
    lcd.setCursor(0,1);
    lcd.print(s1);
  }
}

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

// Servo Function
void sortBin(int binPos){
  servoSeg.write(binPos);
  delay(dt);
  servoLid.write(srvoOpen);
  delay(dt);
  servoLid.write(srvoClosed);
  delay(dt);
  servoSeg.write(binCenter);
}

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

void loop() {
  unsigned long msec = millis();

  //Sensor State
  bool indActive = !digitalRead(indSensorPin);    // Active on LOW
  bool capActive = !digitalRead(capSensorPin);     // Active on HIGH
  bool Moverflow = !digitalRead(overflowMetal);     //Overflow Detection
  bool Noverflow = !digitalRead(overflowNon);       //Overflow Detection

// -----------------------------------------------------------------------------
  switch(state){
  case Prompt:// Waiting for a waste to be inserted
      Serial.println("State Idle");
      Serial.println("               Insert waste");
      lcdDisp("Please Insert A","Waste Material");
      state = Idle;
      break;
  // -----------------------------------------------------------------------------
  case Idle: // Waste inserted ready to charge phone
      // Sorting Functions
      if (capActive && !indActive) {            // Non-Metal Detected
        lcdDisp("Sorting:","    Non-Metal");
        Serial.println("Waste Inserted - Metal Detected");
        sortBin(binNonMetal);                // Segway to non-metal bin
        delay(dt);
        lcdDisp("Press Button","To Charge");
        Serial.println("state BotReady - Press Button");
        countdown = addTime;
        state = BotReady;
        msec1 = msec;
      }
      else if (capActive && indActive) {        // Metal Detected
        lcdDisp("Sorting: ","      Metal");
        Serial.println("Waste Inserted - Metal Detected");
        sortBin(binMetal);                   // Segway to metal bin
        delay(dt);
        lcdDisp("Press Button","To Charge");
        Serial.println("state BotReady - Press Button");
        countdown = addTime;
        state = BotReady;
        msec1 = msec;
      }
      break;
    // -----------------------------------------------------------------------------
    case BotReady: // Station buttons
        if (Moverflow || Noverflow) {
          lcdDisp(" Trash Bin Full","Please Continue");
          Serial.println("Trash Bin Full - Sorting Disabled");
          delay(dt);
        }
        else{
          if (capActive && !indActive) {            // Non-Metal Detected
            lcdDisp("Already Sorted","Press To Charge");
            Serial.println("Non-Metal Detected - Added Time");
            sortBin(binNonMetal);                // Segway to non-metal bin
            countdown = countdown + addTime;
            msec1 = msec;
          }
          else if (capActive && indActive) {        // Metal Detected
            lcdDisp("Already Sorted","Press To Charge");
            Serial.println("Metal Detected - Added Time");
            sortBin(binMetal);                   // Segway to metal bin
            countdown = countdown + addTime;
            msec1 = msec;
          }
        }
        if (digitalRead(chargeBut) == LOW){ // Charging starts
          lcdDisp("Charging Activated","Connect Phone");
          Serial.println("state Charging");
          Serial.println("Button Pressed - Start Timer");
          delay(dt);
          digitalWrite(chargerRelay,LOW);
          digitalWrite(greenLED,HIGH);
          msec1 = msec;
          state = Charging;
        }
        if (msec - msec1 >=TimeOutInac){ // Timeout if no actions was made
          digitalWrite(chargerRelay,HIGH);
          digitalWrite(greenLED,LOW);
          lcdDisp("   Inactivity","Restart Required");
          Serial.println ("state Prompt - Inactivity");
          delay(dtinac);
          msec1 = msec;
          state = Prompt;
        }
        break;
    // -----------------------------------------------------------------------------
    case Charging:
    // -----------------------------------------------------------------------------
    case Wait:
      // Overflow Warning
        if (Moverflow || Noverflow){
          state = Overflow;
          servoSeg.write(binCenter);
          servoLid.write(srvoClosed);
          lcdDisp(" Trash Bin Full","Please Empty");
          Serial.println("state Overflow - Trash Bin Full");
          delay(dt);
        }
        else{
        digitalWrite(chargerRelay, HIGH);
        digitalWrite(greenLED, LOW);
        lcdDisp(" Unplug Charger","   Thank You!");
        Serial.println("state Prompt - Charging Complete");
        delay(dtdone);
        state = Prompt;
        }
        break;
    // -----------------------------------------------------------------------------
    case Overflow: // Overflow Warning
        if (!Moverflow && !Noverflow){
          lcdDisp("Trash Bin Empty","   Thank You");
          Serial.println("State Prompt - Trash Bin Emptied");
          delay(dtover);
          state = Prompt;
        }
        break;
  }
}
// -----------------------------------------------------------------------------

Why negate every input state?

Charging defaults to Wait so Charge indicator is always on.
Status indicator lights for a very short length of time... more like "accidentally lights."

If "capacitive" is HIGH (negated to LOW), "inductive" has no effect whether LOW (negated to HIGH) or HIGH (negated to LOW).

No time added when first "material" is sensed after start or after Charge.

You should show your wiring and provide a truth table for the sensor input translating to the relay/servo/indicator output.

Your // comments are getting out of sync with your changes.

You are not ensuring your character strings fit on the LCD.

diagram.json for wokwi simulation
{
  "version": 1,
  "author": "foreignpigdog x",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": 0, "left": 0, "attrs": {} },
    { "type": "wokwi-servo", "id": "servo1", "top": -78.8, "left": 201.6, "attrs": {} },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -78,
      "left": 16.2,
      "rotate": 90,
      "attrs": { "color": "blue" }
    },
    { "type": "wokwi-servo", "id": "servo2", "top": -126.8, "left": 201.6, "attrs": {} },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": 44.8,
      "left": 178.4,
      "attrs": { "pins": "i2c" }
    },
    {
      "type": "wokwi-led",
      "id": "led2",
      "top": -49.2,
      "left": 16.2,
      "rotate": 90,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-text",
      "id": "text1",
      "top": -28.8,
      "left": 374.4,
      "attrs": { "text": "SEG" }
    },
    {
      "type": "wokwi-text",
      "id": "text2",
      "top": -76.8,
      "left": 374.4,
      "attrs": { "text": "LID" }
    },
    {
      "type": "wokwi-slide-switch",
      "id": "sw1",
      "top": -123.2,
      "left": 163.7,
      "rotate": 90,
      "attrs": {}
    },
    {
      "type": "wokwi-slide-switch",
      "id": "sw2",
      "top": -152,
      "left": 163.7,
      "rotate": 90,
      "attrs": {}
    },
    {
      "type": "wokwi-slide-switch",
      "id": "sw3",
      "top": -180.8,
      "left": 163.7,
      "rotate": 90,
      "attrs": {}
    },
    {
      "type": "wokwi-slide-switch",
      "id": "sw4",
      "top": -209.6,
      "left": 163.7,
      "rotate": 90,
      "attrs": {}
    },
    {
      "type": "wokwi-text",
      "id": "text3",
      "top": -211.2,
      "left": 201.6,
      "attrs": { "text": "OVF NON" }
    },
    {
      "type": "wokwi-text",
      "id": "text4",
      "top": -182.4,
      "left": 201.6,
      "attrs": { "text": "OVF MAG" }
    },
    {
      "type": "wokwi-text",
      "id": "text5",
      "top": -153.6,
      "left": 201.6,
      "attrs": { "text": "CAP" }
    },
    {
      "type": "wokwi-text",
      "id": "text6",
      "top": -124.8,
      "left": 201.6,
      "attrs": { "text": "IND" }
    },
    {
      "type": "wokwi-pushbutton",
      "id": "btn1",
      "top": -128.2,
      "left": -9.6,
      "attrs": { "color": "green", "xray": "1" }
    },
    {
      "type": "wokwi-text",
      "id": "text7",
      "top": -153.6,
      "left": -9.6,
      "attrs": { "text": "CHARGE" }
    },
    {
      "type": "wokwi-text",
      "id": "text9",
      "top": -28.8,
      "left": -67.2,
      "attrs": { "text": "STATUS" }
    },
    {
      "type": "wokwi-text",
      "id": "text8",
      "top": -57.6,
      "left": -67.2,
      "attrs": { "text": "CHARGE" }
    }
  ],
  "connections": [
    [ "lcd1:GND", "nano:GND.1", "black", [ "h0" ] ],
    [ "lcd1:VCC", "nano:5V", "red", [ "h0" ] ],
    [ "lcd1:SDA", "nano:A4", "green", [ "h0" ] ],
    [ "lcd1:SCL", "nano:A5", "green", [ "h0" ] ],
    [ "nano:7", "servo1:PWM", "green", [ "v0" ] ],
    [ "nano:6", "servo2:PWM", "green", [ "v0" ] ],
    [ "nano:GND.1", "servo2:GND", "black", [ "v0" ] ],
    [ "nano:GND.1", "servo1:GND", "black", [ "v0" ] ],
    [ "nano:13", "led2:A", "green", [ "v-4.8", "h-10.1", "v-76.8" ] ],
    [ "nano:GND.1", "led2:C", "black", [ "v14.4", "h-144.5", "v-106" ] ],
    [ "nano:GND.1", "led1:C", "black", [ "v14.4", "h-144.5", "v-134.4" ] ],
    [ "nano:5V", "sw1:1", "red", [ "v0" ] ],
    [ "nano:5V", "sw2:1", "red", [ "v0" ] ],
    [ "nano:5V", "sw3:1", "red", [ "v0" ] ],
    [ "nano:5V", "sw4:1", "red", [ "v0" ] ],
    [ "nano:GND.1", "sw1:3", "black", [ "v0" ] ],
    [ "nano:GND.1", "sw2:3", "black", [ "v0" ] ],
    [ "nano:GND.1", "sw3:3", "black", [ "v0" ] ],
    [ "nano:GND.1", "sw4:3", "black", [ "v0" ] ],
    [ "nano:2", "sw1:2", "green", [ "v0" ] ],
    [ "nano:3", "sw2:2", "green", [ "v0" ] ],
    [ "nano:4", "sw3:2", "green", [ "v0" ] ],
    [ "nano:5", "sw4:2", "green", [ "v0" ] ],
    [ "nano:GND.1", "btn1:2.r", "black", [ "v0" ] ],
    [ "nano:8", "btn1:1.r", "green", [ "v0" ] ],
    [ "nano:11", "led1:A", "green", [ "v-14.4", "h-10.1" ] ]
  ],
  "dependencies": {}
}

I used an Ir-Sensor(active on LOW) as a temporary replacement for the Capacitive Sensor(active on HIGH), because the wires of the Capacitive sensor is messy. My inductive is npn and capacitive is pnp and the rest is ir sensor that are active on LOW

What do you mean by that

Alright, I'll reply with a circuit diagram. And what is a truth table and how it works?

I believe i do ensure that the character strings fit on my lcd

The first "material added" does not get a "time added" reaction/response.

Prove it.

This happens to everyone... you write the code... read the code... edit the code... re-write the code.. and so you have been staring at the same code... to the point you do not "see" your code (because you have seen it so many times). You will discover in your programming/job/life that you can miss little parts, but a "second set of eyes" (untrained, unknowing) will immediately spot the anomaly. Don't get too defensive of your code. There will always be someone who finds something.

i see, i've change it now

it does add up i've check it in serial monitor too

/*
SMART MATERIAL SORTER - AUTOMATED WASTE SEGREGATION SYSTEM

Program Description:
This program automates the process of sorting waste materials (metal and non-metal) 
and rewards users with phone charging time in return. The system uses capacitive and inductive sensors 
to identify the type of waste, and IR sensors to detect if bins are full. 
Servo motors manage the waste sorting mechanism and lid control. 
A pushbutton allows users to start or stop the charging process, while an LCD provides instructions,
timer updates, and status messages. The relay module controls power delivery to the charging port.

Key Features:
- Material detection using a combination of capacitive and inductive proximity sensors.
- Automatic sorting into metal or non-metal bins via servo-controlled mechanisms
- Overflow detection for both bins using infrared sensors to prevent overfilling.
- Pushbutton-controlled charging that activates a countdown timer and can be extended with more waste input.
- User feedback via LCD, displaying instructions, sorting status, and countdown during charging.
- Relay and LED control for managing and indicating charger activity.
- Timeout mechanism resets the system if no activity is detected within a specific time.
*/

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

#include <LiquidCrystal_I2C.h>
#include <Servo.h>

// Re-named servo for clarity
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo servoLid;
Servo servoSeg;

// Sensor Pins
const int indSensorPin              = 2;      // Inductive
const int capSensorPin              = 3;      // Capacitive
const int overflowMetal             = 4;      // Ir-Sensor
const int overflowNon               = 5;      // Ir-Sensor

// Servo Pins
const int servoLidPin               = 6;
const int servoSegPin               = 7;

//Servo Positions
const int srvoClosed                = 0;      // Lid Closed
const int srvoOpen                  = 180;    // Lid Open
const int binCenter                 = 90;
const int binMetal                  = 135;
const int binNonMetal               = 45;

// Button Pins
const int chargeBut                 = 8;      // Start/Stop Button

// Charger Controls Pins
const int chargerRelay              = 11;     // Power Control
const int greenLED                  = 13;     // Status Light

// Charging Time Countdown
int countdown                       = 0;
const int timeDone                  = 0;
const int addTime                   = 60;
const unsigned long msecTimer       = 1000;
unsigned long msec1                 = 0;

// Inactivity Timeout
const unsigned long TimeOutInac     = 20000;  // 20 seconds till timeout

// Delay Time
const int dt                        = 1000;   // Delay for 1 seconds
const int dtover                    = 4000;   // Delay for 4 seconds
const int dtinac                    = 2000;   // Delay for 2 seconds
const int dtdone                    = 3000;   // Delay for 3 seconds

// Switch Statement Cases
enum { Prompt,Idle,BotReady,Charging,Wait,Overflow };
int state;

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

void setup() {

  // LCD Startup
  lcd.begin(16, 2);
  lcd.backlight();

  // Servo Startup
  servoLid.attach(servoLidPin);
  servoSeg.attach(servoSegPin);
  servoLid.write(srvoClosed);         // Calibration check
  servoSeg.write(binCenter);          // Calibration check

  // Sensor Startup
  pinMode(indSensorPin, INPUT);       // Inductive Sensor
  pinMode(capSensorPin, INPUT);       // Capacitive Sensor
  pinMode(overflowMetal, INPUT);      // Ir-Sensor
  pinMode(overflowNon, INPUT);        // Ir-Sensor

  // Charger Controls Startup
  pinMode(chargerRelay, OUTPUT);      // Power Control
  pinMode(greenLED, OUTPUT);          // Status Light
  digitalWrite(chargerRelay, HIGH);   // Calibration check - Active on low
  digitalWrite(greenLED, LOW);        // Calibration check

  // Button Startup
  pinMode(chargeBut, INPUT_PULLUP);   // Start/Stop Button

  //Serial Monitor Startup
  Serial.begin(9600);
  Serial.println("Charging Station Initializing...");
  state = Prompt;
}

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

// LCD Function
void lcdDisp(const char *s0, const char *s1) {
  lcd.clear();
  if (s0) {
    lcd.setCursor(0, 0);
    lcd.print(s0);
  }
  if (s1) {
    lcd.setCursor(0, 1);
    lcd.print(s1);
  }
}

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

// Servo Function
void sortBin(int binPos) {
  servoSeg.write(binPos);        // Rotate to selected bin
  delay(dt);
  servoLid.write(srvoOpen);      // Open lid to drop waste
  delay(dt);
  servoLid.write(srvoClosed);    // Close lid
  delay(dt);
  servoSeg.write(binCenter);     // Rotate to center
}

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

void loop() {
  unsigned long msec = millis();

  //Sensor State
  bool indActive = !digitalRead(indSensorPin);   // Active on LOW
  bool capActive = !digitalRead(capSensorPin);   // Active on HIGH
  bool Moverflow = !digitalRead(overflowMetal);  //Overflow Detection
  bool Noverflow = !digitalRead(overflowNon);    //Overflow Detection

  // -----------------------------------------------------------------------------
  switch (state) {
    case Prompt:  // Waiting for a waste to be inserted
      Serial.println("State Idle");
      Serial.println("               Insert waste");
      lcdDisp("Please Insert A", "Waste Material");
      state = Idle;
      break;
    // -----------------------------------------------------------------------------
    case Idle:  // Waits for waste detection
      // ------ Sorting Functions ------
      if (capActive && !indActive) {                            // Non-Metal Detected
        lcdDisp("Sorting:", "    Non-Metal");
        Serial.println("Waste Inserted - Metal Detected");
        sortBin(binNonMetal);                                   // Segway to non-metal bin
        delay(dt);
        lcdDisp("Press Button", "To Charge");
        Serial.println("state BotReady - Press Button");
        countdown = addTime;
        state = BotReady;
        msec1 = msec;
      } else if (capActive && indActive) {                      // Metal Detected
        lcdDisp("Sorting: ", "      Metal");
        Serial.println("Waste Inserted - Metal Detected");
        sortBin(binMetal);                                      // Segway to metal bin
        delay(dt);
        lcdDisp("Press Button", "To Charge");
        Serial.println("state BotReady - Press Button");
        countdown = addTime;
        state = BotReady;
        msec1 = msec;
      }
      break;
    // -----------------------------------------------------------------------------
    case BotReady: // Ready to start charging
      // ------ Overflow Check ------
      if (Moverflow || Noverflow) {
        lcdDisp(" Trash Bin Full", "Please Continue");
        Serial.println("Trash Bin Full - Sorting Disabled");
        delay(dt);
      } 
      else { 
        // ------ Add Time If New Waste Detected Before Charging ------
        if (capActive && !indActive) {                          // Non-Metal Detected
          lcdDisp("Already Sorted", "Press To Charge");
          Serial.println("Non-Metal Detected - Added Time");
          sortBin(binNonMetal);                                 // Segway to non-metal bin
          countdown = countdown + addTime;
          msec1 = msec;
        } else if (capActive && indActive) {                    // Metal Detected
          lcdDisp("Already Sorted", "Press To Charge");
          Serial.println("Metal Detected - Added Time");
          sortBin(binMetal);                                    // Segway to metal bin
          countdown = countdown + addTime;
          msec1 = msec;
        }
      }
      // ------ Start Button To Start Charging ------
      if (digitalRead(chargeBut) == LOW) {  // Charging starts
        lcdDisp("Charging Started", "Plug In Phone");
        Serial.println("     state Charging");
        Serial.println("Button Pressed - Start Timer");
        delay(dt);
        digitalWrite(chargerRelay, LOW);
        digitalWrite(greenLED, HIGH);
        msec1 = msec;
        state = Charging;
      }
      // ------ Timeout If No Actions Where Made ------
      if (msec - msec1 >= TimeOutInac) {  // Timeout if no actions was made
        msec1 = msec;
        lcdDisp("   Inactivity", "Restart Required");
        Serial.println("state Prompt - Inactivity");
        delay(dtinac);
        state = Prompt;
      }
      break;
    // -----------------------------------------------------------------------------
    case Charging: // Phone charging is active
      // ------ Check if user stops charging manually ------
      if (digitalRead(chargeBut) == LOW) {
        lcdDisp("Charging Stopped", "Unplug Charger");
        Serial.println("Charging Stopped - Stopped by the user");
        digitalWrite(chargerRelay, HIGH);
        digitalWrite(greenLED, LOW);
        delay(dt);
        msec1 = msec;
        state = Wait;
      }
      // ------ Countdown timer logic ------
      if (msec - msec1 >= msecTimer){
        countdown--;
        msec1 = msec;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Timer left:");
        lcd.setCursor(0,1);
        lcd.print(countdown);
      }
      // ------ Stop charging when finished ------
      if (countdown <= timeDone){
        Serial.println("Charging Stopped - Timer Finished");
        digitalWrite(chargerRelay, HIGH);
        digitalWrite(greenLED, LOW);
        delay(dt);
        msec1 = msec;
        state = Wait;
      }
      break;
    // -----------------------------------------------------------------------------
    case Wait:
      // ------ Overflow Warning ------
      if (Moverflow || Noverflow) {
        state = Overflow;
        servoSeg.write(binCenter);
        servoLid.write(srvoClosed);
        lcdDisp(" Trash Bin Full", "  Please Empty");
        Serial.println("state Overflow - Trash Bin Full");
        delay(dt);
      }
      // ------ Charging Compete ------
      else {
        lcdDisp(" Unplug Charger", "   Thank You!");
        Serial.println("state Prompt - Charging Complete");
        delay(dtdone);
        state = Prompt;
      }
      break;
    // -----------------------------------------------------------------------------
    case Overflow:  // Sorting is disabled until emptied
      // ------ Wait For The Bin To Be Emptied ------
      if (!Moverflow && !Noverflow) {
        lcdDisp("Trash Bin Empty", "   Thank You!");
        Serial.println("State Prompt - Trash Bin Emptied");
        delay(dtover);
        state = Prompt;
      }
      break;
  }
}
// -----------------------------------------------------------------------------

That was not what I found, so...

I will wait to verify with your drawing.

i dont get it, can you explain it to me?

btw i want to add minutes seconds like 15:00?

What are the two yellow things?

those are the Inductive(at the top) and Capacitive(at the bottom) Proximity Sensors

From the picture in post #16 it looks like you are using a Uno. You have a lot of string constants such as in Serial.println("State Prompt - Trash Bin Emptied"); which tend to fill the RAM. What does the compiler output tell you about the usage of storage?

this