Hi there guys
Im bulding an automatic cat feeder for my pets.
Everyday I try to add more complexity and features altough the only thing it has to do is open or closed the lid using a servo, based on time schedules with help of a RTC 1302.
However, I´ve put a LED in combination with a LDR to act as a low food sensor level.
Now I would like to trigger an event when the LDR output goes HIGH, so that it can store the date in which the food level went low. So in between refills I can check the amount of days each load lasted.
I came up with two ways:
Use the eeprom of arduino, so if there is a power loss (or reset, we do use the reset button to "manually" override the lid) the date is kept, I think that 100.000 cycles to the eeprom considering the trigger event will be 1 a week or 3 times a month is good enough.
The other way, and I think is more complex, is to use the 32 bytes (I can be wrong) of memory in the DS1302 chip.
I would gladly need help with both codings.
Here is the sketch
Milo
, Daisy
and Obdulio
are thankful (sorry, no cat emoticon)
https://drive.google.com/open?id=13NTEIbwn6ZsEwpIld2JymUq2lG0u0yTt
Comments are in spanish, sorry
Also feel free to use the code to build your own, if you want pictures of the rig I can send them. And also feel free to tweak the code if you have any suggestions, or improvements.
Regards
That 100,000 cycles is for each address in eeprom, if you increment each write it would take you years just to fill up the entire eeprom once, then you still have 99,999 certified times you can repeat it.
Next hack might be to add additional LDR or two and have the arduino estimate how many days of food are left.
Maybe just flash sequence for remaining days per flash then a pause and repeat.
Once a week a write to eeprom
100,000 cycles / 52 is approx 1900 years before one 'location' is worn out.
I suggest that you just store in eeprom using eeprom.put and read from eeprom using eeprom.get.
What I would do: Write a sketch to store the current date-time in the first four bytes of EEPROM and zeroes the remaining 1020 bytes.
In your working sketch, read the start date-time from EEPROM. When you detect a refill: Calculate 'n', the days since date zero and set bit 32+'n' in EEPROM.
The ATmega328p has 1024 bytes of EEPROM so after saving the date-time you have 8160 bits. That's one bit per day for 22.34 YEARS. Since the refills average once a week, most bytes will only have one bit set. A few (roughly one every 64 days) will have two bits set. At that rate you can run for 1.1 million years before you have to worry about wearing out the EEPROM. 
After 22 years you can store the old data and run the initializer sketch again. 
Thanks! To all for the good ideas. I´m learning quite a bit since I started with arduino in March of this year. However EEPROM is still new (and a bit scary) until I tackle it.
Thanks for the input, I shall read some more documentation on the mather and try to come up with a working solution.
Here is a picture of the rig (still in prototype stage, I´m also trying to make a PCB with all the components and switch the NANO for a PRO MINI
Best regards
Slumpert:
That 100,000 cycles is for each address in eeprom, if you increment each write it would take you years just to fill up the entire eeprom once, then you still have 99,999 certified times you can repeat it.
Next hack might be to add additional LDR or two and have the arduino estimate how many days of food are left.
Maybe just flash sequence for remaining days per flash then a pause and repeat.
I was thinking about the viability to add a ultrasonic sensor on the upper lid of the feeder (a pvc pipe) in order to measure the distance to the ground and show the capacity of the container in %.
Would this be feasible? Since I´m putting an ultrasonic sensor in a 5 inches wide pvc pipe? Would this not interfere the signal of the sensor?
Thanks
I came up with this code so far. Now I think the only thing needed is to use EEPROM.get to retrieve the date and then make a (current_date - EEPROM_date) to fetch the calculous
void LowLevel () // Debug
{
Time t = rtc.time ();
level = digitalRead (LDR); //Low level sensor
if (level == false && level! = previous_level) // If it's empty, and before it was full, save date
{
days = t.date;
EEPROM.put (0, days);
previous_level = level; // Update level.
}
else if (level == true && level! = previous_level) // If it's full, and before it was empty, reset counter
{
days = 0;
EEPROM.put (0, days);
previous_level = level; // Update level.
}
}
For now I will use address 0. When I have a working function I shall add the address increment.