Tuesday, March 8, 2011

Data transfer from microcontroller to notebook (Part 1)

This post will be of interest to programmers. I document how measured and calculated data are transferred from the microcontroller to the notebook, which is responsible to build the real-time displays.
In this Part 1, we look at the microprocessor side of the transfer.
For efficiency, all transferred data are in binary form, mostly in floating point format.
Within each cycle of 0.1 second (10 Hz), the microprocessor populates the ‘dump_info’ structure with measured and calculated values. At the end of the cycle, this data structure is copied to the ‘ubuff’ transmit buffer. The first 6 bytes of the transmit buffer, which contain the magic word ‘MERLIN’ , remain unchanged. This magic word will be used by the notebook to identify and confirm the beginning of a new data structure.

The transmit buffer is sent through USART0 of the microcontroller to the serial-to-USB converter, at a baud rate of 9600. This baud rate is the fastest that the notebook can handle at the other end among its other tasks. Higher baud rates could be handled by more powerful laptops, but the notebook has been chosen because of its longer battery life (around 9 hours). The transfer uses interrupt-based routines, because with poll-based strategy, it would not be possible to achieve the 10 Hz rate.


// Initialization

typedef union
{
     unsigned char dump[76];
     struct
     {
           double mwa;     // measured apparent wind angle
           double awa;     // awa corrected for heel
           double twa;     // true wind angle
           double aws;     // apparent wind speed
           double tws;     // true wind speed
           double wdir;    // wind direction
           double mbs1;    // measured boat speed (starboard)
           double mbs2;    // measured boat speed (port)
           double stw;     // boat speed through water
           double vmg;     // velocity made good
           double heading; // corrected heading
           double heel;    // heel angle
           double leeway;  // calculated leeway angle
           double doc;     // direction of current
           double soc;     // speed of current
           double cog;     // GPS course over ground
           double sog;     // GPS speed over ground
           int long1;      // GPS longitude (1st part)
           int long2;      // GPS longitude (2nd part)
           int lat1;       // GPS latitude (1st part)
           int lat2;       // GPS latitude (2nd part)
     };
} dump_union;  //  double are 4 bytes, int are 2 bytes 

dump_union dump_info;

static char ubuff[82];

int main(void)
{
     /* USART0 : Set baud rate : 9600 @ 16MHz */
      UBRR0L = (unsigned char)(103);
     /* Enable transmitter */
     UCSR0B =_BV(TXEN0);

     // initialize the magic word
     ubuff[0] = 'M';
     ubuff[1] = 'E';
     ubuff[2] = 'R';
     ubuff[3] = 'L';
     ubuff[4] = 'I';
     ubuff[5] = 'N';

     txindex = 0;

     /* enable interrupts */
     sei();

     for(;;)
     {   
          // begin a new cycle

          // Measure and calculate new data,
          // put results in dump_info structure
          // ...
          // dump_info.mwa = ...
          // dump_info.awa = ...
          // dump_info.twa = ...
          // ...
          // dump_info.long2 = ...
          // dump_info.lat1 = ...
          // dump_info.lat2 = ...
         
          // Populate the transmit buffer,
          // without changing the first 6 bytes
          for(i = 6; i < 82; i++)    // 76 + 6 = 82
               ubuff[i] = dump_info.dump[i-6];

          UCSR0B |= _BV(UDRIE0);  // start transmitting

          // Wait for timer signal to begin a new cycle
          //...
     }
}


// This interrupt routine will be called 82 times within
// the next 100 ms then will disable itself
ISR(USART0_UDRE_vect)
{
     if(txindex < 81)
           UDR0 = ubuff[txindex++];
     else
     {
           UDR0 = ubuff[81];
           txindex = 0;
           UCSR0B &= ~(_BV(UDRIE0));  // stop transmitting
     }
}


No comments:

Post a Comment