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.

MSP430F1611: Wireless Ultrasound transmission and reception

Part Number: MSP430F1611

Dear all,

I am currently building a wireless ultrasound transmisson and reception system.

My clock of the system is synchrnoised to the wireless network by exchaning the data packet.

I am trying to transmit and receive ultrasound periodically, and this should be possible as TX module and RX module time synchronisation is within 5us error as they share the same master clock(wireless network)

The ultrasound module I am using is HC-SR04, but I have modifeid it so that each one can only transmit and recieve.

Trying to merge these two seems more complicated than I thought, looking at this code:

Pin and Interrupts are initilaised, then it goes while loop where synchronisation of the clock is carried out.

Here is where I face a problem, as the board goes to sleep when it does not receive any packet, the module can't transmit periodically unless it recieves packets which comes in approximately every 6 seconds.

So the Tx module should be able to transmit around 3 times, but It doesn't.

I attached for both Tx and Rx codes here.

// initialising ultrasound
P2DIR |= 0x08; // Set P2.3 as output (1 = out, 0 = in)
P2OUT &= ~0x08; // Set P2.3 low

TACCTL0 = CCIE; // capture/compare interrupt enable
TACTL = TASSEL_1 | MC_1 | ID_2; // Select ACLK, 'counts up' mode, input divider (4)
TACCR0 += 18000; // ~ 2.2s

while (1) {

if (app_vars.trig != 0){ // if flag's been raised with alternation
leds_all_off();
P5OUT ^= 0x10; // toggle red led
P2OUT ^= 0x08; // toggle P2.3 - trig
__delay_cycles(96); // delay ~ 20 us
P2OUT ^= 0x08;
__delay_cycles(240000); // delay 50 ms
P5OUT ^= 0x10;
app_vars.trig = 0; // clear flag
}

// sleep while waiting for at least one of the rxpk_done to be set
app_vars.rxpk_done = 0;
while (app_vars.rxpk_done == 0) {
board_sleep();
}

// if I get here, I just received a packet

//===== send notification over serial port

// format frame to send over serial port, displays the value of ASN retrieved from the manager
if (app_vars.rxpk_buf[0] == 0x08){

app_vars.ASN = (uint64_t)app_vars.uart_txFrame[0] + ((uint64_t)app_vars.uart_txFrame[1]<<8) + ((uint64_t)app_vars.uart_txFrame[2]<<16)+((uint64_t)app_vars.uart_txFrame[3]<<24)+((uint64_t)app_vars.uart_txFrame[4]<<32);
app_vars.current_network_time = (app_vars.ASN * 7.25)*1000000;  
app_vars.current_local_time = app_vars.num_asn;

// ----- before calculating the new alpha and stuff you toggle led if error is too big
app_vars.compensated_time = (app_vars.current_local_time - app_vars.previous_local_time)*app_vars.alpha + app_vars.previous_network_time;

/*if (abs(app_vars.current_network_time - app_vars.compensated_time) > 5) {
leds_all_on();
} else {
leds_all_off();
}*/

// ----- then you calculate the new alpha
app_vars.local_delta = app_vars.current_local_time - app_vars.previous_local_time;
app_vars.network_delta = app_vars.current_network_time - app_vars.previous_network_time;

if (app_vars.previous_local_time == 0) {
app_vars.alpha = 1;
} else {
app_vars.alpha = app_vars.local_delta / app_vars.network_delta; // consider smoothening this value over time to reduce noise. Something like an exponential mooving average is easy to implement
// also consider ignoring alpha values that are too big or too small. Something line 1.001 or 0.999 is already strange
}

app_vars.previous_local_time = app_vars.current_local_time;
app_vars.previous_network_time = app_vars.current_network_time;

// ---- printing the values of differences between the calculaetd value and the network
app_vars.compensated_time_dbg = abs((app_vars.compensated_time)-(app_vars.current_network_time));

app_vars.uart_counterFrame[0] = app_vars.compensated_time_dbg;
app_vars.uart_counterFrame[1] = app_vars.compensated_time_dbg>>8;
app_vars.uart_counterFrame[2] = app_vars.compensated_time_dbg>>16;
app_vars.uart_counterFrame[3] = app_vars.compensated_time_dbg>>24;
app_vars.uart_counterFrame[4] = app_vars.compensated_time_dbg>>32;
app_vars.uart_counterFrame[5] = app_vars.compensated_time_dbg>>40;
app_vars.uart_counterFrame[6] = app_vars.compensated_time_dbg>>48;
app_vars.uart_counterFrame[7] = app_vars.compensated_time_dbg>>56;

app_vars.uart_done = 0;
app_vars.uart_counterByte = 0;

// send app_vars.uart_txFrame over UART
uart_clearTxInterrupts();
uart_enableInterrupts();
uart_writeByte(app_vars.uart_counterFrame[app_vars.uart_counterByte]);
while (app_vars.uart_done==0); // busy wait to finish
uart_disableInterrupts();
}


Any Help will be greatly appreciated.

Thank you

Kind regards

Yong Kim

#include "sctimer.h"
#include "stdint.h" 
#include "string.h"
#include "stdlib.h"
#include "board.h"
#include "radio.h"
#include "leds.h"
#include "uart.h"

//=========================== defines =========================================

#define LENGTH_PACKET        125+LENGTH_CRC ///< maximum length is 127 bytes
#define CHANNEL              20             
#define LENGTH_SERIAL_FRAME  8              ///< length of the serial frame
#define LENGTH               8              ///< length of the serial frame

//=========================== variables =======================================

typedef struct {
   //radio
   uint8_t    num_startFrame;
   uint8_t    num_endFrame;

} app_dbg_t;

app_dbg_t app_dbg;

typedef struct {
   // rx packet
   volatile   uint8_t    rxpk_done;
              uint8_t    rxpk_buf[LENGTH_PACKET];
              uint8_t    rxpk_len;

   // uart
              uint8_t    uart_txFrame[LENGTH_SERIAL_FRAME];
              uint8_t    uart_counterFrame[LENGTH];
              uint8_t    uart_counterByte;
              uint8_t    uart_lastTxByte;
   volatile   uint8_t    uart_done;
   volatile   uint8_t    uart_counterdone;


   //ultrasound

   volatile   uint8_t    trig;
   volatile   uint8_t    echo; 

   //ASN

   volatile   uint64_t   ASN;
   volatile   uint64_t   num_asn;
   volatile   uint64_t   alpha;
   volatile   uint64_t   local_delta;
   volatile   uint64_t   network_delta;
   volatile   uint64_t   previous_network_time;
   volatile   uint64_t   current_network_time ;
   volatile   uint64_t   previous_local_time;
   volatile   uint64_t   current_local_time;
   volatile   uint64_t   compensated_time;
   volatile   uint64_t   compensated_time_dbg;

} app_vars_t;

app_vars_t app_vars;


//=========================== prototypes ======================================

// radio
void cb_startFrame(PORT_TIMER_WIDTH timestamp);
void cb_endFrame(PORT_TIMER_WIDTH timestamp);

//ASN counter
void cb_asncounter(void);

// uart
void cb_uartTxDone(void);


//=========================== main ============================================

int mote_main(void) {
   
   // clear local variables
   memset(&app_vars,0,sizeof(app_vars_t));
   
   // initialize board
   board_init();

   // initialising ultrasound
   P2DIR     |=  0x48;                          // Set P2.6/3 as output (1 = out, 0 = in)
   P2OUT     &= ~0x08;                          // Set P2.3 initially low - For trig

   // Echo detection on falling edge
   P2DIR     &= ~0x80;                           // Set P2.7 as an input
   P2OUT     |=  0x80;                           // put P2.7 initially high
   P2IE      |=  0x80;                           // enable P2.7 interrupt
   P2IFG     &= ~0x80;                           // clear pin flag in advance
   P2IES     |=  0x80;                           // interrupt on falling edge

   TACCTL0    =  CCIE;                           // capture/compare interrupt enable
   TACTL      =  TASSEL_1 | MC_1 | ID_2;         // Select ACLK, 'counts up' mode, input divider (4)
   TACCR0     +=  18000;                          // 18000k@32kHz ~ 550 ms

   // set asn counter
   sctimer_setasnreadCb(cb_asncounter);
   
   // add callback functions radio
   sctimer_setStartFrameCb(cb_startFrame);
   sctimer_setEndFrameCb(cb_endFrame);

   // setup UART
   uart_setCallbacks(cb_uartTxDone);
   
   // prepare radio
   radio_rfOn();
   radio_setFrequency(CHANNEL);
   
   // switch in RX
   radio_rxEnable();
   radio_rxNow();
   
   while (1) {

      if (app_vars.trig != 0){            // for timer
            P5OUT ^= 0x10;          // toggle red led
            P2OUT ^= 0x08;          // toggle P2.3 - trig
            __delay_cycles(100);    // delay ~ 20 us
            P2OUT ^= 0x08;
            __delay_cycles(144000); // delay 50 ms
            P5OUT ^= 0x10;
            app_vars.trig = 0;              // clear flag
              }
      else if (app_vars.echo != 0){            // for echo
                if (TAR < 1000){        // if detected before 30 ms 
                  int j;
                    for (j=0; j<8; j++){ // flash blue led repeatedly
                        P5OUT ^= 0x40;
                        __delay_cycles(96000); // delay 20 ms
                        }
                      }
                  app_vars.echo = 0;              // clear flag
                }
      /*
      // sleep while waiting for at least one of the rxpk_done to be set
      app_vars.rxpk_done = 0;
      while (app_vars.rxpk_done  == 0) {
         board_sleep();
      
      ]*/
      
      // if I get here, I just received a packet
      
      //===== send notification over serial port
      
      // format frame to send over serial port, displays the value of ASN retrieved from the manager
      else if (app_vars.rxpk_buf[0] == 0x08){

        app_vars.ASN = (uint64_t)app_vars.uart_txFrame[0] + ((uint64_t)app_vars.uart_txFrame[1]<<8) + ((uint64_t)app_vars.uart_txFrame[2]<<16)+((uint64_t)app_vars.uart_txFrame[3]<<24)+((uint64_t)app_vars.uart_txFrame[4]<<32);
        app_vars.current_network_time = (app_vars.ASN * 7.25)*1000000; 
        app_vars.current_local_time = app_vars.num_asn;

        // ----- before calculating the new alpha and stuff you toggle led if error is too big
        app_vars.compensated_time = (app_vars.current_local_time - app_vars.previous_local_time)*app_vars.alpha + app_vars.previous_network_time;
      
         /* if (abs(app_vars.current_network_time - app_vars.compensated_time) > 5) {
              leds_all_on();
              } else {
              leds_all_off();
              }*/

          // ----- then you calculate the new alpha
          app_vars.local_delta = app_vars.current_local_time - app_vars.previous_local_time;
          app_vars.network_delta = app_vars.current_network_time - app_vars.previous_network_time;

          if (app_vars.previous_local_time == 0) { 
          app_vars.alpha = 1; 
          } else {
          app_vars.alpha = app_vars.local_delta / app_vars.network_delta; // consider smoothening this value over time to reduce noise. Something like an exponential mooving average is easy to implement
                                                                          // also consider ignoring alpha values that are too big or too small. Something line 1.001 or 0.999 is already strange
          }

          app_vars.previous_local_time = app_vars.current_local_time;
          app_vars.previous_network_time = app_vars.current_network_time;

          // ---- printing the values of differences between the calculaetd value and the network
          app_vars.compensated_time_dbg = abs((app_vars.compensated_time)-(app_vars.current_network_time));
                 
          app_vars.uart_counterFrame[0] = app_vars.compensated_time_dbg;
          app_vars.uart_counterFrame[1] = app_vars.compensated_time_dbg>>8;
          app_vars.uart_counterFrame[2] = app_vars.compensated_time_dbg>>16;
          app_vars.uart_counterFrame[3] = app_vars.compensated_time_dbg>>24;
          app_vars.uart_counterFrame[4] = app_vars.compensated_time_dbg>>32;
          app_vars.uart_counterFrame[5] = app_vars.compensated_time_dbg>>40;
          app_vars.uart_counterFrame[6] = app_vars.compensated_time_dbg>>48;
          app_vars.uart_counterFrame[7] = app_vars.compensated_time_dbg>>56;

          app_vars.uart_done = 0;
          app_vars.uart_counterByte = 0;

          // send app_vars.uart_txFrame over UART
          uart_clearTxInterrupts();
          uart_enableInterrupts();
          uart_writeByte(app_vars.uart_counterFrame[app_vars.uart_counterByte]);
          while (app_vars.uart_done==0); // busy wait to finish
          uart_disableInterrupts();
       }
      else {
          app_vars.uart_done=1;
      }
   }
}


//=========================== callbacks =======================================

//===== radio

void cb_startFrame(PORT_TIMER_WIDTH timestamp) {
   
   // update debug stats
   app_dbg.num_startFrame++;

}

void cb_endFrame(PORT_TIMER_WIDTH timestamp) {
   
   // update debug stats
    app_dbg.num_endFrame++;
   // indicate I just received a packet
    app_vars.rxpk_done = 1;

   // get packet from radio
    radio_getReceivedFrame(
      app_vars.rxpk_buf,
      &app_vars.rxpk_len,
      sizeof(app_vars.rxpk_buf));
}


//==== ASN counter


void cb_asncounter(void){
   
    app_vars.num_asn++;
}

//===== uart

void cb_uartTxDone(void) {
   
   uart_clearTxInterrupts();
   
   // prepare to send the next byte
   // app_vars.uart_lastTxByte++;
   app_vars.uart_counterByte++;

/*  if (app_vars.uart_lastTxByte<sizeof(app_vars.uart_txFrame)) {
      uart_writeByte(app_vars.uart_txFrame[app_vars.uart_lastTxByte]);
   }else */if(app_vars.uart_counterByte<sizeof(app_vars.uart_counterFrame)){
         uart_writeByte(app_vars.uart_counterFrame[app_vars.uart_counterByte]);
      }
         else {
               app_vars.uart_done=1;
   }
}

//brief This function is called when the TimerA interrupt fires.
#pragma vector = TIMERA0_VECTOR
__interrupt void TIMERA0_ISR (void) {
    app_vars.trig = 1;                  // raise trig flag
}

//brief This function is called when the P2.7 interrupt fires.
#pragma vector = PORT2_VECTOR
__interrupt void PORT2_ISR (void) {
    app_vars.echo = 1;              // raise echo flag
    P2IFG &= ~0x80;        // clear pin flag
}

#include "sctimer.h"
#include "stdint.h" 
#include "string.h"
#include "stdlib.h"
#include "board.h"
#include "radio.h"
#include "leds.h"
#include "uart.h"

//=========================== defines =========================================

#define LENGTH_PACKET        125+LENGTH_CRC ///< maximum length is 127 bytes
#define CHANNEL              20             
#define LENGTH_SERIAL_FRAME  8              ///< length of the serial frame
#define LENGTH               8              ///< length of the serial frame

//=========================== variables =======================================

typedef struct {
   //radio
   uint8_t    num_startFrame;
   uint8_t    num_endFrame;

} app_dbg_t;

app_dbg_t app_dbg;

typedef struct {
   // rx packet
   volatile   uint8_t    rxpk_done;
              uint8_t    rxpk_buf[LENGTH_PACKET];
              uint8_t    rxpk_len;

   // uart
              uint8_t    uart_txFrame[LENGTH_SERIAL_FRAME];
              uint8_t    uart_counterFrame[LENGTH];
              uint8_t    uart_counterByte;
              uint8_t    uart_lastTxByte;
   volatile   uint8_t    uart_done;
   volatile   uint8_t    uart_counterdone;


   //ultrasound

   volatile   uint8_t    trig;
   volatile   uint8_t    echo; 

   //ASN

   volatile   uint64_t   ASN;
   volatile   uint64_t   num_asn;
   volatile   uint64_t   alpha;
   volatile   uint64_t   local_delta;
   volatile   uint64_t   network_delta;
   volatile   uint64_t   previous_network_time;
   volatile   uint64_t   current_network_time ;
   volatile   uint64_t   previous_local_time;
   volatile   uint64_t   current_local_time;
   volatile   uint64_t   compensated_time;
   volatile   uint64_t   compensated_time_dbg;

} app_vars_t;

app_vars_t app_vars;


//=========================== prototypes ======================================

// radio
void cb_startFrame(PORT_TIMER_WIDTH timestamp);
void cb_endFrame(PORT_TIMER_WIDTH timestamp);

//ASN counter
void cb_asncounter(void);

// uart
void cb_uartTxDone(void);


//=========================== main ============================================

int mote_main(void) {
   
   // clear local variables
   memset(&app_vars,0,sizeof(app_vars_t));
   
   // initialize board
   board_init();

   // set asn counter
   sctimer_setasnreadCb(cb_asncounter);
   
   // add callback functions radio
   sctimer_setStartFrameCb(cb_startFrame);
   sctimer_setEndFrameCb(cb_endFrame);

   // setup UART
   uart_setCallbacks(cb_uartTxDone);
   
   // prepare radio
   radio_rfOn();
   radio_setFrequency(CHANNEL);
   
   // switch in RX
   radio_rxEnable();
   radio_rxNow();

  // initialising ultrasound
   P2DIR     |=  0x08;                           // Set P2.3 as output (1 = out, 0 = in)
   P2OUT     &= ~0x08;                           // Set P2.3 low
   
   TACCTL0    =  CCIE;                           // capture/compare interrupt enable
   TACTL      =  TASSEL_1 | MC_1 | ID_2;         // Select ACLK, 'counts up' mode, input divider (4)
   TACCR0     +=  32768;                          // 18000k@32kHz ~ 550 ms

   while (1) {
      
      if (app_vars.trig != 0){              // if flag's been raised with alternation
        leds_all_off();
        P5OUT ^= 0x10;                      // toggle red led
        P2OUT ^= 0x08;                      // toggle P2.3 - trig
        __delay_cycles(96);                 // delay ~ 20 us
        P2OUT ^= 0x08;
        __delay_cycles(240000);             // delay 50 ms
        P5OUT ^= 0x10;
        app_vars.trig = 0;                           // clear flag
        }
      // sleep while waiting for at least one of the rxpk_done to be set
      app_vars.rxpk_done = 0;
      while (app_vars.rxpk_done  == 0) {
        board_sleep();
      }

      // if I get here, I just received a packet
      
      //===== send notification over serial port
      
      // format frame to send over serial port, displays the value of ASN retrieved from the manager
      if (app_vars.rxpk_buf[0] == 0x08){

        app_vars.ASN = (uint64_t)app_vars.uart_txFrame[0] + ((uint64_t)app_vars.uart_txFrame[1]<<8) + ((uint64_t)app_vars.uart_txFrame[2]<<16)+((uint64_t)app_vars.uart_txFrame[3]<<24)+((uint64_t)app_vars.uart_txFrame[4]<<32);
        app_vars.current_network_time = (app_vars.ASN * 7.25)*1000000; 
        app_vars.current_local_time = app_vars.num_asn;

        // ----- before calculating the new alpha and stuff you toggle led if error is too big
        app_vars.compensated_time = (app_vars.current_local_time - app_vars.previous_local_time)*app_vars.alpha + app_vars.previous_network_time;
      
          /*if (abs(app_vars.current_network_time - app_vars.compensated_time) > 5) {
              leds_all_on();
              } else {
              leds_all_off();
              }*/

          // ----- then you calculate the new alpha
          app_vars.local_delta = app_vars.current_local_time - app_vars.previous_local_time;
          app_vars.network_delta = app_vars.current_network_time - app_vars.previous_network_time;

          if (app_vars.previous_local_time == 0) { 
          app_vars.alpha = 1; 
          } else {
          app_vars.alpha = app_vars.local_delta / app_vars.network_delta; // consider smoothening this value over time to reduce noise. Something like an exponential mooving average is easy to implement
                                                                          // also consider ignoring alpha values that are too big or too small. Something line 1.001 or 0.999 is already strange
          }

          app_vars.previous_local_time = app_vars.current_local_time;
          app_vars.previous_network_time = app_vars.current_network_time;

          // ---- printing the values of differences between the calculaetd value and the network
          app_vars.compensated_time_dbg = abs((app_vars.compensated_time)-(app_vars.current_network_time));
                 
          app_vars.uart_counterFrame[0] = app_vars.compensated_time_dbg;
          app_vars.uart_counterFrame[1] = app_vars.compensated_time_dbg>>8;
          app_vars.uart_counterFrame[2] = app_vars.compensated_time_dbg>>16;
          app_vars.uart_counterFrame[3] = app_vars.compensated_time_dbg>>24;
          app_vars.uart_counterFrame[4] = app_vars.compensated_time_dbg>>32;
          app_vars.uart_counterFrame[5] = app_vars.compensated_time_dbg>>40;
          app_vars.uart_counterFrame[6] = app_vars.compensated_time_dbg>>48;
          app_vars.uart_counterFrame[7] = app_vars.compensated_time_dbg>>56;

          app_vars.uart_done = 0;
          app_vars.uart_counterByte = 0;

          // send app_vars.uart_txFrame over UART
          uart_clearTxInterrupts();
          uart_enableInterrupts();
          uart_writeByte(app_vars.uart_counterFrame[app_vars.uart_counterByte]);
          while (app_vars.uart_done==0); // busy wait to finish
          uart_disableInterrupts();
       }
      else {
          app_vars.uart_done=1;
      }
   }
}


//=========================== callbacks =======================================

//===== radio

void cb_startFrame(PORT_TIMER_WIDTH timestamp) {
   
   // update debug stats
   app_dbg.num_startFrame++;

}

void cb_endFrame(PORT_TIMER_WIDTH timestamp) {
   
   // update debug stats
    app_dbg.num_endFrame++;
   // indicate I just received a packet
    app_vars.rxpk_done = 1;

   // get packet from radio
    radio_getReceivedFrame(
      app_vars.rxpk_buf,
      &app_vars.rxpk_len,
      sizeof(app_vars.rxpk_buf));
}


//==== ASN counter


void cb_asncounter(void){
   
    app_vars.num_asn++;
}

//===== uart

void cb_uartTxDone(void) {
   
   uart_clearTxInterrupts();
   
   // prepare to send the next byte
   // app_vars.uart_lastTxByte++;
   app_vars.uart_counterByte++;

/*  if (app_vars.uart_lastTxByte<sizeof(app_vars.uart_txFrame)) {
      uart_writeByte(app_vars.uart_txFrame[app_vars.uart_lastTxByte]);
   }else */if(app_vars.uart_counterByte<sizeof(app_vars.uart_counterFrame)){
         uart_writeByte(app_vars.uart_counterFrame[app_vars.uart_counterByte]);
      }
         else {
               app_vars.uart_done=1;
   }
}

//brief This function is called when the TimerA interrupt fires.
#pragma vector = TIMERA0_VECTOR
__interrupt void TIMERA0_ISR (void) {
    app_vars.trig = 1;                   // raise flag
    leds_all_on();
}



  • It's not at all clear to me how the (ultrasonic) sender and receiver are supposed to synchronize. Having a synchronized network clock doesn't mean that the respective while() loops run in synch -- if nothing else, they contain different code and thus will take different amounts of time to loop.

    Also, the trigger period in the transmitter is 32768 (~4 seconds) but the receiver enable period is 18000 (~2.25 seconds), so even if they get synchronized they'll drift quickly.

    Each side stops and waits to receive a (clock-sync?) packet. Do they both receive the same packet? If so, they might be close to lock-step at that moment.

    How certain are you that your modified HC-SR04 is acting the way you expect? It might be worth trying it (them) outside this system, i.e. without duty cycling to make sure they work at all together.
  • Thank you for your reply.

    Tx and Rx are not synchronised to each other, they both retreive timestamp from the same network and will be synced to this timestamp meaning that two modules will be working on the same time frame.

    Here is what I am trying to do, I am going to implement the code so that TX  module will start transmit every 2 seconds, and RX starts listenin every 2 seconds too. And you correctly so, their both TACCR0 should be eqault to 18000.

    I can get modules work if i connected them via a wire. I have tested them before I got to this as this is my final step of the system.

    Any help will be appreciated

    Than you

    Kind regards

    Yong

  • The receiver is only on for 50ms out of 2 seconds (~2% duty cycle), and it must on be during the 20us (out of 2 seconds) that the transmitter's audio burst arrives. The RX and TX need to be fairly closely synchronized.

    The two sides have a common clock, but I don't see any mechanism for triggering something at a particular time.

    Can you run the receiver and/or the transmitter more often? An easy answer would be to run the receiver all the time. Alternatively, you can run the receiver at some period, and then run the transmitter "continuously" (I don't know whether the HC-SR04 can do this very effectively) for at least that period. This latter method is used in some radio protocols (ContikiMAC comes to mind).
  • The TX and RX modules is synchronised to each other within 5us, as they are both sharing the same master clock.

    The mechanism for triggering the TX is set to trigger every 18000 ticks and Rx is set to trigger every 17000ticks to make sure that RX does not miss.

    This interrupts the TIMERA_Vector which raises flag for triggering.

    //brief This function is called when the TimerA interrupt fires.
    #pragma vector = TIMERA0_VECTOR
    __interrupt void TIMERA0_ISR (void) {
    app_vars.trig = 1; // raise flag 
    
    leds_all_on();
    
    }

    I have been working on thsi for a bit now, and for the TX the code works fine, but with the RX module the code doesn't seem to follow the function that I wrote.

    The code should be able to listen to the US and should trigger the ISR accordingly. However, I do not seem to get any of these working.

    int mote_main(void) {
    
    // clear local variables
    memset(&app_vars,0,sizeof(app_vars_t));
    
    // initialize board
    board_init();
    
    // set asn counter
    sctimer_setasnreadCb(cb_asncounter);
    
    // add callback functions radio
    sctimer_setStartFrameCb(cb_startFrame);
    sctimer_setEndFrameCb(cb_endFrame);
    
    // setup UART
    uart_setCallbacks(cb_uartTxDone);
    
    // prepare radio
    radio_rfOn();
    radio_setFrequency(CHANNEL);
    
    // switch in RX
    radio_rxEnable();
    radio_rxNow();
    
    // initialising ultrasound
    P2DIR |= 0x08; // Set P2.3 as output (1 = out, 0 = in)
    P2OUT &= ~0x08; // Set P2.3 low
    P2DIR &= ~0x80; // Set P2.7 as an input
    P2OUT |= 0x80; // put P2.7 initially high
    P2IE |= 0x80; // enable P2.7 interrupt
    P2IFG &= ~0x80; // clear pin flag in advance
    P2IES |= 0x80; // interrupt on falling edge
    
    while (1){
    
    TACCTL0 = CCIE; // capture/compare interrupt enable
    TACTL = TASSEL_1 | MC_2 | ID_2; // Select ACLK, 'counts up' mode, input divider (4)
    TACCR0 += 17000; // 18000k@32kHz ~ 550 ms
    
    if (app_vars.rxpk_buf[0 == 0x08]){
    
    app_vars.ASN = (uint64_t)app_vars.rxpk_buf[17] + ((uint64_t)app_vars.rxpk_buf[18]<<8) + ((uint64_t)app_vars.rxpk_buf[19]<<16)+((uint64_t)app_vars.rxpk_buf[20]<<24)+((uint64_t)app_vars.rxpk_buf[21]<<32);
    app_vars.current_network_time = (app_vars.ASN * 7.25)*1000000; 
    app_vars.current_local_time = app_vars.num_asn;
    
    // ----- before calculating the new alpha and stuff you toggle led if error is too big
    app_vars.compensated_time = (app_vars.current_local_time - app_vars.previous_local_time)*app_vars.alpha + app_vars.previous_network_time;
    
    /*if (abs(app_vars.current_network_time - app_vars.compensated_time) > 5) {
    leds_all_on();
    } else {
    leds_all_off();
    }*/
    
    // ----- then you calculate the new alpha
    app_vars.local_delta = app_vars.current_local_time - app_vars.previous_local_time;
    app_vars.network_delta = app_vars.current_network_time - app_vars.previous_network_time;
    
    if (app_vars.previous_local_time == 0) { app_vars.alpha = 1; } 
    else { app_vars.alpha = app_vars.local_delta / app_vars.network_delta;} // consider smoothening this value over time to reduce noise. Something like an exponential mooving average is easy to implement
    // also consider ignoring alpha values that are too big or too small. Something line 1.001 or 0.999 is already strange
    app_vars.previous_local_time = app_vars.current_local_time;
    app_vars.previous_network_time = app_vars.current_network_time;
    
    // ---- printing the values of differences between the calculaetd value and the network
    app_vars.compensated_time_dbg = abs((app_vars.compensated_time)-(app_vars.current_network_time));
    
    app_vars.uart_counterFrame[0] = app_vars.compensated_time_dbg;
    app_vars.uart_counterFrame[1] = app_vars.compensated_time_dbg>>8;
    app_vars.uart_counterFrame[2] = app_vars.compensated_time_dbg>>16;
    app_vars.uart_counterFrame[3] = app_vars.compensated_time_dbg>>24;
    app_vars.uart_counterFrame[4] = app_vars.compensated_time_dbg>>32;
    app_vars.uart_counterFrame[5] = app_vars.compensated_time_dbg>>40;
    app_vars.uart_counterFrame[6] = app_vars.compensated_time_dbg>>48;
    app_vars.uart_counterFrame[7] = app_vars.compensated_time_dbg>>56;
    app_vars.uart_done = 0;
    app_vars.uart_counterByte = 0;
    
    // send app_vars.uart_txFrame over UART
    uart_clearTxInterrupts();
    uart_enableInterrupts();
    uart_writeByte(app_vars.uart_counterFrame[app_vars.uart_counterByte]);
    while (app_vars.uart_done==0); // busy wait to finish
    uart_disableInterrupts();
    app_vars.rxpk_buf[0] = 0;
    }
    else if (app_vars.trig != 0){
    //leds_all_off(); //debugging purpose
    P2OUT ^= 0x08; // toggle P2.3 - trig
    __delay_cycles(96); // delay ~ 20 us
    P2OUT ^= 0x08;
    __delay_cycles(240000); // delay 50 ms
    app_vars.trig = 0;
    }
    else if(app_vars.echo != 0){
    leds_all_off();
    __delay_cycles(96000); // delay 20 ms
    //leds_all_on();
    app_vars.echo = 0; // raise echo flag
    }
    else{
    app_vars.uart_done = 1;
    } 
    }
    }

    any help will be appreciated.

    Thank you

    Kind regards

    Yong Kim

  • Your RX and TX are being activated (or at least triggered) based on their local clocks, at a fixed period (~2.2sec) from the time each mote was booted. Unless they were both booted at exactly the same time (highly improbable) they won't sync on the ultrasonic signal.

    I've seen that you're computing a synchronized clock, but I don't see where you're using it to synchronize the actions of the two sides.

    Is the RX duty-cycling a requirement of your project?

**Attention** This is a public forum