Looping program Problem.

Hi all I have a question that is doing my nut in >:( .
I have a project on the go that I plan to be automatic bird feeder, which will ideally feed at a set time in the code.
Now I have the code and the hardware set up.
It is set to read the time from an RTC (I think?) and feed at a time which is 9am in the code.
The code has verified all Ok and uploaded to an Arduino Mega.
Now, I have looked through this code and cannot see why it is constantly looping.
The arm I have fashioned for the servo is constantly moving every 10 seconds from its open to closed position.....
I am fairly new to this and this is only my third major project and the most complex to date.

After the looping is sorted I plan to add in an override so I can operate via Bluetooth.
I have the code for this already and tried it and it works Ok.......
Any help would be appreciated.

looping code.txt (2.61 KB)

It looks to me like getTime returns true or false, but you're comparing that to a time.

Your code is a mess. Please use the AutoFormat tool of the IDE to format it correctly. You will probably find out then that the two functions getTime() and BirdsToBeFed() got mixed up and the later returns it's result for the former. Even worse the constants that are compared are never set, so the result is always false and the two times are always 0 so the if statements always match and OpenFeeder() and CloseFeeder() are always called. The 10 seconds result from the delay() inside these two functions.

Thanks I will give that a go... Im Fairly new to coding so I am still trying to get to grips with it....

I have tried the auto formatting as suggested and I am still getting the software loop..... ::slight_smile:

AWOL:
It looks to me like getTime returns true or false, but you're comparing that to a time.

Could you explain this Further AWOL?

SpookyFlash:
I have tried the auto formatting as suggested and I am still getting the software loop..... ::slight_smile:

Auto formatting just makes the code more readable. It doesn't change the content.
Did you not read through it after auto-formatting it?

Post your re-formatted code so we can all see it - use code tags (the scroll with <> on top)

so it looks like this

...R

Hi Robin .... Yes I have looked through it after auto-formatting and I am still at a loss... :frowning:

#include <Servo.h>
#include <Wire.h>
const byte DS1307_CTRL_ID = 0x68; // address of the DS1307 real-time clock
const byte constNumberOfFields = 6; // the number of fields (bytes) to request from the RTC
const int constServoSignalPin = 9;  // Servo connected to Digital 9
const int constTimeToFeed_min = 9*60;  // 9:00 am
const int constTimeToNot_min = 8*60 + 30;  // 8:30AM
int Second ;
int Minute;
int Hour;
int Day;
int Month;
int Year;
int currentTime;
int timeToClose;
int timeToFeed;
int Time
Servo myservo;  // create servo object to control a servo
// variable to store the initial servo position
void setup()
{
  Serial.begin(9600);
  Wire.begin();
}
// Convert Binary Coded Decimal (BCD) to Decimal
byte bcd2dec(byte num){
  return ((num/16 * 10) + (num % 16));
}
int getTime()
{
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.write((uint8_t)0x00);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_CTRL_ID, constNumberOfFields); 
  Second = bcd2dec(Wire.read() );  // (0-59)
  Minute = bcd2dec(Wire.read() );  // (0-59)
  Hour   = bcd2dec(Wire.read() );  //assumes 24hr clock (0-23)
  Day    = bcd2dec(Wire.read() );  // (1-31)
  Month  = bcd2dec(Wire.read() );  // (1-12)
  Year   = bcd2dec(Wire.read() );
  Year   = Year + 2000; // RTC year 0 is year 2000
  bool BirdsToBeFed(int time);
  if (Time < timeToFeed && Time > timeToClose)
    return true;
  else
    return false;
}
void OpenFeeder(){
  myservo.attach(constServoSignalPin);  // attaches the servo on pin 9 to the servo object
  myservo.write(57);    // tell servo to go to position in variable 'angle'
  delay(10000);                       // delay in ms 
  myservo.detach(); 
}
void CloseFeeder(){
  myservo.attach(constServoSignalPin);  // attaches the servo on pin 9 to the servo object
  myservo.write(28);    // tell servo to go to position in variable 'angle'
  delay(10000);                       // waits 10 seconds between servo movement  
  myservo.detach();
}
// utility function for clock 
void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
void digitalClockDisplay(){// digital clock display of the time
  Serial.print(Hour);
  printDigits(Minute);
  printDigits(Second);
  Serial.print(" ");
  Serial.print(Day);
  Serial.print(" ");
  Serial.print(Month);
  Serial.print(" ");
  Serial.print(Year);
  Serial.println();
}
void loop()
{
  currentTime = getTime();   //if (BirdShoudlBeFed)
  if (currentTime == timeToClose)
    CloseFeeder();
  if (currentTime == timeToFeed)
    OpenFeeder();
  digitalClockDisplay();
}

So now you can see that currentTime will be false (zero) because Time is zero, and timeToClose and timeToFeed are also zero.
You've got a function prototype for birdsToBeFed in getTime that isn't doing anything useful.

I have removed the function prototype :slight_smile: I didn't realise that would be a problem.
Still have a loop though..... I will keep looking at it..

It wasn't a problem, but it was probably confusing.

When the clock runs, what output do you see from the call to digitalClockDisplay()?

econjack:
When the clock runs, what output do you see from the call to digitalClockDisplay()?

I see the current time hh:mm:ss and current date updated every second...

Why are you attaching and detaching the servo each time the functions are called ? Attach it once in setup() and leave it attached.

How is the servo powered ?

UKHeliBob:
Why are you attaching and detaching the servo each time the functions are called ? Attach it once in setup() and leave it attached.

How is the servo powered ?

I plan to power it by battery as it has to be mobile....
So enabling it each time saves battery power I was thinking instead of having it permanently powered on....

I am no longer looping now as I made some modifications to the code and it stopped.
I ma now unsure if I am getting any useful times to judge whether to feed or not ???
I changed the feeding time to test it and it didn't cycle at all.....

#include <Servo.h>
#include <Wire.h>
const byte DS1307_CTRL_ID = 0x68; // address of the DS1307 real-time clock
const byte constNumberOfFields = 6; // the number of fields (bytes) to request from the RTC
const int constServoSignalPin = 9;  // Servo connected to Digital 9
const int constTimeToFeed = 21*60 + 02;  // 9:00 am
const int constTimeToNot = 8*60 + 30;  // 8:30AM
int Second;
int Minute;
int Hour;
int Day;
int Month;
int Year;
int currentTime;
int Time;
Servo myservo;  // create servo object to control a servo
// variable to store the initial servo position
void setup()
{
  Serial.begin(9600);
  Wire.begin();
}
// Convert Binary Coded Decimal (BCD) to Decimal
byte bcd2dec(byte num){
  return ((num/16 * 10) + (num % 16));
}
int getTime(){
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.write((uint8_t)0x00);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_CTRL_ID, constNumberOfFields); 
  Second = bcd2dec(Wire.read() );  // (0-59)
  Minute = bcd2dec(Wire.read() );  // (0-59)
  Hour   = bcd2dec(Wire.read() );  //assumes 24hr clock (0-23)
  Day    = bcd2dec(Wire.read() );  // (1-31)
  Month  = bcd2dec(Wire.read() );  // (1-12)
  Year   = bcd2dec(Wire.read() );
  Year   = Year + 2000; // RTC year 0 is year 2000
  if (Time == constTimeToFeed && Time < constTimeToNot)
    OpenFeeder;
  else
    CloseFeeder;
}
void OpenFeeder(){
  myservo.attach(constServoSignalPin);  // attaches the servo on pin 9 to the servo object
  myservo.write(57);    // tell servo to go to position in variable 'angle'
  delay(10000);                       // delay in ms 
  myservo.detach(); 
}
void CloseFeeder(){
  myservo.attach(constServoSignalPin);  // attaches the servo on pin 9 to the servo object
  myservo.write(28);    // tell servo to go to position in variable 'angle'
  delay(10000);                       // waits 10 seconds between servo movement  
  myservo.detach();
}
// utility function for clock 
void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
void digitalClockDisplay(){// digital clock display of the time
  Serial.print(Hour);
  printDigits(Minute);
  printDigits(Second);
  Serial.print(" ");
  Serial.print(Day);
  Serial.print(" ");
  Serial.print(Month);
  Serial.print(" ");
  Serial.print(Year);
  Serial.println();
}
void loop()
{
  currentTime = getTime();   //if (BirdShoudlBeFed)
  if (currentTime == constTimeToNot)
    CloseFeeder();
  if (currentTime == constTimeToFeed)
    OpenFeeder();
  digitalClockDisplay();
}

I plan to power it by battery as it has to be mobile....
So enabling it each time saves battery power I was thinking instead of having it permanently powered on....

Have you tested whether the servo draws less idle current when not attached than when it is attached ?

Right, I have taken on board what people have been saying, and have binned some of the code that I feel was probably causing a problem.
I have binned the date month and year as it is not essential at the moment.
and the Time constant which was doing nothing i feel....
I have also binned the time not to feed and instead put in a servo sweep lasting 10 seconds to feed at a set time (I think).
I have also set the servo to start at 57 degrees as this is where the hole is to take in the food.....
It has made the code easier to read as well I think.... but I have yet to test it views would be appreciated on what I am doing wrong as it will help me learn :slight_smile:

#include <Servo.h>
#include <Wire.h>
const byte DS1307_CTRL_ID = 0x68; // address of the DS1307 real-time clock
const byte constNumberOfFields = 3; // the number of fields (bytes) to request from the RTC
const int constServoSignalPin = 9;  // Servo connected to Digital 9
const int constTimeToFeed = 9*60;  // 9:00 am
int Second;
int Minute;
int Hour;
int currentTime;
Servo myservo;  // create servo object to control a servo
int pos = 57;// variable to store the initial servo position
void setup()
{Serial.begin(9600);
  Wire.begin();}
  
byte bcd2dec(byte num){
  return ((num/16 * 10) + (num % 16));// Convert Binary Coded Decimal (BCD) to Decimal
  }
int getTime(){
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.write((uint8_t)0x00);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_CTRL_ID, constNumberOfFields); 
  Second = bcd2dec(Wire.read() );  // (0-59)
  Minute = bcd2dec(Wire.read() );  // (0-59)
  Hour   = bcd2dec(Wire.read() );  //assumes 24hr clock (0-23)
  }
int OpenFeeder(){
  myservo.attach(constServoSignalPin);  // attaches the servo on pin 9 to the servo object
  for (pos = 57; pos <=28; pos+=1)
  myservo.write(pos);    // tell servo to go to position in variable 'angle'
  delay(5000);
 for (pos = 28; pos >=57; pos+=1)
  myservo.write(pos);    // tell servo to go to position in variable 'angle'
  delay(5000);     // delay in ms 
  myservo.detach(); }

void printDigits(int digits)// utility function for clock 
{Serial.print(":");
 if(digits < 10)
 Serial.print('0');
 Serial.print(digits);}
 
void digitalClockDisplay(){// digital clock display of the time
  Serial.print(Hour);
  printDigits(Minute);
  printDigits(Second);
  Serial.println();}

void loop()
{currentTime = getTime();   //if (BirdShoudlBeFed)
   if (currentTime == constTimeToFeed)
    OpenFeeder();
  digitalClockDisplay();}

Now getTime doesn't return anything

Hi Awol, So what am I doing wrong ?