#include "SPI.h"
#include "wiring_private.h"
#include "pins_arduino.h"
#define SERIAL 1
#define SAMPLE 1
// const static float G = 9.80505; // Gravity's acceleration in Milan
// const static float MG = 0.00980505; // G/1000
// const static float SENS = 2.9; // mG/LSB from ADXL312 Datasheet
const static byte ID = 0x80; // READ ID
const static byte BW = 0xAC; // READ BW
const static uint8_t CS = 9; // Chip Selet connected at PIN9
const static float SPMG = 0.028434645; // sens*mG
byte data[6]; // Array where to save DATA registers content
uint16_t value; // Store DATA_1 & DATA_0 values for X, Y and Z
byte out;
/* digitalWrite()'s overhead avoidance */
uint8_t CSport;
uint8_t CSbit;
volatile uint8_t *CSreg;
void setup()
{
CSport = digitalPinToPort(CS);
CSbit = digitalPinToBitMask(CS);
CSreg = portOutputRegister(CSport);
delay(1000);
pinMode(CS, OUTPUT); // Set Chip Selet pin as output
digitalWrite(CS, HIGH); // Chip Select HIGH, no comunication
// SCLK 13, MISO 12, MOSI 11, CS 10, MASTER, CPOL_1, CPHA_1, MSB, 4MHz, NO INT
SPI.begin();
#if SAMPLE
spiWrite(0x31, 0x0B); // Set DATA_FORMAT as RIGHT_JUSTIFIED
spiWrite(0x2D, 0x08); // Set POWER_CTL in FULL_RES at +/-12g
spiWrite(0x2E, 0x80); // Set INT_ENABLE at DATA_READY
#endif
#if SERIAL
Serial.begin(115200); // Start serial comunication at 115200 bps
Serial.println("/------------------------------------------------------------+");
Serial.println("|
|");
Serial.println("|
SYSTEM READY!
|");
Serial.println("|
|");
Serial.println("+------------------------------------------------------------/");
Serial.println();
#endif
}
void loop()
{
spiRead(ID, &out);
#if SERIAL
Serial.println(out, HEX);
#endif
#if SAMPLE
int j = 0; // For Serial.print purpouse
float out = 0; // Store x^2 + y^2 + z^2 value
float comp = 0; // Store the positive complement value of acceleration
spiReadMore(0xF2, data);
for(int i = 5; i >= 0; i = i - 2){
value = 0;
value = ((data[i] << 8) | data[i-1]);
comp = complement(value); // Calculate g value
out += (comp*comp); // Calculare z^2 + y^2 + z^2
Serial.write(90 - j); // Axis
Serial.print(": ");
printData(value); // Print Two's complement value
Serial.print(" >> ");
j++;
}
Serial.print("g: ");
Serial.print(sqrt(out)); // Calculate g vector value and print it on Serial terminal
Serial.println();
// delayMicroseconds(1);
delay(200);
#endif
}
// Prints the parameters value in Two's complement
void printData(uint16_t data)
{
uint16_t temp;
if (data & 0xF000) // If negative
{
temp = ((data ^ 0xFFFF) + 1) * (-1); // Calculate complement
Serial.print((temp * SPMG), DEC); // Calculate acceleration value
}
else // If positive
{
Serial.print(PSTR(" "));
Serial.print(((data) * SPMG), DEC); // Calculate acceleration value
}
}
// Returns the positive Two's complement of the parameter
float complement(uint16_t data)
{
float temp; // Store the calculated output value
if (data & 0xF000) // If negative
{
temp = SPMG * ((data ^ 0xFFFF) + 1) * (-1); // Calculate two's complement and acceleration
}
else // If positive
{
temp = SPMG * data; // Caculate acceleration value
}
return temp;
}
// TX two bytes of data. Writes data d in register a via SPI
void spiWrite (byte a, byte d)
{
WriteCS(LOW, CSbit, CSreg);
SPI.write(a, d);
WriteCS(HIGH, CSbit, CSreg);
}
// TX and RX one byte on data via SPI and return RXed
void spiRead (byte a, byte *data)
{
WriteCS(LOW, CSbit, CSreg);
SPI.transfer(a, data);
WriteCS(HIGH, CSbit, CSreg);
}
// TX one byte and RX 6 bytes of data via SPI, starting from register a
// Store received bytes in data array
void spiReadMore (byte a, byte *data)
{
WriteCS(LOW, CSbit, CSreg);
SPI.readmore(a, data);
WriteCS(HIGH, CSbit, CSreg);
}
void WriteCS(uint8_t CSval, uint8_t CSbit, volatile uint8_t *CSreg)
{
if (CSval == LOW) {
*CSreg &= ~CSbit;
} else {
*CSreg |= CSbit;
}
}