Infinite loop in Stop&Wait Implementation

Hi guys, im coding a communication system with 2 arduinos UNO and 2 nrf24, and my purpose is to implement a Stop and Wait mechanism, but my program seems to stuck in 1st frame i’m trying to send i can’t moove on. I’m stuck in this problem for 2 weeks already. i’m desperate so any help will be realy really usefull! If u go to if(papel==1) there is my transmitting code and if(papel==0) is my receiving code. My problem seems to be in transmiting mode. I have two types of frames one of data and another one of control in order no decide if the message was delivered or not and if it has to retransmit or send the new one. really need some help. Thank you for your attention.
Here is my code

#include <SPI.h>
#include "RF24.h"

/* Configurações do utilizador*/
bool radioNumber = 1 ; // um arduino é o 0 outro é o 1
RF24 radio(9, 10); /* Configuração do Hardware: Set up nRF24L01 radio on SPI bus plus pins 9 e 10 */


byte addresses[][6] = {"1Pipe", "2Pipe"};
bool papel = 1;//variavel usada para saber se transmite ou recebe
int len = 0;
int contador = 0;

struct Package {
byte id;
byte startBit = 0;  //
byte stopBit = 1;  //
char mensagem[28] = "";

typedef struct Package package;
package dados;

struct Acknowledge {
int ack;            //Toma valor 1 para ACK e 2 para NACK
typedef struct Acknowledge acknowledge;
acknowledge controlo;

void setup() {
Serial.begin(57600);// Boundrate nem muito alto nem muito baixo (bps)
Serial.println("*********** Trabalho de LTI Grupo1 **********");
Serial.println("-Caso queira comecar a transmitir, precione T");
radio.setChannel(110);// opera no canal 120 existem 126 canais diferente
radio.setPALevel(RF24_PA_MAX);//Modulo a trabalhar com maxima potencia (maior alcance)
radio.setDataRate( RF24_2MBPS ); // menor data rate possivel (maior alcance)
radio.setRetries(5, 15);

if (radioNumber) {
  radio.openReadingPipe(1, addresses[0]);
} else {
  radio.openReadingPipe(1, addresses[1]);
radio.startListening();// funciona á partida como receptor até ordem em contrario

unsigned char CRC7_POLY = 0x91;

unsigned char getCRC(char message[], char length)
char i, j, crc = 0;

for (i = 0; i < length; i++)
  crc ^= message[i];
  for (j = 0; j < 8; j++)
    if (crc & 1)
      crc ^= CRC7_POLY;
    crc >>= 1;

return crc;

void loop() {
/********************************************************************* Transmissão **************************************************************************************/

if (papel == 1) {
  char aux [28] = "";

  for (int j = 0; j < 28; j++) {
    aux[j] = dados.mensagem[j];

  if (Serial.available()) {
    len = Serial.readBytesUntil('\n', dados.mensagem, 27);
  if (len > 0) {

    if (radio.available()) {
      Serial.print("\nleu trama ack");, sizeof(controlo));

      if (controlo.ack == 1) {
        Serial.print("\nACK recebido com sucesso!");
        Serial.print("\nPreencha a mensagem");
        if (Serial.available()) {
          len = Serial.readBytesUntil('\n', dados.mensagem, 27);
          Serial.print("\nMensagem: ");


        dados.mensagem[28] = getCRC(dados.mensagem, 28); = 1;
        Serial.print("\nACK recebido com sucesso!");
        Serial.print("\nID da trama:");
        Serial.print("  \nFCS(frame check sequence):  ");
        if (!radio.write(&dados, sizeof(package))) {
          Serial.print("\nnao enviou nada");
        Serial.print("\nenviou trama ");

      }//fim do ack

      else if ( controlo.ack == 2 ) { = 0;
        Serial.print("\n Recebeu NACK");
        Serial.print("\nTrama ");
        Serial.print(" a ser reenviada  ");

        if (!radio.write(&dados, sizeof(package))) {
          Serial.print("Nao reenviou a trama com sucesso");
      }//fim do nack
      else {
        Serial.print("\nEnvio da primeira trama");
        if (!radio.write(&dados, sizeof(package))) {
          Serial.print("1n nao enviou a primeira trama");
      } //fim do else da primeira trama

    else {
      if (!radio.write(&dados, sizeof(dados))) {
        Serial.print("\,naoescreveeu nada");

  }//fim do if id>0

  else {
    Serial.print("\n Preencha a mensagem");
}//fim do transmiissor
/******************************************************************** Recepção *************************************************************************************/

if ( papel == 0 ) {
  byte start_compare = 0;
  byte stop_compare = 1;
  if (radio.available()) { &dados, sizeof(package));

    Serial.print("\n\nMensagem:  ");
    Serial.print("\nACK id: ");
    if (start_compare == dados.startBit) {
      if (stop_compare == dados.stopBit) {
        if (dados.mensagem[28] == 0) {      // Verifica se a trama chegou com o byte de CRC a 0, significado de que chegou sem erros
          controlo.ack = 1;
          radio.write(&controlo, sizeof(acknowledge));
          Serial.print("\nACK enviado");
        }//fim do if crc
      }//fim do if stop bit
    }//fim do  if startBit
    else {
      controlo.ack = 2;                        ;
      radio.write(&controlo, sizeof(acknowledge));
      Serial.print("\nNACK enviado");
    }//fim else
  }//fim radio available
}//fim do recetor
}//fim do loop

You should always read direction first. Now go do that. The thread is titled "How to Use This Forum" and it is at the top of any board on the forum. There you will learn, among other things, how to post code properly so it doesn't come out in italics.

Thank you for that recomendation.

Also, the moderator gets a little cranky when you double post. Don't do that.

What do you mean by "Stop and Wait"?

This Simple nRF24L01+ Tutorial may be helpful.


Stop and wait is the flow data control mechanism that works with ACK, thing is i can't use the auto ACK, i have to build my own.

andremartins4: thing is i can't use the auto ACK,

Why ever not? It makes things very simple.

i have to build my own.

Then the 3rd example in my Tutorial should help get you started.


Yes, i'm getting new ideas with your examples thank your so much. I found my receiver is not writing the ACK struct, probably it has to be with pipes i haven't figgured out yet. And yes, AUTO ACK would simply solve this problem but my professor wants us to implement everything from ground zero. Thank you so much for your attention.

andremartins4: but my professor wants us to implement everything from ground zero.

Why is it not "ground zero" to use the normal features of a product?


My guess is that AutoAck doesn't allow us to implent mechanisms such as Stop and Wait and Sliding Window. Basicly we have to build our own protocols. Next step will be to do a Medium Access Control. If you noticed we had to build our own CRC, we can't use the one provided by the rf24 module.

we can’t use the one provided by the rf24 module.

I did not know it is possible to disable the CRC in the module.

I can understand the desirability of teaching students how to write CRC code. But you don’t need to use an nRF24 for that. You can do it with a simple serial link.

My guess is that AutoAck doesn’t allow us to implent mechanisms such as Stop and Wait and Sliding Window.

As you have not described what you actually need to do I cannot comment except to say I would be surprised autoAck or ackPayload would be an obstacle. My guess is that you are confusing the business of communication and the business of control.

Is your Professor actually familiar with the features of the nRF24L01+ ?


I totally aggree with you. And yes i'm sure he knows all the features nrf24 provides. I could solve the problem by the way. Next fase we will implement a CSMA/CA protocol very interesting though.