Looking for assistance in refining my code

Hello,

Ive been working on a little project trying to add automatic headlights to an older car. I have a light sensor from a newer vehicle sending a signal to arduino to control a relay turning the lights on.
I have everything working however, when the light is at the threshold value it is spamming the relay and making a buzzing noise. I was wondering what I could add to the code to try and make it work better. Thanks!

void setup() {
pinMode(10, OUTPUT);    // sets the digital pin 10 as output relay ground signal

}

void loop() {
int analogPin = analogRead(A1);  // read the input pin
if(analogPin <=390){
  digitalWrite(10,LOW); // sets the digital pin 10 on
}
else{
  (digitalWrite(10,HIGH)); 
}
}

Post the code that you have.

Read about "hysteresis" for a full explanation. It is used in thermostats, light sensors, motor RPM...

For your particular issue, rather than having ON/OFF border on a single value (for example, 50), use a "deadband" that lets the current state remain active even while out-of-bounds. Assuming your current code ON/OFF threshold is "50"... try...

if (light_value > 55) // more light present, turn lights off
  lightOFF();

// if light_value is between 45 and 55... nothing changes the state

if (light_value < 45) // less light present, turn lights on
  lightON();

This shows a deadband of 45 to 55 where the light will stay in the current state until well past the opposite threshold. For example if the light is OFF due to light_value being over 55 and light_value then changed to 50, there is no discrete condition for 50, so the light is neither turned off nor turned on... until it passes the deadband.

1 Like

Add hysteresis.

A LDR demo.

const byte ldrInPin = A0;

int ldrValue;
int ldrThreshold = 500;
int hysteresis = 50;

void setup()
{
   Serial.begin(115200);
   pinMode(ldrInPin, INPUT_PULLUP);
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long lnterval = 250;
   if (millis() - timer >= lnterval)
   {
      timer = millis();
      ldrValue = analogRead(ldrInPin);
      Serial.println(ldrValue);
      if (ldrValue > ldrThreshold + hysteresis)
      {
         Serial.println("It is dark");
      }
      else if (ldrValue < ldrThreshold - hysteresis)
      {
         Serial.println("It is not dark");
      }
   }
}

This is not wrong but against conventions.

Do:
Before setup:

const int ambientLightPin = A0:

In loop:

int ambientLight = analogRead(ambientLightPin);

.

Hello dgarg

Welcome back.

Consider this example using the constrain macro.

//https://forum.arduino.cc/t/looking-for-assistance-in-refining-my-code/1253393
#define ProjectName "automatic headlights "
#define NotesOnRelease "Arduino MEGA tested"

// make names
enum Brightness {Low, High};

// make variables
uint16_t brightness[] {300, 600};
constexpr uint8_t lightSensor {A1};
constexpr uint8_t relayPin {10};

// make application
void setup()
{
  Serial.begin(115200);
  for (uint8_t n = 0; n < 32; n++) Serial.println("");
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
  pinMode(relayPin, OUTPUT);
  delay(2000);
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  (constrain(analogRead(lightSensor), brightness[Low], brightness[High]) == brightness[Low]) ? digitalWrite(relayPin, LOW) : digitalWrite(relayPin, HIGH);
}

Have a nice day and enjoy coding in C++.

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