I flagged this as "hardware help" — this could be a software issue, but I suspect not.
I'm trying to read an ADXL345 accelerometer over 3-wire SPI, but I keep getting "-1, -1, -1" despite lots of motion. I've tried a couple of example sketches and run into the same issue. I need SPI communication for the speed (otherwise I'd use the I2C quick connector). What's going on? Thanks in advance! I'm using a Seeed Studio ESP32-C3. Details:
ADXL SDA to XIAO D18 (MOSI)
ADXL SCL to XIAO D8 (SCK)
ADXL CS to XIAO D1 (I've tried the GPIO: "3", label: "D1", and "1" in the code)
Powering the ADXL from 3v3 (lists 3-5v range)
Code:
#include <SparkFun_ADXL345.h> // Include the ADXL345 library
// Initialize the ADXL345 object for SPI communication
ADXL345 adxl = ADXL345(9); // Use GPIO 9 as the CS pin (modify this if needed)
void setup() {
Serial.begin(9600); // Initialize serial communication at 9600 baud
adxl.powerOn(); // Power on the ADXL345 sensor
adxl.setRangeSetting(2); // Set accelerometer range to ±2g
adxl.setSpiBit(1); // Set to 3-wire SPI mode
}
void loop() {
int x, y, z; // Variables to store the XYZ values
adxl.readAccel(&x, &y, &z); // Read the XYZ values from the accelerometer
// Output the values to the serial monitor
Serial.print(x);
Serial.print(y);
Serial.println(z);
delay(100); // Add a short delay for readability
}
Sorry, don't know the device, but you declared x, y, z as integers; the range is set to +/- 2g; does that mean you get -2, -1, 0, 1, 2 as results, or does it return some number like milli-g?
It sets the sensitivity — this is from Sparkfun's demo:
adxl.setRangeSetting(2); // Give the range settings
// Accepted values are 2g, 4g, 8g or 16g
// Higher Values = Wider Measurement Range
// Lower Values = Greater Sensitivity
Hi @TomGeorge, thank you for the welcome
I have looked at that tutorial, and my wiring matches what it suggests for 3-wire SPI. However, with that sample code I don't see anything on the serial monitor — not even the "There was a problem detecting the ADXL345 ... check your connections".
My first thought was that there was an ESP32 laptop communication problem, but Arduino's ReadAnalogVoltage.ino example works and sends an accurate voltage to the monitor
Yes, that is the one I started from. It constantly returns a loop of
*** ACTIVITY ***
*** DOUBLE TAP ***
*** TAP ***
*** FREE FALL ***
*** INACTIVITY ***
. When I comment out the code for those detections, and uncomment the code for listing coordinates, I get the "-1, -1, -1"
As @camsysca mentioned, I need SPI for speed — the ADXL345 can only sample up to 800Hz over I2c, and I need at least 1000Hz. It can do 3,200Hz via SPI.
I tried previously with I2C, and got the same results.
I'm confused — why do I need to define the pins? None of the example codes for this sensor define them, and MOSI and SCK are fixed on the board (GPIO 10 and 8, respectively as I have it wired). Image attached. The CS pin should work with any output, and I specify GPIO 3 in line 4
In electronics 'assuming' wont provide any solution.
In the example, I believe they use a esp32 wroover, but you are using a c3. They are not totally compatible.
You are sure your connection is ok, you are sure your pin out definition for the spi bus is ok, but your code doesnt work properly. because you assume many things.
I cant see why you are not even trying to define pins (or try other buses/connections), it will save time.
For the C3, something like this might work:
#include <SPI.h>
#define SD_CS GPIO_NUM_21 // SD Chip Select (SS)
#define SD_CLK GPIO_NUM_20 // SD Clock (SCK)
#define SD_MOSI GPIO_NUM_10 // SD Master Out Slave In (MOSI)
#define SD_MISO GPIO_NUM_9 // SD Master In Slave Out (MISO)*/
// void setup
static SPIClass spi(FSPI);
pinMode(SD_CS, OUTPUT); // SD SS.
// call setup_SPI to init SPI bus.
if (setup_SPI(spiValue)) { // spiValue is your SPI speed in Hz.
spiStatus = true;
break; // Leave SPI config attemp. Place this into a loop for retries.
}
// setup function for the SPI bus
bool setup_SPI(int i) {
bool success = false;
Serial.print("Init SD | .");
for (int attempt = 0; attempt < maxAttempts; attempt++) {
SD.end();
SPI.end();
spi.begin(SD_CLK, SD_MISO, SD_MOSI, SD_CS);
SdSpiConfig sdConfig(SD_CS, DEDICATED_SPI, SD_SCK_MHZ(i), &spi);
if (SD.begin(sdConfig)) {
Serial.println("SPI CLK = " + String(i) + " MHz SUCCESS!!! ");
success = true;
break;
}
Serial.println("Retry SPI and SD...");
delay(100);
}
if (!success) return false;
return true;
}
You can also try a sketch for others SPI peripherals and check if they work as expected.