Using UAV DevBoard serial port Tx interrupts

UAV DevBoard Pilots:This topic concerns an efficient way to transfer data through the transmitter of a USART using transmit interrupts.There are two general approaches to sending out a message through a USART. The simplest way to do it, but not the most efficient, is to transfer a byte at a time to the transmit buffer of the USART, and wait for the transmitter to be ready before transferring another byte. This method is fine if there is not much data to be sent. This is the method that I use in my firmware to send messages to the GPS to initialize it. Since only a few short messages are sent only during initialization, it is not worth the trouble to be efficient.However, telemetry traffic is another matter. If you would like to send a lot of data through a USART on a regular basis, the extra programming effort of using transmit interrupts pays off in efficiency.Conceptually, the idea is simple: use the empty-Tx-buffer interrupt to trigger the transfer of the data to the transmit buffer. That way, your firmware can be off doing something else between characters.As an example, I have modified the roll-pitch-yaw demo for the UAV DevBoard to use transmit interrupts to pump out GPS data and direction-cosine data through the spare serial port.Here are some of the highlights of the C code:When you are ready to send a message, prepare it and place it in a transmit buffer, as shown in the following routine. Then, simply transfer only the first byte of the message to the USART transmitter:void debug_output( void ){unsigned char txchar ;db_index = 0 ;sprintf( debug_buffer , "lat: %li, long: %li, alt: %li\r\nrmat: %i, %i, %i, %i, %i, %i, %i, %i, %i\r\n" ,lat_gps.WW , long_gps.WW , alt_sl_gps.WW ,rmat[0] , rmat[1] , rmat[2] ,rmat[3] , rmat[4] , rmat[5] ,rmat[6] , rmat[7] , rmat[8] ) ;txchar = debug_buffer[ db_index++ ] ;U1TXREG = txchar ;return ;}Some of you may be wondering why I did not transfer the byte directly to the transmitter with a statement such as:U1TXREG = debug_buffer[ db_index++ ] ;The reason is that the Microchip C compiler is too smart for its own good, or maybe not smart enough. It updates db_index after the transfer of the byte to U1TXREG. That is too late, because a Tx interrupt will be generated immediately.The statement U1TXREG = txchar will transfer the first character to the transmitter, and trigger a Tx interrupt. After that, whenever the transmitter is ready for another character, it will generate another interrupt. The interrupt service routine responds as follows:void __attribute__((__interrupt__,__no_auto_psv__)) _U1TXInterrupt(void){unsigned char txchar ;IFS0bits.U1TXIF = 0 ; // clear the interrupttxchar = debug_buffer[ db_index++ ] ;if ( txchar ) U1TXREG = txchar ;return ;}The example in this case is for an ASCII message. The sprintf() call places a 0 at the end of the message, which is used to detect the end of the message, and completes the transfer.A binary message would be handled a little differently. In that case, you would need to use a message length variable to detect the end of message.-Bill

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –


  • I tested the code using UC00A uart converter.
    But i never can see any response in the hyperterminal in my computer.
    you put the value of txchar into U1TXREG variable,but i can not see U1TXREG value in debug mode.
    this register is always 0.
    what problem is that?
    van you kindly explain it?
    thank you and regards
  • Hi Bill,

    I noticed in option.h that I can select #define SERIAL_OUTPUT_FORMAT/Serial_Ardustation.

    Would this mean that the Ardustation work with his actual code?
    Are the received data the same as from Ardupilot?
    If yes I suppose that antenna tracking works too, right?

    Thanks and best reards,

  • It seems quite a good way to send the telemetry to ground with a Xbee

    As I am quite new in C30
    But I just wondering about db_index it seems to be declared local in void debug_output( void )

    I suppose its declared global somewhere else to be modified in _U1TXInterrupt(void)

    so the code could be :

    void debug_output( void )
    unsigned char txchar ;
    // commented db_index = 0 ;
    sprintf( debug_buffer , "lat: %li, long: %li, alt: %li\r\nrmat: %i, %i, %i, %i, %i, %i, %i, %i, %i\r\n" ,
    lat_gps.WW , long_gps.WW , alt_sl_gps.WW ,
    rmat[0] , rmat[1] , rmat[2] ,
    rmat[3] , rmat[4] , rmat[5] ,
    rmat[6] , rmat[7] , rmat[8] ) ;
    txchar = debug_buffer[ 0] ; // modified im am not sure about it ??
    U1TXREG = txchar ;
    return ;

This reply was deleted.


DIY Robocars via Twitter
RT @chr1sa: Just a week to go before our next @DIYRobocars race at @circuitlaunch, complete with famous Brazilian BBQ. It's free, fun for k…
DIY Robocars via Twitter
How to use the new @donkey_car graphical UI to edit driving data for better training https://www.youtube.com/watch?v=J5-zHNeNebQ
Nov 28
DIY Robocars via Twitter
RT @SmallpixelCar: Wrote a program to find the light positions at @circuitlaunch. Here is the hypothesis of the light locations updating ba…
Nov 26
DIY Robocars via Twitter
RT @SmallpixelCar: Broke my @HokuyoUsa Lidar today. Luckily the non-cone localization, based on @a1k0n LightSLAM idea, works. It will help…
Nov 25
DIY Robocars via Twitter
@gclue_akira CC @NVIDIAEmbedded
Nov 23
DIY Robocars via Twitter
RT @luxonis: OAK-D PoE Autonomous Vehicle (Courtesy of zonyl in our Discord: https://discord.gg/EPsZHkg9Nx) https://t.co/PNDewvJdrb
Nov 23
DIY Robocars via Twitter
RT @f1tenth: It is getting dark and rainy on the F1TENTH racetrack in the @LGSVLSimulator. Testing out the new flood lights for the racetra…
Nov 23
DIY Robocars via Twitter
RT @JoeSpeeds: Live Now! Alex of @IndyAChallenge winning @TU_Muenchen team talking about their racing strategy and open source @OpenRobotic…
Nov 20
DIY Robocars via Twitter
RT @DAVGtech: Live NOW! Alexander Wischnewski of Indy Autonomous Challenge winning TUM team talking racing @diyrobocars @Heavy02011 @Ottawa…
Nov 20
DIY Robocars via Twitter
Incredible training performance with Donkeycar https://www.youtube.com/watch?v=9yy7ASttw04
Nov 9
DIY Robocars via Twitter
RT @JoeSpeeds: Sat Nov 6 Virtual DonkeyCar (and other cars, too) Race. So bring any car? @diyrobocars @IndyAChallenge https://t.co/nZQTff5…
Oct 31
DIY Robocars via Twitter
RT @JoeSpeeds: @chr1sa awesomely scary to see in person as our $1M robot almost clipped the walls as it spun at 140mph. But it was also awe…
Oct 29
DIY Robocars via Twitter
RT @chr1sa: Hey, @a1k0n's amazing "localize by the ceiling lights" @diyrobocars made @hackaday! It's consistently been the fastest in our…
Oct 25
DIY Robocars via Twitter
RT @IMS: It’s only fitting that @BostonDynamics Spot is waving the green flag for today’s @IndyAChallenge! Watch LIVE 👉 https://t.co/NtKnO…
Oct 23
DIY Robocars via Twitter
RT @IndyAChallenge: Congratulations to @TU_Muenchen the winners of the historic @IndyAChallenge and $1M. The first autonomous racecar comp…
Oct 23
DIY Robocars via Twitter
RT @JoeSpeeds: 🏎@TU_Muenchen #ROS 2 @EclipseCyclone #DDS #Zenoh 137mph. Saturday 10am EDT @IndyAChallenge @Twitch http://indyautonomouschallenge.com/stream
Oct 23