Wednesday, 26 March 2014

microcontroller - Communicating via USART with an AVR - Input Buffer?


I am currently building a robot (as some of you may know from my previous questions). The current task I a dealing with is that of communication. To keep things simple, assume I have 5 commands to deliver from my ground station to my robot:



  1. Drive forward

  2. Drive reverse

  3. Activate servo 1

  4. Activate servo 2

  5. Motor speed


Now, I am sending these commands from my computer to a USB to Serial adapter and then over an RF link. But this is not important, as far as I know, to my question.



So my question is, how does communication work in general? My idea is that I will have five different 8 bit data packets (one for each command) which I will continuously send from my computer. So I will keep an infinite loop going which will check, say, the position of an analog joystick. If it is pointing upward, command 1 will carry the drive forward message. If it is pointing downward, command 2 will carry the message, etc. Depending on how far the joystick is in the up/down position will dictate the contents of command 5. And the state of some keys on the keyboard will dictate whether commands 4 and 5 contain info to actuate servos.


So, again, I plan on having a continuous loop which will check each of the 5 states and send the appropriate commands over the USART from the computer's side.


The problem I am having, conceptually at least, is that what if there is a lag on the robot's end to process the data coming through the USART? As I understand, to ensure data isn't lost, the data is stored in a buffer on the MCU. Essentially, I want a "last in first out" system on my robot, so even if I miss the older commands for whatever reason, the robot is doing what I want it to do now, not what I wanted 2 seconds ago. But with this methodology, I'm also afraid that I will skip data packets of commands 1-4 because it will just keep reading the last data packet (i.e. command 5).


I came up with this communication "roadmap" on my own, so I'm sure there are much better ways to accomplish what I want. But I hope you understand what I mean. Also, I am using an ATmega328 on my robot, if it matters.


I would appreciate any advice pertaining to this situation.



Answer



What I usually do is I try to ensure that the controller doesn't send commands faster than the robot can process. Sending instructions consistently faster than can be processed by the robot will always eventually result in a loss of information with either a FIFO or a LIFO buffer. As a backup to intermittent lag on the robot I would use a small FIFO buffer. The exact size depends on what the trade-off between lost commands vs. responsiveness.


a LIFO buffer really doesn't make much sense in any case because you'll end up with an out of order operation in case the robot responds to commands slowly. consider the following:



  1. Send drive forward command


  2. Send Activate servo 1

  3. Send drive back command

  4. Send Activate servo 2


With a LIFO structure, say all the commands get sent before the robot gets time to process any commands. The commands are now going to be executed in reverse order! The robot will activate servo 2, drive back, activate servo 1, then drive forward. Most likely this is never what you want.


If you're only ever processing the latest instruction, then no additional buffer would be needed at all.


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...