Need help in final steps

So I have most things up and running. That is three rfid readers that activate servos for a period of time and a rtc that controls another servo on time intervals. I tested them both independently and they work fine but when I put them together they loop just stops running after about a minute. I’m sure it has something to do with my rtc code but I’m kind of rushing and I have in a few minutes so I can’t mess with it too much atm. I tested the rtc by the minute but I switched it to what I’m actually going to be using if for(8 hour increments) in my code.

/* MOSI: Pin 11 / ICSP-4
 * MISO: Pin 12 / ICSP-1
 * SCK : Pin 13 / ICSP-3
 * SS : Pin 4,8,7 (Configurable)
 * RST : Pin 9 (Configurable)
 */
                               
#include <SPI.h>
#include <MFRC522.h>
#include <VarSpeedServo.h>
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
                               
#define SS1_PIN 4
#define SS2_PIN 7
#define SS3_PIN 8
#define RST_PIN 9
//#define redLed 7

VarSpeedServo feeder;
VarSpeedServo cover1;
VarSpeedServo cover2;
VarSpeedServo cover3;

MFRC522 readerOne(SS1_PIN, RST_PIN);
MFRC522 readerTwo(SS2_PIN, RST_PIN);
MFRC522 readerThree(SS3_PIN, RST_PIN);

long coverDuration = 2000;
long feedDuration = 1000;
long closeTime1 = 0;
long closeTime2 = 0;
long closeTime3 = 0;
long feedTime = 0;

void setup() {
  //pinMode(redLed, OUTPUT);
  SPI.begin();
  readerOne.PCD_Init();
  readerTwo.PCD_Init();
  readerThree.PCD_Init();
  feeder.attach(10);
  feeder.write(0,255,true);
  cover1.attach(3);
  cover1.write(0,255,true);
  cover2.attach(5);
  cover2.write(0,255,true);
  cover3.attach(6);
  cover3.write(5,255,true);
}
       
  int myCat = 0x03;  
  int readTagOne;
  int readTagTwo;
  int readTagThree; 
  
void loop() { 
  tmElements_t tm;    
  RTC.read(tm);
  
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillisF = millis();
  
  if (tm.Hour == 0 || tm.Hour == 8 || tm.Hour == 16){
    if (tm.Minute == 0){
      if (tm.Second == 0){
    feeder.write(180,127,false);
    feedTime = currentMillisF;
      }
    }
  }
  if (currentMillisF - feedTime > feedDuration) {  
    feeder.write(0,127,true);
  }
     
  if (readerOne.PICC_IsNewCardPresent()){
     readerOne.PICC_ReadCardSerial();
     readTagOne = (readerOne.uid.uidByte[0]);  
        if(readTagOne == myCat){
            cover1.write(160,255,false);
            closeTime1 = currentMillis1;            
        }  
  }   

  if(currentMillis1 - closeTime1 > coverDuration) {
    cover1.write(0,255,true);
  }  
      
  if (readerTwo.PICC_IsNewCardPresent()){
     readerTwo.PICC_ReadCardSerial();  
       readTagTwo = (readerTwo.uid.uidByte[0]);
        if(readTagTwo == myCat){
          cover2.write(140,255,true);
          closeTime2 = currentMillis2;
        }
  } 
 
   if(currentMillis2 - closeTime2 > coverDuration) {
     cover2.write(0,255,true);
   } 
  
      
   if (readerThree.PICC_IsNewCardPresent()){
     readerThree.PICC_ReadCardSerial(); 
       readTagThree = (readerThree.uid.uidByte[0]); 
        if(readTagThree == myCat){
          cover3.write(160,255,true);
          closeTime3 = currentMillis3;
        }
   }
   
   if(currentMillis3 - closeTime3 > coverDuration) {
     cover3.write(0,255,true);
   }   
}

I would appreciate any help.

I’m still quite new, so it won’t surprise me if it’s something ridiculous.

Thanks

I can't really work out what your code is trying to do, but this is unnecessary and confusing

unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillisF = millis();

In theory (but maybe not in practice) they all have the same value and you should just use a single variable (perhaps currentMillis) for everything.

It also seems that when you have statements like if (currentMillisF - feedTime > feedDuration) { you don't have any subsequent statements to update feedTime for a future test.

Can you explain how your code is supposed to work?

...R

Okay. Every 8 hours, a servo turns, dropping food. That food has selective access via rfid. If a cat who isn't allowed to eat that specific food tries, a servo covers the food with a cover on a servo.

It all works separately, and I've only tried it together once, but here's my logic.

  tmElements_t tm;    
  RTC.read(tm);
  
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillisF = millis();

read time and define four separate currentmillis because, if two servos are triggered with overlapping time, I don't want things to get screwed up. for example. If a cat activates a servo for 3 second and I use a generic currentmillis, and during that 3 second wait the feeder servo activates, also using the generic currentmillis, things might get all weird.

 if (tm.Hour == 0 || tm.Hour == 8 || tm.Hour == 16){
    if (tm.Minute == 0){
      if (tm.Second == 0){
    feeder.write(180,127,false);
    feedTime = currentMillisF;
      }
    }
  }
  if (currentMillisF - feedTime > feedDuration) {  
    feeder.write(0,127,true);
  }

basically,
If the hour is 12am. 8am or 4pm
then check minute
if minute is 0
then check second
if second is 0 then feed
define the time that feeding started
if (current time) - (the time that the feeding started) > previously defined interval for the feeding procedure.
then turn the servo back

if (readerOne.PICC_IsNewCardPresent()){
     readerOne.PICC_ReadCardSerial();
     readTagOne = (readerOne.uid.uidByte[0]);  
        if(readTagOne == myCat){
            cover1.write(160,255,false);
            closeTime1 = currentMillis1;            
        }  
  }   

  if(currentMillis1 - closeTime1 > coverDuration) {
    cover1.write(0,255,true);
  }

I have three separate ones like these.
if theres a card present
read the card
define uid
if uid = whatever uid I want to deny food to
move servo
define time that servo was moved
if (current time)-(time servo was moved) > defined duration for denial
then move servo back

to address your specific questions/issues

1.I kind of already went over this but I don't want overlapping delays to get the currentmillis that it is using confused. It seem to me that they must be different so the delays use the correct times

  1. I'm not sure why I would need subsequent statements. The time of completion for feeding or food denial is irrelevant for my uses. I define feedTime just as the feeding process starts and it's only necessary to know the start time so the atmega can know when to turn the servo back.

Why ypur are not using RTC here, Instead of miilis()

Because if use RTC it will give exact time.

  1. do you think using mills() can you achieve condtion minute=sec=0 condition as in algorithm.
    its better to covert all things to sec or minute, then if

tercelkisor:
define four separate currentmillis because, if two servos are triggered with overlapping time, I don't want things to get screwed up. for example. If a cat activates a servo for 3 second and I use a generic currentmillis, and during that 3 second wait the feeder servo activates, also using the generic currentmillis, things might get all weird.

It won't. How could it. What does it matter whether you get the number 12345 from box A, box B or box C?
Just use a single currentMillis variable

  1. I'm not sure why I would need subsequent statements. The time of completion for feeding or food denial is irrelevant for my uses. I define feedTime just as the feeding process starts and it's only necessary to know the start time so the atmega can know when to turn the servo back.

I think you are correct with this. I had been wondering how a repeat would start - but I guess that won't happen for 4 hours (or whatever).

Back to your original question. What do you mean by the "loop just stops running after about a minute". How do you know - what are the symptoms?

...R

When you say "here," I assume you're talking about my use of millis() at all. I guess I'm just using it because that's what I had written before I chose to use a rtc. It would probably make sense to use rtc, but All the situations that use millis() aren't really time sensitive. They're just how long the food will be covered, so It doesn't have to be super precise.

The automated feeding, on the other hand, is going to be running constantly for months to years, so I can't have error accumulation and losing time when the power goes out.

  1. I see what you're saying. I agree and I'll try that for simplicity.

Do you have any idea what might be causing the loop to stop?

I did a little testing and can describe the problem a bit more.

When I power up the circuit, I can read tags that turn servos but If I go too long without reading, everything just stops. My 8 hour servo goes seemingly at random and I can keep functionality going if i repeatedly scan the rfid tags.

I'll try converting my time to just seconds and see what that does.

@Robin2, I see what you mean. Thanks. I'll fix that pronto.

basically I just use the rfid controlled servo to test. The servos stop turning when I scan tags.

I just tried commenting out everything that pertains to the rtc and it still does it. Just narrowing it down a bit.

tercelkisor:
The servos stop turning when I scan tags.

Is this what you mean when you say the "loop just stops running after about a minute" ?

Perhaps the RFID reader library and the varspeed servo library are incompatible? (a common Arduino problem). I have never used that library. have you tried the nornal servo library - though that also conflicts with some libraries. There is also a ServoTimer2 library which (as its name suggests) uses a different hardware timer.

If this was my project I would gather all the RFID reading into one function and put all the servo code in another function. That way each part can be tested on its own. This style is illustrated in several things at a time and planning and implementing a program

...R

I think that might have been it. I switched to servo from varspeedservo and It seems to run fine. I don't even need varspeed. I just used it because It was different, and I wanted to learn as much as possible in the project. It's good to know that some libraries are incompatible. Thanks for the help. I'll add the timed servo now and see how it works.

Ok. I can't get it to work with the servo.h either. Could you give me a hint as to how to separate the servo and rfid functions? It seems to me that they are inextricable. I've been looking into the time.h thing, as well as some other options, but I'm not sure which would be best to replace what I have.

edit** sorry. i see your links. I'll check them out

Okay. I’m not having much luck at all. I can get both functions separately but as soon as I put them together things go wonky. I’ve decided to try timeAlarm stuff. I’ve given it a quick attempt but it hasn’t worked. Not sure why. Maybe I haven’t accessed the rtc time or something?

#include <TimeAlarms.h>
#include <Servo.h>
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>

Servo feeder;


long feedDuration = 1000;
long feedTime = 0;

void setup() {
  Wire.begin();
  feeder.attach(10);
  feeder.write(0);
  setSyncProvider(RTC.get);
  
  
Alarm.alarmRepeat(23,33,0, feederOpen);
Alarm.alarmRepeat(23,33,2, feederClose);
}

void loop() {
}

void feederOpen() {
  feeder.write(160);
}

void feederClose() {
  feeder.write(0);
}

I doubt if the TimeAlarm will be any help. It may even make things worse.

Unfortunately you need to study the code in the RFID library to find out what Arduino resources it uses that may be conflicting with the servo library. Two libraries trying to use the same hardware timer is a common problem - which is where ServoTimer2 may help.

I have never used RFID. I wonder is it really necessary to use a library at all?

It is really irritating that there is no standard requirement for library developers to list the resources their library uses.

...R

Robin2:
It is really irritating that there is no standard requirement for library developers to list the resources their library uses

This could be quite an interesting project in it's own right. It shouldn't be too difficult to go through any library, seeking out it's usage of resources. Some of them will be dependent on which arduino you have selected at compile time. This could be quite doable though.

KenF:
This could be quite an interesting project in it’s own right.

That’s very generous of you.

…R

Robin2:
That's very generous of you.

I'll bookmark this page as a reminder. It'll make an interesting exercise for the new year.

KenF:

That's very generous of you.

I'll bookmark this page as a reminder. It'll make an interesting exercise for the new year.

I wasn't being serious ... but it would actually be very useful if you have the time.

...R

did you solve the problem, I think that it's very interesting