NRF24L01 with the Adafruit FT232H board, Confirming data is being sent

36 Views Asked by At

I am working with the NRF24 module and I need a way to transmit data back and forth to a rpi that also has an nrf module installed. The pi is pretty easy but there doesnt seem to be any projects that use the nrf with a FT232H. This is the python program that I put together but I cant seem to figure out if the response im getting is a sucess flag or not. I get "cd" hex in the "status" variable. cd in hex is 205 or b'11001101' which im not quite sure what that means in the context of the status register. all in all the rpi should be working correctly as most of the heavy lifting is done by the libraries but im not sure what is wrong with my code on the transmitter. If anyone has any input lmk like i said i cant seem to find a good resource that would allow me to just skip over trying to handle the registers myself.

transmitter-

import usb.core
from pyftdi.ftdi import Ftdi
from pyftdi.spi import SpiController, SpiIOError
from pyftdi.gpio import GpioController
import time

spi = SpiController()
gpio = GpioController()
#Ftdi.show_devices()

#pin definitions for the FT232H to NRF24 module
CSN_PIN = 4
CE_PIN = 5

R_REGISTER = 0x00
STATUS_REGISTER = 0x00

spi.configure('ftdi://ftdi:232h/1')
slave = spi.get_port(cs=0, freq=10E6, mode=0)
gpio.open_from_url('ftdi://ftdi:232h/1', direction=int('00110000', 2), initial=int('00100000', 2))

def read_status_register(spi_port):
    # The NOP command is used to read the status register
    nop_command = 0xFF
    status = spi_port.exchange([nop_command], duplex=True)
    return status[0]  # Return the first byte which is the status register


def set_csn(state):
    # Use the gpio.write() to set the CSN state. Convert CSN_PIN to the appropriate bit value.
    value = gpio.read()
    if state:
        value |= (1 << CSN_PIN)  # Set D4 high
    else:
        value &= ~(1 << CSN_PIN)  # Set D4 low
    gpio.write(value)

def set_ce(state):
    # Use the gpio.write() to set the CE state. Convert CE_PIN to the appropriate bit value.
    value = gpio.read()
    if state:
        value |= (1 << CE_PIN)  # Set D5 high
    else:
        value &= ~(1 << CE_PIN)  # Set D5 low
    gpio.write(value)

# Constants for NRF24L01 commands
W_REGISTER = 0x20
WRITE_TX_PAYLOAD = 0xA0
FLUSH_TX = 0xE1
TX_ADDR = 0x10  # Register for TX address
RF_SETUP = 0x06  # Register for RF setup
CONFIG = 0x00  # Register for configuration
EN_TXADDR = 0x02  # Enable auto-acknowledgment on pipe 0
RF_CH = 0x4C #channel 76

# Function to write a payload to the TX buffer
def write_payload(spi_port, payload):
    set_csn(False)
    spi_port.exchange([WRITE_TX_PAYLOAD] + payload)
    set_csn(True)

# Function to write to a register
def write_register(spi_port, register, value):
    set_csn(False)
    command = [W_REGISTER | register] + value  # Combine command and value into one list
    spi_port.exchange(command)  # Pass the combined list to exchange
    set_csn(True)

# Function to flush TX buffer
def flush_tx(spi_port):
    set_csn(False)
    spi_port.exchange([FLUSH_TX])
    set_csn(True)

# Function to send data wirelessly
def send_data(spi_port, payload):
    # Ensure payload is a list of bytes
    if not isinstance(payload, list) or not all(isinstance(item, int) and 0 <= item <= 255 for item in payload):
        raise ValueError("Payload must be a list of byte values (0-255).")

    # Set the TX address (ensure this matches the receiver's address)
    write_register(spi_port, TX_ADDR, [0xE7, 0xE7, 0xE7, 0xE7, 0xE7])
    
    # Set RF channel, data rate, and output power (adjust as necessary)
    write_register(spi_port, RF_SETUP, [0x06])  # Example: 1Mbps, 0dBm
    
    # Enable TX address
    write_register(spi_port, EN_TXADDR, [0x01])
    
    # Power up in transmit mode
    write_register(spi_port, CONFIG, [0x0A])  # Enable CRC, power up, and set as transmitter
    
    flush_tx(spi_port)  # Ensure TX FIFO is empty
    
    write_payload(spi_port, payload)  # Write payload to TX buffer
    
    # Pulse CE to start transmission
    set_ce(True)
    time.sleep(0.0001)  # CE must be high for at least 10us
    set_ce(False)
    
    # Wait a short period to ensure transmission completes
    time.sleep(0.01)

# Example payload to send
payload = [0x01, 0x02, 0x03, 0x04, 0x05]

# Set TX_ADDR to "2Node"
write_register(slave, TX_ADDR, [0x65, 0x64, 0x6f, 0x4e, 0x32])  # Match RX_ADDR_P0 or P1 as needed

# Other example configurations
write_register(slave, RF_CH, [0x4c])  # Channel 76
write_register(slave, RF_SETUP, [0x0A])  # 1Mbps, PA_LOW
# Ensure CRC length and other configurations are set as needed


while(1):
    # Send the data
    send_data(slave, payload)
    status = read_status_register(slave)
    tx_ds = status & (1 << 5)  # TX_DS bit
    max_rt = status & (1 << 4)  # MAX_RT bit

    if tx_ds:
        print("Data sent successfully.")
    elif max_rt:
        print("Transmission failed: maximum retries reached.")
    else:
        print("Status: ", status)



spi.terminate()
gpio.close()

receiver on the rpi5 -

#include <RF24/RF24.h>
#include <iostream>

using namespace std;

RF24 radio(22, 0); // CE, CSN pins
const uint8_t addresses[][6] = {"1Node", "2Node"};

void setup() {
    radio.begin();
    radio.setPALevel(RF24_PA_HIGH); // Set PA to the second highest level
    radio.openReadingPipe(1, addresses[1]); // Use the second address for receiving
    radio.setChannel(76); // Match the transmitter's channel
    radio.setPayloadSize(32); // Match the transmitter's payload size
    radio.startListening();
}

void loop() {
    if (radio.available()) {
        char text[32] = {0};
        radio.read(&text, sizeof(text));
        cout << text << endl;
    }
}

int main() {
    setup();
    while (true) {
        loop();
    }
    return 0;
}

I have mostly tried modifying the channel, address, and power levels to no avail.

0

There are 0 best solutions below