I'm trying to write and read **ADXL345** (but ADXL accelerometers are all pretty similar) through **SPI**; there are many posts on this topic but none that uses **ESP32** based device.
List of related topics I've found:
* viewtopic.php?f=6&t=1743&p=10020&hilit= ... spi#p10020
* viewtopic.php?f=2&t=6539&p=51710&hilit= ... spi#p51710
* viewtopic.php?f=20&t=8076&p=46416&hilit ... sor#p46416
* viewtopic.php?f=18&t=8717&p=49172&hilit=spi#p49172
* https://github.com/dzheng256/adxl345spi ... adxl345.py
First thing I don't understand reading others code is why and when while reading and writing to the device the buffers must be compared with 0x40 and 0x80. Is this an SPI rule? It seems to me every piece of code have a different approach to this.
ESP32 ADXL345 (accelerometer) SPI
-
- Posts: 28
- Joined: Mon Aug 27, 2018 4:43 pm
ESP32 ADXL345 (accelerometer) SPI
Last edited by aleskeyfedorovich on Thu Oct 22, 2020 7:09 am, edited 1 time in total.
Re: ESP32 ADXL345 (accelerometer) SPI
Just looking at a snippet from one of the threads you linked to: viewtopic.php?f=6&t=1743&p=10020#p10022aleskeyfedorovich wrote: ↑Wed Oct 21, 2020 5:00 pmFirst thing I don't understand reading others code is why and when while reading and writing to the device the buffers must be compared with 0x40 and 0x80. Is this an SPI rule? It seems to me every piece of code have a different approach to this.
Code: Select all
READWRITE_CMD = const(0x80)
MULTIPLEBYTE_CMD = const(0x40)
-
- Posts: 28
- Joined: Mon Aug 27, 2018 4:43 pm
Re: ESP32 ADXL345 (accelerometer) SPI
Ok I found on the [datasheet](https://www.analog.com/media/en/technic ... DXL345.pdf), in the SPI paragraph that:
* first bit of the transmission must be 1 if reading and 0 if writing
* second bit must be 1 if reading or writing multiple bytes, 0 otherwise
Still after this clarification I get some strange results
In order to test if the comunication is working properly I'm reading the id of the device, setting the frequency and then reading back the frequency:
The first time I run this after turning on the device I get the proper id of the device that is 0xe5, BUT I get 0xe5 also reading the frequency I just set to 0x0f!
In the second run I get always 0x00 for both the reading, what am I doing wrong?
* first bit of the transmission must be 1 if reading and 0 if writing
* second bit must be 1 if reading or writing multiple bytes, 0 otherwise
Still after this clarification I get some strange results
In order to test if the comunication is working properly I'm reading the id of the device, setting the frequency and then reading back the frequency:
Code: Select all
from machine import Pin, SPI
from micropython import const
# addresses
regaddr_id = const(0x00)
regaddr_freq = const(0x2C)
# SPI definitions
READ_MASK = const(0x80)
MULTIBYTE_MASK = const(0x40)
# set up
spi = SPI(2, sck=Pin(18, Pin.OUT), mosi=Pin(23, Pin.OUT), miso=Pin(19), baudrate=2000000, polarity=1, phase=1, bits=8,
firstbit=SPI.MSB)
CS = Pin(5, Pin.OUT, value=1)
def read(regaddr, nbytes):
wbuf = regaddr | READ_MASK
if nbytes > 1:
wbuf = wbuf | MULTIBYTE_MASK
CS.value(0)
value = spi.read(nbytes, wbuf)
CS.value(1)
return value
def read_into(rbuf, regaddr):
wbuf = bytearray(len(rbuf))
wbuf[0] = regaddr | READ_MASK | MULTIBYTE_MASK
CS.value(0)
spi.write_readinto(wbuf, rbuf)
CS.value(1)
return rbuf
def write(regaddr, bt):
CS.value(0)
spi.write(bytearray(regaddr | MULTIBYTE_MASK, bt))
CS.value(1)
# device id
devid = read(regaddr_id, 1)
if devid == b'\xE5':
print('OK devid')
else:
print('Not OK: devid = ' + str(devid))
# set frequency 3.2 kHz
write(regaddr_freq, 0x0F)
freq = read(regaddr_freq, 1)
if freq == b'\x0F':
print('OK frequency')
else:
print('Not OK: freq = ' + str(freq))
spi.deinit()
In the second run I get always 0x00 for both the reading, what am I doing wrong?
-
- Posts: 28
- Joined: Mon Aug 27, 2018 4:43 pm
Re: ESP32 ADXL345 (accelerometer) SPI
The key is the SPI diagram in the datasheet (figure 37, figure 38).
It's necessary to read at least 2 bytes and the first must be ignored.
This way I get correct results
It's necessary to read at least 2 bytes and the first must be ignored.
Code: Select all
def read(regaddr, nbytes):
wbuf = regaddr | READ_MASK
if nbytes > 1:
wbuf = wbuf | MULTIBYTE_MASK
CS.value(0)
value = spi.read(nbytes + 1, wbuf)[1:]
CS.value(1)
return value
-
- Posts: 28
- Joined: Mon Aug 27, 2018 4:43 pm
Re: ESP32 ADXL345 (accelerometer) SPI
I decided to put the final library on github at this [link](https://github.com/AlekseyFedorovich/ADXL345_spi)