Данные постоянны и всегда нулевые от акселерометра ADXL345 с ESP32 через SPI
Я пытаюсь получить данные с акселерометра ADXL345 с помощью ESP32 через SPI-связь. Я настроил свой код в соответствии со спецификациями библиотеки ADXL345_WE и проверил аппаратные соединения, но у меня возникают проблемы с получением достоверных данных с датчика.
Проблема в том, что даже если я правильно настроил датчик и установил SPI-связь, получаемые значения всегда равны нулю, даже когда я перемещаю датчик.
...
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
DATA_END
3195 Sample(s) missed
RMS : X 0.024839 Y nan Z 0.000000
Beginning capture.
...
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
0.000000 0.000000 0.000000
DATA_END
3195 Sample(s) missed
RMS : X 0.024839 Y nan Z 0.000000
Beginning capture.
Вот мой код:
/***************************************************************************
* Example sketch for the ADXL345_WE library
*
* This sketch shows how use SPI for the basic data sketch. Please apply the
* same steps in the other sketches if you want to use SPI.
*
* Further information can be found on:
* https://wolles-elektronikkiste.de/adxl345-teil-1 (German)
* https://wolles-elektronikkiste.de/en/adxl345-the-universal-accelerometer-part-1 (English)
*
***************************************************************************/
#include<ADXL345_WE.h>
#include<SPI.h>
#define CS_PIN 5 // Chip Select Pin
#define NUM_SAMPLES 3200
bool spi = true; // flag indicating that SPI shall be used
xyzFloat samples[NUM_SAMPLES];
ADXL345_WE myAcc = ADXL345_WE(CS_PIN, spi);
const int int2Pin = 22; // interrupt pin
volatile bool dataReady = false;
void setup(){
Serial.begin(921600);
Serial.println("ADXL345 Demo");
if(!myAcc.init()){
Serial.println("ADXL345 not connected!");
}
// Prepare int pin for input
pinMode(int2Pin, INPUT);
/* You can set the SPI clock speed. Default is 5 MHz. */
// myAcc.setSPIClockSpeed(4000000);
/* Choose the data rate Hz
ADXL345_DATA_RATE_3200 3200
ADXL345_DATA_RATE_1600 1600
ADXL345_DATA_RATE_800 800
ADXL345_DATA_RATE_400 400
ADXL345_DATA_RATE_200 200
ADXL345_DATA_RATE_100 100
ADXL345_DATA_RATE_50 50
ADXL345_DATA_RATE_25 25
ADXL345_DATA_RATE_12_5 12.5
ADXL345_DATA_RATE_6_25 6.25
ADXL345_DATA_RATE_3_13 3.13
ADXL345_DATA_RATE_1_56 1.56
ADXL345_DATA_RATE_0_78 0.78
ADXL345_DATA_RATE_0_39 0.39
ADXL345_DATA_RATE_0_20 0.20
ADXL345_DATA_RATE_0_10 0.10
*/
myAcc.setDataRate(ADXL345_DATA_RATE_3200);
// Safety delay
delay(100);
Serial.print("Data rate: ");
Serial.print(myAcc.getDataRateAsString());
/* In full resolution the size of the raw values depend on the
range: 2g = 10 bit; 4g = 11 bit; 8g = 12 bit; 16g =13 bit;
uncomment to change to 10 bit for all ranges.
*/
// myAcc.setFullRes(false);
/* Choose the measurement range.
ADXL345_RANGE_16G 16g
ADXL345_RANGE_8G 8g
ADXL345_RANGE_4G 4g
ADXL345_RANGE_2G 2g
*/
myAcc.setRange(ADXL345_RANGE_4G);
Serial.print(" / g-Range: ");
Serial.println(myAcc.getRangeAsString());
Serial.println();
// Define interrupt routine and move data_ready to adxl int2
attachInterrupt(digitalPinToInterrupt(int2Pin), dataReadyISR, RISING);
myAcc.setInterrupt(ADXL345_DATA_READY, INT_PIN_2);
myAcc.readAndClearInterrupts();
// TODO add calibration routine
}
void loop() {
int missed = 0;
Serial.println("Beginning capture.");
// Begin data acq
for(int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
// Wait for new data
while(!dataReady) {}
dataReady = false;
samples[cnt] = myAcc.getGValues();
if (dataReady) {
// new data received before we were ready to process it => probable miss
missed ++;
}
}
Serial.println("Capture done.");
Serial.println("Removing DC");
processRemoveDC();
Serial.println("DATA_START");
Serial.println("X\tY\tZ");
for(int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
Serial.printf("%f\t%f\t%f\n", samples[cnt].x,samples[cnt].y,samples[cnt].z);
}
Serial.println("DATA_END");
Serial.printf("%d Sample(s) missed\n", missed);
printRMS();
delay(5000);
}
/* Removes the continuous (dc) component
This will operate inplace and edit the acquired data !
*/
void processRemoveDC() {
float meanX, meanY, meanZ = 0;
for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
meanX += samples[cnt].x;
meanY += samples[cnt].y;
meanZ += samples[cnt].z;
}
meanX /= (float) NUM_SAMPLES;
meanY /= (float) NUM_SAMPLES;
meanZ /= (float) NUM_SAMPLES;
for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
samples[cnt].x -= meanX;
samples[cnt].y -= meanY;
samples[cnt].z -= meanZ;
}
}
/* Computes and print the RMS per axis
*/
void printRMS() {
float rmsX, rmsY, rmsZ = 0;
for (int cnt = 0; cnt < NUM_SAMPLES; cnt++) {
rmsX += pow(samples[cnt].x, 2);
rmsY += pow(samples[cnt].y, 2);
rmsZ += pow(samples[cnt].z, 2);
}
rmsX = sqrt(rmsX/(float)NUM_SAMPLES);
rmsY = sqrt(rmsY/(float)NUM_SAMPLES);
rmsZ = sqrt(rmsZ/(float)NUM_SAMPLES);
Serial.printf("RMS : X %f\tY %f\tZ %f\n", rmsX, rmsY, rmsZ);
}
void dataReadyISR(){
dataReady = true;
}
Вот моя проводка:
Вот что я понял:
Я пробовал отлаживать код и проверять аппаратные соединения, но не смог найти проблему. Может быть, я что-то упускаю из виду или мне нужно изменить какие-то настройки, чтобы получить достоверные данные от датчика?
Любая помощь или предложения будут высоко оценены. спасибо!
На более простом примере
Я попробовал использовать этот учебник с меньшим количеством соединений и кода:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
/*Initialize an instance of Adafruit_ADXL345_Unified with a unique id*/
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
void setup() {
Serial.begin(9600);
Serial.println("");
Serial.println("Small example to read from ADXL345 accelerometer");
}
void loop() {
/*Read from ADXL345 accelerometer*/
sensors_event_t event;
accel.getEvent(&event);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" ");
Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" ");
Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print(" ");Serial.println("m/s^2 ");
/*Take a one second break*/
delay(1000);
}
Но теперь возникла проблема с чтением или доступом к недопустимому адресу памяти:
A10 : 0x3ffc1e70 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x40086244 LEND : 0x4008624f LCOUNT : 0x00000000
Backtrace: 0x400d1c54:0x3ffb2170 0x400d1c8e:0x3ffb2190 0x400d1cb5:0x3ffb21b0 0x400d18b1:0x3ffb21d0 0x400d18c1:0x3ffb2200 0x400d1912:0x3ffb2220 0x400d14dc:0x3ffb2240 0x400d4281:0x3ffb2290
ELF file SHA256: 5143f7db4d6401a9
Rebooting...
�
Small example to read from ADXL345 accelerometer
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d1c57 PS : 0x00060230 A0 : 0x800d1c91 A1 : 0x3ffb2170
A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000000
A6 : 0x3ffb833c A7 : 0x00000000 A8 : 0x3ffb22b0 A9 : 0x3ffb2290
A10 : 0x3ffc1e70 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x40086244 LEND : 0x4008624f LCOUNT : 0x00000000
Backtrace: 0x400d1c54:0x3ffb2170 0x400d1c8e:0x3ffb2190 0x400d1cb5:0x3ffb21b0 0x400d18b1:0x3ffb21d0 0x400d18c1:0x3ffb2200 0x400d1912:0x3ffb2220 0x400d14dc:0x3ffb2240 0x400d4281:0x3ffb2290
�