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.

SimpliciTI - Communication between End Device and Access Point in AP -> ED direction

Other Parts Discussed in Thread: SIMPLICITI

We're trying to set up a SimpliciTI network in a star topology, so that the Access Point (AP) have properties of an End Device (ED). Shortly, it means that the AP will have some buttons and LEDs just like the other peripheral End Devices. Therefore, the communication between AP and EDs have to be bidirectional. This network have just one AP and up to six EDs. Meanwhile, for this issue, consider only one ED and one AP.

From SimpliciTI sample application "AP as Data Hub”, with some changes for our specific device containing CC2511F32, we verified that is possible to establish a communication between two devices, where ED is transmitter and AP receiver. We need to make it in the other way. It means, we need to set up the devices so the ED could receive a packet transmitted from AP. The problem is presented below.

In both devices (AP and ED) the callback was used, declared by the funcion SMPL_Init(). During the initialization the JOIN procedure takes place and after that there is a LINK procedure, what is made using the functions SMPL_LinkListen() (on AP) and SMPL_Link() (on ED).

In the AP side, the transfer of the packet is made with success using the function SMPL_Send() from SimpliciTI API. Although, no ACKNOWLEDGE is returned for the AP, what is verified when the function SMPL_Send() is replaced by SMPL_SendOpt(), that requires the ACKNOWLEDGE token to return SUCCESS.

In the ED side, the packet transfered from AP is not recognized, because the ED's callback function never executes. We expect that the callback function would be executed always a packet is received, but it never happens.

Please, can you give us some tips to send packets from AP to ED, based on sample application "AP as Data Hub"?

 

Thanks in advance.

 

Rômulo Mendes

  • This is quite simple - just read out the SimpliciTI API. Default state for AP is RX.

    During SMPL_Send the device (AP) is set to TX and just transmits and returns back to RX. On ED you have to set for this moment the RX manually.

    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

    And read out the queue with SMPL_Receive.

    Of course, you have to modify the code on both side. But be prepared, that demo apps are not usable standalone, they miss a lot of important features like failed to link policy etc.

     

  • Adam,

     

    That's exactly what was missing! Thank you!

    The ED's callback can be executed now because I configured the device for RX operation just like you said.

    I would appreciate if you help me in the post SimpliciTI - Communication between End Devices in a star topology. These posts are issues related to proof of concepts we are having with SimpliciTI.

     

    Thank you!

     

    Rômulo Mendes

  • Hi, I am trying to set something similar, but a little more complicated.

    I am setting each End Device with an ID, which I do manually. The End Devices link to the Access Point correctly using the base of the "AP as Data Hub" example. I am trying to write a code in which the Access Point receives messages through the UART port, and those messages includes the ID of the End Devices that must be transmitted to.

    I have been trying to program something such that when the End Devices link to the Access Point, they send its ID such that the Access Point relates the ID of the End Device with the respective LinkID, in order to know what LinkID to use to transmit the messages received from the UART port. Until now, I haven't had any success.

    Is there an easy method to do what I am trying to do using the example "AP as Data Hub"?

    Thanks in advance.

    Gustavo.

  • gchaconr said:

    Hi, I am trying to set something similar, but a little more complicated.

    I am setting each End Device with an ID, which I do manually. The End Devices link to the Access Point correctly using the base of the "AP as Data Hub" example. I am trying to write a code in which the Access Point receives messages through the UART port, and those messages includes the ID of the End Devices that must be transmitted to.

    I have been trying to program something such that when the End Devices link to the Access Point, they send its ID such that the Access Point relates the ID of the End Device with the respective LinkID, in order to know what LinkID to use to transmit the messages received from the UART port. Until now, I haven't had any success.

    Is there an easy method to do what I am trying to do using the example "AP as Data Hub"?

    Thanks in advance.

    Gustavo.

    Hi,

    Do you have problems with communication or with the IDs? I need a method to identify the EDs in the AP, could you tell me a guideline of your method?Right now, I have a bidirectional communication, but some troubles with IDs too.

    About the serial communication to AP, and ED-AP communication, the main problem I see is that ED are devices created initially for transmission. So for enabling AP to ED communication, you need:

    - Implementing a callback function in the ED and enable the RX (reception) mode when AP sends the message.

    - The RX mode increases the power consumption, so it would be recommendable to avoid it all the time that it is possible if it is a battery powered device. In this case, I would implement a way to enable the RX mode with an external interrupt, and then send by serial port the command with the ID to the AP, and this one by RF to the device whose ID matches. If you sent data periodically, you could enable a timer interrupt in both sides, so in these interval you could turn on the RX mode in ED, AP sends messages, and when the interval ends,ED goes to sleep.

    Summarizing, the main problem, if you do not want that the EDs are always on RX, is when ED enables this mode. In my project, to do testing/debugging, I enable the RX mode by serial port in ED.

    I hope this can help you.

  • Thanks for answering.

    What I am doing now is the following:

    - At the Access Point: once an End Device links to it in the main loop (using the AP as Data Hub example), inside the "if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers])" I set the AP to be be listening (through a main loop) for a msg from the ED corresponding to the current link sLID[sNumCurrentPeers]. Thus, the message it will receive contains the ID from that ED, just then the code will continue the same as the original AP as Data Hub example, with the exception that will also wait for information from the UART port to send information to the respective ED. Part of the code is the following:

          /* listen for a new connection */
          while (1)
          {
            if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers]))
            {
                toggleLED(1);
                done = 0;
                while (!done)
                {
                    if (SMPL_SUCCESS == SMPL_Receive(sLID[sNumCurrentPeers], msg, &len))
                    {
                        toggleLED(2);
                        ArrayPeer[count] = sNumCurrentPeers;
                        ArraySenID[count] = msg[0];
                        *msg |= NWK_APP_REPLY_BIT;
    #ifdef FREQUENCY_AGILITY
                        SMPL_Send(sLID[sNumCurrentPeers], msg, len);
    #endif
                        BSP_ENTER_CRITICAL_SECTION(intState);
                        sPeerFrameSem--;
                        BSP_EXIT_CRITICAL_SECTION(intState);
                        done = 1;
                    }
                }
                count = count + 1;
                  break;
            }
            /* Implement fail-to-link policy here. otherwise, listen again. */
          }

    - At the End Devices: Once it links to the AP, it will start sending message to the AP with its ID in it, this transmission will keep going until the AP has sent an ACK that it has received the ID. Just then the code will enter to the while(1) loop from the main_manyEDs.c code, with the exception that it will stay in RX mode for ever waiting for a message from the AP. Part of the code is the following:

    while (SMPL_SUCCESS != SMPL_Link(&sLinkID1))
      {
        toggleLED(1);
        SPIN_ABOUT_A_SECOND;
      }
      if (BSP_LED1_IS_ON())
      {
        toggleLED(1);
      }
      // Code to send info about the ID
          msg[1] = sensorID;
          msg[0] = sensorID;
          SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
          done = 0;
          while (!done)
          {
              if (SMPL_SUCCESS == SMPL_Send(sLinkID1, msg, sizeof(msg)))
              {
                  //toggleLED(2);
    #if defined( FREQUENCY_AGILITY )
                {
                  bspIState_t intState;
     
                  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
                  NWK_REPLY_DELAY();
                  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);
     
                  if (!sPeerFrameSem)
                  {
                    // Try again if we havn't received anything. 
                    continue;
                  }
                  else
                  {
                    uint8_t len;
     
                    BSP_ENTER_CRITICAL_SECTION(intState);
                    sPeerFrameSem--;
                    BSP_EXIT_CRITICAL_SECTION(intState);
                    toggleLED(2);
                    // We got something. Go get it.  
                    if (SMPL_SUCCESS == SMPL_Receive(sLinkID1, msg, &len))
                    {
                         done = 1;
                    }
                  }
                }
    #else
                break;
    #endif
              }
          }

     I have checked that the transmission from UART port to the AP and then from the AP to the ED works (I have test it with just one ED), but once I try to set more than one ED with the code I explained before it does not work at all (when the second ED tries to link and then transmits its ID, the AP does not even link it).

    One question: from the examples provided by TI, I have not seen any setting for the AP to receive or transmit information (such SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0) or SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_TXON, 0)). Does the AP have the capacity to receive and transmitt at any time without setting the transceiver for such situations?

    Thanks in advance for new ideas.

  • Hi,

    thanks for your answer, but your solution does not work for me. I am trying to  use sPersisInfo struct for managing the ID of devices. My radio modules would have to be turned off, so I need a way to identify them, even after a radio module power off.

    About your second ED that does not connect, is its address (in smpl_config.dat) different from the other two devices? And do the join and link token match between AP and ED? They are "noob bugs", but after a lot of coding and debugging, we forget them sometimes. It would be useful knowing what SMPL_Link() is returning in the second ED. I have not worked with two ED yet, so I cannot give you more "real" information.

    About your last point, I have read some related to it, but I cannot find it now, so I prefer to not say anything for not making a mistake.

    Best regards.

  • Hi, I have been searching that structure you mentioned (sPersisInfo), but haven't found it. Where is it defined? and how is it related to the link between the AP and ED?

    Thanks,

    Gustavo.

  • Hi,

    the structure is in nwk.c and about the second question, I am trying to understand it. If you have any idea, please post it.

    My main problem in my project is identify, with the same ID, a device whose radio module has been turned off. If each time a radio module and the stack is initialized, the AP give it a new ID, it is impossible make a communication network. And I  try to use this to avoid generate more code to identify.

    If it does not work, I will have to check another way.

    Best regards.

  • I finally could not figure out how to use the structure you mentioned, but after debugging what I was working on, I finally could get a code to identify each ED with an unique ID, which is stored in the AD.

    Part of the code for the AD is the following:

      while (1)
      {
        // LINKING EDs
        if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))
        {
          /* listen for a new connection */
          while (1)
          {
            if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers]))
            {        
              break;
            }
          }
          sNumCurrentPeers++;
          BSP_ENTER_CRITICAL_SECTION(intState);
          sJoinSem--;
          BSP_EXIT_CRITICAL_SECTION(intState);
        }
        ///////////////////////////////////////////////////////////////
        // GETTING THE ID FROM THE SENSORS
        if (sPeerFrameSem)
        {    
            uint8_t     msg[MAX_APP_PAYLOAD], len, i;
            for (i=0; i<sNumCurrentPeers; ++i)
            {
                if (SMPL_SUCCESS == SMPL_Receive(sLID[i], msg, &len))
                {
                    ArraySenID[i] = msg[2]; // store the ID of the ED in an array, which relates the index "i" (and therefore its respective link) with the ID
                    LcdWriteValue(ArraySenID[i]);
    #ifdef FREQUENCY_AGILITY
                    SMPL_Send(lid, msg, len);
    #endif
                    BSP_ENTER_CRITICAL_SECTION(intState);
                    sPeerFrameSem--;
                    BSP_EXIT_CRITICAL_SECTION(intState);
                }
            }
        }
        ///////////////////////////////////////////////////////////////
        .... // do something....

       }

    Part of the code for the EDs is the following:

      while (1)
      {
        if (sendingID2AP)
        {
          SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

          // some msg with the ID to be sent t the AP
          msg[3] = pressBef;
          msg[2] = sensorID;
          msg[1] = ++sTid;
          msg[0] = (button == 1) ? 1 : 2;
          done = 0;
          while (!done)
          {
            for (misses=0; misses < MISSES_IN_A_ROW; ++misses)
            {
              if (SMPL_SUCCESS == SMPL_Send(sLinkID1, msg, sizeof(msg)))
              {
    #if defined( FREQUENCY_AGILITY )
                {
                  bspIState_t intState;
                  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
                  NWK_REPLY_DELAY();
                  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);

                  if (!sPeerFrameSem)
                  {
                    continue;
                  }
                  else
                  {
                    uint8_t len;

                    BSP_ENTER_CRITICAL_SECTION(intState);
                    sPeerFrameSem--;
                    BSP_EXIT_CRITICAL_SECTION(intState);

                    if (SMPL_SUCCESS == SMPL_Receive(sLinkID1, msg, &len))//len && (*msg & NWK_APP_REPLY_BIT))
                    {
                      toggleLED(1);
                      break;
                    }
                  }
                }
    #else
                break;
    #endif
              }
            }
            if (misses == MISSES_IN_A_ROW)
            {
              ioctlScanChan_t scan;
              freqEntry_t     freq[NWK_FREQ_TBL_SIZE];

              scan.freq = freq;
              SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SCAN, &scan);

              if (1 == scan.numChan)
              {
                SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SET, freq);
              }
            }
            else
            {
              done = 1;
              sendingID2AP = 0;
            }
          }
          SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
        }
        else
        {
          // do something after the ID has been sent to the AP
        }

    It may not be the most sophisticated code I could write, but at least it works. I hope it works for you. Both codes are based on the AP as Data hub example.

    Gustavo.

  • Thanks for your time.

    Finally I have done something similar. But instead of sending an ID form the ED to the AP, I read the address of each device who joins to the network (each one has a different address) to identify them. By this way, I avoid to make a double identification.

    I tell you for if it can be useful for you.

    Thanks again.

  • Yes, I would like to know how you do that. Where can I get the address from each ED at the AD? Are you referring to the address variable define in "THIS_DEVICE_ADDRESS" in the file "smpl_config.dat"?

    Also, how do you set the EDs to be able to receive packets from the AP? Is it enough with the command "SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0)" or you need to set something else?

    Thanks in advance.

  • gchaconr said:
    Yes, I would like to know how you do that. Where can I get the address from each ED at the AD? Are you referring to the address variable define in "THIS_DEVICE_ADDRESS" in the file "smpl_config.dat"?

    Yes, when I talk about address, I am refering to the array where is cointained the values of "THIS_DEVICE_ADDRESS". This is explained in the SimpliciTI FAQ, poin 2.12 "How to obtain the remote peer address in SimpliciTI? ", http://processors.wiki.ti.com/index.php/SimpliciTI_FAQ#How_to_obtain_the_remote_peer_address_in_SimpliciTI.3F.

    You have to add that function in nwk.c, and declare it in the main file like the FAQ says. So, for example, when a SMPL_Link has success, you can call this function with this sLID[i], and store all the address or only a part of it in an array.

    gchaconr said:
    Also, how do you set the EDs to be able to receive packets from the AP? Is it enough with the command "SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0)" or you need to set something else?

    About this, you have to implement a callback similar to the AP one, and call it in SMPL_Init(sCB) for example. So when you have the radio in RX mode, when a packet is received, the calback function set a flag like sPeerFrame, and you have a function where you call a SMPL_Receive(...).

    I am not in the lab, so I cannot paste code right now and maybe i have done some mistake. If there is something that seems rare or wrong, tell me.

  • Thanks a lot for the information, now the code is much simpler.

    Although for some reason even when I changed the device address in the file "smpl_config.dat", it has no effect (seems that all the EDs have the same address). So I finally followed the section "How to override the address configuration in smpl_config.dat?" from the same page you posted, and then finally works.

    Thanks again for the help.

  • Hi,

    sometime this happened to me too. I modified the smpl_config.dat, but it did not have effect. I solved this doing a cleaning of project each time I modified something in the *.dat files. It seems that works.

  • Thanks for helping, that works great.

  • Hi,

    just adding information. Personally i also don't like to use the THIS_DEVICE_ADDRESS in smpl_config.dat. So usually i use this:

    http://processors.wiki.ti.com/index.php/SimpliciTI_FAQ#How_to_override_the_address_configuration_in_smpl_config.dat.3F

  • Hi,

    I am going give you a quick tips, maybe you have taken in consideration:

    1) The ACKNOWLEDGE option has to be enabled on both devices, therefore, uncomment the line in smpl_nwk_config.dat if you do not do it already.

    2)  EDs need to be on reception mode to get the message from AP with the function SMPL_Receive(...). So before the AP try to send the message, ED has to be in reception mode: SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);. Moreover the radio must be awaken.

    I hope it can help you. Take a look to the other post in this thread too.

  • Hi "Is T da S",

    I follow your instruction for Reception of EDs, but it still did not work. I use these codes to put ED into the reception mode

    /* wake up radio. we need it to listen for others babbling. */
      SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);
      /* turn on RX. default is RX off. */
      SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

    Should I do at the AP side? I use SMPL_SendOpt() to send data