Current Updates

This blog is an informal, and sometimes intermittent, record of my MEng project.

Wednesday 22 February 2012

Considering Requirements

I started the day by researching more about FreeRTOS, specifically the differences between tasks and coroutines.  I then went on to explore whether FreeRTOS would be the best option for the robot, or whether I could make do with a simpler multi-tasking system.

Tasks and Coroutines
FreeRTOS allows the programmer to define both tasks and coroutines in a given program.  Tasks are executed pre-emptively, and each has its own stack, etc.  Coroutines are a bit different - the stack is never saved, and they run cooperatively during the idle period.  This makes coroutines much more lightweight, but at a cost of flexibility.  The following points are quite noteworthy:
  • Tasks are always prioritised over coroutines
  • If a coroutine blocks, it will be cooperatively switched out, but its stack will be lost.  Any local variables must be declared static, to prevent loss.
  • API functions used in a coroutine mustn't block for the above reason, as the environment will be lost.
  • Blocking functions aren't allowed in switch statements.  I expect this is for a similar reason due to the way switch blocks might be handled by the compiler.
Necessities
The following functions must be performed on the AVR, however the code is implemented:
  • Serial link transmission and reception
  • Wheel sensing (quite time-critical)
  • Dead reckoning
  • Floor Sensing
  • Control Algorithm
I posed the following question to myself:
Is FreeRTOS the best option?  How big will the overhead be?  How restrictive is it?  Would it be better to write a basic cooperative system?

Here, I refer to overheads such as requiring a dedicated timer unit, the time required to swap volatile environments, the memory overhead, and the overheads of programming critical sections, etc.  The answer I came up with is as follows:
It may be better to write a basic cooperative system, to keep the overhead down.  Prioritising tasks can be a lot harder than at first glance, and synchronisation of tasks can be very challenging.  If interrupts are used for certain functions, and return quickly, the system may be programmed much more simply.

I determined the following requirements of such a system:
  • The wheel sensors must be polled at least every 5ms;
  • Reception of a serial packet must be handled as soon as it arrives, to prevent loss of data;
  • Transmission of serial data can wait, though it should be transmitted as soon as is practicable;
  • Dead reckoning could be performed less frequently, for example every 20ms or so, as long as the arc angle is small and moderately constant;
  • Floor sensing frequency is unknown, but 20ms will likely be more than frequent enough;
  • The control algorithm can probably work on 20ms steps - this allows 50 updates per second, which should be enough.
Hardware Capabilities
It's worth learning what the hardware you're working with is capable of.  I consulted the AVR's data book for information on interrupt sources and priorities.  I was pleased to find out that the watchdog timer can be used to trigger an interrupt, and doesn't force the system to reset, unless you specify this behaviour in the fuse bits.  The watchdog timer can time out over any period of 16ms, 32ms, ... 8s (in factors of 2).  This gives it good flexibility.

The USART has some interesting capabilities - it can decode data/address flags from an extra bit in the serial stream - this allows addressing of multiple units without extra software overhead.  To use this with a PC, the data would need to be reduced to 7 bits, to fit in the extra bit.  Using only microcontrollers would allow 8-bit data too, as most can handle a ninth data bit.  I'm probably going to leave this alone, as I'm working with a PC board, and a single link is probably enough for now.

There are two transmission-related interrupts on the USART - Data Register Empty means that you can load another byte into the transmit buffer, and Transmit Complete means that the byte has left the port - this might be useful for systems which release a bus or power down a transmitter.  The DRE interrupt is handy for keeping data flowing.

The receive buffer of the USART uses a two level FIFO, so there's a little slack in the system.  Interrupts are generated whenever there is at least one item left in the FIFO, so it's quite transparent.  There's also a buffer overrun flag related to the USART, so you can tell if data has been lost.

I plan to use one of the timer modules to poll the wheel sensor at appropriate intervals - either by polling every 5ms, or by generating an interrupt-on-change for each wheel, then disabling that interrupt for about 4ms to prevent multiple transitions from wasting CPU time.  The former seems much simpler, though the latter would allow better resolution on any state time measurements to determine speed.

The interrupt priorities on an AVR are very simple - lower addressed interrupts (the RESET end) always have priority.

Hardware Considerations
Since a PCB will be required very soon, I decided to investigate the best use of the AVR's pins.  I've not assigned everything yet, but I'd suggest it as a good move, taking into account future expansion possibilities.
I drafted a couple of floor sensor circuit possibilities - I expect that a simple load resistor will produce a good output.  The alternative is a current to voltage converter with variable bias using an op-amp - it seems overly complex, but it depends how linear the resistor circuit turns out to be.

I had a probe around the motor sense terminals, and noticed how noisy the signals are.  I'll try a simple RC filter tomorrow to see if it can be improved much.  If the noise can be reduced, it shouldn't be hard to use a simple op-amp circuit to derive back-EMF at all PWM conditions.  Due to the noise, I'll need to consider some alternative speed measurement options.

No comments:

Post a Comment

Comments are moderated. Sometimes it might take me a long time to get round to it, so please be patient.