Remembering Last State (Analog Input)

I am making window blinds that open/shut depending whether it is light or dark. I have everything connected and working the problem is the code checks every 1 second the light, which it needs to do but in doing this it turns the servo again.

The way I want it to work is the servo will turn if the input is <400 and the next time it will turn will only be if the input is >400. Is there a way of telling the Arduino to look at the last input and decide whether it is less than/ more than 400?


#include <Servo.h>

Servo servo;

int photocellPin = 0; // LDR connected to pin 0
int photocellReading; // Analog reading from resistor

void setup(void) {
servo.attach(10);
Serial.begin(9600);
}

void loop(void) {

photocellReading = analogRead(photocellPin);

Serial.print("Analog reading = ");
Serial.print(photocellReading); // Analog Reading from LDR

// IF statement determaining whether to OPEN/SHUT
if (photocellReading < 400) {
servo.write(110); // 110 makes the servo turn one way.
delay(3000); // Servo will turn this way for 3 seconds
servo.write(90); // 90 stops the servo
} else {
servo.write(50); // 50 makes the servo turn the other way.
delay(3000); // Servo will turn this way for 3 seconds.
servo.write(90); // 90 stops the servo
}
delay(1000);
}


Any ideas?

Save the last reading in a variable "lastState" updated each cycle, then if the value is the same (or the absolute value of the difference of the current and the last values is less than some threshold) then do nothing.

Thanks for the reply, I am not very good at the Processing side of things mostly just bits n bobs of code. Iv gave it a go, I just dont know what the language is for “Do Nothing”… Is this on the right lines:


#include <Servo.h>

Servo servo;

int photocellPin = 0; // LDR connected to pin 0
int photocellReading; // Analog reading from resistor
int lastState = (photocellReading) // Last State

void setup(void) {
servo.attach(10);
Serial.begin(9600);
}

void loop(void) {

photocellReading = analogRead(photocellPin);

Serial.print("Analog reading = ");
Serial.print(photocellReading); // Analog Reading from LDR

** // IF statement determaining lastState**
** if (lastState <= photocellReading)**

// IF statement determaining whether to OPEN/SHUT
if (photocellReading < 400) {
servo.write(110); // 110 makes the servo turn one way.
delay(3000); // Servo will turn this way for 3 seconds
servo.write(90); // 90 stops the servo
} else {
servo.write(50); // 50 makes the servo turn the other way.
delay(3000); // Servo will turn this way for 3 seconds.
servo.write(90); // 90 stops the servo
}
delay(1000);
}

I am not very good at the Processing side of things

That's OK, neither am I, but luckily, this is Wiring!

int lastState = (photocellReading)

Doesn't need parentheses, does need a semicolon.
"photocellreading" is initialised with a value of zero, since you did't specify anything else.

You didn't assign anything to "lastState" in "loop", so it will always be zero.

#include <Servo.h>

Servo servo;

int photocellPin = 0; // LDR connected to pin 0
int photocellReading; // Analog reading from resistor
int lastState = photocellReading; // Last State

void setup(void) {
servo.attach(10);
Serial.begin(9600);
}

void loop(void) {

photocellReading = analogRead(photocellPin);

Serial.print("Analog reading = ");
Serial.print(photocellReading); // Analog Reading from LDR

// IF statement determaining lastState
if (lastState <= photocellReading)
{
//Do Nothing
}

// IF statement determaining whether to OPEN/SHUT
if (photocellReading < 400) {
servo.write(110); // 110 makes the servo turn one way.
delay(3000); // Servo will turn this way for 3 seconds
servo.write(90); // 90 stops the servo
} else {
servo.write(50); // 50 makes the servo turn the other way.
delay(3000); // Servo will turn this way for 3 seconds.
servo.write(90); // 90 stops the servo
}
delay(1000);
}


Thanks,

You didn’t assign anything to “lastState” in “loop”, so it will always be zero.

I want the Arduino to assign a value to lastState, sorry if this is a pain.

I want the Arduino to assign a value to lastState,

It will do that, if you tell it to, just like you’ve told it to assign values to your other variables.

(Can you please use the Code (#) button in the editor when posting code?)

#include <Servo.h> 

Servo servo; 

int photocellPin = 0;     // LDR connected to pin 0
int photocellReading;     // Analog reading from resistor
int lastState = photocellReading;     // Last State



void setup(void) {
  servo.attach(10); 
  Serial.begin(9600);   
}

  
void loop(void) {
  
  photocellReading = analogRead(photocellPin); 
[b]  lastState = (photocellReading); [/b]
  

  Serial.print("Analog reading = ");
  Serial.print(photocellReading);     // Analog Reading from LDR
[b]  Serial.print(lastState);[/b]
  
   // IF statement determaining lastState
   if (lastState <= photocellReading)
      {
        //Do Nothing
      }
   
  // IF statement determaining whether to OPEN/SHUT
  if (photocellReading < 400) {
      servo.write(110); // 110 makes the servo turn one way.
      delay(3000); // Servo will turn this way for 3 seconds
      servo.write(90); // 90 stops the servo
  } else { 
      servo.write(50); // 50 makes the servo turn the other way.
      delay(3000); // Servo will turn this way for 3 seconds.
      servo.write(90); // 90 stops the servo
  }
  delay(1000);
}

Still not getting it :frowning:

You add the line after delay(1000);

lastValue = currentValue;

then next time round the loop lastvalue is the last value you had.

#include <Servo.h> 

Servo servo; 

int photocellPin = 0;     // LDR connected to pin 0
int photocellReading;     // Analog reading from resistor
int lastState = photocellReading;     // Last State



void setup(void) {
  servo.attach(10); 
  Serial.begin(9600);   
}

  
void loop(void) {
  
  photocellReading = analogRead(photocellPin); 
  
  Serial.print("Analog reading = ");
  Serial.print(photocellReading);     // Analog Reading from LDR
  
   // IF statement determaining lastState
   if (lastState <= photocellReading)
      {
        //Do Nothing
      }
   
  // IF statement determaining whether to OPEN/SHUT
  if (photocellReading < 400) {
      servo.write(110); // 110 makes the servo turn one way.
      delay(3000); // Servo will turn this way for 3 seconds
      servo.write(90); // 90 stops the servo
  } else { 
      servo.write(50); // 50 makes the servo turn the other way.
      delay(3000); // Servo will turn this way for 3 seconds.
      servo.write(90); // 90 stops the servo
  }
  delay(1000);
[b]  lastState = currentValue;[/b]
}

In function ‘void loop()’:
error: ‘currentValue’ was not declared in this scope

Getting there I think but still not working. I changed lastValue to lastState and I tryed changing currentValue to photocellReading but that didn’t work either.

You haven't declared "currentValue" - Mike was just using it as an example

lastState =  photocellReading;

That code wasn't meant to drop literally into you code it was to tell you what to do!

You give the computer instructions to get it to do your exact bidding.
Think what you are trying to do.

but that didn't work either.

In what way did it not work.
Did it not compile?
Did it not do what you wanted it to do?

The code compiled fine, it doesn't do what I want it to do but. It is just acting like it did before with it rotating every 3 seconds. I checked the LDR and it works fine turning the servo CW and CCW.

You add the line after delay(1000);

lastValue = currentValue;

It sounded like it was literal since I don't have much knowledge of the code that's why I just dropped it in.

Your “do nothing” clause ironically does something - it doesn’t stop the code that you had before from still running.

if (lastState <= photocellReading) {
  //Do Nothing
} else {
  //Do something
}
if (lastState <= photocellReading)

Don’t forget that as it starts to get lighter in the morning that this statement will assure that the blinds stay closed.