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.

Transmit data using eZ430-RF2500T

Other Parts Discussed in Thread: SIMPLICITI, MSP430F2274

Hi guys, first I'm an undergrad so I'm really really unfamiliar with using these staff. Please have some patience.

What I want to do is just receive some analog data from one of the pins on the board and then transmit it to a PC. I have read the example about temperature transmission. What should I do right now? Can I just modify  some parts of the demo_ED.c code and keep the demo_AP.c the same?

And also, how can I get the data? I don't know which is the interface between the board and PC. Is it just the sensor monitor visualizer?

Thanks in advance!

Nereus

  • No one replied? Please help!

  • Hey,

    I may not be the best of help since I'm fairly new to working with this too, but I can offer some pointers. First of all, get all the documentation you can from the TI site, datasheets, user guides, etc.. I can send you the important ones if you give me your email. If you're new to this, you're going to be doing a lot of reading haha.

    First with the end device. So each pin on the board is connected to a pin on the chip itself. I'll give you an example from the MSP430x22x2/ MSP430x22x4 series because that's what I'm using. All this stuff is in the documentation I mentioned earlier btw. So let's say you have an input you want to send wirelessly to your computer. So we connect it to, say P3 on the red board with a wire or something. P3 on the red board  then connects to pin 6 on the actual square chip. Pin 6 is referred to as P2.0 and the way you access that in the code is in this whole section:

      // SimpliciTI will change port pin settings as well
      P1DIR = 0xFF;
      P1OUT = 0x00;
      P2DIR = 0x27;
      P2OUT = 0x00;
      P3DIR = 0xC0;
      P3OUT = 0x00;
      P4DIR = 0xFF;
      P4OUT = 0x00;

    The PxDIR (where x is a number between 1 and 4) controls whether each pin on the chip is an input or output. 0 means it's an input and 1 means it's an output. So if you're reading in a value to P2.0 then you'd set P2DIR = 0xFE or 11111110. If you wanted to set P2.1 as an input as well you'd make P2DIR = 0xFC etc.

    Next important chunk of code:

        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;

    So each pin on the chip is also connected to a channel. We define the channel in use in this section    ADC10CTL1 = INCH_10 + ADC10DIV_4;  section. I believe this channel connects to the temperature sensor (which would make sense because this is taken from that code). So find the right channel according to the pin you're using. The data is put in an array in this section: results[0] = ADC10MEM; I think the ADC10MEM is a register that reads incoming data to the msp430 chip or something like that. Then they take the results, do a bunch of conversions and send it over. That's a bit for the end device.

    Okay, so now, how you communicate with the device, if you have XP then it should come with hyper terminal. Otherwise, someone here recommended docklight to me. I personally use Putty which is useful for SSH but now can connect to COM ports as well. If you go to the hardware manager, it should tell you what COM port the MSP chip is connected to and just use one of these programs to connect to that port.

    Now for the Access point.

    The main function used to send data to the output terminal is void TXString( char* string, int length ); which is pretty self explanatory. What you're probably going to want to do is mess around with the

    void transmitData(int addr, signed char rssi,  char msg[MESSAGE_LENGTH] );

    function because those are specifically designed for outputting temperature in this case. Oh yeah, and also, you can delete all the stuff in the AP that takes and outputs its own temperature becuase you probably don't need that either. That should get you started on things. I first picked up one of these things a few months ago and it was a pain to find out all this on my own, but if you have any other questions, this forum is a great place to ask them. I've def got a lot of good answers here.

    Good luck!

  • Oh right, one more thing:

    /*------------------------------------------------------------------------------
    * USCIA interrupt service routine
    ------------------------------------------------------------------------------*/
    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void USCI0RX_ISR(void)
    {
      char rx = UCA0RXBUF;
      if ( rx == 'V' || rx == 'v' )
      {
        verboseMode = 1;
      }
      else if ( rx == 'M' || rx == 'm' )
      {
        verboseMode = 0;
      }
      else if ( rx == 'F' || rx == 'f' )
      {
        degCMode = 0;
      }
      else if ( rx == 'C' || rx == 'c' )
      {
        degCMode = 1;
      }
    }

    All this stuff means is that when you've got you're connection program running, you can hit different keys to set different modes. The RXBuffer is kinda like an input buffer. The TXbuffer is the output one (hence the TXstring function). You can modify this or add your own to give more functionality to your program.

  • Wow, thank you sooooooooooooooooooooooo much!   I really really appreciate it.

    Ok, now I have a rough idea of what's going on here. But I also have another question that is how to collect the data on  PC. Use the sensor monitor visualizer provided in the CD? Can I save the data in a file or something?

    btw, my email is nereusz@hotmail.com. I would be very grateful If you can send me some documentation. Thanks again!

    -Nereus

  • Okay, sent the files.

    In terms of data collection, what we use is a c++ program based on Thierry Schneider's PC serial port connection object for event-driven programs. I didn't write or modify it so I don't know exactly how it works, but I know you can download the base for free. Maybe look there for some direction. I feel like there's gotta be a way to export from the hyper terminal or write code in the IAR to have it save the data to a txt file or something. Unfortunately, I don't know how haha.

  • KCheung said:

    Okay, sent the files.

    In terms of data collection, what we use is a c++ program based on Thierry Schneider's PC serial port connection object for event-driven programs. I didn't write or modify it so I don't know exactly how it works, but I know you can download the base for free. Maybe look there for some direction. I feel like there's gotta be a way to export from the hyper terminal or write code in the IAR to have it save the data to a txt file or something. Unfortunately, I don't know how haha.

    All right, got it. Thanks a lot! This is very helpful. I really appreciate it.

    Nereus

  • Helllo can u email the documents to mee also at ajay41086@gmail.com

  • Hey KCheung, if possible, send me the documents you have about wireless/msp430. I'm in the same situation of  "Nereus".

    brunosergio@gmail.com

    Thanks  a lot.

  • Hey KCheung, if possible, send me the documents you have about wireless/msp430. Am also in the same situation of  "Nereus".

    arvind_s1990@yahoo.co.in

  • Hello,

     

    I'm in the same situation og NEREUS.

    Can you send me the documents about wireless/msp430?

    Regards,

    Saúl Costa

  • Hi,

    I am using eZ430-RF2500 which is MSP430F2274 series and I want to connect to external humidity sensor. The humidity sensor is provided with voltage analog output so I has connected its output to the P2.0, pin 3, A0 of the target board. Besides that, I have also connected the humidity sensor to an external 5V supply.

    As stated in the above explanation, the pin settings below are needed to put in which part of the code?

      P1DIR = 0xFF;
      P1OUT = 0x00;
      P2DIR = 0x27;
      P2OUT = 0x00;
      P3DIR = 0xC0;
      P3OUT = 0x00;
      P4DIR = 0xFF;
      P4OUT = 0x00;

    Below shows the modified main_ED.c code that I have made for getting the humidity data. What else that I have to make in order to get the data? Thanks.


    #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"

    /*------------------------------------------------------------------------------
     * Defines
     *----------------------------------------------------------------------------*/
    /* How many times to try a TX and miss an acknowledge before doing a scan */
    #define MISSES_IN_A_ROW  2

    /*------------------------------------------------------------------------------
     * Prototypes
     *----------------------------------------------------------------------------*/
    static void linkTo(void);
    void createRandomAddress(void);
    __interrupt void ADC10_ISR(void);
    __interrupt void Timer_A (void);

    /*------------------------------------------------------------------------------
    * Globals
    ------------------------------------------------------------------------------*/
    static linkID_t sLinkID1 = 0;
    /* Temperature offset set at production */
    volatile int * tempOffset = (int *)0x10F4;
    /* Initialize radio address location */
    char * Flash_Addr = (char *)0x10F0;
    /* Work loop semaphores */
    static volatile uint8_t sSelfMeasureSem = 0;

    /*------------------------------------------------------------------------------
     * Main
     *----------------------------------------------------------------------------*/
    void main (void)
    {
      addr_t lAddr;

      /* Initialize board-specific hardware */
      BSP_Init();

      /* Check flash for previously stored address */
      if(Flash_Addr[0] == 0xFF && Flash_Addr[1] == 0xFF &&
         Flash_Addr[2] == 0xFF && Flash_Addr[3] == 0xFF )
      {
        createRandomAddress(); // Create and store a new random address
      }

      /* Read out address from flash */
      lAddr.addr[0] = Flash_Addr[0];
      lAddr.addr[1] = Flash_Addr[1];
      lAddr.addr[2] = Flash_Addr[2];
      lAddr.addr[3] = Flash_Addr[3];

      /* Tell network stack the device address */
      SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);

      /* Initialize TimerA and oscillator */
      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 (a side effect of successful initialization) until
       * successful. Toggle LEDS to indicate that joining has not occurred.
       */
      while (SMPL_SUCCESS != SMPL_Init(0))
      {
        BSP_TOGGLE_LED1();
        BSP_TOGGLE_LED2();
        /* Go to sleep (LPM3 with interrupts enabled)
         * Timer A0 interrupt will wake CPU up every second to retry initializing
         */
        __bis_SR_register(LPM3_bits+GIE);  // LPM3 with interrupts enabled
      }

      /* LEDs on solid to indicate successful join. */
      BSP_TURN_ON_LED1();
      BSP_TURN_ON_LED2();

      /* Unconditional link to AP which is listening due to successful join. */
      linkTo();

      while(1);
    }

    static void linkTo()
    {
      uint8_t msg[4];
    #ifdef APP_AUTO_ACK
      uint8_t misses, done;
    #endif

      /* Keep trying to link... */
      while (SMPL_SUCCESS != SMPL_Link(&sLinkID1))
      {
        BSP_TOGGLE_LED1();
        BSP_TOGGLE_LED2();
        /* Go to sleep (LPM3 with interrupts enabled)
         * Timer A0 interrupt will wake CPU up every second to retry linking
         */
        __bis_SR_register(LPM3_bits+GIE);
      }

      /* Turn off LEDs. */
      BSP_TURN_OFF_LED1();
      BSP_TURN_OFF_LED2();

      /* Put the radio to sleep */
      SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);

      while (1)
      {
        /* Go to sleep, waiting for interrupt every second to acquire data */
        __bis_SR_register(LPM3_bits);

        /* Time to measure */
        if (sSelfMeasureSem) {
          volatile long temp,a;
          int degC, volt;
          int humidity;
          int results[3];
         
    #ifdef APP_AUTO_ACK
          uint8_t      noAck;
          smplStatus_t rc;
    #endif

          /* Get temperature */
          ADC10CTL1 = INCH_10 + ADC10DIV_4;       // Temp Sensor ADC10CLK/5
          ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
          /* Allow ref voltage to settle for at least 30us (30us * 8MHz = 240 cycles)
           * See SLAS504D for settling time spec
           */
          __delay_cycles(240);
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
          results[0] = ADC10MEM;                  // Retrieve result
          ADC10CTL0 &= ~ENC;
          
          /* Get humidity */
          //P2DIR = 0xFE;
          //P2OUT = 0x00;
          ADC10CTL1 = INCH_0 + ADC10DIV_4;       // Humidity Sensor ADC10CLK/5
          ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
          __delay_cycles(240);
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
          results[1] = ADC10MEM;                  // Retrieve result
          ADC10CTL0 &= ~ENC;
          
          /* Get voltage */
          ADC10CTL1 = INCH_11;                     // AVcc/2
          ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
          __delay_cycles(240);
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
          results[2] = ADC10MEM;                  // Retrieve result

          /* Stop and turn off ADC */
          ADC10CTL0 &= ~ENC;
          ADC10CTL0 &= ~(REFON + ADC10ON);
     
          /* 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
          */
          
          a = results[1];
          humidity = (a-0.379)/0.032;
          temp = results[2];
          volt = (temp*25)/512;
          msg[0] = degC&0xFF;
          msg[1] = (degC>>8)&0xFF;
          msg[2] = volt;
          msg[3] = humidity;
          
          
          /* Get radio ready...awakens in idle state */
          SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

    #ifdef APP_AUTO_ACK
          /* Request that the AP sends an ACK back to confirm data transmission
           * Note: Enabling this section more than DOUBLES the current consumption
           *       due to the amount of time IN RX waiting for the AP to respond
           */
          done = 0;
          while (!done)
          {
            noAck = 0;

            /* Try sending message MISSES_IN_A_ROW times looking for ack */
            for (misses=0; misses < MISSES_IN_A_ROW; ++misses)
            {
              if (SMPL_SUCCESS == (rc=SMPL_SendOpt(sLinkID1, msg, sizeof(msg), SMPL_TXOPTION_ACKREQ)))
              {
                /* Message acked. We're done. Toggle LED 1 to indicate ack received. */
                BSP_TURN_ON_LED1();
                __delay_cycles(2000);
                BSP_TURN_OFF_LED1();
                break;
              }
              if (SMPL_NO_ACK == rc)
              {
                /* Count ack failures. Could also fail becuase of CCA and
                 * we don't want to scan in this case.
                 */
                noAck++;
              }
            }
            if (MISSES_IN_A_ROW == noAck)
            {
              /* Message not acked */
              BSP_TURN_ON_LED2();
              __delay_cycles(2000);
              BSP_TURN_OFF_LED2();
    #ifdef FREQUENCY_AGILITY
              /* Assume we're on the wrong channel so look for channel by
               * using the Ping to initiate a scan when it gets no reply. With
               * a successful ping try sending the message again. Otherwise,
               * for any error we get we will wait until the next button
               * press to try again.
               */
              if (SMPL_SUCCESS != SMPL_Ping(sLinkID1))
              {
                done = 1;
              }
    #else
              done = 1;
    #endif  /* FREQUENCY_AGILITY */
            }
            else
            {
              /* Got the ack or we don't care. We're done. */
              done = 1;
            }
          }
    #else

          /* No AP acknowledgement, just send a single message to the AP */
          SMPL_SendOpt(sLinkID1, msg, sizeof(msg), SMPL_TXOPTION_NONE);

    #endif /* APP_AUTO_ACK */

          /* Put radio back to sleep */
          SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);

          /* Done with measurement, disable measure flag */
          sSelfMeasureSem = 0;
        }
      }
    }

    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
    }

    /*------------------------------------------------------------------------------
     * 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)
    {
      sSelfMeasureSem = 1;
      __bic_SR_register_on_exit(LPM3_bits);        // Clear LPM3 bit from 0(SR)
    }


  • One thing that hit my eye immediately:

    ADC10MEM is a 12 bit integer. So result[1] and therefore a is a value between 0 and 4095.

    So for a value of 1023 (== maximum input voltage == VRef applied to the input) "humidity = (a-0.379)/0.032;" translates to "humidity = (1023-0.379)/0.032 = 31956. Surely not what you want. Not to mention that /0.032 == *31.25, which is a much faster multiplication than a slow division. Even better would be an integer multiplication or a shift (/0.03125 == *32 == <<5 => much, much, much faster, but of course not as exact)

    Anyway, you need to first translate the the ADC10 reading into a voltage before you can apply your formula. Or you transform your formula constants into 'ADC units' instead of Volt. Since this is done at compile time, it won't consume any time with slow, slow, slow float calculations at runtime. See the formula and comments for the degC calculation for a hint how to do it.

  • Hi,

    Could you give me an example on how to translate the ADC10 reading into a voltage? Besides that, there was some incorrect humidity value appear on the hyperterminal although I'm not connected the humidity sensor to the target board. Anyone know what is the reason that causing this?

    This is the equation that given in the humidity sensor datasheet >>> humidity = (a-0.379)/0.032

    So, what must I do in order to get the accurate value? I really have no idea in this.

    And could anyone explain to me the following code? Thanks.

      if( (*tempOffset) != 0xFFFF )
          {
            degC += (*tempOffset);
          }

          /* message format,  UB = upper Byte, LB = lower Byte
          -------------------------------
          |degC LB | degC UB |  volt LB |
          -------------------------------
             0         1          2
          */
          
          a = results[1];
          humidity = (1000*a-379)*0.03125;
          temp = results[2];
          volt = (temp*25)/512;
          msg[0] = degC&0xFF;
          msg[1] = (degC>>8)&0xFF;
          msg[2] = volt;
          msg[3] = humidity;
         

  • The formula assumes 'a' being the sensor voltage.
    The voltage read by an ADC is
    V=result*Vref/((2^n)-1)

    where 'result' is the ADC reading, and 'n' is the ADC resolution in bit.
    So for ADC10 and 2.5V reference:
    V= result * (2.5/1023) = result * 0.002443792

    Bridget Tham Chia Mei said:
    And could anyone explain to me the following code? Thanks.


    The first part subtracts the temperature offset from degC, but only if it is valid (0xffff indicates that the calibration values have been erased).

    in 'volt=(temp*25)/512, the reading temp is converted into a voltage. However, the result is 20 times larger (*25 instead of *2.5 and /512 instead of /1023). So the result is not in V bit in 1/20V. A bit strange. Maybe there was a 2:1 divider on the input.
    The other lines extract the lower 8 bits and then the higher 8 bits from degC for storing the 16 bit value into an 8 bit array msg[]. However, the &0xff isn't necessary, in both lines, since it is implicitely done when assigning a 16 bit value to an 8 bit target.

  • Hi,

    I have added this p = a*0.002443792 to the code and the humidity value shown is 50 and it keep constant without changing. When unplugged the connection for humidity sensor and target board, the data displayed 50 too..why is this happen?

    To confirm, is it the target board will display a value although I am not connecting the humidity sensor? If not connected, it should display 0 RH right? why there is still a value displayed in hyperterminal?

    Thanks.

    while (1)
      {
        /* Go to sleep, waiting for interrupt every second to acquire data */
        __bis_SR_register(LPM3_bits);

        /* Time to measure */
        if (sSelfMeasureSem) {
          volatile long temp,a;
          int degC, volt, p;
          int humidity;
          int results[3];
         
    #ifdef APP_AUTO_ACK
          uint8_t      noAck;
          smplStatus_t rc;
    #endif

          /* Get temperature */
          ADC10CTL1 = INCH_10 + ADC10DIV_4;       // Temp Sensor ADC10CLK/5
          ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
          /* Allow ref voltage to settle for at least 30us (30us * 8MHz = 240 cycles)
           * See SLAS504D for settling time spec
           */
          __delay_cycles(240);
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
          results[0] = ADC10MEM;                  // Retrieve result
          ADC10CTL0 &= ~ENC;
          
          /* Get humidity */
          P2DIR = 0xFD;
          P2OUT = 0x00;
          ADC10AE0 |= 0x02;  // analog input enable for A1
          ADC10CTL1 = INCH_1 + ADC10DIV_4;       // Humidity Sensor ADC10CLK/5
          ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;
          __delay_cycles(240);
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
          results[1] = ADC10MEM;                  // Retrieve result
          ADC10CTL0 &= ~ENC;
          
          /* Get voltage */
          ADC10CTL1 = INCH_11;                     // AVcc/2
          ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;
          __delay_cycles(240);
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
          results[2] = ADC10MEM;                  // Retrieve result

          /* Stop and turn off ADC */
          ADC10CTL0 &= ~ENC;
          ADC10CTL0 &= ~(REFON + ADC10ON);
          
          

          /* 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
          */
          
          a = results[1];
          p = a*0.002443792;
          humidity = (p-0.379)/0.032;
          temp = results[2];
          volt = (temp*25)/512;
          msg[0] = degC&0xFF;
          msg[1] = (degC>>8)&0xFF;
          msg[2] = volt;
          msg[3] = humidity;
          
          
          /* Get radio ready...awakens in idle state */
          SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

  • 'p' is an int.
    'a' is in the range of 0..1023.
    So 'p=a*0.02443792 has only three possible results:For a = 0..409 it is 0, for a= 410..818, it is 1 and for A=819..1023 it is 2.
    humidity then is either -11, 19 or 50.

    So if you get 50 with ot without sensor, the ADC is 'seeing' an input value of 819..1023 all the time, which corresponds to a voltage of > 0.8*Vref.

    If you rearrange your math by multiplying both factors with 1000, you'll get different results:

    p = a*2.443792;
    humidity = (p-379)>>5; // '>>5' == '/32', only much faster

    Then p is in the range of 0..2499 (which is millivolts on 2.5V reference), and humidity will be -11..+66

    Looks like offset (apparently 379mV) and/or the divider for calculating the humidity from the voltage is wrong. Or the sensor will only cover a relatively small range from 0..66% or output more than 2.5V for > 66%.

  • Hi,

    Thanks for the previous information. I able to get the humidity value at 66% RH. Is it normal if the humidity value always in constant all the time without value changing? Because the humidity value I got is 66%RH all the time. May I know why it is remain constant?

    Is it the output voltage from humidity sensor keep constant at 2.5V? Will the temperature in the surrounding influence the output voltage for humidity sensor and therefore will be value change in humidity?

    Other than that, when I was not connecting humidity sensor to the end device, it displayed 26%RH. While connected the humidity sensor, it displayed 66%RH. Is it a normal situation?

    Besides that, may I know the 2.5V reference in the calculation for p = a*2.443792 a constant?

    Thanks.

  • Bridget Tham Chia Mei said:
    Is it normal if the humidity value always in constant all the time without value changing? Because the humidity value I got is 66%RH all the time.

    With the given input voltage and the 2.5V reference, 66 is the maximum value you can ever get. 66% (or more) means the input voltage is 2.5V (or more), which results in maximum conversion result (=66). The ADC will always report the reference voltage, if the input is higher than the reference. It "latches up" at 100%.

    To be able to measure higher voltages than 2.5V (which with your humidity formula seems to be the case for a humidity >66%), you'll have to eithe ruse a higher reference (you may use VCC, but that's instable and unprecise!) or divide the input voltage by a factor of 2 (with e.g. two 100% identical 10k resistors in series between sensor and GND, picking the ADC signal between the two) and multiplying the voltage taken with 2.

    Bridget Tham Chia Mei said:
    Besides that, may I know the 2.5V reference in the calculation for p = a*2.443792 a constant?

    For a 2.5V reference, the value ofa single bit is 2.5V/1023 = 2.443792mV.
    If your input signal uses a /2 divider, you can double this factor to get a voltage from 0 to 5V instead of 0 to 2.5V.

  • Hi,

    Now I have modified the following calculation:

    a = results[1];
          p = a*4.88;
          humidity = (p-379);
          if( (*tempOffset) != 0xFFFF )
          {
            humidity += (*tempOffset);
          }

    msg[3] = (humidity>>5)&0xFF;

    But I still can't get the actual results and it fixed at a value. On the other hand, I also tried the temperature sensor on the humidity sensor board and I have the following code:

          a = results[1];
          p = a*4.88;
          degree = (p+550);
          if( (*tempOffset) != 0xFFFF )
          {
            degree += (*tempOffset);
          }

    msg[3] = (degree>>7)&0xFF;

    The temperature I got from the eZ430-RF2500 Target Board is around 31.1 degree celsius while the temperature I got from the humidity sensor board is 32 degree celsius.
    I have done an experiment, I on the fan to reduce the surrounding temperature. It has shown that the temperature on eZ430-RF2500 Target Board has decreased to 30.3 degree while the other temperature still remain at 32 degree. Why can't the temperature decrease too? I'm doing this is to compare the temperature output for both the board.

    Thanks.      

  • Bridget Tham Chia Mei said:
    Now I have modified the following calculation:

    Did you also apply the external voltage divider? The software change only doubles the voltage result, as if using a 5V reference. But since you still have a 2.5V reference, you'll need to halve the input voltage by a resistor divider or an OpAmp with a gain of 0.5. So if the sensor emits 3V, they will arrive on the MSP as 1.5V (which is below the 2.5V reference and therefore won't latch up anymore on 2.5V) and the doubling of the factor int the software 'corrects' the result back to 3V.

    I can't say anything definite about the temperature thing. The MSP temperature sensor is measuring the temperature on the MSP die, so value and reaction times ma differ from an external sensor result. Also, the absolute value is subject to calibration. Just 'assuming' 555 as offset is, well, maybe you realyl measured it. You'll need a two-point calibration for temperature measurement. If you measure at 30 and 80°C, then you know th edifference between the two results is the gain over 50°C, so gain = (R80-R30), and the offset = R30 - (30*gain) = R80 - (80*gain).
    On MSPs with calibration values, the measurement is done at production. If not, you'll have to do it yourself. Using default values results in a relatively large error.

  • Hi Jens-Michael Gross,

    I'm doing almost same as Bridget Tham. I'm required to transmit the data obtained from the function generator to PC.

    Hi guys. I'm required to transmit the data from the function generator by connecting the output of the function generator directly to the MSP430 eZ430-RF2500 board and transmit the data to PC. I couldn't get the data. Can anyone help me on it ? Below are my code. Can anyone tell me where i've write it wrongly ? Thanks...

        /* Time to measure */

        if (sSelfMeasureSem) {

          volatile long temp;

          int degC, TransmittedData,value;

          int results[2];

    #ifdef APP_AUTO_ACK

          uint8_t      noAck;

          smplStatus_t rc;

    #endif

     

          /* Get temperature */

          ADC10CTL1 = INCH_10 + ADC10DIV_4;       // Temp Sensor ADC10CLK/5

          ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;

          /* Allow ref voltage to settle for at least 30us (30us * 8MHz = 240 cycles)

           * See SLAS504D for settling time spec

           */

          __delay_cycles(240);

          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start

          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled

          results[0] = ADC10MEM;                  // Retrieve result

          ADC10CTL0 &= ~ENC;

         

          /* Get TransmittedData */

          ADC10AE0 |= 0x02;

          ADC10CTL1 = INCH_4 + ADC10DIV_4;       // waveform Sensor ADC10CLK/5

          ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;

          __delay_cycles(240);

          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start

          __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled

          results[1] = ADC10MEM;                  // Retrieve result

          ADC10CTL0 &= ~ENC;

     

             /* Stop and turn off ADC */

          ADC10CTL0 &= ~ENC;

          ADC10CTL0 &= ~(REFON + ADC10ON);

     

          /* 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

          */

          TransmittedData = results[1];

          value = TransmittedData*0.024;

          msg[0] = degC&0xFF;

          msg[1] = (degC>>8)&0xFF;

          msg[2] = value;

     

    This is the code I'm using. I couldn't get the data from the function generator. Can you tell me which part of the code I've write it wrongly ?

  • im doing project using msp430rf2500. my part of application is to send analog sine wave signal in hertz from one board to other board. i changed the channel 10 to channel to 1 in end device program. what i want is to view that signal at any extension pin which could be pin10 (4.5). what are the modification needed  to access point program?

**Attention** This is a public forum