Triggering a servo motor using RTC module

Thread Starter

Gabriel Cruz

Joined Oct 17, 2017
9
Hey guys, I have this project that turns on the servo motor at a specific time using the RTC module.

Here's my code
C:
#include <DS3231.h>
#include <Servo.h>

Servo myservo;

int pos = 0;
int Relay = 9;

DS3231  rtc(SDA, SCL);
Time t;

const int OnHour = 1;
const int OnMin = 15;
const int OffHour = 1;
const int OffMin = 16;

void setup() {
  Serial.begin(9600);
  rtc.begin();
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
  myservo.attach(9);
}

void loop() {

  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);
  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
   {
  for (pos = 0; pos <= 60; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(10);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 60; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(10);                       // waits 15ms for the servo to reach the position
  }
}

}
I tried uploading this program to my mega but what happens is that the RTC code is being bypassed and the servo starts moving.
I'm not really good at programming. I hope anyone could help me :)

P.S. I tried using an i2c scanner, it did scanned the module

Mod edit: added code tags
 
Last edited:
Hello and welcome to AAC.

Let me try and help. I am going to assume that both your RTC and servo code will work. These should be tested as part of the steps of writing the program.

Given that they do, I can see several problems in your program.

First off, these code lines will be executed every time through loop(). That is why you think that "the RTC code is being bypassed and the servo starts moving". It's not that the RTC code is being bypassed, it is that your servo movement code is being executed every time through the loop();
Also, you have a set of unnecessary brackets.
C:
{
  for (pos = 0; pos <= 60; pos += 1) { // goes from 0 degrees to 180 degrees
  // in steps of 1 degree
  myservo.write(pos); // tell servo to go to position in variable 'pos'
  delay(10); // waits 15ms for the servo to reach the position
  }
  for (pos = 60; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
  myservo.write(pos); // tell servo to go to position in variable 'pos'
  delay(10); // waits 15ms for the servo to reach the position
  }
  }
So, let's fix those two parts by putting the servo code in the for-next loops inside the if-then...BUT there is more...
C:
  if (t.hour == OnHour && t.min == OnMin) {
  digitalWrite(Relay, HIGH);
  Serial.println("LIGHT ON");
  for (pos = 0; pos <= 60; pos += 1) { // goes from 0 degrees to 180 degrees
  // in steps of 1 degree
  myservo.write(pos); // tell servo to go to position in variable 'pos'
  delay(10); // waits 15ms for the servo to reach the position
  }
  }

  else if (t.hour == OffHour && t.min == OffMin) {
  digitalWrite(Relay, LOW);
  Serial.println("LIGHT OFF");
  for (pos = 60; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
  myservo.write(pos); // tell servo to go to position in variable 'pos'
  delay(10); // waits 15ms for the servo to reach the position
  }
  }
Now, the problem is that when the times are hit, the servo code will be executed for most of a whole minute, so let's make a new variable, light that is 1 if the light is on and 0 if the light is off.

If we hit an alarm time to turn the light on, we only do so if the light is off - and when we turn the light on and operate the servo, we set light=1. Now we will only operate the servo once per minute of alarm.

Change the light off part in an anlagous way.

We also need to start loop() with light set correctly - so let's make light=0 in setup() since you don't have the relay starting in loop() as energized.

Now we have:
C:
#include <DS3231.h>
#include <Servo.h>

Servo myservo;

int pos = 0;
int Relay = 9;

DS3231 rtc(SDA, SCL);
Time t;

const int OnHour = 1;
const int OnMin = 15;
const int OffHour = 1;
const int OffMin = 16;

bool light;

void setup() {
  Serial.begin(9600);
  rtc.begin();
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
  myservo.attach(9);
  light=0;
}

void loop() {

  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);
  if (t.hour == OnHour && t.min == OnMin&& light=0) {
  digitalWrite(Relay, HIGH);
  Serial.println("LIGHT ON");
  for (pos = 0; pos <= 60; pos += 1) { // goes from 0 degrees to 180 degrees
  // in steps of 1 degree
  myservo.write(pos); // tell servo to go to position in variable 'pos'
  delay(10); // waits 15ms for the servo to reach the position
  }
  light=1;
  }

  else if (t.hour == OffHour && t.min == OffMin&& light=1) {
  digitalWrite(Relay, LOW);
  Serial.println("LIGHT OFF");
  for (pos = 60; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
  myservo.write(pos); // tell servo to go to position in variable 'pos'
  delay(10); // waits 15ms for the servo to reach the position
  }
  light=0;
  }
}
You also need to make certain that the servo is in position 0 degrees at the start of the program.

I have not tested this out and am really just browsing your code. Also, I am sure that there are many ways to go about this. Regardless, hopefully, this gives you some idea about changing your code so that it does what you want. That is, if you can understand why I am making changes.
 
Last edited:

Sa Yem Khan

Joined Feb 15, 2016
2
Hey guys, I have this project that turns on the servo motor at a specific time using the RTC module.

Here's my code
#include <DS3231.h>
#include <Servo.h>

Servo myservo;

int pos = 0;
int Relay = 9;

DS3231 rtc(SDA, SCL);
Time t;

const int OnHour = 1;
const int OnMin = 15;
const int OffHour = 1;
const int OffMin = 16;

void setup() {
Serial.begin(9600);
rtc.begin();
pinMode(Relay, OUTPUT);
digitalWrite(Relay, LOW);
myservo.attach(9);
}

void loop() {

t = rtc.getTime();
Serial.print(t.hour);
Serial.print(" hour(s), ");
Serial.print(t.min);
Serial.print(" minute(s)");
Serial.println(" ");
delay (1000);
if(t.hour == OnHour && t.min == OnMin){
digitalWrite(Relay,HIGH);
Serial.println("LIGHT ON");
}

else if(t.hour == OffHour && t.min == OffMin){
digitalWrite(Relay,LOW);
Serial.println("LIGHT OFF");
}
{
for (pos = 0; pos <= 60; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
for (pos = 60; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
}

}

I tried uploading this program to my mega but what happens is that the RTC code is being bypassed and the servo starts moving.
I'm not really good at programming. I hope anyone could help me :)

P.S. I tried using an i2c scanner, it did scanned the module
 

Sa Yem Khan

Joined Feb 15, 2016
2
Uploading your code , the servo is running always .
Can u help me to tun the servo in a fixed time and after a certain period it will be off?


please don't mind about my English , i am not good at all.
 
Uploading your code , the servo is running always .
Can u help me to tun the servo in a fixed time and after a certain period it will be off?


please don't mind about my English , i am not good at all.
change if (t.hour == OnHour && t.min == OnMin&& light=0) to if (t.hour == OnHour && t.min == OnMin&& light==0)
else if (t.hour == OffHour && t.min == OffMin&& light==1)

see what difference that makes...and include your entire program in your post.
 
Top