So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By jucall
#64923 Hello.

This is my first post.
I want to connect a Nodemcu Amica to an accelerometer ADXL345 using the SPI.h library from Arduino IDE.


I tested the code in the arduino UNO board and it's ok. I take data from ADXL345 SPI for one second.
But when I try to same code to Nodemcu, the output data is always the same output.

I use those pins:
Nodemcu Amica ADXL345
D5 (14) SCK SCL
D6 (12) MISO SDIO
D7 (13) MOSI SDA
D8 (15) CS CS


My questions are:

1.- If I want to use the SPI.h from the arduino IDE with Nodemcu or another esp8266 board, what I have to modify?. I saw many post where they talk to change the frequency, use clock divider, but another said is just to change the CS pin.

2.- Do you have an example .ino file (arduino ide) working with Nodemcu and ADXL345 using SPI?


This is my code.

//Add the SPI library so we can communicate with the ADXL345 sensor
#include <ESP8266WiFi.h>
#include <SPI.h>

//Assign the Chip Select signal to pin 10.
int CS=15;

int k=0;
int j=0;
double xg;
double fx;
double xganterior= 0;
double yg;
double fy;
double yganterior= 0;
double zg;
double fz;
double zganterior= 0;
float ALPHA=0.5;

unsigned long tiempo = 0;

int interval=1000;
unsigned long previousMillis=0;

//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D; //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1
char BW_RATE = 0x2C; // DATA RATE

//This buffer will hold values read from the ADXL345 registers.
char values[10];
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z;

void setup(){
//Initiate an SPI communication instance.
SPI.begin();
//Configure the SPI connection for the ADXL345.
SPI.setDataMode(SPI_MODE3);
//Create a serial connection to display the data on the terminal.
Serial.begin(230400);

//Set up the Chip Select pin to be an output from the Arduino.
pinMode(CS, OUTPUT);
//Before communication starts, the Chip Select pin needs to be set high.
digitalWrite(CS, HIGH);

//Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
writeRegister(DATA_FORMAT, 0x03);
//Data rate at 3200 Hz.
writeRegister(BW_RATE, 0x0F);
//Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
writeRegister(POWER_CTL, 0x08); //Measurement mode


}

void loop(){
unsigned long delta;
unsigned long actual;
int k=0;
unsigned long inicio = millis();
do
{

readRegister(DATAX0, 6, values);
x = ((int)values[1]<<8)|(int)values[0];
xg=x*0.0078*4*9.8;
fx = xg * ALPHA + (xganterior * (1.0-ALPHA));
xganterior = fx;
Serial.println(fx);

k=k+1;
actual=millis();
delta= actual - inicio;
}while ((delta) <= interval);

Serial.println(delta);
Serial.println(k);
delay(1000);

}
//This function will write a value to a register on the ADXL345.
//Parameters:
// char registerAddress - The register to write a value to
// char value - The value to be written to the specified register.
void writeRegister(char registerAddress, char value){
//Set Chip Select pin low to signal the beginning of an SPI packet.
digitalWrite(CS, LOW);
//Transfer the register address over SPI.
SPI.transfer(registerAddress);
//Transfer the desired register value over SPI.
SPI.transfer(value);
//Set the Chip Select pin high to signal the end of an SPI packet.
digitalWrite(CS, HIGH);
}

//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
// char registerAddress - The register addresse to start the read sequence from.
// int numBytes - The number of registers that should be read.
// char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
//Since we're performing a read operation, the most significant bit of the register address should be set.
char address = 0x80 | registerAddress;
//If we're doing a multi-byte read, bit 6 needs to be set as well.
if(numBytes > 1)address = address | 0x40;

//Set the Chip select pin low to start an SPI packet.
digitalWrite(CS, LOW);
//Transfer the starting register address that needs to be read.
SPI.transfer(address);
//Continue to read registers until we've read the number specified, storing the results to the input buffer.
for(int i=0; i<numBytes; i++){
values[i] = SPI.transfer(0x00);
}
//Set the Chips Select pin high to end the SPI packet.
digitalWrite(CS, HIGH);
}

Thanks.
jucall
User avatar
By jucall
#64990 I respond to myself.

The problem: I was using SPI mode3.
With Nodemcu you have to use SPI mode2 and it works.

void setup() {
SPI.begin();
SPI.setDataMode(SPI_MODE2);
SPI.setBitOrder(MSBFIRST);
SPI.setFrequency(1000000);
...


This code works ok

#include <SPI.h>

//ADXL345
#define BW_RATE 0x2C //Data rate and power mode control
#define POWER_CTL 0x2D //Power Control Register
#define DATA_FORMAT 0x31 //Data format control
#define DATAX0 0x32 //X-Axis Data 0


//Nodemcu pin D5 GPIO 14 -----> pin SCL ADXL345
//Nodemcu pin D6 GPIO 12 -----> pin SDO ADXL345
//Nodemcu pin D7 GPIO 13 -----> pin SDA ADXL345
//Nodemcu pin D8 GPIO 15 -----> pin CS ADXL345
//Nodemcu pin 3.3 -----> pin VCC ADXL345
//Nodemcu pin GND -----> pin GND ADXL345

#define SS 15 //(IO15 -> IO5)

char values[10];
int16_t x, y, z;
float xg, yg, zg;

void setup() {
SPI.begin();
SPI.setDataMode(SPI_MODE2);
SPI.setBitOrder(MSBFIRST);
SPI.setFrequency(1000000);
//SPI.setClockDivider(SPI_CLOCK_DIV16);


Serial.begin(250000);

// SS Hight
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);

// ADXL345
writeRegister(DATA_FORMAT, 0x03); // ±16g 10bit
writeRegister(POWER_CTL, 0x08); //
writeRegister(BW_RATE, 0x0F); //
}

void loop() {
// DATAX0
readRegister(DATAX0, 6, values);

// 2Byte
x = ((int16_t)values[1] << 8) | (int16_t)values[0];
y = ((int16_t)values[3] << 8) | (int16_t)values[2];
z = ((int16_t)values[5] << 8) | (int16_t)values[4];

// 0.03125 = (16*2)/(2^10)
xg = x * 0.03125;
yg = y * 0.03125;
zg = (z * 0.03125) - 1;



//
Serial.print(xg);
Serial.print("\t");
Serial.print(yg);
Serial.print("\t");
Serial.println(zg);
}

void writeRegister(char registerAddress, char value) {
// SPI
digitalWrite(SS, LOW);
//
SPI.transfer(registerAddress);
//
SPI.transfer(value);
// SPI
digitalWrite(SS, HIGH);
}

void readRegister(char registerAddress, int16_t numBytes, char * values) {
//
char address = 0x80 | registerAddress;
//
if (numBytes > 1)address = address | 0x40;
// SPI
digitalWrite(SS, LOW);
//
SPI.transfer(address);
//
for (int16_t i = 0; i < numBytes; i++) {
values[i] = SPI.transfer(0x00);
}
// SPI CS HIGH
digitalWrite(SS, HIGH);
}


Thanks
Jucall
User avatar
By KARTHIK_ARDUINO
#68591 hi i am new in nodemcu progaraming.
i want to get acceleration data from adxl 345
i used in your updated code but i got error.
i have attached file .
please help me and send clear information to get acceleration data
as a graph time domine and FFT domine.
please help me and set me the detail my email id karthik27mech@gmail.com
You do not have the required permissions to view the files attached to this post.