This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Timestamping events

Other Parts Discussed in Thread: MSP430F2619


Hi

I have to use a MSP430F2619 to make a sort of data logger. I will have to timestamp 3 voltages (from ADCXMEMO) which will be written to a SD card. A user can ask those data to be sent thru the serial port.
So I will put an interrupt on UART0 to listen for orders coming from the serial port and an interrupt on the TIMER A to wake it up every second (for the timestamping). In the TIMER A interrupt, the voltage will be measured by the ADC and written to the SD card every X seconds. How to correct the "real time" to take care of the time spent in ADC and sd card processing (writing and reading of the sd card) ?

Thanks for any tip.

Karim

  • Actually I don't know what your problem is.

    karim bernardet said:
    How to correct the "real time"

    That's the part I don't understand. What do you need to correct and why? The meaning of timestamping is that you know when what happened even if it was somewhere in the past. So either you add a timestamp or not.

    If you have a timestamp, what do you want/need to correct? If you don't, well...


  • I thought doing something like this

    void main()
    {
    ...

    initialisations();

    _EINT();  // Enable interrupts

     while(1)
      {
     _BIS_SR(LPM3_bits); // Enter LPM3
      }
    }

    void readSDandSendToRS232(...)
    {
    ...
    }

    void  acquireAndWriteToSD()
    {
    ...
    }

    void usart0_rx (void) __interrupt[UART0RX_VECTOR]
     {
       ...
      switch (RXBUF0)
        {
        case 'a': {Mode=1;break;}                            
        case 'z': {Mode=2;break;}                           
        case 'o': {Mode=10;break;}                          
        case 'p': {Mode=20;break;}                          
        case 'b': {Mode=30;break;}
    ...
    }

    void Timer_A(void) __interrupt[TIMERA0_VECTOR]
    {
    // increment seconds
    seconds++;

    if ( seconds%10 == 0 ) // acquire and write to SD every 10 secs
       {
       acquireAndWriteToSD();
       } 

    if ( s > 59 )
       s=0;

    switch (Mode)  // Mode
      {
      case 1:...
      case 2:...
      case 10:...
      case 20:...
      case 30: readSDandSendToRS232(); break;
    ...
    }


    The data will be stored and sent to the serial port using this format :
    hours:min:sec,V1=some value,V2=some value,V3=some value
    hours:min:sec,V1=some value,V2=some value,V3=some value
    hours:min:sec,V1=some value,V2=some value,V3=some value
    ...

    In the TIMER_A interrupt (which occurs every second), it will spend several seconds for example to send the content of the SD card to the serial port (using the method readSDandSendToRS232()) so it can not increment the variable seconds (it is in readSDandSendToRS232() called by the interrupt) and the timestamping wont be close to the "real time".

    Karim

  • Ah, now I understand what you mean. Well, the problem is not adjusting the timestamp, i tis the concept of the program flow.

    It is a common error that perople try to 'do the job' inside the ISR. That's the wrong approach. It is not like an event thread in VisualSomething. The ISR is meant to do what is necessary to be done exactly now. And everything else is the job of main.

    So if the ISR detects that it is time to send the stuff, it should wake up main (clear the LPM bits) and let main send the stuff. So it is still ready to be triggered at the next second. interval.

    Main will send the stuff, however long it may take and go to sleep after.

    You can even fill a buffer with the data (so main does not have to wait until all is sent) and set up a DMA channel to feed it into the UART.

    The ISR is meant ot just accept the fact that something has happened and set some flags for main or wake it up or increment a variable or whhatever. But doing anything that takes longer time (including busy-waiting, such as readign or writing to SD) is the job of unsynchronized main loop.

    It does not make a difference whether you exit your ISR with the LPM bits clear, or do it in the ISR, in terms of execution speed, as the wakeup time from LPM is _before_ the ISR is called. And if you don'T clear the LPm bits, it will simply fall back into sleep after the ISR, so main stays frozen. While if you clear the bits inside the ISR, main can seamplessly continue, doing the job, while the interrupt mechanism is ready again for any new interrupt.

    If you have problems to execute things inside a single main loop, there are some libraries for multi-threading. Then you can have different separate threads (not ISRs) which can do different jobs pseudo-simultaneously and/or interleaved and when non of them has something to do, the system will enter LPM automatically.
    In invented one myself for some pseudo-parallel jobs. (sorry, companies property)

  • Thanks !  I am putting most of the work in the main loop

     

    Cheers

     

    Karim

**Attention** This is a public forum