I am trying to write my first library for the Arduino and am having some trouble with it. The library is for the Sonix ADC chip SNAD01A. I used Tod E. Kurt’s ( as my base.
First, here is the compiler output:
SNAD01.cpp: In member function 'uint8_t SNAD01::SNAD01_Convert(uint8_t)':
SNAD01.cpp:113: error: 'SNAD01_sendChan' was not declared in this scope
SNAD01.cpp: In member function 'uint8_t SNAD01::SNAD01_readbit()':
SNAD01.cpp:245: error: '_DIOpinRegister' was not declared in this scope
SNAD01.cpp: At global scope:
SNAD01.cpp:269: error: no 'void SNAD01::SNAD01_sendChan(uint8_t)' member function declared in class 'SNAD01'
SNAD01.cpp:284: error: no 'void SNAD01::SNAD01_sendReg(uint8_t)' member function declared in class 'SNAD01'
But I can’t figure out what is wrong. Perhaps I am just going cross-eyed here. Could anyone lend a hand?
Here is my header:
/*
* SONIX SNAD01x Series ADC library for Arduino
* Modified version of SoftI2CMaster written by Tod E. Kurt, http://todbot.com/blog/
* Mod written by Scott McDonnell 01/2013
*/
#ifndef SNAD01_h
#define SNAD01_h
#include
#define _SNAD01_VERSION 0 // software version of this library
class SNAD01
{
private:
// per object data
uint8_t _DIOpin;
uint8_t _CLKpin;
uint8_t _STARTpin;
uint8_t _DIOBitMask;
uint8_t _CLKBitMask;
uint8_t _STARTBitMask;
volatile uint8_t *_DIOPortRegister;
volatile uint8_t *_CLKPortRegister;
volatile uint8_t *_STARTPortRegister;
volatile uint8_t *_DIOPortModeRegister;
volatile uint8_t *_CLKPortModeRegister;
volatile uint8_t *_STARTPortModeRegister;
volatile uint8_t *_DIOPinRegister;
// private methods
void setPins(uint8_t DIOpin, uint8_t CLKpin, uint8_t STARTpin);
void SNAD01_writebit( uint8_t c );
uint8_t SNAD01_readbit(void);
void SNAD01_start(void);
void SNAD01_stop(void);
void PulseClock(void);
void SNAD01_writebyte( uint8_t c );
uint8_t SNAD01_readbyte( );
void SNAD01_sendCMD(uint8_t c);
void SNAD01_SendChan(uint8_t c);
void SNAD01_SendReg(uint8_t c);
public:
// public methods
SNAD01(uint8_t DIOpin, uint8_t CLKpin, uint8_t STARTpin);
void SNAD01_init(uint8_t reg, uint8_t mode, uint8_t Wkup);
void SNAD01_PWRDN();
uint8_t SNAD01_Convert(uint8_t chan);
uint8_t SNAD01_getDigital();
};
#endif
And here is my library:
/*
* SONIX SNAD01x Series ADC Library for Arduino
* Modified version of SoftI2CMaster by Tod E. Kurt, http://todbot.com/blog/
* Mod written by scott McDonnell 01/2013
*/
#include "Arduino.h"
#include "pins_arduino.h"
#include "SNAD01.h"
#include
#include
#define SNAD01bitdelay 50
//Define commands (in binary)
#define cmd_Reg 0x60
#define cmd_PDN 0x00
#define cmd_wkup 0x40
#define cmd_attrib 0x20
#define cmd_conv 0x80
#define cmd_dig 0xa0
//_XXXPortModeRegister = DDR register
//_XXXPortRegister = Port data register
//_XXXPinRegister = Input Register
//macro for setting DIO pin HIGH
#define SNAD01_DIO_hi() \
*_DIOPortModeRegister &=~ _DIOBitMask; \
*_DIOPortRegister |= _DIOBitMask;
//macro for setting DIO pin Low
#define SNAD01_DIO_lo() \
*_DIOPortRegister &=~ _DIOBitMask; \
*_DIOPortModeRegister |= _DIOBitMask;
//Macro for setting CLK pin HIGH
#define SNAD01_CLK_hi() \
*_CLKPortModeRegister &=~ _CLKBitMask; \
*_CLKPortRegister |= _CLKBitMask;
//Macro for setting CLK pin Low
#define SNAD01_CLK_lo() \
*_CLKPortRegister &=~ _CLKBitMask; \
*_CLKPortModeRegister |= _CLKBitMask;
//Macro for setting START pin HIGH
#define SNAD01_start_hi() \
*_STARTPortRegister &=~ _STARTBitMask; \
*_STARTPortModeRegister |= _STARTBitMask;
//Macro for setting START pin Low
#define SNAD01_start_lo() \
*_STARTPortRegister &=~ _STARTBitMask; \
*_STARTPortModeRegister |= _STARTBitMask;
//Macro for setting DIO as input
#define SNAD01_DIO_IN() \
*_DIOPortModeRegister |= _DIOBitMask;
//Macro for setting DIO pin as output
#define SNAD01_DIO_OUT() \
*_DIOPortModeRegister &=~ _DIOBitMask;
//
// Constructor
//
//Usage: ADC = SNAD01(2,3,4); DIO = pin 2, CLK = pin 3, START = pin 4
SNAD01::SNAD01(uint8_t DIOpin, uint8_t CLKpin, uint8_t STARTpin)
{
setPins(DIOpin, CLKpin, STARTpin);
}
//****************************************************************
//External Functions
//****************************************************************
//Usage: ADC.SNAD_init(reg,attrib,wkup);
void SNAD01::SNAD01_init(uint8_t reg, uint8_t attrib, uint8_t wkup)
{
//Write registers
//Write attributes
//Write wkup
// //I2C_PORT &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
// *_CLKPortRegister &=~ (_DIOBitMask | _CLKBitMask);
// SNAD01_CLK_hi();
// SNAD01_DIO_hi();
_delay_us(SNAD01bitdelay);
}
void SNAD01::SNAD01_PWRDN(){
//Prepare for power down (set RF and MB bits to 0)
//send cmd for powerdown (0x000b)
}
//--------------------------------------------------------------------
//Get Readings (Digital and Analog Routines)
//--------------------------------------------------------------------
uint8_t SNAD01::SNAD01_Convert(uint8_t chan){
//Send command for analog conversion
//read one byte and return byte
uint8_t res;
SNAD01_start();
SNAD01_sendCMD(cmd_conv);
SNAD01_sendChan(chan);
SNAD01_CLK_hi();
SNAD01_CLK_lo();
//SNAD01_DIO_IN;
SNAD01_CLK_hi();
SNAD01_CLK_lo();
res=SNAD01_readbyte();
SNAD01_stop();
return res;
}
uint8_t SNAD01::SNAD01_getDigital(){
//send command for digital reading
//read one byte, return byte
uint8_t res;
SNAD01_start();
SNAD01_sendCMD(cmd_dig);
res=SNAD01_readbyte();
SNAD01_stop();
return res;
}
//***************************************************************
//Internal Functions
//***************************************************************
//--------------------------------------------------------------------
//Set pins and register configuration
//--------------------------------------------------------------------
//
// Turn Arduino pin numbers into PORTx, DDRx, and PINx
//
void SNAD01::setPins(uint8_t DIOpin, uint8_t CLKpin, uint8_t STARTpin)
{
//Define pins for CLK, START, DIO
uint8_t port;
_DIOpin = DIOpin;
_CLKpin = CLKpin;
_STARTpin = STARTpin;
_DIOBitMask = digitalPinToBitMask(DIOpin);
_CLKBitMask = digitalPinToBitMask(CLKpin);
_STARTBitMask = digitalPinToBitMask(STARTpin);
port = digitalPinToPort(CLKpin);
_CLKPortRegister = portOutputRegister(port);
_CLKPortModeRegister = portModeRegister(port);
port = digitalPinToPort(DIOpin);
_DIOPortRegister = portOutputRegister(port);//Port Register
_DIOPortModeRegister = portModeRegister(port); //DDR register
_DIOPinRegister = portInputRegister(port);//Pin Register (input)
port = digitalPinToPort(STARTpin);
_STARTPortRegister = portOutputRegister(port);
_STARTPortModeRegister = portModeRegister(port);
}
// START Conditions
//
void SNAD01::SNAD01_start(void)
{
// set both to high at the same time
//I2C_DDR &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
SNAD01_DIO_lo();//set to low before switching between input to output
// *_DIOPortModeRegister &=~ (_DIOBitMask); //Set DIO DDR as output
SNAD01_DIO_OUT();
_delay_us(SNAD01bitdelay);
SNAD01_start_lo();
_delay_us(SNAD01bitdelay);
}
// STOP Conditions
//
void SNAD01::SNAD01_stop(void)
{
SNAD01_start_hi();//deactivate chip select
_delay_us(SNAD01bitdelay);
SNAD01_DIO_lo(); //set DIO to low before switching directions
SNAD01_DIO_IN(); //set DIO for input (HIz)
_delay_us(SNAD01bitdelay);
}
void SNAD01::SNAD01_writebit( uint8_t c )
{
if ( c > 0 ) {
SNAD01_DIO_hi();
} else {
SNAD01_DIO_lo();
}
PulseClock();
// if ( c > 0 ) {
// SNAD01_DIO_lo();
// }
_delay_us(SNAD01bitdelay);
}
//
uint8_t SNAD01::SNAD01_readbit(void)
{
SNAD01_DIO_lo();//set dio pin low before switching directions
SNAD01_DIO_IN(); //set to input
SNAD01_CLK_hi();
_delay_us(SNAD01bitdelay);
uint8_t port = digitalPinToPort(_DIOpin);
volatile uint8_t* pinReg = portInputRegister(port);
uint8_t c = *pinReg;
SNAD01_CLK_lo();
_delay_us(SNAD01bitdelay);
return ( c & _DIOBitMask) ? 1 : 0;
}
void SNAD01::SNAD01_sendCMD(uint8_t c )
{
SNAD01_start();
for ( uint8_t i=0;i<3;i++)
{
SNAD01_writebit( c & 128 );
c<<=1;
}
SNAD01_stop();
}
void SNAD01::SNAD01_sendChan(uint8_t c )
{
SNAD01_start();
for ( uint8_t i=0;i<3;i++)
{
SNAD01_writebit( c & 128 );
c<<=1;
}
SNAD01_stop();
}
void SNAD01::SNAD01_sendReg(uint8_t c )
{
SNAD01_start();
for ( uint8_t i=0;i<4;i++)
{
SNAD01_writebit( c & 128 );
c<<=1;
}
SNAD01_stop();
}
// write a byte to theSNAD01
//
void SNAD01::SNAD01_writebyte( uint8_t c )
{
SNAD01_start();
for ( uint8_t i=0;i<8;i++)
{
SNAD01_writebit( c & 128 );
c<<=1;
}
SNAD01_stop();
}
// read a byte from the SNAD01
//
uint8_t SNAD01::SNAD01_readbyte( )
{
uint8_t res = 0;
SNAD01_start();
for ( uint8_t i=0;i<8;i++)
{
res <<= 1;
res |= SNAD01_readbit();
}
_delay_us(SNAD01bitdelay);
SNAD01_stop();
return res;
}
void SNAD01::PulseClock(){
//Send one clock transition
SNAD01_CLK_lo();
_delay_us(SNAD01bitdelay);
SNAD01_CLK_hi();
_delay_us(SNAD01bitdelay);
}