6. generate interrupts that change state of the port at required freqency. (CTC)

on a single timer (timer2) this works perfectly as we can see on a video. However I have found it difficult to do the same thing when using 2 timers (one for each motor) simultaneously, so when, for example, I send from smartphone 'turn' signal which is simply difference between rotation speed of two motors ( half of this difference should be added to motor1 speed and half should be deducted from motor2 speed) I have 2 different interrupt frequencies one for each motor.

My tests prove that on small frequencies this routine works, however over certain frequency program just stopps working.

So there is time for some codes. I will paste just the interrupt test codes to keep this post as clear as possible.

interrupt test is aplication sending letters with bluetooth from 3 different sources.

Result is 'rather unacceptable' (too often I lose main loop of program):

and finally when I again increase frequency 5 times the result is absolutely unaccaptable.

Additional test I made includes 1 timer (timer2) but with increased frequency AGAIN 5 times

I receive just B letter from time to time (not in 1s delay). EDIT: '_' shows up once per few min :)

I think it is worth to mention that the usart commends might be slowing down the work (however its easiest to share with you way of debugging in my opinion, tell me if I am wrong) as in the original balacning robot program the interrupt on timer occurs with this last frequency.

Only thing that comes to my mind that could perhaps solve this problem is adding external oscilator and increasing F_CPU to 16Mhz for example.

the question is, if it is possible to do it on this frequency or perhaps there is a better way to control two motors. I am quite new to AVR enviroment and still learning a lot so I can be doing it completly wrong way and in this case please correct me.

1) I have measured this frequency, as I am not using external oscilator I have checked what is my accual frequency when the fuse bits are set for 4 mhz.

2) true, however I have tested it with my own, self written funtions that include checking if UDR jis empty and results were the same, however the program was a bit slower. I replaced them for UDR and repeated tests to just make it more 'clear' for other users of the forum.

EDIT: I have checked it once again. with the whole 'checking' ,for the OCR = 5 and less seems like the program does not respond or works very very slowly. on OCR value equal 25 however and higher results are the same

Why are you using double variables when you are doing integer operations? Apart from double actually only being single precision with avrgcc, doing any floating point is going to suck cpu cycles needlessly. The AVR is an 8bitcpu, so choose your variable types carefully if you are concerned about code size and/or performance.

There are a number of techniques you can use for driving multiple stepper motors. The highest performant would be to use a timer for each motor and have it toggle it's associated output pin.
Another technique is to use one timer in CTC mode to generate an interrupt at a constant rate and use a DDS technique to generate the timing for each motor. This technique gives you very fine control of the motor speed.

@Kartman, thank you, good point about these doubles, I've been testing if there are some changes (not according to this problem) and mindlessly left them there to be.

I updated this to code and it significantly reduced 'skip' rate. Here are results (1st line is with double, the second is with ints).

I assume my solution (idea to make them work) is the second you mention. I use 2 timers in CTC mode and generate steps with calculated frequency. However so far I suppose my problem would be that interrupts overlaps each other, or just the MEGA cant handle this amount of interrupts per second. The ints help a lot however they dont solve it completly.

@EDIT: I have realised the skipping is result of mega spending big amounts of time calculating things and slowing down accual 'main' loop.

As stepper motors do step of 1.8* and my wheels are quite small, I need to generate pretty high frequencies.

What do you think? I am going to make some tests today and update whenever I can.

...that include checking if UDR jis empty and results were the same...

But what do you do if UDR is NOT empty? If you wait in one ISR then you may well miss the other one. Or rather it will be delayed so that the 1ms offset you put in at the start will instantly disappear.

'This forum helps those who help themselves.'

pragmatic►adjective dealing with things sensibly and realistically in a way that is based on practical rather than theoretical consideration.

Yes, I have realised that, however no better way of debugging this comes to my mind.

The max of this code I use is 62500 interrupts per secons per timer and I want to use 2 timers. At the same time main loop(5ms) is supposed to calculate angle from mpu6050 measurements, set control signal from PID and calculate required freqency.

I have absolutely no idea how many interrupts atmega can manage in a 1s time window. The code for each interrupt looks this way and does not include UART transmission:

WTF does extratime1 do? What are you wanting to achieve? The timers have associated output ports that can be toggled by the timer without isr or software intervention. You are constrained to using specific port bits. Thus you avoid slow down or issues with overlap.

I've been accually testing it. I ended up at the current settings mainly because I can have longer time between next interrupts. The Robot requires some very low frequencies around the angle 0*. It is impossible to achieve this as the register that stores the compare value has 8 bits so can't store bigger numbers.

Apparently the most of the problems were coming ( as usual ) from my lack of brain. I have left comment about prescaler "64" on a timer2 with prescaler accually set to 256. This amount was the limit set for this task to be performed properly. Nothing surprising that with the other timer (timer1) set to prescaler 4 times lower, the program did not want to work.

Also, as I can't paste exact code, for anyone that will have similar problem, I'd advice to pay a lot of attention during tests if you are absolutely sure that everything you are currently testing is set in a mode you think it is.

I'm saying it because I also wasted a lot of time and didnt accually recognise easly that is was prescaler problem (even after lowering down compare value where everything begun to work) as I left unproper command in the interrupt function and even changing prescaler value didn't make things work instantly.

I got the lesson to keep not only code clean but also comments up to date!