Declarations using SPI

(Disclosure) I did a little C programming in the 70's, and have recently worked through some beginner's tutorials in C++. My background is as an 84 year-old physicist, not a programmer. I am working on a question in fundamental physics for which I need to create a continuous carrier in the uhf range. 2.4 GHz is a good choice. I now have a transmitter module (nRF24L01+ LNA PA) which will do the job, but it needs to be set up by an MCU. The steps are very simple, and I could do it easily except that the Arduino Uno ver 1.8.6 compiler complains in ways that I don't understand.

Here is the extent of the code to date:

#include <SPI.h>

byte REGISTER;
byte VALUE;
unsigned int SPI_RW_Reg(REGISTER, VALUE);
byte WRITE_REG;
byte CONFIG;
void setup() {

void TX_Mode(void);
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
SPI_RW_Reg(WRITE_REG + CONFIG,0x0a); // Set PWR_UP = 1 and prim_rx=0 in the CONFIG
SPI.endTransaction();

}

void loop() {
// put your main code here, to run repeatedly:

}

Here is the error message:

C:\Users\Allen\Documents\Arduino\continuous_carrier\continuous_carrier.ino: In function 'void setup()':

continuous_carrier:13:35: error: 'SPI_RW_Reg' cannot be used as a function

SPI_RW_Reg(WRITE_REG + CONFIG,0x0a); // Set PWR_UP = 1 and prim_rx=0 in the CONFIG

^

exit status 1
'SPI_RW_Reg' cannot be used as a function

I cannot find the correct SPI library to check, but it seems that the compiler cannot find the code for the SPI_RW_Reg() function in the library. Check to make sure 1) you spelled the name correctly, and 2) you used the proper case for the characters in the name. The fact that it says you can't use it as a function sort of tells me it might be a symbolic constant and not a function. Can you post the SPI.h header file you are using?

If you are using the Arduino's built-in SPI library, then you need to use SPI.transfer(val) where val is the 8 bits you are trying to send.

Thanks, EconJack. I wish I could post the SPI.h that I am using, but neither I nor my Windows 10 search can find it resident on my computer. Yet, if I comment out the #include SPI.h, I get a totally different series of error messages from the compiler. I conclude that the IDE has hidden access to SPI.h that I do not know about.

And thanks to you, aapatil. It compiles with no problem when I comment out references to SPI_RW_Reg, and use

SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
//SPI_RW_Reg(WRITE_REG + CONFIG,0x0a); // Set PWR_UP = 1 and prim_rx=0 in the CONFIG
VALUE = 0x0a;
SPI.transfer(VALUE);
SPI.endTransaction();

But then, how will the target peripheral, nRF24L01+, know where to put VALUE? It has to go to its CONFIG register at 0x00.

Do I simply concatenate all of the data that needs to go to nRF24L01 into one long string and assume that it will be stored properly, beginning at 0x00?

I have found instructions in Nordic's Product Specifications pertaining to using SPI. It says use W_REGISTER, but the compiler isn't happy with that either. I will sort through it tomorrow. No time right now.

Hello alrobnett

unsigned int SPI_RW_Reg(REGISTER, VALUE);

1/ that's not a good way to declare :
--> unsigned int SPI_RW_Reg(byte REGISTER, byte VALUE);

2/SPI_RW_Reg has to be defined somewhere

Where did you copy your code?

Regards,
bidouilleelec

alrobnett:
I could post the SPI.h that I am using, but neither I nor my Windows 10 search can find it resident on my computer.

Windows’s search capability sucks. Try Agent Ransack.

But, in this case, you can get to the appropriate library folder fairly easily:

  1. Make sure the board you’re using is selected in the Arduino IDE under “Tools --> Board”

  2. In the IDE under “File --> Examples” scroll down to “SPI” and open one of the example sketches.

  3. With the example open, select “Sketch --> Show Sketch Folder”

  4. In the Explorer window that opens, navigate up two levels.

  5. There you should find the .h and .cpp files for the library. Open those files in a text editor. All the answers you need are contained within.

Thanks bidoilleelec, I copied the code from a conversation in 2015 regarding attempting to get the nRF24L01 chip to send a continuous carrier. swe-dude said:

Hello i have done some experimenting with nrf24l01 myself and this is the code i use as a starting point most times. It gives a lot easier access to all registers and its easy to add whatever u need. Just change the pins in nrf24l01.h to whatever you are using now and edit in void TX_Mode(void) to set the right registers. The rest should be pretty straightforward.

SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);

For example this writes 0x0e (B00001110)to the config register. i usually use binary instead a lot easier when you read from the data sheet.

if you need to write to a register not in the api file you can do this too

SPI_RW_Reg(WRITE_REG + 0x00, 0x0e); (writes to register 0x00....)

give it a try and if you get stuck write a line and i will take a closer look at it.

Neither he nor the person he was communicating with indicated what #include(s) nor declarations were required.

And thanks to you, gfvalvo. Agent Ransack is awesome. It found seven files labeled SPI.h, none of which dealt with writing a byte of data out to a designated register in the slave peripheral device.

I tried your suggestion for finding the .h files.

There were two example sketches under SPI. Both gave similar results:

C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.14.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\libraries\SPI\examples\DigitalPotControl

Backing up two levels takes me to ...arduino/avr/libraries/SPI where I find a folder called "examples", and one called "src". In the src folder, I find SPI.cpp and SPI.h.

SPI.cpp has in it, #include "SPI.h", but does not contain anything pertinent to my project.

SPI.h deals with clock and interrupts, and has nothing pertinent to my project. It starts off with:

#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED

#include <Arduino.h>

I did not have the #include <Arduino.h> in my program, but it seems likely that the Arduino IDE would have taken care of that.

Hello alrobnett

I think that you should create a new thread with a title like :
nRF24L01+ : how to create a continuous carrier

Regards,
bidouilleelec

Hi

If you download the code posted in THIS post by swe-dude (reply #1), the INO contains the definition of SPI_RW_Reg

Here is a snippet :

/************************************************************************
**   * Function: SPI_RW();
 * 
 * Description:
 * Writes one unsigned char to nRF24L01, and return the unsigned char read
 * from nRF24L01 during write, according to SPI protocol
************************************************************************/
unsigned char SPI_RW(unsigned char Byte)
{
  return SPI.transfer(Byte);
}

/**************************************************/

/**************************************************
 * Function: SPI_RW_Reg();
 * 
 * Description:
 * Writes value 'value' to register 'reg'
/**************************************************/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
  unsigned char status;

  digitalWrite(CSN, 0);                   // CSN low, init SPI transaction
  SPI_RW(reg);                            // select register
  SPI_RW(value);                          // ..and write value to it..
  digitalWrite(CSN, 1);                   // CSN high again

  return(status);                   // return nRF24L01 status unsigned char
}
/**************************************************/

Cheers...

Thanks, Bidouilleelec, I will follow your suggestion about a new thread if darrob's find doesn't do the trick.

Many thanks, darrob. When I looked at swe_dude's post before, I didn't notice that he had attached a zip file. I'm still not used to the ins and outs of posting.