Good night everyone, this code i'm posting here is an implementation of a wireless connection operating with 2 transmiters and one receiver. Receiver is able to transmitt aswell due to my need to send "manual" ACK when he succssefully receives a frame. My problem is i want both transmitters to compete for transmit although, what is really happening is, they are jamming each other and cant transmit anything. If i operate with only one transmitter the transmition goes as expected. Sorry for my english, so here is the 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 as duas estações transmissoras
//estrutura do meu pacote.
typedef struct pacote {
byte startBit = 0;
byte stopBit = 1;
byte id_trama; //ID do 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; i < 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 do CRC dos dados que vou ler.... -> Se esse valor = 0, bem rececionado.*
- //Serial.print("\n\nCumpriu testes de startbit e stopbit");*
- //Serial.print("\nValor do CRC: ");*
- //Serial.print(incoming);*
- if (data.crc == 0) { //crc = 0 , sem erros*
- //Serial.print("\nCumpriu testes do 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 a 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 a 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 do pacote
char payload[3] = {0x81, 0x89, 0x00}; //meus dados a 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("\nTransmissor 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 into 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; i < 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 i = 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 i = 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 a ouvir , comecou a 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 a trama...");*
* dados.id_trama;
_ LTI.stopListening();_
_ LTI.write(&dados, sizeof(pacote)); //envio trama outra vez*_
* dados.id_trama++;
_ LTI.startListening();_
_ Serial.print("\nVou reenviar a 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 do 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 is basicly the same as transmitter 1 only pipes will change. Any tip will be helpfull! thank you guys