Tinkercad LED doesn't stay turned off

I have an IR sensor detecting input from an IR Remote. When a button is pressed, the IR sensor should take the input and turn off the LED. However, after a few seconds of being turned off, it turns back on. It also causes errors in an LCD display connected to the network. What is the problem with my code? Is there something like a memory leak causing the circuit to lag instead? For reference, I have attached my code with comments for better understanding.

#define DECODE_NEC
#define IR_RECEIVE_PIN      2

#define EXCLUDE_UNIVERSAL_PROTOCOLS   // Saves up to 1000 bytes program space.
#define EXCLUDE_EXOTIC_PROTOCOLS      // saves around 650 bytes program space if all other protocols are active
	
#include <Adafruit_LiquidCrystal.h>
#include <IRremote.hpp>
// Initialize the LCD, specifying the I2C address (usually 0x27 or 0x3F)
Adafruit_LiquidCrystal lcd(0);

const int irPin1 = 9; // PIR Sensor 1 Output
const int irPin2 = 10; // PIR Sensor 2 Output
const int ledPin1 = 4;  // LED for Parking Spot 1 
const int ledPin2 = 5;  // LED for Parking Spot 2
const int irReceiverPin = 2; // IR receiver pin

int button = 0;
bool manualControl1 = false; // Flag for manual control of LED 1
bool manualControl2 = false; // Flag for manual control of LED 2

// Map the IR code to the corresponding remote button.
int mapCodeToButton(unsigned long code) {
  if ((code & 0x0000FFFF) == 0x0000BF00) {
    code >>= 16;
    if (((code >> 8) ^ (code & 0x00FF)) == 0x00FF) {
      return code & 0xFF;
    }
  }
  return -1;
}

// Read infrared input from remote
int readInfrared() {
  int result = -1;
  if (IrReceiver.decode()) {
    unsigned long code = IrReceiver.decodedIRData.decodedRawData;
    result = mapCodeToButton(code);
    IrReceiver.resume();
  }
  return result;
}

void setup() {
  Serial.begin(9600);
  pinMode(irPin1, INPUT);
  pinMode(irPin2, INPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  IrReceiver.begin(IR_RECEIVE_PIN,ENABLE_LED_FEEDBACK);
  lcd.begin(16, 2);
  lcd.print("Available Spots:");
}

void loop() {
  Serial.println("again");
  button = readInfrared();
  int availableSpots = 0;
  
  // Read the sensor states
  int sensor1State = digitalRead(irPin1);
  int sensor2State = digitalRead(irPin2);
  
  // Debouncing delay
  delay(50);

  // Check parking spot 1
  if (sensor1State == LOW && !manualControl1) {
    digitalWrite(ledPin1, HIGH); // Parking spot 1 available
    availableSpots++;
  } else if (!manualControl1) {
    digitalWrite(ledPin1, LOW); // Parking spot 1 occupied
  }

  // Check parking spot 2
  if (sensor2State == LOW && !manualControl2) {
    digitalWrite(ledPin2, HIGH); // Parking spot 2 available
    availableSpots++;
  } else if (!manualControl2) {
    digitalWrite(ledPin2, LOW); // Parking spot 2 occupied
  }
  Serial.print("Button value (hex): ");
  Serial.println(button, HEX);
  // Process IR remote control buttons
  if (button != -1) {
    switch (button) {
      case 0: // Example button code for turning off LED 1
      	Serial.println(0);
        manualControl1 = true;
        digitalWrite(ledPin1, LOW);
        break;
      case 1: // Example button code for turning on LED 1
      	Serial.println(1);
        manualControl1 = true;
        digitalWrite(ledPin1, HIGH);
        break;
      case 2: // Example button code for disabling manual control of LED 1
      	Serial.println(2);
        manualControl1 = false;
        break;
      case 6: // Example button code for turning off LED 2
      	Serial.println(3);
        manualControl2 = true;
        digitalWrite(ledPin2, LOW);
        break;
      case 4: // Example button code for turning on LED 2
      	Serial.println(4);
        manualControl2 = true;
        digitalWrite(ledPin2, HIGH);
        break;
      case 5: // Example button code for disabling manual control of LED 2
      	Serial.println(5);
        manualControl2 = false;
        break;
    }
  }
  
  // Display the number of available spots on the LCD
  lcd.setCursor(0, 1);  
  lcd.print("     ");
  lcd.setCursor(0, 1);  
  lcd.print(availableSpots);
  Serial.println(availableSpots);
  
  delay(500);
}

I am grateful to any comments and suggestions. Thank you in advance!

One more thing:

In my Serial Monitor there is a random character that I did not request for, it looks like this:

ΓΏ

Nevermind. I found the solution.

It was because my LCD display was using the <Adafruit_LiquidCrystal.h> package. I made the switch over to <LiquidCrystal_I2C.h>, changed the LCD type from MCP23008 to PCF8574 and all was well again.

Perhaps there was something inherently wrong with the package and its compatibility with the LCD. Nevertheless, this is my improved code for reference:

#define DECODE_NEC
#define IR_RECEIVE_PIN      2

#define EXCLUDE_UNIVERSAL_PROTOCOLS   // Saves up to 1000 bytes program space.
#define EXCLUDE_EXOTIC_PROTOCOLS      // saves around 650 bytes program space if all other protocols are active
	
//#include <Adafruit_LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.hpp>
// Initialize the LCD, specifying the I2C address (usually 0x27 or 0x3F)
//Adafruit_LiquidCrystal lcd(0);
LiquidCrystal_I2C lcd(0x20,16,2);
const int irPin1 = 9; // PIR Sensor 1 Output
const int irPin2 = 10; // PIR Sensor 2 Output
const int ledPin1 = 4;  // LED for Parking Spot 1 
const int ledPin2 = 5;  // LED for Parking Spot 2
const int irReceiverPin = 2; // IR receiver pin

int button = 0;
bool manualControl1 = false; // Flag for manual control of LED 1
bool manualControl2 = false; // Flag for manual control of LED 2

// Map the IR code to the corresponding remote button.
int mapCodeToButton(unsigned long code) {
  if ((code & 0x0000FFFF) == 0x0000BF00) {
    code >>= 16;
    if (((code >> 8) ^ (code & 0x00FF)) == 0x00FF) {
      return code & 0xFF;
    }
  }
  return -1;
}

// Read infrared input from remote
int readInfrared() {
  int result = -1;
  if (IrReceiver.decode()) {
    unsigned long code = IrReceiver.decodedIRData.decodedRawData;
    result = mapCodeToButton(code);
    IrReceiver.resume();
  }
  return result;
}

void setup() {
  Serial.begin(9600);
  pinMode(irPin1, INPUT);
  pinMode(irPin2, INPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  IrReceiver.begin(IR_RECEIVE_PIN,ENABLE_LED_FEEDBACK);
  lcd.init();
  lcd.clear();         
  lcd.backlight();
  lcd.print("Available Spots:");
}

void loop() {
  Serial.println("again");
  button = readInfrared();
  int availableSpots = 0;
  
  // Read the sensor states
  int sensor1State = digitalRead(irPin1);
  int sensor2State = digitalRead(irPin2);
  
  // Debouncing delay
  delay(500);

  // Check parking spot 1
  if (sensor1State == LOW && !manualControl1) {
    digitalWrite(ledPin1, HIGH); // Parking spot 1 available
    availableSpots++;
  } else if (!manualControl1) {
    digitalWrite(ledPin1, LOW); // Parking spot 1 occupied
  }

  // Check parking spot 2
  if (sensor2State == LOW && !manualControl2) {
    digitalWrite(ledPin2, HIGH); // Parking spot 2 available
    availableSpots++;
  } else if (!manualControl2) {
    digitalWrite(ledPin2, LOW); // Parking spot 2 occupied
  }
  Serial.print("Button value (hex): ");
  Serial.println(button, HEX);
  // Process IR remote control buttons
  if (button != -1) {
    switch (button) {
      case 0: // Example button code for turning off LED 1
      	Serial.println(0);
        manualControl1 = true;
        digitalWrite(ledPin1, LOW);
        break;
      case 1: // Example button code for turning on LED 1
      	Serial.println(1);
        manualControl1 = false;
        digitalWrite(ledPin1, HIGH);
        break;
      case 2: // Example button code for disabling manual control of LED 1
      	Serial.println(2);
        manualControl1 = false;
        break;
      case 4: // Example button code for turning off LED 2
      	Serial.println(3);
        manualControl2 = true;
        digitalWrite(ledPin2, LOW);
        break;
      case 5: // Example button code for turning on LED 2
      	Serial.println(4);
        manualControl2 = false;
        digitalWrite(ledPin2, HIGH);
        break;
      case 6: // Example button code for disabling manual control of LED 2
      	Serial.println(5);
        manualControl2 = false;
        break;
    }
  }
  
  // Display the number of available spots on the LCD
  lcd.setCursor(0, 1);  
  lcd.print("     ");
  lcd.setCursor(0, 1);  
  lcd.print(availableSpots);
  Serial.println(availableSpots);
  
  delay(500);
}

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