Go Down

Topic: Trying to get motor to turn on at specific time (Read 3793 times) previous topic - next topic

mbasile

This works for multiple feedings, but only at times where the hour just turned.. AKA 9 and 6 or 10 and 5... etc. anyway to make it feed at say 10 and 530, or is that just way over my head.....



Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <TimeAlarms.h>
#include <Time.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
int motorPin = 11;
int lastHour = 24;
int lastMinute = 59;
int lastSecond = 59;
bool feedPet = false;
unsigned long feedTime = 0;
unsigned long lastPrintTime = 0;


void setup ()
{
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  Wire.begin();
  RTC.begin();

  if (! RTC.isrunning()) {
    lcd.println("RTC NOT Running!");
    RTC.adjust(DateTime((__DATE__), (__TIME__)));
  }
}


void loop ()
{

  DateTime now = RTC.now();
  int currentHour = now.hour();
  int currentMinute = now.minute();
  int currentSecond = now.second();
  if ((currentHour == 21 || currentHour == 21) && (lastMinute != currentMinute) && (currentMinute == 21 || currentMinute == 22) && (lastSecond != currentSecond) && (currentSecond == 00)) // if the hour just changed to 9:00AM or 6:00PM

  {
    feedTime = millis();
    feedPet = true;
    lastHour = currentHour;
  }
  if (feedPet)
  {
    turnFeeder();
  }
  if (millis() - lastPrintTime > 1000UL)

    // display the date
    lcd.setCursor(0, 0);
  char nowDate[24] = "";
  sprintf(nowDate, "DATE: %02d/%02d/%d", now.month(), now.day(), now.year());
  lcd.print(nowDate);

  // display the time
  lcd.setCursor(0, 1);
  char nowTime[24] = "";
  sprintf(nowTime, "Time: %02d:%02d:%02d", now.hour(), now.minute(), now.second());
  lcd.print(nowTime);
  lastPrintTime = millis(); //<<<<<<you need to reset the timer here (What does this mean???)
}

void turnFeeder(void)
{
  static bool pinState = true;
  if (millis() - feedTime < 2000UL) // 2 second(s)
  {
    if (pinState)

    {
      digitalWrite(motorPin, HIGH);
      pinState = false;
    }
  }

  else
  {
    digitalWrite(motorPin, LOW);
    pinState = true;
    feedPet = false;
  }
}

BulldogLowell

#76
Nov 16, 2015, 11:51 am Last Edit: Nov 16, 2015, 11:54 am by BulldogLowell
This works for multiple feedings, but only at times where the hour just turned.. AKA 9 and 6 or 10 and 5... etc. anyway to make it feed at say 10 and 530, or is that just way over my head.....
Yes, it seems so...

You don't need seconds unless your pet needs to be fed at EXACTLY 17:30:42, so don't go there.

Stop arbitrarily deleting curly braces, they are there for a very important reason, for which you need to learn somehow.

I'm introducing a struct to your little program here, where you will use the struct to contain the Hour and the Minute of your times.  Take a look and see if you understand.

Code: [Select]
struct FeedTime{
  int hour, minute;
};

FeedTime amFeed = {10, 0};  // i.e. 10:00am  // don't do anything silly like use two zeroes for the time here!
FeedTime pmFeed = {17,30};  // i.e. 5:30pm


Code: [Select]
if((currentTime.minute != lastMinute) && (((currentTime.hour == amFeed.hour) && (currentTime.minute == amFeed.minute)) || ((currentTime.hour == pmFeed.hour) && (currentTime.minute == pmFeed.minute))))

While I cannot test this, I would think that it works.  It says in english:

Evaluate the current minute to determine if it just changed.  -> e.g. if(currentTime.minute != lastMinute)
If so, evaluate to determine if it is either the amFeed time or the pmFeed time.
if either of these conditions is so, run the fedPet() function

I hope this gets you there:

Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <TimeAlarms.h>
#include <Time.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
int motorPin = 11;
int lastHour = 24;
int lastMinute = 59;
int lastSecond = 59;
bool feedPet = false;
unsigned long feedTime = 0;
unsigned long lastPrintTime = 0;

struct FeedTime{
  int hour, minute;
};

FeedTime amFeed = {10, 0};  // i.e. 10:00am  // don't do anything silly like use two zeroes for the time here!
FeedTime pmFeed = {17,30};  // i.e. 5:30pm

void setup ()
{
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning())
  {
    lcd.println("RTC NOT Running!");
    RTC.adjust(DateTime((__DATE__), (__TIME__)));
  }
}

void loop ()
{
  DateTime now = RTC.now();
  FeedTime currentTime;
  currentTime.hour = now.hour();
  currentTime.minute = now.minute();
  if((currentTime.minute != lastMinute) && (((currentTime.hour == amFeed.hour) && (currentTime.minute == amFeed.minute)) || ((currentTime.hour == pmFeed.hour) && (currentTime.minute == pmFeed.minute))))
  {
    feedTime = millis();
    feedPet = true;
    lastHour = currentTime.hour;
  }
  if (feedPet)
  {
    turnFeeder();
  }
  if (millis() - lastPrintTime > 1000UL)
  {
    lcd.setCursor(0, 0);
    char nowDate[24] = "";
    sprintf(nowDate, "DATE: %02d/%02d/%d", now.month(), now.day(), now.year());
    lcd.print(nowDate);
    // display the time
    lcd.setCursor(0, 1);
    char nowTime[24] = "";
    sprintf(nowTime, "Time: %02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.print(nowTime);
    lastPrintTime = millis();
  }
}

void turnFeeder(void)
{
  static bool pinState = true;
  if (millis() - feedTime < 2000UL) // 2 second(s)
  {
    if (pinState)
    {
      digitalWrite(motorPin, HIGH);
      pinState = false;
    }
  }
  else
  {
    digitalWrite(motorPin, LOW);
    pinState = true;
    feedPet = false;
  }
}


I can't test it but you can...

PaulS

Code: [Select]
if ((currentHour == 6 || currentHour == 18) && (lastMinute != currentMinute) && (currentMinute == 30) && (lastSecond != currentSecond) && (currentSecond == 00)) // if the hour just changed to 6:30PM
  if ((currentHour == 10 || currentHour == 10) && (lastMinute != currentMinute) && (currentMinute == 00) && (lastSecond != currentSecond) && (currentSecond == 00)) //if the hour just changed to 10:0AM

The second if statement will be evaluated only if the first is true. You really must live on a strange planet...

Why do you insist on crap like this?
Code: [Select]
(currentHour == 10 || currentHour == 10)
currentHour is either 10 or it isn't. Checking twice is NOT going to change anything.
The art of getting good answers lies in asking good questions.

BulldogLowell

Checking twice is NOT going to change anything.
Leaves me wondering why Santa is so fastidious...

"he's making a list, checking it twice..."

 :o

PaulS

Leaves me wondering why Santa is so fastidious...

"he's making a list, checking it twice..."

 :o
I know where I am on that list...
The art of getting good answers lies in asking good questions.

GrooveFlotilla

Code: [Select]
better !pout !cry
        better watchout
        lpr why
        santa claus < north pole >town

        cat /etc/passwd >list
        ncheck list
        ncheck list
        cat list | grep naughty >nogiftlist
        cat list | grep nice >giftlist
        santa claus < north pole >town

        who | grep sleeping
        who | grep awake
        who | egrep 'bad|good'
        for (goodness sake) {
                be good
                }
Some people are like Slinkies.

Not really good for anything, but they bring a smile to your face when pushed down the stairs.

mbasile

trying to comment out the RTC code where it sets the time because when i unplug the arduino from the USB the time is not kept on the RTC and it picks up where it left off uplugged, when this happens i plug the arduino back into the USB and rerun the code, but it wont sync the time correctly, i usually have to rerun the code on the arduino multiple times before the time resyncs..... anyone else think my RTC is shot?

mbasile

also with the last code bulldog wrote, it has the same problem where it will run for a full minute until the trigger time is no longer, (i.e. set for 12:30 for 2 seconds, it will spin until 12:31:02) seconds has to be incorporated like i did in the last code for it to run right. Currently trying to add seconds to the set time command stuff that bulldog rewrote recently.

BulldogLowell

Currently trying to add seconds to the set time command stuff that bulldog rewrote recently.
YOU DON"T NEED THE SECONDS, so don't waste your time.  Think about it, minutes change only once a minute.

I simply forgot a line of code to set lastMinute... that is why you are testing.  So I incorporated that into this revised code:

Code: [Select]
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
#include <TimeAlarms.h>
#include <Time.h>

RTC_DS1307 RTC;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
int motorPin = 11;
int lastHour = 24;
int lastMinute = 60;

bool feedPet = false;
unsigned long feedTime = 0;
unsigned long lastPrintTime = 0;

struct FeedTime{
  int hour, minute;
};

FeedTime amFeed = {10, 0};  // i.e. 10:00am  // don't do anything silly like use two zeroes for the time here!
FeedTime pmFeed = {17,30};  // i.e. 5:30pm

void setup ()
{
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning())
  {
    lcd.println("RTC NOT Running!");
    RTC.adjust(DateTime((__DATE__), (__TIME__)));
  }
}

void loop ()
{
  DateTime now = RTC.now();
  FeedTime currentTime;
  currentTime.hour = now.hour();
  currentTime.minute = now.minute();
  if((currentTime.minute != lastMinute) && (((currentTime.hour == amFeed.hour) && (currentTime.minute == amFeed.minute)) || ((currentTime.hour == pmFeed.hour) && (currentTime.minute == pmFeed.minute))))
  {
    feedTime = millis();
    feedPet = true;
    // lastHour = currentTime.hour; // <<<<<<<<<<<<<<< I removed this
  }
  lastMinute = currentTime.minute; //<<<<<<<<<<<<< I Forgot This
  if (feedPet)
  {
    turnFeeder();
  }
  if (millis() - lastPrintTime > 1000UL)
  {
    lcd.setCursor(0, 0);
    char nowDate[24] = "";
    sprintf(nowDate, "DATE: %02d/%02d/%d", now.month(), now.day(), now.year());
    lcd.print(nowDate);
    // display the time
    lcd.setCursor(0, 1);
    char nowTime[24] = "";
    sprintf(nowTime, "Time: %02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.print(nowTime);
    lastPrintTime = millis();
  }
}

void turnFeeder(void)
{
  static bool pinState = true;
  if (millis() - feedTime < 2000UL) // 2 second(s)
  {
    if (pinState)
    {
      digitalWrite(motorPin, HIGH);
      pinState = false;
    }
  }
  else
  {
    digitalWrite(motorPin, LOW);
    pinState = true;
    feedPet = false;
  }
}

mbasile

ok, the code seems to be working fine now, the motor is spinning at the correct times and for the correct length of time i set. The only problem i have now is that when i unplug the arduino from USB and plug it back in, the time will go back to when i first ran the program (i.e. if i ran the program at 1:00pm and left it alone until 1:05pm, when i unplug the arduino at 1:05pm and plug it back in within a few seconds, the arduino will revert the time back to 1:00pm) does anyone know why this happens?

BulldogLowell


mbasile

i checked it with my multimeter and the battery itself was running around 4V (bettery is a 3.6V) so it seems alright, however when i tested the batter pin on the rtc board i could only get around 1.2V readings.....

BulldogLowell

i checked it with my multimeter and the battery itself was running around 4V (bettery is a 3.6V) so it seems alright, however when i tested the batter pin on the rtc board i could only get around 1.2V readings.....
Well, maybe post a question on the Hardware section of the forum...

Go Up