(Help) Trouble with receiving Radio Frequency With nRF905

Hi all
I have just spent the last week trying to transmit Radio Frequency's on the 433mhz band using a nRF905 and the nRF905 Radio Library for Arduino and i finally got my code working and i've now been trying to receive the transmission on another nRF905 but for some reason its not receiving anything even when i put it right next to my transmitter. Im almost positive its something wrong with my receivers code but i cant figure out what. If anyone can see anything wrong with it then please let me know, Thanks.

Bites i'm Transmitting

0b00000000, 0b10000001, 0b10000010, 0b10000011, 0b10000100, 0b10000101, 0b10000110, 0b10000111, 0b10001000, 0b10011000, 0b10101000, 0b10111000, 0b11001000, 0b11011000, 0b11101000, 0b11111001, 0b00101001, 0b00111001, 0b01011001, 0b01101001, 0b01111001, 0b10011010, 0b10011011, 0b10011101, 0b10011110, 0b10011111, 0b10101010, 0b11101011, 0b01101011, 0b11101101, 0b11101110, 0b11111111

Receiver Code:

/*
 * Project: nRF905 Radio Library for Arduino (Low power node base station example)
 * Author: Zak Kemble, contact@zakkemble.net
 * Copyright: (C) 2020 by Zak Kemble
 * License: GNU GPL v3 (see License.txt)
 * Web: https://blog.zakkemble.net/nrf905-avrarduino-librarydriver/
 */

// This examples requires the low power library from https://github.com/rocketscream/Low-Power

// This examples configures the nRF905 library to only use 5 connections:
// MOSI
// MISO
// SCK
// SS -> 6
// DR -> 3

// The following pins on the nRF905 must be connected to VCC (3.3V) or GND:
// CE (TRX_EN) -> VCC
// TXE (TX_EN) -> GND
// PWR -> VCC

// The nRF905 will always be in low-power receive mode, waiting for packets from sensor nodes.

#include <nRF905.h>
#include <SPI.h>
#include <LowPower.h>

#define BASE_STATION_ADDR	0xB54CAB34
#define PAYLOAD_SIZE		32
#define LED					A5

#define PACKET_NONE		0
#define PACKET_OK		1
#define PACKET_INVALID	2

nRF905 transceiver = nRF905();

static volatile uint8_t packetStatus; // NOTE: In interrupt mode this must be volatile

void nRF905_int_dr(){transceiver.interrupt_dr();}

void nRF905_onRxComplete(nRF905* device)
{
	packetStatus = PACKET_OK;
}

void nRF905_onRxInvalid(nRF905* device)
{
	packetStatus = PACKET_INVALID;
}

void setup()
{
	Serial.begin(115200);
	Serial.println(F("Base station starting..."));
	
	pinMode(LED, OUTPUT);


	// standby off TODO
	//pinMode(7, OUTPUT);
	//digitalWrite(7, HIGH);
	// pwr
	//pinMode(8, OUTPUT);
	//digitalWrite(8, HIGH);
	// trx
	//pinMode(9, OUTPUT);
	//digitalWrite(9, LOW);
	
	
	// This must be called first
	SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV128);
	// Minimal wires (interrupt mode)
	transceiver.begin(
		SPI,
		125000,
		6,
		NRF905_PIN_UNUSED, // CE (standby) pin must be connected to VCC (3.3V)
		NRF905_PIN_UNUSED, // TRX (RX/TX mode) pin must be connected to GND (force RX mode)
		NRF905_PIN_UNUSED, // PWR (power-down) pin must be connected to VCC (3.3V)
		NRF905_PIN_UNUSED, // Without the CD pin collision avoidance will be disabled
		3, // DR
		NRF905_PIN_UNUSED, // Without the AM pin the library the library must poll the status register over SPI.
		nRF905_int_dr,
		NULL // No interrupt function
	);

	// Register event functions
	// NOTE: In interrupt mode these events will run from the interrupt, so any global variables accessed inside the event function should be declared 'volatile'.
	// Also avoid doing things in the event functions that take a long time to complete or things that rely on interrupts (delay(), millis(), Serial.print())).
	transceiver.events(
		nRF905_onRxComplete,
		nRF905_onRxInvalid,
		NULL,
		NULL
	);

	transceiver.setLowRxPower(true);
  transceiver.setChannel(106);
  transceiver.setBand(NRF905_BAND_433);
  transceiver.setPayloadSize(0, 32); // Will transmit 5 byte payloads, receive 32 byte payloads
  transceiver.setAddressSize(4, 4);
  transceiver.setListenAddress(0xB54CAB34);
	Serial.println(F("Base station started"));
}

void loop()
{
	static uint32_t good;
	static uint32_t invalids;
	static uint32_t badData;

	digitalWrite(LED, HIGH);
	
	// Atomically copy volatile global variable to local variable since the radio is still in RX mode and another packet could come in at any moment
	noInterrupts();
	uint8_t pktStatus = packetStatus;
	packetStatus = PACKET_NONE;
	interrupts();

	if(pktStatus == PACKET_NONE)
	{
		Serial.println("Woke for no reason?");
	}
	else if(pktStatus == PACKET_INVALID)
	{
		Serial.println("Invalid packet");
		invalids++;
	}
	else
	{
		Serial.println("Got packet");
		
		// Make buffer for data
		uint8_t buffer[PAYLOAD_SIZE];

		// Read payload
		transceiver.read(buffer, sizeof(buffer));

		// Show received data
		Serial.print(F("Data from client:"));
		for(uint8_t i=0;i<PAYLOAD_SIZE;i++)
		{
			Serial.print(F(" "));
			Serial.print(buffer[i], DEC);
		}
		Serial.println();

		Serial.print(F("Analog values: "));
		Serial.print(buffer[4]<<8 | buffer[5]);
		Serial.print(F(" "));
		Serial.print(buffer[6]<<8 | buffer[7]);
		Serial.print(F(" "));
		Serial.println(buffer[8]<<8 | buffer[9]);
		
		Serial.print(F("Digital values: "));
		Serial.print(buffer[1]);
		Serial.print(F(" "));
		Serial.print(buffer[2]);
		Serial.print(F(" "));
		Serial.println(buffer[3]);
		
		good++;
	}

	Serial.println(F("Totals:"));
	Serial.print(F(" Good    "));
	Serial.println(good);
	Serial.print(F(" Invalid "));
	Serial.println(invalids);
	Serial.print(F(" Bad     "));
	Serial.println(badData);
	Serial.println(F("------"));
	
	Serial.flush();
	
	digitalWrite(LED, LOW);

	// Sleep

	delay(1000);
}

Transmitter Code

/*
   Project: nRF905 Radio Library for Arduino (Low power sensor node example)
   Author: Zak Kemble, contact@zakkemble.net
   Copyright: (C) 2020 by Zak Kemble
   License: GNU GPL v3 (see License.txt)
   Web: https://blog.zakkemble.net/nrf905-avrarduino-librarydriver/
*/

// This examples requires the low power library from https://github.com/rocketscream/Low-Power

// This examples configures the nRF905 library to only use 5 connections:
// MOSI
// MISO
// SCK
// SS -> 6
// PWR -> 8

// The following pins on the nRF905 must be connected to VCC (3.3V) or GND:
// CE (TRX_EN) -> VCC
// TXE (TX_EN) -> VCC

#include <nRF905.h>
#include <SPI.h>
#include <LowPower.h>

byte mess_Address = {0xB54CAB34};
byte Message[] = {0b00000000, 0b10000001, 0b10000010, 0b10000011, 0b10000100, 0b10000101, 0b10000110, 0b10000111, 0b10001000, 0b10011000, 0b10101000, 0b10111000, 0b11001000, 0b11011000, 0b11101000, 0b11111001, 0b00101001, 0b00111001, 0b01011001, 0b01101001, 0b01111001, 0b10011010, 0b10011011, 0b10011101, 0b10011110, 0b10011111, 0b10101010, 0b11101011, 0b01101011, 0b11101101, 0b11101110, 0b11111111};
const int buttonPin = 2;
int buttonState = 0; 

nRF905 transceiver = nRF905();

static bool txDone; // NOTE: In polling mode this does not need to be volatile

// Event function for TX completion
void nRF905_onTxComplete(nRF905* device)
{
  txDone = true;
}

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Sensor node starting..."));

  pinMode(buttonPin, INPUT);
  // standby off TODO
  //pinMode(7, OUTPUT);
  //digitalWrite(7, HIGH);
  // pwr
  //pinMode(8, OUTPUT);
  //digitalWrite(8, HIGH);
  // trx
  //pinMode(9, OUTPUT);
  //digitalWrite(9, HIGH);


  // This must be called first
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV128);
  // Minimal wires (polling mode)
  // Up to 5 wires can be disconnected, however this will reduce functionalliy and will put the library into polling mode instead of interrupt mode.
  // In polling mode the .poll() method must be called as often as possible. If .poll() is not called often enough then events may be missed.
  transceiver.begin(
    SPI,
    125000,
    6,
    NRF905_PIN_UNUSED, // CE (standby) pin must be connected to VCC (3.3V)
    NRF905_PIN_UNUSED, // TRX (RX/TX mode) pin must be connected to VCC (3.3V) (force TX mode)
    8, // PWR
    NRF905_PIN_UNUSED, // Without the CD pin collision avoidance will be disabled
    NRF905_PIN_UNUSED, // Without the DR pin the library will run in polling mode and poll the status register over SPI. This also means the nRF905 can not wake the MCU up from sleep mode
    NRF905_PIN_UNUSED, // Without the AM pin the library must poll the status register over SPI.
    NULL, // Running in polling mode so no interrupt function
    NULL // Running in polling mode so no interrupt function
  );

  // Register event functions
  transceiver.events(
    NULL,
    NULL,
    nRF905_onTxComplete,
    NULL
  );

  // Low-mid transmit level -2dBm (631uW)
  transceiver.setTransmitPower(NRF905_PWR_10);
  transceiver.setChannel(106);
  transceiver.setBand(NRF905_BAND_433);
  transceiver.setPayloadSize(32, 0); // Will transmit 5 byte payloads, receive 32 byte payloads
  transceiver.setAddressSize(4, 4);

  Serial.println(F("Transciever Started"));
  Serial.println(F("Waiting for input"));
}

void loop()
{
  buttonState = digitalRead(buttonPin);
  // Write data to radio
  transceiver.write(mess_Address, Message, sizeof(Message));

  txDone = false;

  if (buttonState == HIGH) {
    // This will power-up the radio and send the data
    transceiver.TX(NRF905_NEXTMODE_STANDBY, false);

    // Transmission will take approx 6-7ms to complete (smaller paylaod sizes will be faster)
    while (!txDone) {
      transceiver.poll();
      delay(1);
    }
    // Transmission done, power-down the radio
    //transceiver.powerDown();
    Serial.println(F("Transciever complete"));

    // NOTE:
    // After the payload has been sent the radio will continue to transmit an empty carrier wave until .powerDown() is called. Since this is a sensor node that doesn't need to receive data, only transmit and go into low power mode, this example hard wires the radio into TX mode (TXE connected to VCC) to reduce number of connections to the Arduino.
    // TODO
    // Sleep for 64 seconds
    //uint8_t sleepCounter = 8;
    //while(sleepCounter--)
    // Sleep for 1 second
    delay(1000);  
  }
}

Are there some example transmit and receive sketches included with the nrf905 library? Have you tried those to test that your hardware is wired and working correctly?

You have a delay(1000) at the end of your receiver loop().
The chances are good that the transmitter, which also transmits at 1 second intervals, sends something when the receiver is stuck in the delay and so it gets lost.

The original receiver code, https://github.com/zkemble/nRF905-arduino/blob/master/examples/lowpwr_node_baseStation/lowpwr_node_baseStation.ino , on which you have loosely based your version, uses an interrupt to wake the receiver host when its radio received something.

Why not get the original examples working first, then try incrementally adding your own modifications ?

No it didn’t work, I have to change the original examples because i'm using a logic level converter which is to slow for the SPI, this is why i had asked about my Transmitter code not working in previous posts and also why i was using Delay(1000) At the end of the receiver code instead of the original code

Well, if you can’t use the interrupt then simply remove the delay at the end of the receiver loop().

But anyway the suggestion still stands. Make the absolute minimum changes to the standard examples just to get something working before progressing further.

Sounds like that is your true problem. Are you using one because the Arduino is 5V and the nrf905 is 3.3V? Are you using one of those 4-channel level shifters sold on eBay for i2c bus? If so, you probably don't need one. For the MOSI, CLK and other signals going from the Arduino to the nrf, use voltage dividers, e.g. 10K+4K7. For MISO and other signals going from the nrf to the Arduino, 3.3V will probably be enough to be received correctly, so just connect them directly.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.