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.

ez430-rf250 temperature sensor demo modification

Other Parts Discussed in Thread: SIMPLICITI

Hi
 
I am trying to modify the program for temperature sensor to do the following: 
 
I do not want any reading from the AP. Only the ED reading needs to be displayed. Also, the ED can transmit its reading ONLY when the Push Button on the board is pressed.
 
Any help will be appreciated.
 
Thanks
  • In demo_AP.c I made the sSelfMeasureSem = 0 under Timer A0 interrupt service routine. This made the AP readings stop.

    Then by adding the example code msp430x22x4_p1_04 to demo_ED.c I can stop the continous readings sent from ED by pressing the push button.

    This is opposite from what I want :).

    I want just ONE reading to be sent when the push button on the ED is pressed.

    Any help will be appreciated

    Thanks

  • Would you be willing to post your demo_ED.c?  This would help steer the discussion and provide recommendations.

  • Hey Brandon, my code is not much different than the demo_ED.c that comes with the package. I have made changes in the Port1 settings under the SipliciTI part and added an interrupt routine for Port1. Anyway here is the code that I have right now. The changes are bold. I am new to this but have an understanding. ED stops transmitting completely only when I use any other mode than LMP3, for the Port1 interrupt. When LMP3 is used the ED transmission does stop for a couple of seconds but starts again. But thats not the problem :). I want a single transmission from ED when the push button is pressed. So, any help will be appreciated.

    #include "bsp.h"
    #include "mrfi.h"
    #include "nwk_types.h"
    #include "nwk_api.h"
    #include "bsp_leds.h"
    #include "bsp_buttons.h"
    #include "vlo_rand.h"

    void linkTo(void);
    void MCU_Init(void);

    __no_init volatile int tempOffset @ 0x10F4; // Temperature offset set at production
    __no_init volatile char Flash_Addr[4] @ 0x10F0; // Flash address set randomly

    void createRandomAddress();

    void main (void)
    {
      addr_t lAddr; 
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      {
      // delay loop to ensure proper startup before SimpliciTI increases DCO
      // This is typically tailored to the power supply used, and in this case
      // is overkill for safety due to wide distribution.
        volatile int i;
        for(i = 0; i < 0xFFFF; i++){}
      }
      if( CALBC1_8MHZ == 0xFF )                 // Do not run if cal values are erased
      {
        volatile int i;
        P1DIR |= 0x03;
        BSP_TURN_ON_LED1();
        BSP_TURN_OFF_LED2();
        while(1)
        {
          for(i = 0; i < 0x5FFF; i++){}
          BSP_TOGGLE_LED2();
          BSP_TOGGLE_LED1();
        }
      }
     
      // SimpliciTI will change port pin settings as well
      P1DIR = 0x01;                               //P1.0 output, toggle red LED to show that the push button was pressed
      P1OUT = 0x04;                             // P1.2 pullup
      P1REN |= 0x04;                            // P1.2 pullup
      P1IE |= 0x04;                             // P1.2 interrupt enabled
      P1IES |= 0x04;                            // P1.2 Hi/lo edge
      P1IFG &= ~0x04;                           // P1.2 IFG cleared

      P2DIR = 0x27;
      P2OUT = 0x00;
      P3DIR = 0xC0;
      P3OUT = 0x00;
      P4DIR = 0xFF;
      P4OUT = 0x00;
     
      BSP_Init();
     
      if( Flash_Addr[0] == 0xFF &&
          Flash_Addr[1] == 0xFF &&
          Flash_Addr[2] == 0xFF &&
          Flash_Addr[3] == 0xFF )
      {
        createRandomAddress();                  // set Random device address at initial startup
      }
      lAddr.addr[0]=Flash_Addr[0];
      lAddr.addr[1]=Flash_Addr[1];
      lAddr.addr[2]=Flash_Addr[2];
      lAddr.addr[3]=Flash_Addr[3];
      SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
      BCSCTL1 = CALBC1_8MHZ;                    // Set DCO after random function
      DCOCTL = CALDCO_8MHZ;
     
      BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO
      TACCTL0 = CCIE;                           // TACCR0 interrupt enabled
      TACCR0 = 12000;                           // ~ 1 sec
      TACTL = TASSEL_1 + MC_1;                  // ACLK, upmode
     
      // keep trying to join until successful. toggle LEDS to indicate that
      // joining has not occurred. LED3 is red but labeled LED 4 on the EXP
      // board silkscreen. LED1 is green.
      while (SMPL_NO_JOIN == SMPL_Init((uint8_t (*)(linkID_t))0))
      {
        BSP_TOGGLE_LED1();
        BSP_TOGGLE_LED2();;
        __bis_SR_register(LPM3_bits + GIE);     // LPM3 with interrupts enabled
      }
      // unconditional link to AP which is listening due to successful join.
      linkTo();
    }

    void createRandomAddress()
    {
      unsigned int rand, rand2;
      do
      {
        rand = TI_getRandomIntegerFromVLO();    // first byte can not be 0x00 of 0xFF
      }
      while( (rand & 0xFF00)==0xFF00 || (rand & 0xFF00)==0x0000 );
      rand2 = TI_getRandomIntegerFromVLO();
     
      BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
      DCOCTL = CALDCO_1MHZ;
      FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
      FCTL3 = FWKEY + LOCKA;                    // Clear LOCK & LOCKA bits
      FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation

      Flash_Addr[0]=(rand>>8) & 0xFF;
      Flash_Addr[1]=rand & 0xFF;
      Flash_Addr[2]=(rand2>>8) & 0xFF;
      Flash_Addr[3]=rand2 & 0xFF;
     
      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY + LOCKA + LOCK;             // Set LOCK & LOCKA bit
    }

    void linkTo()
    {
      linkID_t linkID1;
      uint8_t  msg[3];
      
      // keep trying to link...
      while (SMPL_SUCCESS != SMPL_Link(&linkID1))
      {
        __bis_SR_register(LPM3_bits + GIE);     // LPM3 with interrupts enabled
        BSP_TOGGLE_LED1();
        BSP_TOGGLE_LED2();
      }
      
      // Turn off all LEDs
      if (BSP_LED1_IS_ON())
      {
        BSP_TOGGLE_LED1();
      }
      if (BSP_LED2_IS_ON())
      {
        BSP_TOGGLE_LED2();
      }
     
      while (1)
      {
        volatile long temp;
        int degC, volt;
        int results[2];
        SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
        __bis_SR_register(LPM3_bits+GIE);       // LPM3 with interrupts enabled
        SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );
     
        BSP_TOGGLE_LED2();
        ADC10CTL1 = INCH_10 + ADC10DIV_4;       // Temp Sensor ADC10CLK/5
        ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
        for( degC = 240; degC > 0; degC-- );    // delay to allow reference to settle
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
        results[0] = ADC10MEM;
     
        ADC10CTL0 &= ~ENC;
     
        ADC10CTL1 = INCH_11;                     // AVcc/2
        ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
        for( degC = 240; degC > 0; degC-- );    // delay to allow reference to settle
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
        results[1] = ADC10MEM;
        ADC10CTL0 &= ~ENC;
        ADC10CTL0 &= ~(REFON + ADC10ON);        // turn off A/D to save power
       
        // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
        // the temperature is transmitted as an integer where 32.1 = 321
        // hence 4230 instead of 423
        temp = results[0];
        degC = ((temp - 673) * 4230) / 1024;
        if( tempOffset != 0xFFFF )
        {
          degC += tempOffset;
        }
        /*message format,  UB = upper Byte, LB = lower Byte
        -------------------------------
        |degC LB | degC UB |  volt LB |
        -------------------------------
           0         1          2
        */
        temp = results[1];
        volt = (temp*25)/512;
        msg[0] = degC&0xFF;
        msg[1] = (degC>>8)&0xFF;
        msg[2] = volt;
        if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
        {
          BSP_TOGGLE_LED2();
        }
        else
        {
          BSP_TOGGLE_LED2();
          BSP_TOGGLE_LED1();
        }
      } 
    }


    /*------------------------------------------------------------------------------
    * ADC10 interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR(void)
    {
      __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
    }

    /*------------------------------------------------------------------------------
    * Timer A0 interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      __bic_SR_register_on_exit(LPM3_bits);        // Clear LPM3 bit from 0(SR)
    }

    /*------------------------------------------------------------------------------
    * Port 1 interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    {
     P1OUT ^= 0x01;                            // P1.0 = toggle
     P1IFG &= ~0x04;                           // P1.2 IFG cleared
     __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4 w/interrupt
    }

  • Okay, this helps paint the picture.  So, to recap, you desire to have the ED only transmit on a button press.

    Right now, there are two events that will wake up the MSP430 from the LPM3 state.  The Timer_A interrupt and the Port_1 button press.  Your linkTo() still has a while(1) loop that will be executed when the device leaves the LPM3 state.
    However, the way the code is currently implemented, a button press places the device in the LPM4 state, which turns off almost everything including the Timer A.  This would explain why a button press has the exact opposite effect.

    The Timer A is used in the beginning to periodically wake the device up to perform a SMPL_init() to join the network.  You should probably leave this, but that means the Timer A will always be running when you are in the linkTo() while(1) loop.  You could trun it off at that point, if not needed.  This would remove the Timer A as being a source of continually waking up and sending the reading on the network.

    Another approach is to have the Port_1() interrupt service routine actually set a flag which is used instead of the while(1).  At the end of the while(1), clear the flag and go back to the LPM3 state.  This is what I have illustrated below.  My updates are in bold.

     

    Moiz said:

    int buttonPressflag = 0 ;

    void linkTo()
    {
      linkID_t linkID1;
      uint8_t  msg[3];
      
      // keep trying to link...
      while (SMPL_SUCCESS != SMPL_Link(&linkID1))
      {
        __bis_SR_register(LPM3_bits + GIE);     // LPM3 with interrupts enabled
        BSP_TOGGLE_LED1();
        BSP_TOGGLE_LED2();
      }
      
      // Turn off all LEDs
      if (BSP_LED1_IS_ON())
      {
        BSP_TOGGLE_LED1();
      }
      if (BSP_LED2_IS_ON())
      {
        BSP_TOGGLE_LED2();
      }
     
      while (1)
      {
        volatile long temp;
        int degC, volt;
        int results[2];
        SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, "" );
        __bis_SR_register(LPM3_bits+GIE);       // LPM3 with interrupts enabled
        SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, "" );

       if (buttonPressflag)
       { 

        BSP_TOGGLE_LED2();
        ADC10CTL1 = INCH_10 + ADC10DIV_4;       // Temp Sensor ADC10CLK/5
        ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
        for( degC = 240; degC > 0; degC-- );    // delay to allow reference to settle
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
        results[0] = ADC10MEM;
     
        ADC10CTL0 &= ~ENC;
     
        ADC10CTL1 = INCH_11;                     // AVcc/2
        ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
        for( degC = 240; degC > 0; degC-- );    // delay to allow reference to settle
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
        results[1] = ADC10MEM;
        ADC10CTL0 &= ~ENC;
        ADC10CTL0 &= ~(REFON + ADC10ON);        // turn off A/D to save power
       
        // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
        // the temperature is transmitted as an integer where 32.1 = 321
        // hence 4230 instead of 423
        temp = results[0];
        degC = ((temp - 673) * 4230) / 1024;
        if( tempOffset != 0xFFFF )
        {
          degC += tempOffset;
        }
        /*message format,  UB = upper Byte, LB = lower Byte
        -------------------------------
        |degC LB | degC UB |  volt LB |
        -------------------------------
           0         1          2
        */
        temp = results[1];
        volt = (temp*25)/512;
        msg[0] = degC&0xFF;
        msg[1] = (degC>>8)&0xFF;
        msg[2] = volt;
        if (SMPL_SUCCESS == SMPL_Send(linkID1, msg, sizeof(msg)))
        {
          BSP_TOGGLE_LED2();
        }
        else
        {
          BSP_TOGGLE_LED2();
          BSP_TOGGLE_LED1();
        }
        buttonPressflag = 0 ;
      } 
    }


    /*------------------------------------------------------------------------------
    * ADC10 interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR(void)
    {
      __bic_SR_register_on_exit(CPUOFF);        // Clear CPUOFF bit from 0(SR)
    }

    /*------------------------------------------------------------------------------
    * Timer A0 interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      __bic_SR_register_on_exit(LPM3_bits);        // Clear LPM3 bit from 0(SR)
    }

    /*------------------------------------------------------------------------------
    * Port 1 interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    {
     P1OUT ^= 0x01;                            // P1.0 = toggle
     P1IFG &= ~0x04;                           // P1.2 IFG cleared
    buttonPressflag = 1 ;
     __bic_SR_register_on_exit(LPM3_bits);       // Clear LPM3 from 0(SR)
    }

     

  • works like a charm....thanks a lot dude :)

**Attention** This is a public forum