Problems implementing CSMA/CA Protocol (ARDUINO + RF24L01)


good night everyone, code i'm posting here implementation of wireless connection operating 2 transmiters , 1 receiver. receiver able transmitt aswell due need send "manual" ack when succssefully receives frame. problem want both transmitters compete transmit although, happening is, jamming each other , cant transmit anything. if operate 1 transmitter transmition goes expected. sorry english, here code:

receiver


//recetor
#include <spi.h>
#include <nrf24l01.h>
#include "rf24.h"
#include <printf.h>

//rf24 lti(9, 10); //pinos pa com
const int pince = 9;
const int pincsn = 10;
rf24 lti(pince, pincsn);
const uint64_t raddress[] = {0xb00b1e50d2ll, 0xb00b1e50c3ll}; // endereços dos pipes para receber dados das duas estações transmissoras
const uint64_t waddress[] = {0xb00b1e50b1ll, 0xb00b1e50a4ll}; // endereços dos pipes para enviar dados para duas estações transmissoras

//estrutura meu pacote.

typedef struct pacote {
byte startbit = 0;
byte stopbit = 1;
byte id_trama; //id pacote
char payload[3] = "";
unsigned char crc;
char rede[3] = "";
};

typedef struct tramacontrolo {
byte ack;
pacote id_trama;

};


void setup() {
//configs
serial.begin(115200); //baud
serial.println("*********************recetor***********************");

lti.begin();
lti.setpalevel(rf24_pa_max);
lti.setchannel(120);
lti.setdatarate(rf24_2mbps);
lti.enabledynamicpayloads();
lti.setretries(15, 15);

lti.openreadingpipe(1, raddress[0]);
lti.openreadingpipe(2, raddress[1]);
lti.startlistening();

}

const unsigned char crc7_poly = 0x91;

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


for (i = 0; < length; i++)
{
 crc ^= message;
 for (j = 0; j < 8; j++)
 {
   if (crc & 1)
     crc ^= crc7_poly;
   crc >>= 1;
 }
}

return crc;

}


void loop() {

pacote data;
tramacontrolo ok;

byte startb = 0; //b11111110;
byte stopb =  1; //b00000001;
char network[3] = "aa";
unsigned char incoming;
byte pipeno = 0;

if (lti.available(&pipeno)) {
 while (lti.available(&pipeno)) {
   lti.read(&data, sizeof(pacote)); //pega na trama , lê
 }
 if (startb == data.startbit) {

   if (stopb == data.stopbit) {
     data.crc = getcrc(data.payload, 3); //vejo o valor crc dos dados que vou ler....  -> se esse valor = 0, bem rececionado.
     //serial.print("\n\ncumpriu testes de startbit e stopbit");
     //serial.print("\nvalor crc:    ");
     //serial.print(incoming);
     if (data.crc == 0) { //crc = 0 , sem erros
       //serial.print("\ncumpriu testes crc");
       if (network == data.rede) {

       }
     }
   }
   serial.print("\nrecebi dados da estacao: ");
   serial.print(pipeno);
   serial.print("\ntrama numero: ");
   serial.print(data.id_trama);
   enviarackcorreto(pipeno);
   serial.print("\nack enviado");
 }
 else
 {
   enviarnackcorreto(pipeno);
   serial.print("\nnack enviado");
 }


}

}

//funcao para enviar ack para estação correta
void enviarackcorreto(byte papa) {
tramacontrolo ok;
lti.stoplistening();
lti.openwritingpipe(waddress[papa - 1]);
ok.ack = 1;
lti.write(&ok, sizeof(tramacontrolo));
lti.startlistening();
}

//funcao para enviar nack para estação correta
void enviarnackcorreto(byte papa) {
tramacontrolo ok;
lti.stoplistening();
lti.openwritingpipe(waddress[papa - 1]);
ok.ack = 0;
lti.write(&ok, sizeof(tramacontrolo));
lti.startlistening();
}

transmitter 1:

//transmissor 1
#include <spi.h>
#include <nrf24l01.h>
#include "rf24.h"
#include <printf.h>

const int pince = 9;
const int pincsn = 10;
rf24 lti(pince,pincsn); //rf24 radio(9, 10);
const uint64_t waddress = 0xb00b1e50d2ll;   //pipe de transmissão de tramas
const uint64_t raddress = 0xb00b1e50b1ll;  //pipe de receção de tramas


typedef struct pacote {
byte startbit = 0; //combinacao binário
byte stopbit = 1; //combinacao binária
byte id_trama; //id pacote
char payload[3] = {0x81, 0x89, 0x00}; //meus dados serem enviados
unsigned char crc;
char rede[3] = "aa";
};

typedef struct tramacontrolo {
byte ack;       //ack = 1 nack = 0
byte ackcount;
//byte estacao;
};

bool tx = 1;
int tempo_slot = 4;
/******************************************************setup**********************************************************/

void setup() {
//configs
serial.begin(115200); //baud
serial.println("\n**************transmissor 1******************");
lti.begin();
lti.setpalevel(rf24_pa_max);
lti.setchannel(120);
lti.setdatarate(rf24_2mbps);
lti.setretries(15, 15);
lti.enabledynamicpayloads();

lti.openwritingpipe(waddress);        //open writing or transmit pipe
lti.openreadingpipe(1,raddress);  //open reading or recieve pipe
lti.stoplistening(); //go transmit mode


//serial.println("hello!");

}

/*******************************************************crc*************************************************************/
const unsigned char crc7_poly = 0x91;

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

for (i = 0; < length; i++)
{
 crc ^= message;
 for (j = 0; j < 8; j++)
 {
   if (crc & 1)
     crc ^= crc7_poly;
   crc >>= 1;
 }
}

return crc;

}
/**************************************************transmissor*************************************************************/
void loop() {
//config trama e defs necessárias
pacote dados;
tramacontrolo ok; //trama controlo

dados.payload[2] = getcrc(dados.payload, 2);
dados.crc = getcrc(dados.payload, 3);
serial.print("crc:    ");
serial.print(dados.crc);

if (tx == 1)
{  
 delay(4);   // atraso isf
 bool estado_meio = false;
 int fator_k;
 lti.startlistening();
 if (lti.testcarrier()) {
   serial.print("\n canal ocupado, esperar...");
   fator_k = rand() % 10;
   int = 0;
   while (i < fator_k)
   {
     delay(1);
     i++;
   }
   estado_meio = true;
   
 }
 else if(estado_meio==false)
 {
   lti.stoplistening();
   serial.println("\ncanal aparenta estar livre. vou esperar um tempo random e enviar........\n");
   delay(4);
   int = 0;
   fator_k = rand() % 10;
   while (i < fator_k)
   {
     delay(1);
     i++;
   }

   unsigned long tempo_inicio = micros(); //mal implementado
   if (!lti.write(&dados, sizeof(pacote))) { //escrever o meu pacote
     serial.println("\nfalhou o envio....\n");
   }

   lti.startlistening(); //começo ouvir , comecou enviar

   unsigned long espera = micros();
   boolean timeout = false;

   while (!lti.available()) {
     if ( (micros() - espera)  > 200000) {
       timeout = true;
       break;
     }
   }
   if (timeout)
   {

     serial.print("\ntimeout");
     delay(1500);
     serial.print("\ntentar enviar novamente trama...");
     dados.id_trama;
     lti.stoplistening();

     lti.write(&dados, sizeof(pacote)); //envio trama outra vez
     dados.id_trama++;
     lti.startlistening();

     serial.print("\nvou reenviar trama:  ");
     serial.print(dados.payload);
     serial.print("\nid da trama:    ");
     serial.println(dados.id_trama);

   }
   else {
     lti.read(&ok, sizeof(tramacontrolo));

     unsigned long tempo_fim = micros();

     if (ok.ack == 1) { //recebeu ack actualizar dados
       serial.print("\ntrama enviada: ");
       serial.print(dados.payload);
       serial.print("\ntamanho da trama: ");
       serial.print(sizeof(pacote));
       serial.print("\nack recebido "); //esperamos aqui ok.ack = 1 && ok.nack = 0;
       serial.print("\nid da trama :   ");
       serial.print(dados.id_trama);
       serial.print("\nrtt ");
       serial.print(tempo_fim - tempo_inicio);
       serial.println(" microsegundos");

       dados.id_trama++; //incremento para o proximo pacote
       lti.stoplistening();
       serial.println("vou enviar o proximo....!\n"); //ter em conta que pode falhar no envio transmissor outra vez!!!!!
     
       lti.stoplistening();
     }
     else { //recebeu nack enviar trama anterior
       dados.id_trama; //reenvia pacote com id anterior
       //reenvia pacote anterior.
       serial.print("\ntrama enviada: ");
       serial.print(dados.payload);
       serial.print("\nnack recebido  "); //esperamos aqui ok.ack = 1 && ok.nack = 0;
       serial.print("\nid da trama :   ");
       serial.print(dados.id_trama);
       serial.print("\nrtt ");
       serial.print(tempo_fim - tempo_inicio);
       serial.println(" microseconds");
       lti.stoplistening();
       //continua();
       dados.id_trama++; //incrementa para o proximo
     }

   }
 }
 lti.stoplistening();
}

}


transmitter 2 basicly same transmitter 1 pipes change. tip helpfull! :) thank guys

up


Arduino Forum > Using Arduino > Programming Questions > Problems implementing CSMA/CA Protocol (ARDUINO + RF24L01)


arduino

Comments

Popular posts from this blog

DHT11 Time out error using v0.4.1library

Sketch upload fails with Java error (___REMOVE___/bin/avrdude)!

Arduino Uno + KTY81/210 temperature sensor