Creating Arduino Library

I have been working with nRF24L01+ transceivers the last month, and as part of a larger project, am now trying to create an Arduino library for it. I have experience in C, and some in C++. However, my knowledge falls short when it comes to the compilation process, etc.

My attempt includes a .cpp file, defining a class and the code for all my functions, a .h header file, defining global variables, function definitions, and including needed libraries (SPI, stdint), and another .h file defining nRF24L01+ specific constants. I wrote these using Visual Studio, but for some reason, it will not build (cannot find CL.exe). I am confident in my syntax (apart from some glaring mistakes, line 49, for example), so I though I’d write it in VS using its Intellisense and syntax highlighting features, and then test it using an Arduino sketch.

When I try and import it into a sketch (#include <nRFSN.h>) and then try and call a function (nRFSN.init(…)), it does not regconize nRFSN as a library. It gives

BareMinimum:8: error: expected unqualified-id before '.' token

I am not sure what I am doing wrong. Here are the three afore mentioned files:
nRFSN.h

#ifndef SPI_H_
#include <SPI.h>
#endif

#ifndef EEPROM_H_
#include <EEPROM.h>
#endif

#include "Arduino.h"
#include <stdint.h>

#ifndef nRFSN_h
#define nRFSN_h

class nRFSN
{

public:
	void init(uint8_t SPIDiv, uint8_t CEpin, uint8_t CSNpin, uint8_t IRQpin, uint8_t intNum);
	uint8_t sync(void);
	void setPower(uint8_t pwrLvl);
	void setTXMode(void);
	void setRXMode(void);
	void setMAX_RT(uint8_t numRT);
	void setChannel(uint8_t ch);
	void transfer(char wrn, uint8_t command, uint8_t len);
	uint8_t getPayloadSize(void);
	void getPayload(uint8_t payloadSize);
	void initSPI(uint8_t SPIDiv);
	void updateStatus(void);
	void clearInt(uint8_t interrupt);

	uint8_t nRFSN_CE;
	uint8_t nRFSN_CSN;
	uint8_t nRFSN_IRQ;

	uint8_t nRFSN_BufIn[32];		// 32 uint8_t buffer for all incoming SPI data
	uint8_t nRFSN_BufOut[32];		// 32 uint8_t buffer for all outgoing SPI data

	uint8_t nRFSN_Status;			// nRF24L01+ STATUS register

	volatile uint8_t nRFSN_Busy;	// nRF busy flag; set when transmitting

	volatile uint8_t nRFSN_RXInt;		// nRF received packet flag set by ISR
	volatile uint8_t nRFSN_TXInt;       // nRF packet sent flag set by ISR
	volatile uint8_t nRFSN_MAXInt;      // nRF max retransmit flag set by ISR

protected:
	uint8_t checkAddrs(void);
	void nRF_ISR(void);
	uint8_t configReg(char wr, uint8_t command, uint8_t data);
	void setTXAddr(uint8_t addr[], uint8_t len);
	void setRXAddr(uint8_t pipe, uint8_t addr[], uint8_t len);
	
	/*------------------------------------------------
	 * nRF24L01+ config variables
	------------------------------------------------*/
	uint8_t CONFIG_CURR;
	uint8_t EN_AA_CURR;
	uint8_t EN_RXADDR_CURR;
	uint8_t SETUP_AW_CURR;
	uint8_t SETUP_RETR_CURR;
	uint8_t RF_CH_CURR;
	uint8_t RF_SETUP_CURR;
	uint8_t RX_PW_P0_CURR;
	uint8_t DYNPD_CURR;
	uint8_t FEATURE_CURR;
	uint8_t RX_ADDRESS[4];
	uint8_t TX_ADDRESS[4];
};

#endif

nRFSN.cpp

#include "nRF24L01+.h"
#include "nRFSN.h"


/*------------------------------------------------
 * Initialize function
 * - Initializes CE, CSN, IRQ pins
 * - Initializes SPI
 * - Initializes nRF settings to default
 * - Sets TX, RX addresses to default/EEPROM stored values
 * - Initializes interrupt flags and enables IRQ interrupt
 * uint8_t SPIDiv: SPI frequency divider (default is SPI_CLOCK_DIV4)
 * - SPI_CLOCK_DIVx
 *	where valid x values are: 4, 8, 16, 32, 64, 128
------------------------------------------------*/
void nRFSN::init(uint8_t SPIDiv, uint8_t CEpin, uint8_t CSNpin, uint8_t IRQpin, uint8_t intNum)
{
	nRFSN_CE = CEpin;
	nRFSN_CSN = CSNpin;
	nRFSN_IRQ = IRQpin;

	pinMode(nRFSN_CE, OUTPUT);
	pinMode(nRFSN_CE, OUTPUT);
	pinMode(nRFSN_IRQ, INPUT);
	digitalWrite(nRFSN_CE, HIGH);
	digitalWrite(nRFSN_CSN, HIGH);

	if (!SPIDiv)
	{
		SPIDiv = SPI_CLOCK_DIV4;	// Default to Fosc/4 (4MHz on 16MHz Arduino)
	}
	initSPI(SPIDiv);

	// nRF defaults
	CONFIG_CURR           = B00101011;   // Show RX_DR and MAX_RT interrupts; Enable CRC - 1 uint8_t; Power up; RX
	EN_AA_CURR            = B00000011;   // Enable Auto Ack for pipe 0,1
	EN_RXADDR_CURR        = B00000011;   // Enable data pipe 0,1
	SETUP_AW_CURR         = B00000010;   // Set up for 4 address
	SETUP_RETR_CURR       = B00110000;   // 1000us retransmit delay; 10 retransmits
	RF_CH_CURR            = B01101001;   // Channel 105 (2.400GHz + 0.105GHz = 2.505GHz)
	RF_SETUP_CURR         = B00000110;   // RF data rate to 1Mbps; 0dBm output power (highest)
	RX_PW_P0_CURR         = B00000001;   // 1 payload
	DYNPD_CURR            = B00000011;   // Set dynamic payload for pipe 0
	FEATURE_CURR          = B00000100;   // Enable dynamic payload

	if (!checkAddrs())		// Is there an address in EEPROM?
	{
		RX_ADDRESS[4]         = {0xE7,0xE7,0xE7,0xE7};	// If no EEPROM stored addresses,
		TX_ADDRESS[4]         = {0xE7,0xE7,0xE7,0xE7};	// set deafults
	}

	// nRF24L01+ setup
	// Write to CONFIG register
	configReg('w',CONFIG,CONFIG_CURR);
	// Write to EN_RXADDR register  
	configReg('w',EN_RXADDR,EN_RXADDR_CURR);
	// Write to EN_AA register
	configReg('w',EN_AA,EN_AA_CURR);
	// Write to SETUP_AW register
	configReg('w',SETUP_AW,SETUP_AW_CURR);
	// Write to SETUP_RETR register
	configReg('w',SETUP_RETR,SETUP_RETR_CURR);
	// Write to RF channel register
	configReg('w',RF_CH,RF_CH_CURR);
	// Write to RF setup register  
	configReg('w',RF_SETUP,RF_SETUP_CURR);
	// set TX address
	setTXAddr(TX_ADDRESS,4);
	// set RX address
	setRXAddr(RX_ADDR_P0,RX_ADDRESS,4);
	// Set dynamic payload for pipe 0
	configReg('w',DYNPD,DYNPD_CURR);
	// Write to FEATURE register
	configReg('w',FEATURE,FEATURE_CURR);
	// Flush RX FIFO
	spiTransfer('n',FLUSH_RX,0);
	// Flush TX FIFO
	spiTransfer('n',FLUSH_TX,0);

	// Initialize interrupt flags
	nRFSN_RXInt = 0;
	nRFSN_TXInt = 0;
	nRFSN_MAXInt = 0;
	attachInterrupt(intNum,nRF_ISR,LOW);	// Enable IRQ interrupt
}

... truncated

and nRF24L01+.h

// nRF24L01+ commands
#define R_REGISTER      = 0x00      // Read; Bits <5:0> = register map address (LSB first)
#define W_REGISTER      = 0x20      // Write; Bits <5:0> = register map address (LSB first)
#define R_RX_PAYLOAD    = 0x61      // Read RX payload 1-32 bytes (LSB first)
#define W_TX_PAYLOAD    = 0xA0      // Write TX payload 1-32 bytes (LSB first)
#define FLUSH_TX        = 0xE1      // Flush TX FIFO
#define FLUSH_RX        = 0xE2      // Flush RX FIFO
#define REUSE_TX_PL     = 0xE3      // TX; Reuse last transmitted payload; active until FLUSH_TX or W_TX_PAYLOAD
#define R_RX_PL_WID     = 0x60      // Read RX payload width for top R_RX_PAYLOAD in RX FIFO
#define W_ACK_PAYLOAD   = 0xA8      // RX; Write payload + ACK packet; <2:0> = write payload (LSB first)
#define W_TX_PAYLOAD_NO = 0xB0      // TX; Disable AUTOACK on this specific packet
#define NRF_NOP         = 0xFF      // No operation; used as dummy data

// nRF24L01+ registers
#define CONFIG          = 0x00      // Configuration register
#define EN_AA           = 0x01      // Enable AUTOACK function
#define EN_RXADDR       = 0x02      // Enable RX addresses
#define SETUP_AW        = 0x03      // Setup address widths
#define SETUP_RETR      = 0x04      // Setup auto retransmission
#define RF_CH           = 0x05      // RF channel
#define RF_SETUP        = 0x06      // RF setup register
#define STATUS          = 0x07      // Status register
#define OBSERVE_TX      = 0x08      // Transmit observe register
#define RPD             = 0x09      // RPD (Carrier Detect)
#define RX_ADDR_P0      = 0x0A      // Receive address data for pipes 0-5
#define RX_ADDR_P1      = 0x0B
#define RX_ADDR_P2      = 0x0C
#define RX_ADDR_P3      = 0x0D
#define RX_ADDR_P4      = 0x0E
#define RX_ADDR_P5      = 0x0F
#define TX_ADDR         = 0x10      // Transmit address
#define RX_PW_P0        = 0x11      // Receive data width for pipes 0-5
#define RX_PW_P1        = 0x12
#define RX_PW_P2        = 0x13
#define RX_PW_P3        = 0x14
#define RX_PW_P4        = 0x15
#define RX_PW_P5        = 0x16
#define FIFO_STATUS     = 0x17      // FIFO status register
#define DYNPD           = 0x1C      // Enable dynamic payload length
#define FEATURE         = 0x1D		// Feature register

// nRF24L01+ interrupts
#define RX_DR			= 0x40		// Data received interrupt
#define TX_DS			= 0x20		// Data sent interrupt
#define MAX_RT			= 0x10		// Max retransmit interrupt

Any and all help is appreciated!

Thanks, Hengy

no time to review it all,

You do not need all the #ifdef 's Every .h file should take care of it himself.

#ifndef nRFSN_h
#define nRFSN_h

#include "Arduino.h"
#include <stdint.h>

#include <SPI.h>
#include <EEPROM.h>

Is it needed that these are public? Only if you really want to expose those vars as part of the interface.
e.g. direct access to the internal buffer seems not “smart”
OO prefers so called getter and setter functions to guard the state of the objects.

	uint8_t nRFSN_CE;
	uint8_t nRFSN_CSN;
	uint8_t nRFSN_IRQ;

	uint8_t nRFSN_BufIn[32];		// 32 uint8_t buffer for all incoming SPI data
	uint8_t nRFSN_BufOut[32];		// 32 uint8_t buffer for all outgoing SPI data

	uint8_t nRFSN_Status;			// nRF24L01+ STATUS register

	volatile uint8_t nRFSN_Busy;	// nRF busy flag; set when transmitting

	volatile uint8_t nRFSN_RXInt;		// nRF received packet flag set by ISR
	volatile uint8_t nRFSN_TXInt;       // nRF packet sent flag set by ISR
	volatile uint8_t nRFSN_MAXInt;      // nRF max retransmit flag set by ISR

When I try and import it into a sketch (#include <nRFSN.h>) and then try and call a function (nRFSN.init(…)), it does not regconize nRFSN as a library. It gives
Code:

BareMinimum:8: error: expected unqualified-id before ‘.’ token

You have not shown us the sketch. The assertion that “it” does not recognize nRFSN as a library is not necessarily correct. You need to show us the sketch and the COMPLETE error message(s).

The sketch that I was using was the BareMinimum, with an #include of the library, and a call to nRFSN init() function in the setup() routine. That’s it. I even used the “Import Library” menu option, so the IDE recognizes it as a library.

I didnt save the sketch, so I don’t remember what arguments I put in the init() function call…
Sketch:

#include <nRFSN.h>

Void setup() {
     nRFSN.init(arguments I don't recall...);
}

Void loop () {

}

The error message was (as far as I can recall)

Error in method setup()
BareMinimum:8: error: expected unqualified-id before '.' token

The error message was (as far as I can recall)

When you bother to re-create the original code, feel free to post is AND the exact error message.

I KNOW that you didn't compile that code.

What, EXACTLY, do you think that the nRFSN in front of the . is? It is SUPPOSED to be an instance of the class. It is NOT.