Go Down

Topic: My Automatic Cat Feeder (Read 7983 times) previous topic - next topic


Here is my first try to use atmega328 in a cat feeder device.
My feeder is supposed to work without AC power and without maintenance long time.
Previously I designed a device without avr controller, just using digital alarm clock and very simple electrical circuit. In that project met several problems.
1. Functionality - That alarm clock has only 2 alarms to set and I needed more to set more feeding times;
2. Power supply - I used batteries (AC power wasn't an option) that may drain suddenly and cause feeder to stop;
3. Stability - some times clock may reset accidentally loosing alarm sets.

I think new project with Arduino board solved these problems.

I designed electrical circuit with charger via solar panel and rechargeable battery, also I used atmega power down mode to save battery power.
Here is my scheme attached.
And here is the code http://code.google.com/p/petfeeder/source/browse/#svn%2Ftrunk%2FCatFeeder_07
I used simple KeyPad and LCD1602.
Device can be programmed to feed up to 15 times per day.
Now it's designed to feed with the same interval but I upgrade this version to able to program any time feeding.
Solar panel also used as day time detector to rerun the schedule (Arduino timer isn't good to be used as permanent timer).

?????? ?????? ?????, ??? ??? - ??????????!


Dec 25, 2011, 06:12 pm Last Edit: Dec 25, 2011, 06:49 pm by kaor Reason: 1
for KeyPad I use only 1 pin, that drove me to write complicated module for KeyPad, preventing bouncing and electrical noise.

Here is whole project archived - http://petfeeder.googlecode.com/files/CatFeeder_07-111225a.zip


cat's are happy :)
?????? ?????? ?????, ??? ??? - ??????????!


Dec 27, 2011, 09:27 am Last Edit: Dec 27, 2011, 10:08 am by kaor Reason: 1
Some details of the project.
1) Mechanical part
The main engine is simple brushed geared motor from DX

The feeder consists of food tank and food issuing device that is like Archimedes Screw made of simple comb
I used comb to prevent the device from sticking due to food pieces.

2) Solar Panel
The whole device works autonomously, without any external AC/DC power supply. For powering I use a 1.5 watt/12 volt solar panel.
There are many of them at ebay for about 10$. I mounted a panel outdoor at safe place to prevent it from bad weather conditions and same time let to get more solar light. The panel gives enough power even in very cloudy weather. Keep in mind that window glass isn't 100% transparent.

3) Rechargeable Battery
The device should work all the time, even in bad weather or dark time, therefore I need some battery to supply it at that time when there is no sufficient solar power. I used very simple 6Volt VRLA battery with capacity 4AH. Even if we suppose that this battery really gives out only 1AH, it will be enough to power the device few days without solar energy (device average consumption is 1.5-2ma).
The battery is charging via solar panel. Atmega controls charging process via electrical scheme.
Charging algorithm is very simple, goal is floating voltage for VRLA battery that is mentioned in datasheet. If voltage from solar panel is greater then battery voltage and battery voltage is less then floating voltage, then the MOSFET opens and charging starts.
Here is a part of code
Code: [Select]

    if((VExt>VBat) && (VBat<LevBat))

The first SetCharge(false) guarantees that solar panel voltage doesn't drops due to load. Coefficients kVExt and KVBat normalize analog reading to real voltage and should be tuned according drop resistors of the scheme.
The solar panel also used as daytime detector. I reset the time counter on sun rise. To detect sun rise I use averaged voltage of solar panel

Code: [Select]

    IsDay = IsDay ? SAn >= LevNigth : SAn > LevDay;

Code seems little complicated but easy to understand, first line works like voltage integrator, SAn accumulates and averages voltage with some delay, delay time depends on  AvgKS and  AvgKA coefficients (AvgKA + AvgKS = 1), as closer AvgKS is to 1 as longer delay we get.
But what for do we need this delay? - To prevent any accidental light detection at night time (for example car headlamps).
Second line is hysteresis trigger - without it the code begins twilight bouncing. If voltage on panel is about day and night threshold, code can switch between day and night mode many times during such light conditions. So we have 2 threshold voltages, one for detecting day after night and another for detecting night after day (LevDay and LevNigt).
?????? ?????? ?????, ??? ??? - ??????????!


Dec 27, 2011, 11:44 am Last Edit: Dec 27, 2011, 12:06 pm by kaor Reason: 1
4) KeyPad
I used simple 16 4x4 Matrix Keyboard Keypad. you can buy it online or locally for few dollars.
This keypad has 8 connectors (4x4 matrix rows and columns).
I decided to connect it Arduino via only one wire. Usually most people connects each row/column out to controller digital pin, therefore uses 8 digital in-s.
But why 8 pin when there is one pin enough?!
You just need few resistors.
Resistors should be selected to guarantee voltages spread as mach as possible.
here is a table with resistors and according voltage readings (after ADC converted it to int, we suppose VCC is converted to 1024 as in Arduino)

R (in kOhm)0224768
0   0185327414

This numbers are more presentable in chart. Goal is to avoid chart lines crossing.
Even though the readings from ADC may cross due to electrical noises in circuit.
To avoid this I use software filter
Code: [Select]

char KeyPad::ReadKey(int KeyReads, int KeyReadDelay)
  char ret=NoKeyChar;
  int ai;
  int aiMin=1024, aiMax=0;
  float aiAvr=0;
  for (int i=0;i<KeyReads;i++)
     if (ai<aiMin)
     if (ai>aiMax)
  float dev;
  if (aiAvr==0)
  if (dev<KeyReadPrec)
    for (int i=0;i<mKeyCount;i++)
      if(ai>=mKeyIntsL[i] and ai<=mKeyIntsH[i])

The function ReadKey has 2 parameters KeyReads  and KeyReadDelay.
Code reads KeyPin several times (KeyReads) with some delay (KeyReadDelay) to get average reading that prevents analog noise.
But noise isn't the only problem for KeyPad, there is transitional state during pressing or releasing key, when resistance of connector is changing from 0 to disconnected and if this function runs this moment, it may get wrong reading. To prevent this, I use max and min values of readings and compare them to average value, than I calculate difference (let call it deviation). If the deviation is too big, then KeyPad isn't in stable state and reading should be discarded. here we check it
Code: [Select]

  if (dev<KeyReadPrec)

KeyReadPrec is acceptable deviation to guarantee stable readings.

You can note in electrical scheme that there is used another digital pin of Atmega. That is due to Atmega powerdown mode. KeyPad used also wake up interrupt.
Here is intterupt attaching code from main fail of the project.
Code: [Select]

attachInterrupt(0, wakeUpNow, LOW);

In KeyPad library there are many other functions that will discussed lately.
?????? ?????? ?????, ??? ??? - ??????????!


This is great! I know it's been posted for a long time but just thought I'd show my appreciation :) I'm considering making an own feeder and using a simple comb for the feed mechanism is a great idea i hadn't thought of.

Go Up