hello
i just wanted to share something i just figured out, how to make a nrf24l01 transmit using only 2 pins.
first off its easy to get down to 3 pins like this:(really nice work btw)
but i wanted to take it one step further, on a transmitter you really do not need to read any data from the nrf so i rewrote a simple nrf code to work without using the MISO pin. That combined with the fix from Nerd Ralph and 2 pin nrf transmitter here we go.
I made the transmitter code small enough that it will even fit on a attiny13 with (core13 core) here is a link for anyone interested in that core(i use it a lot really nice work too) http://forum.arduino.cc/index.php?topic=89781.0
Binary sketch size: 806 bytes (of a 1 024 byte maximum)
I split the code into 3 files this will transmit 1 analog reading and 1 unsigned long transmission counter
#include "API.h"
#define SCKq 10
#define MOSIq 11
#define TX_ADR_WIDTH 5 // 5 unsigned chars TX(RX) address width
byte TX_ADDRESS[TX_ADR_WIDTH] =
{
0x34,0x43,0x10,0x43,0x34
}; // Define a static TX address
struct dataStruct{
int adcc;
unsigned long counter;
}nrf_data;
unsigned char tx_buf[sizeof(nrf_data)];
int main(void){
init();
{
pinMode(SCKq, OUTPUT);
pinMode(MOSIq, OUTPUT);
csnHi();
TX_Mode();
}
while(1) {
nrf_data.adcc = analogRead(A1);
nrf_data.counter++;
send_stuff();
delay(500);
}
}
and all the functions…
/**************************************************
* Function: SPI_RW();
*
* Description:
* Writes one unsigned char to nRF24L01, and return the unsigned char read
* from nRF24L01 during write, according to SPI protocol
**************************************************/
void SPI_RW(byte Byte)
{
/*
#define SCKq pin 3 B00001000 = 8 B11110111 =247
#define MOSIq pin 1 B00000010 = 2 B11111101= 253
*/
byte i;
for(i=0;i<8;i++) // output 8-bit
{
if(Byte&0x80)
{
// PORTB= PORTB | 2;
digitalWrite(MOSIq, 1);
}
else
{
// PORTB= PORTB & 253;
digitalWrite(MOSIq, 0);
}
// PORTB= PORTB | 8;
digitalWrite(SCKq, 1);
Byte <<= 1; // shift next bit into MSB..
// PORTB= PORTB & 247;
digitalWrite(SCKq, 0);
}
// return read unsigned char
}
/**************************************************/
/**************************************************
* Function: SPI_RW_Reg();
*
* Description:
* Writes value 'value' to register 'reg'
/**************************************************/
void SPI_RW_Reg(byte reg, byte value)
{
csnLow();// digitalWrite(CSNq, 0); // CSN low, init SPI transaction
SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
csnHi();// digitalWrite(CSNq, 1); // CSN high again
}
/**************************************************/
/**************************************************
* Function: SPI_Write_Buf();
*
* Description:
* Writes contents of buffer '*pBuf' to nRF24L01
* Typically used to write TX payload, Rx/Tx address
/**************************************************/
void SPI_Write_Buf(byte reg, byte *pBuf, byte bytes)
{
byte i;
csnLow();// digitalWrite(CSNq, 0); // Set CSN low, init SPI tranaction
SPI_RW(reg); // Select register to write to and read status unsigned char
for(i=0;i<bytes; i++) // then write all unsigned char in buffer(*pBuf)
{
SPI_RW(*pBuf++);
}
csnHi();//digitalWrite(CSNq, 1); // Set CSN high again
}
/**************************************************/
/**************************************************
* Function: TX_Mode();
*
* Description:
* This function initializes one nRF24L01 device to
* TX mode, set TX address, set RX address for auto.ack,
* fill TX payload, select RF channel, datarate & TX pwr.
* PWR_UP is set, CRC(2 unsigned chars) is enabled, & PRIM:TX.
*
* ToDo: One high pulse(>10us) on CE will now send this
* packet and expext an acknowledgment from the RX device.
**************************************************/
void TX_Mode(void)
{
// digitalWrite(CEq, 0);
//SPI_RW_Reg(WRITE_REG + SETUP_AW,0X01);//3 byte adress
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x12); // 500us + 86us, 10 retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 0x40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x27); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:TX. MAX_RT & TX_DS enabled..
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,sizeof(nrf_data));
//SPI_RW_Reg(WRITE_REG + 0x1C,0x01); //dynamic payload pip0
//SPI_RW_Reg(WRITE_REG + 0x1D, 0x04);
//digitalWrite(CEq, 1);
}
void csnHi(){
digitalWrite(SCKq, 1);// SCK->CSN HIGH
delayMicroseconds(80); // allow csn to settle
}
void csnLow(){
digitalWrite(SCKq, 0); // SCK->CSN LOW
delayMicroseconds(15); // allow csn to settle
}
void send_stuff()
{
memcpy(tx_buf, &nrf_data, sizeof(nrf_data));
SPI_RW_Reg(FLUSH_TX,0);
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,sizeof(nrf_data));
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
}
I just let this code run over the night so it seems stable enough.
The files are below i added 2 receiver codes 1 use the rf24 code and the other simple software spi code
I added a few pic of my 2pin nrf module board too, i used a smd variant but its working with ordinary one too.
nrf24l01_2Pin.zip (7.54 KB)