The freeRTOS project is progressing.
Dogbot - Post 4 - Hardware & freeRTOS Complete
The freeRTOS project is progressing.
That robot looks great! It looks like you really have a lot packed onto that little chassis.
So some time has passed and I’ve had some success with different aspects of my robot.
I’m using a test bed based on an Arduino Duemilianova and Nerdkits display. I’ve hooked the display up as if it was a 3Pi or Orangutan SV-328 and am using Pololu libraries to write to it. Also, I’ve been working on the actual SVP based robot, so both of which are working well.
In testing freeRTOS I’ve been able to configure it based on a choice from some settings in the FreeRTOSConfig.h file to define 328p or not, and also in the make file (for each app) to determine whether 1284p Pololu or 328p Arduino is to be used.
328p is used for the Duemilianova and requires Timer0, which implies no motor library code.
1284p is used for the SVP and uses Timer3, which has no limitations on any known libraries.
//#define ARDUINO_328P // Define this to use the Arduino & Timer0 // Otherwise use Pololu & Timer3 # MCU name #MCU = atmega328p # Arduino MCU = atmega1284p # Pololu #AVRDUDE_PROGRAMMER = stk500v1 # Arduino AVRDUDE_PROGRAMMER = avrisp2 # Pololu #AVRDUDE_PORT = /dev/ttyUSB0 # Arduino AVRDUDE_PORT = /dev/ttyACM0 # Pololu #AVRDUDE_SPEED = 57600 # Arduino AVRDUDE_SPEED = 115200 # Pololu
Actually, it is pretty easy to get things working, and swap between the two systems. Currently I’m focussed on getting the i2c bus working to allow the SRT10 sonar and thermopile to work. Also I’ve done some work on the analog sensing. Both are working fine now. Next steps are a PID motor control with quadrature, and z-axis yaw sensor.
One of the nicest things about freeRTOS is not needing to care about timing. Using queues, it is possible to block processes (without tying up resources) until they should run, and using semaphores it is possible to control or limit access to resources (LCD, ADC, I2C Bus, etc) without having to go to critical code.
Some freeRTOS and application code attached, more as a “back up” than anything else.
[deleted as a new version available]
[ Added some more discussion here: DogBot - Post 5 post.ly/fSw6 ]
I’m glad you’re having so much success with RTOS and AVRs!
Here’s a little tip that might make your development easier: Instead of having a line in FreeRTOSConfig.h that says “#define ARDUINO_328P” which you have to comment out whenever you switch to using a different platform, you could use a command-line compiler option to define the ARDUINO_328P macro. I think the right avr-gcc option is “-DARDUINO_328P”. You would include this option in the Makefiles for your 328P projects and not include it in the makefiles for your 1284P projects.
But there’s another way you could do it which would not require you to modify your Makefiles. You can use the preprocessor macros defined by the compiler itself from the -mmcu argument to determine whether or not to define ARDUINO_328P.
#if !(defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284PA__)) #define ARDUINO_328P #endif
Took your advice and made some changes to the FreeRTOSConfig.h file.
Updated source attached, with some other minor changes.
I used FreeROTS with the Orangutan X2 awhile back for my thesis project.
Haven’t looked at it much since then but you’ve just inspired me to get back into it. Thanks for posting up the modifications. As you said before, I definitely find an RTOS much simpler from a timing point of view when you have to manage a number of concurrent tasks.
Time to start buying parts again
Hope you can post your thesis and code at some stage.
My Dogbot is sort of on hold at the moment. I got distracted into making a retrograde (hands rewind back to original position) clock and using this as a project to understand hardware based PWM properly. http://feilipu.posterous.com/freetronics-2010-arduino-duemilanova-freertos
So I wrote a set of little functions to manage the Timer1 or Timer0 PWM hardware, depending upon which timer was being used for the freeRTOS Tick.
As part of this work, I wrote some more extensions to freeRTOSconfig.h file configurations to allow you to use either Timer0 or Timer1 as the Tick timer on the 328p. Though, in hindsight, I think there is no reason to use the more functional Timer1 as the Tick timer at all.
I sort of ran into a wall with Dogbot, in that I wasn’t getting sensible values from the SVP quadrature encoder functions, so the PID couldn’t ever work properly.
100% certain my hardware is right, as the SVP demo code can see the quadrature outputs properly. Need to dig into whether it is a conflict between freeRTOS and the Orangutan libraries, or whether its just bad programming. Will know more once the clock is up on the wall in the next week or so.
One thing to look out for with serial comms and RTOS is that if your comms task is not the highest priority you may end up with some problems if the buffer fills before you have a chance to read it or if the other device depends on some fairly tight timing constraints (or delays) you’ll get some unpredictable behaviour. Although that being said it seems there’s only 5 bytes for the encoder counts + status so I would think it should be okay.
Can also be quite handy to test things before the scheduler takes over just to make sure they work independently. Keep us updated on how the project goes!
When you are retrieving information from the SVP’s auxiliary processor, there should be no issue with the priority of the task. The communication is done over SPI, which means that the master (the AVR ATmega324p/1284p) has total control over when the slave sends the information. It should be fine if the master is a little slow in requesting bytes from the slave because some other task pre-empted the encoder reading task.
The auxiliary processor requires you to have a minimum delay of a few microseconds between SPI bytes so it has time to prepare the next byte, but there is no maximum delay.
Ahh, of course, thanks David.
I’d forgotten about the SPI master/slave setup, the delays are an issue for UART serial comms like a GPS where it’s just streaming data at you that you can miss.
In that case I’m not quite sure what the issue could be, let us know when you work it out.
Been spending some time on a time wasting (its a pun) diversion, building a clock, to learn how to use hardware PWM to drive servos. The reason to use hardware PWM is to allow the servos to work in the background, without interrupting the freeRTOS tick unnecessarily.
As part of that I needed to move one of the OrangutanLCD configured data lines to free both Timer 1 PWM pins to drive two servos. I’ve updated the OrangutanLCD.h file to free Arduino Pins 9 & 10 by moving DB4 onto Pin 11.
The file from the Pololu library is here:
Once the change is made, you’ll need to recompile and reinstall the library as described.
The changes to OrangutanLCD.h are here:
#define LCD_DB4 PORTB3 // Was PORTB1. Use PORTB3 to avoid the Timer1 pins. #define LCD_DB5 PORTB4 // PB4 #define LCD_DB6 PORTB5 // PB5 #define LCD_DB7 PORTD7 // PD7 // PortB: 7 6 5 4 3 2 1 0 // LCD Data: 2 1 0 Use DB3 to avoid Timer1 pins. // LCD Data: 2 1 0 // // PortD: 7 6 5 4 3 2 1 0 // LCD Data: 3 #define LCD_PORTB_MASK ((1 << LCD_DB4) | (1 << LCD_DB5) | (1 << LCD_DB6)) #define LCD_PORTD_MASK (1 << LCD_DB7) #define LCD_PORTB_DATA(data) ((data & 0x07) << 3) // Modified the data mask to avoid using DB1 #define LCD_PORTD_DATA(data) ((data & 0x08) << 4)
I’ve updated the FreeRTOSConfig.h file to allow different timers to be used to drive PWM.
Also, added the use of internal pull up resistors on the I2C SCL and SDA lines.
Also, out of interest, I’ve compiled the Pololu Libraries on a PS3, which uses the PowerPC architecture. Off an Ubuntu 10.4 Lucid platform, it is all surprisingly easy. Here’s a link to the process, though it is exactly the same as with any x86 Ubuntu platform.
freeRTOS_604_retrograde_clock.zip (158 KB)
I had put the Dogbot project aside for a while. It was becoming bad for my state of mind.
But now, it is back on track. This post has some pictures of the new build. Pretty much the same as before, but a little cleaner and more robust.
More soon. Code to anyone who cares to ask.
Thanks for sharing. Your robot looks very cool! Where did you get your standoffs?
Regarding this text from your blog post:
We factory-calibrate each encoder to work properly for input voltages from 4.5 - 5.5 V, and we do not recommend users adjust the pots if their supply voltage is in this range. The only time you should need to touch the pots is if you want to run the encoder from a different voltage (e.g. 3.3 V), or if you are trying to fit it into a custom system for which it wasn’t intended. Had you adjusted the pots prior to your having problems with the encoder?
The SVP doesn’t necessarily require 50% duty cycle signals, it just requires that the transitions on the two quadrature channels always occur in the proper sequence with enough time between successive transitions for the processor to be able to correctly sample the state of both channels on each transition.
thanks. It remains lots of fun watching my coding (bad as it is) coming to life through a mobile robot. One day, I might get it finished.
The stand-offs come from a hardware store, and are called Wall Plugs in Australia.
There might be other names for them in USA.
I originally used them as spacers, but found that the best mounting method was to use them structurally, by putting an appropriate sized screw in each end. Their slight flexibility allows me to match the square holes in your chassis with the corner holes in the Orangutan SVP, and also keep the solution a little robust.
Regarding the Encoders issues I was having. Initially I had one Encoder counting correctly and one counting about 1/3 of the pulses. I ordered a replacement unit, and installed it during rebuild I described.
Unfortunately, when I got it back together the Encoder that was previously working wasn’t any more. But at least the new one worked properly. At that stage, I hadn’t adjusted anything on the Encoders themselves.
So, I decided to look closely at the waveforms with the motors in motion (which I hadn’t previously done). I found that some times they were not triggering properly. So following your suggested adjustment process, I adjusted them to be 50% duty cycle. And, suddenly everything worked as it should.
I guess that my issue would be that my system is drawing a lot of current, and that the voltage may be hovering around 4.5V or even less as the Backpack unit discharges. Hence my need to adjust them.
For information, I’ve been maintaining the freeRTOS code for the Orangutan and Arduino on Sourceforge on a project called avrfreertos.
freeRTOS implemented for selected AVR ATmega devices.
Arduino AVR ATmega328p supported.
Pololu Orangutan SVP AVR ATmega1284p supported.
Arduino Mega 2560 supported. (digitalAnalogue library addresses wrong pins - avoid temporarily).
Recently, I’ve added these features:
Latest freeRTOS revision v7.10
Added library for Rugged Circuits QuadRAM for ATmega2560
Added ChaN’s FatF v0.9 library, including a SDmonitor project (working but buggy).
Reviving this rather old thread, I recently began using feilipu’s port of FreeRTOS in an Orangutan X2-based project. I thought I’d ask (if you are still here) if you hit any hiccups using the Pololu library functions? I’m planning to use serial comms, tones and motor control from the Pololu library, and from FreeRTOS I’m planning to use task scheduling and possibly timers. Provided you hardware conflicts are avoided, did it all work out OK?
Purely FYI, I’m wanting the X2 to handle basic stuff and will use a Raspberry Pi to do anything else on the robot so I do have options as to how complex the Atmel 1284p stuff is if there is a conflict.
Yes, it is an old thread, but I’m still around, and still maintaining the
AVRfreeRTOS on Sourceforge.
The code is now on v7.5.0, which is the current version of freeRTOS.
Because I liked the 1284p in the SVP so much, I built an Arduino clone called the Goldilocks. The Goldilocks is the best way to get all the 1284p features, but keeping Arduino Shield compatibility.
To your question around the pololu libraries. To my knowledge there are no problems in using the libraries. The only reason that I stopped using them was that for me a big part of the fun is to understand what is happening at bit / port level, so building my own (borrowing others) is a good way to learn more.
There are some things that I’ve done (copied / repurposed / modified) with libraries, that I’m happy with:
- Getting the FatFS file system working, means that FAT32 works well.
- The I2C library supports both Master and Slave modes, from one code base.
- The SPI library is designed for multibyte transfers, for example with W5200, and performance.
- Integrating avr-libc time.h code, Contiki timers, and assembly code Timer2 RTC tick solution.
- Integrating uIP from v0.9 and v1.0 and latest Contiki 2.6 into one codebase.
- And I’m testing a new ring-buffer USART library, that is about 100x faster than the current code (using freeRTOS queues) on Sourceforge (update soon as I’m happy).
If you just want to use the core of freeRTOS code together with pololu libraries for the X2, then you can basically clean out all of the libraries and just be left with the files in the root of the freeRTOS folder. Really freeRTOS is only a few files to manage tasks, queues, and lists, and then portability macro layer (portable) and memory (MemMang) allocation options.
Excellent! I’m using the core bits from your FreeRTOS port (very useful indeed, thanks for all your work) and have shown that the QBasic demo works so I’m going to start building up functionality on that now. I would be really interested in your ring-buffer USART library work as well; I’ve done those bits with the Pololu functions but since FreeRTOS is working for me it would be a good time to switch over while my relevant test jigs remain extant.
I’ve updated the Sourceforge AVRfreeRTOS, to use the modified ringbuffer.h code from Dean Camera’s implementation of ring buffers. That’s well tested within LUFA.
I’ve found that sometimes the transmit interrupt will not fire unless the receive flag is cleared, so I implemented a flush function xSerialFlush() to take care of this issue.
If code size is an issue, avr-libc allows a selection of implementation options for vsnprintf() and other string functions. Depending on requirements either the normal, small or full float implementation of string libraries can be linked. See the documentation on avr-libc.
I recommend using the time.h functions for generating a tick timer, and for generating a one second system tick to keep real time. Even without a 32768Hz crystal the normal oscillator keeps good enough time to measure milliseconds and seconds intervals reasonably accurately. I’ve also added simple timer functions (from Contiki) to enable regular millisecond and second intervals to be measured, and checked for expiry.
Having got serial comms going with the standard Pololu Orangutan SVP library functions, I’ve now moved my code across into a freeRTOS tasking structure (containing three tasks and two queues (each of a few 10’s of bytes)) before moving to the freeRTOS serial code. However, I find that I’ve run out of (my 16kbytes) RAM when I enter my very first task (Pololu’s get_free_ram() reports -144 bytes and all malloc()s fail). The linker reports static RAM usage as 829 bytes and I’ve not malloc()ed any memory myself at this point so there must be something up with how I’ve configured the freeRTOS port (I’m using heap_3.c).
Any pointers as to how one goes about debugging the RAM consumption of freeRTOS (aside from taking config items out until it works)? How much RAM should I expect this freeRTOS port to consume (freeRTOSconfig.h attached)?
FreeRTOSConfig.h (5.51 KB)