What i need to do: i want on and off my stuff just in time and display all info on LCD.

So i put RTC communication in TC1 interrupt (every 0.5 s) and LCD routines in main cycle (some information shows on LCD about 10 seconds). When RTC and LCD routines were in main cycle all were fine (exept time accuracy), but when i put communication with RTC in TC1 overflow interrupt something went wrong - device is "hanging up" sometimes.

So here is full code, i will be wery appriciated if someone tell me where turned on wrong way.

It does not matter if you only need hh.mm.ss. Good practice is to spend as few machine cycles as you can get away with in an interrupt service routine.

The standard procedure is to test something (maybe some status bits) or read a register (UART UDR is a good example), set a flag, and get out. Test for that flag in your main loop and act on it there.

You will probably ask - But Why? It seems perfectly logical and setting a flag just takes more memory! The top reason is that, for an AVR, interrupts are blocking (unless you do something "special") - that is, no other interrupt will be recognized as long as some ISR is running. This is the automatic procedure for AVR (Mega and Tiny, not so for XMega).

Second reason is that, even if you make your ISR interruptible, you then have to structure your ISR code so that it will survive being interrupted.

As a result, many of us have learned to structure our main loops into a series of "tasks" for which the execution depends on one or more "flags" or status conditions. Personally, I find that structure more maintainable, easier to debug, and more flexible. For example, I have a data logger that takes samples (measurements) - that is one task. Another is to mathematically process those samples (multiple samples are combined into running averages). Yet another is to format the results into text (strings). Following that is the task to write those strings to removable memory. It was very easy to change this latter task so that the output could be directed either to the memory or to the serial port and none of the rest of the code was touched. Sure, you could do all this in the traditional way, but I find this arrangement MUCH easier to manage.

A common concept seems to be that if you are not doing something "serious" ( like a colider (sic) ), its not important to be careful about how your program is organized. This reminds me of an old comedy routine that goes something like this:

Patient: But Doctor, when I do this, it hurts!

Doctor: Well, if it hurts, don't do it!

That applies to programming, also.

<Warning - philosophical tangent ahead>

Here, one might ask one's self what programming really is. At its core, it is figuring out how to use the resources of a given device, whether it be an absolutely minimal tiny micro or a super computer, to achieve some goal. You have to work with the resources that are built into that device because you cannot, generally, create new resources. If that device cannot add two smallest-unit binary quantities, then you either figure out how, or you figure out a different way to do it. Those are your choices. THAT is where creativity comes in. Sort of like the carpenter. Carpenter has saws, hammers, chisels, and such. The carpenter uses those tools, in creative ways when necessary, to make something new. Programmers are no different, except that a carpenter can go to the hardware store for a curly-shaped chisel but a programmer cannot go to the hardware store for an "interrupt service fixer". A programmer CAN seek help from others about alternate solutions that he or she might not have thought about. But, in the end, it is still all about using the available resources creatively to achieve a goal. Along the way, if you find that your idea does not work the way you planned, then its time to try something different.

i agree with you about structures. but information about time for me is on first place (i cant wait when the 15 second report on lcd will ends), the second place is channels tasks. you can't turn on water pump at 02.00.00 for 50 seconds without information what time is now. or if RTC will die i need to know it immidiately and stop watering my wifes flowers , or i will have problems with neighbors a floor below. hope you understand what i'm talking about

HAve you thought of the arduino structure (eats a timer inerrupt, the interrupt counting elapsed milliseconds since your processor was turned on).

The task of getting seconds from an accurate RTC could be activated "only" every 100 milliseconds -I bet this is overkill, even for plant watering- and stays in the main thread, which can poll for excess of water....

I would argue that for a task like that, you need no more than about 0.1 second "resolution". That is, if you know from your clock that water is needed now, there is nothing lost if it takes 100ms to turn that water on.

I might point out that the main part of your code IS organized as I suggested. It appears to be, pretty much, a finite state machine. That's good. The problem is reading the RTC in your timer overflow ISR. That takes way too many clock cycles. You will probably also have problems with interaction between serial and TWI. And, you also have some longer code in your serial rx service routine; that could well cause problems with a delayed timer overflow service.

So, for both cases, I would suggest moving that code out of the ISRs. Yes, it will require some reorganization of your code. But, that is what happens when you run into a roadblock.

Your timer overflow interrupt should do nothing except inform (through a volatile global shared variable) that xxx time elapsed since processor started/ RTC clock was read. Your RTC clock has a 1 second granularity: you should look at it say, every 100 ms (but timer interrupt can be 1 ms granularity, if you want).

Each time you consult the RTC :

you copy the number of milliseconds (say) elapsed; this copy (typ 4 bytes) should not be interrupted.

You add the time slice you feel necessary (time between RTC information updates).

When you do not consult the RTC :

you do other tasks (which are fairly quick, I hope)

you look at the number of milliseconds (should have called them "ticks") and, if it is greater (or equal, of course) than the time to look at the RTC.... you look at it.

BTW : each time main thread consults number of ticks (32 bits : if an interruot occurs and messes bytes, that would be ugly) , the copy should be made non interruptible...

Edited A drawback of this stucture is that "tasks" C functions called from the main() thread should be rather short; delays of 1 or 2 milliseconds can be tolerated; delays of 500 milliseconds are much more complicated... if they are ysed to flash a LED/light, maybe they can be rewritten by giving for each LED to be flashed a tick counter, and comparing number of overflows with time scheduled to change LED's state....

The very basics of the multitasking approach is ti divide your program into separate "tasks". Your main() function then services these tasks (i.e. calls functions) in some order and priority determined by you. The main() function is essentially a loop calling the functions that constitute your different tasks.

In addition to this the ISRs will run when an interrupt event occurs. As said above, keep the ISRs short. Grab any important data (e.g. incoming data on a communications interface like an UART) and have a global variable act as a flag that is set so as to mark that this event has happened.

Now you can have your tasks execute conditionally in the main loop. E.g. if the flag for an incoming character on the UART has been set you call a function to deal with this, and then you clear the flag (so that you are ready for another incoming character).

If an other interrupt event should occur while running the "incoming char" task then that is no problem. Interrupts are not disabled so that ISR will run, grab important data, set a flag and exit. The next time around the pool in main() the program will find this flag set and run the task for it.

This is the absolute basics. For systems where events come in quick bursts it might be needed to have queues of events waiting to be dealt with, bu this is not likely in a system that switches things like lamps and pumps on and off.

For a detailed treatise with example code, go read the tutorial that was pointed out in post above.

Finally:

1) Don't be angry - it's not a good state of mind for learning to develop software.

2) Welcome to AVRfreaks!

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.

No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]