Correct LDR usage ?

I'm using LDR's for a single axis solar tracker, and it appears that I need some LDR sensor guidance to one point.

I've been through multiple tutorials that have the resistor wired differently. It seems like just about every other one is doing it differently, and it has seemed at times that the analog pins behave differently from one device to another.

Some tutorials/projects have the resistor wired from analog pin to ground, and some analog pin to 5v.

After working on many different combinations, it appears that analog pin to 5v is returning the most consistent results, with my LDR's returning a lower serial value as light is increased.

Wiring from analog pin to ground, seems to return varying results on different boards, where I have tried nano, nano 33 IOT, and most recently, a new R4 wifi.

Is there a right way to wire this ? This that follows was actually working code on a nano that was wired analog - resistor - ground and that moved a linear actuator, pushing the panel up or down. There is a divider between the LDR's aligned with the sun path.

It was prototype soldering, so I was in the process of rebuilding it, and moving from a base nano to the nano 33 IOT, as I want to be able to save the LDR readings, and add web buttons to manually move the panels from the phone app as well, and after re-soldering, started getting unexpected results.

int sensorValue1;
int sensorValue2;

const int Extend = 9;
const int Retract = 6;

int sensorPin1 = A6;
int sensorPin2 = A3;

int counter = 0;
//int valAverage1 = 0;
//int valAverage2 = 0;
int numAverage = 10;

int threshold = 50;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);

  
}

void loop() {
 
  // Your code here
  //valAverage1 =0;
  //valAverage2 =0;

  for (counter = 0; counter < numAverage; counter++) {
    sensorValue1 = analogRead(sensorPin1);
    sensorValue2 = analogRead(sensorPin2);

    //valAverage1 = valAverage1 + sensorValue1;
    //valAverage2 = valAverage2 + sensorValue2;
  }

  //valAverage1 = valAverage1/numAverage;
  //valAverage2 = valAverage2/numAverage;

  //Serial.print(valAverage1, DEC);
  //Serial.print(", ");
  //Serial.println(valAverage2, DEC);

  if (sensorValue1 > sensorValue2 + threshold)
  {
    digitalWrite(Extend, LOW);
    digitalWrite(Retract, HIGH);
    delay(2000);

  }

  else if (sensorValue2 > sensorValue1 + threshold)
  {
    digitalWrite(Retract, LOW);
    digitalWrite(Extend, HIGH);
    delay(2000);
  }

  else(sensorValue2 + sensorValue1 < 5);
  digitalWrite(Extend, LOW);
  digitalWrite(Retract, HIGH);
  delay(1000);


  Serial.print("sens_1 ");
  Serial.print(analogRead(sensorPin1));
  Serial.println();
  Serial.print("sens_2 ");
  Serial.print(analogRead(sensorPin2));
  Serial.println();
  delay(5000);


}

You want to make a "voltage divider" using a fixed resistor and the LDR ("Light Rependent Resistor.) Since the devices are both resistors, I think you can have the LDR in either position (to Vcc or to Gnd), but you DO need the other resistor as well.

Picking the actual resistor values will depend on the characteristics of the LDR, your light source, and the brightness "region" that you are interested in measuring.

nano 33 IOT

Note that some board have a max voltage LOWER than 5V. Carefully chosen resistors can solve that, but it's probably better to make the voltage divider go between the Vcc (or max analog pin voltage) and Gnd, rather than 5V and GND.

1 Like

I often wire my LDR to ground and to an analog input set to pinMode INPUT_PULLUP. That works fine if the sensitivity is good and saves using an external resistor.

const byte ldrPin = A0;

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

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 200;
   if (millis() - timer >= interval)
   {
      timer = millis();
      int ldrValue = analogRead(ldrPin);
      Serial.print("LDR reading = ");
      Serial.println(ldrValue);
   }
}

image

Ugh, you're going to make me study more, but I need to. Thanks!

1 Like

I have seen other projects using the pinmode pullup method. I was trying to make this ultra simple. I actually don't need it to be exact, although the code above did seem like it was actually tracking. All I really need it to do is around mid-day realize that there is more sun on the one LDR on the other side of the divider and then move the panel from the morning sun orientation. Any more than that has limited returns.

Hello murphyslaww69

Use a local clock to follow the sun simply.

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

1 Like

I don't know how to make it any simpler.

Sorry, wasn't asking, just explaining the very basic code. It's just set to run the actuator for 2 seconds, until the next reading. This has seemed to work acceptably when the LDR to LDR threshold is adjusted.

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