This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Apparently two channels are colliding?

Dear Nordic,

Device: nRF51422. Protocol: ANT+. Softdevice: S210 v5.0.0

I have 3 devices: two masters (No. 1 and 2) and one slave (No. 3). In my application, I pair the slave to the two masters, store both channels IDs, and close all channels, until a button in slave is pressed. When masters are plugged, they have always channel opened and they are sending data.

When the button in slave is pressed, I quickly open both channels, send information (broadcast data type), receive a ACK (done by me by SW), and close both channels. This works fine most of the times, even if one of the masters (either 1 or 2) doesn't exist.

The problem is that, apparently randomly, when I try several times communication without one of these masters present, and then I connect them back again, sometimes, at some point information only arrives to one of the masters, and it even switches from one to the other. So if I press once, info may arrive only to master 1, and next time when I press again, info may arrive only to master 2.

The thing is that I do not know the exact cause of this problem. I am trying a lot of things but none of them seem to give any result.

Any idea on what it could be happening? Please feel free to ask more details.

  • Strange. I'm not sure what could cause this. Would it be possible to share your complete projects so I can test them here? Or simple projects that reproduces the behavior?

  • Hi Petter, thanks for the fast reply. Here you have the piece of code I use to send the message:

    void send_message_and_get_ack(message_t* p_message, channel_t* p_channel_0, channel_t* p_channel_1)
    {
        if(p_message->current_status == PROTOCOL_STATUS_DISABLED)
        {
            p_message->payload = PROTOCOL_STATUS_ENABLED;
        }
        else if(p_message->current_status == PROTOCOL_STATUS_ENABLED)
        {
            p_message->payload = PROTOCOL_STATUS_DISABLED;
        }
    
        static uint64_t time_start = 0; //variable for timeout
    
        if(!is_front_paired() || is_only_rear_message(p_message))
        {
            open_channel(p_channel_0);
            static uint8_t ack_retries = 0; // counter for ack retries
            // send and get ack from rear
            send_message(p_channel_0, p_message);
            bool message_failed = false;
            while(p_message->class != p_channel_0->received_ack)
            {
                if((get_timer_count() - time_start) > messages_defined.ack_timeout)
                {
                    time_start = get_timer_count();
                    ack_retries++;
                    send_message(p_channel_0, p_message);
                    if(ack_retries > MAX_ACK_RETRIES)
                    {
                        message_failed = true;
                        break;
                    }
                }
            }
            time_start = get_timer_count();
            ack_retries = 0;
            p_channel_0->received_ack = 0x00;
            if(!message_failed)
            {
                p_channel_0->master_present = 0x01;
                toggle_message_status(p_message, &messages_defined);
            }
            else                    //failed, what do? go to status OFF?
            {
                p_message->current_status = PROTOCOL_STATUS_DISABLED;
            }
            close_channel(p_channel_0);
        }
        else
        {
            static uint8_t ack_retries_0 = 0; // counter for ack retries
            static uint8_t ack_retries_1 = 0; // counter for ack retries
            bool message_failed = false;
    
            open_channel(p_channel_0);
            open_channel(p_channel_1);
            send_message(p_channel_0, p_message);
            send_message(p_channel_1, p_message);
    
            bool message_failed_0 = false;
            bool message_failed_1 = false;
    
            bool message_succeed_0 = false;
            bool message_succeed_1 = false;
    
            while(true)
            {
                if(p_message->class == p_channel_0->received_ack)
                {
                    p_channel_0->master_present = 0x01;
                    message_succeed_0 = true;
                }
                if(p_message->class == p_channel_1->received_ack)
                {
                    p_channel_1->master_present = 0x01;
                    message_succeed_1 = true;
                }
                if((get_timer_count() - time_start) > messages_defined.ack_timeout)
                {
                    time_start = get_timer_count();
    
                    if(p_message->class != p_channel_0->received_ack && !message_succeed_0)
                    {
                        ack_retries_0++;
                        send_message(p_channel_0, p_message);
                    }
    
                    if(p_message->class != p_channel_1->received_ack && !message_succeed_1)
                    {
                        ack_retries_1++;
                        send_message(p_channel_1, p_message);
                    }
    
                    if(ack_retries_0 > MAX_ACK_RETRIES)
                    {
                        message_failed_0 = true;
                    }
    
                    if(ack_retries_1 > MAX_ACK_RETRIES)
                    {
                        message_failed_1 = true;
                    }
    
                    if(message_failed_0 && message_failed_1)
                    {
                        message_failed = true;
                        break;
                    }
                }
                if((message_succeed_0 && message_succeed_1) ||
                   (message_succeed_0 && message_failed_1) ||
                   (message_succeed_1 && message_failed_0) ||
                   (message_failed_0 && message_failed_1)
                    )
                {
                    break;
                }
            }
            time_start = get_timer_count();
            ack_retries_0 = 0;
            ack_retries_1 = 0;
            p_channel_0->received_ack = 0x00;
            p_channel_1->received_ack = 0x00;
    
            if(message_succeed_0 || message_succeed_1) //only if one of them, just to allow everything
            {
                toggle_message_status(p_message, &messages_defined);
            }
            else
            {
                p_message->current_status = PROTOCOL_STATUS_DISABLED;
            }
            close_channel(p_channel_0);
            close_channel(p_channel_1);
        }
    }
    
  • Could you share your complete projects (zip them) so I can compile and test them here?

  • If you open a case through your MyPage at nordicsemi.com you can upload it to me privately there.

Related