Nick Gammon posted some code to setup a counter on an Arduino UNO using timer2 to generate a 38KHZ signal, and I've used it on several IR projects.

On my current project, I'm using FreeRTOS for the Arduino, and the source says it uses timers 0-3 for its own kernel operation, so the timer code obviously will interfere with the RTOS.

I'm using an Arduino MEGA for this project, and AFAICT it also has a timer4 and timer5. Unfortunately, my programming ability for the ATMel products is lacking at that level, so I'm looking for some help to create a timer that will generate a 38KHZ output using timer4 or timer5 of the MEGA 2560 on any output pin. Interrupts shouldn't be used because it would also probably cause issues with RTOS.

BTW, on the Arduino MEGA, you can do a context switch between tasks in less that 200usec, and be able to determine what task YOU want to execute next.

  • Can you show me where I can read that freertos uses timers 0-3? In my opinion it does not use any of those timers. – Jot Dec 6 '18 at 18:59
  • For the life of me, I can't find what I found before.....I did find some example code that setup the watchdog timer to generate the basic tick function time, and the code allows using almost any of the HW timers. I did see that some of the docs posted say that the RTOS timers don't depend on any HW, but it also says that the SW timers don't use any processor time?? That doesn't make sense. The lack of documentation in this area may show that no HW is indeed used, especially because the RTOS will run on almost any Arduino, and the timers are quite different in capability. – crusader27529 Dec 6 '18 at 21:51
  • The file that has the timer stuff is; \avrfreertos-master\avrfreertos-master\freeRTOS10xx\include\FreeRTOSBoardDefs.h – crusader27529 Dec 6 '18 at 21:57
  • The watchdog timer is recommended, but I see that for the arduino mega 2560 the timer3 is used in this one: github.com/feilipu/avrfreertos/blob/master/freeRTOS10xx/include/… That is okay, since timer0, timer1 and timer2 are not used by freertos. The library manager in the arduino ide uses a mini version of freertos, and that one uses the watchdog timer: github.com/feilipu/Arduino_FreeRTOS_Library/blob/… Why did you choose the larger version of freertos? – Jot Dec 6 '18 at 23:05
  • I just downloaded the version that the IDE showed. I didn't know there was another, smalled version. The size of the code isn't important to the project, as there will be only 3 tasks running that are all process dependant, but just scan while running in a state machine. They'll all run at the same priority, and at each exit from each state in the loop they're in, they will yield to the next task. ALL of them will always be in the ready state. Originally, I setup the code to chage their own priority to match all the rest, and then raise the priority of the next task to run. – crusader27529 Dec 6 '18 at 23:33

Using a pre-emptive Real Time Operating System on a Arduino board with a AVR microcontroller (Arduino Uno, Leonardo, Mega 2560) is an academic exercise.

The FreeRTOS is reliable, and for someone that is used to write multitasking code, it can be useful.
In my opinion, the FreeRTOS does not match with the simple AVR Arduino boards:

  • Not enough ram memory.
    Every task gets its own stack. The ram memory is limited on a AVR board. That means that every task should be written very careful to limit the stack usage.
  • Not enough ram when the fun is about to start.
    When there are a few tasks and perhaps a few interrupt routines, then a number of buffers and message queues are needed. There is not enough ram memory for that.
  • The Arduino was not developed with a multitasking system in mind.
    The Arduino libraries are not suitable for that. Some functions wait for something (Serial.parseInt, Wire.requestFrom, Wire.endTransmission) and that makes a RTOS work worse than expected.
  • The FreeRTOS is large, it requires memory and cpu time.

Without FreeRTOS, some known techniques are very efficient for the AVR Arduino boards:

  • A Finite State Machine uses very little ram memory.
    A Finite State Machine without delay() that uses millis() can be very responsive.
  • Avoiding interrupt routines.
    It is often possible to avoid interrupt routines. Reading buttons can often be done by polling the buttons in the loop().
  • Avoiding the String object and moving text into PROGMEM can be used to have enough memory for a more complex and reliable sketch.

At this moment the "FreeRTOS by Richard Barry" is in the Library Manager. It is a smaller version of FreeRTOS and it only uses the WatchDog timer. It has no conflict with Arduino libraries.

A larger FreeRTOS version and many examples can be found at https://github.com/feilipu/avrfreertos
Not every version of FreeRTOS uses the WatchDog timer. Look for the file FreeRTOSBoardDefs.h to see which timer is used for your specific Arduino board.

crusader27529, I don't see a problem to remove the FreeRTOS and call the three tasks sequencially.

void loop() {
  • The nature of the tasks is that they never terminate, but continuously monitor multiple IR sensors that are time critical, all run in multiple state machines. Using RTOS, I can use the YIELD function to force the running task into a state that allows the next task to run. Since all the tasks are the same priority, it results is a cooperative task switching operation with extremely low context switching overhead. AAMOF, I can switch sequentially among 4 tasks in sequence in less than 200usec. That actually works out tf about 50usec per task context switch, with minimal changes to the old code. – crusader27529 Dec 7 '18 at 15:50
  • @crusader27529 I understand now, you stay in the finite state machine and perform a yield to the other ones. Without a RTOS, the loop() runs over and over again and rushes through the finite state machines. That is a different approach. – Jot Dec 7 '18 at 17:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.