Pyboard 1v1: SPI programming MPU9250
Posted: Wed Apr 25, 2018 7:10 am
Hi Folks,
I am so beginner when it comes to embedded systems. I want to learn how to program them and a lot referred me to python since prototyping is fast and codes are simple to understand. I now know the basics of Python and I do like its straight-forwardness. I'm currently programming a Pyboard v1.1 and i now know the syntax on SPI also.
Now, i have my SPI device; it is a MPU9250 and I can't see python tutorial with it regarding SPI - all i2c. This leads me to reading internally the libraries of the SPI for MPU 9250 and done some coding like setting/writing modes then fetching raw/unprocessed gyro + accelerometer data and who_am_i of it. Now, when I'm going to test it out via interactive or script mode programming on python, i get data but all returns 0 or 0 > data. I do print the results and view them via python run by terminal/command line.
so far, i have tried (4) MPU9250 sensors and they always output 0x00 or 0 in whoami, (fifo count) sampling also of gyro and accelerometer is always 1. I have check my connections/wires and all are on their correct places:
MPU -> Pyboard:
SDA -> MOSI
ADO -> MISO
SCL -> SCK
nCS -> CS (GPIO)
Result of my simulation.
I don't have any oscilloscopes or logic analyzers as others suggest me to check it using those
I'll attach the code that I am using and THIS is reference (it's a github spi mpu9250 library, you can check its other files on that site also) I am decoding, what I'm after is the acquisition of initial raw data samples upon start up w/o processing them to real values and the who_am_i operation. The code is straight-forward where i didn't even create a separate file/library to handle spi transmission so you'll see a lot of redundant spi transmission codes.
I hope you can help me, Thanks
EDIT: Somehow I can't attach files (e.g. txt or py extension, always saying invalid extension). Here's the code below:
# main.py -- put your code here!
import pyb
from pyb import SPI
from pyb import Pin
#spi operation
print('\nSPI Pyboard v1.1 Test\n')
print('\nPowering up...')
#wait for power up mpu9250
pyb.delay(500)
print('done!')
#int_spi = Pin('Y11', Pin.IN, Pin.PULL_UP)
cs_spi1 = Pin('Y11', Pin.OUT_PP)
cs_spi2 = Pin('Y9', Pin.OUT_PP)
cs_spi = (cs_spi1, cs_spi2)
cs_spi[1].high()
cs_spi[0].high()
#based on datasheet, baudrate is exception
spi = SPI(1, SPI.MASTER, baudrate=115200, polarity=1, phase=1, firstbit=SPI.MSB)
sendW = bytearray(2)#for write operation (w/data)
sendR = bytearray(1)#for read operation
recvRo = bytearray(1)#for read operation, temporary data container
recvRs = bytearray(12)#for read operation, data container
#pwr mgmt1 addr, reset device
sendW[0] = 0x6B
sendW[1] = 0x80
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
pyb.delay(200)
print('\nReset device1 success!')
#auto select clock source, gyro or internal
sendW[1] = 0x01
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#pwr mgmt2 addr
sendW[0] = 0x6C
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
pyb.delay(400)
#int addr, disable all interrupt
sendW[0] = 0x38
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#fifo addr, disable all fifo
sendW[0] = 0x23
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#pwr mgmt1 addr, turn on clock source internal
sendW[0] = 0x6B
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#i2c enable addr, disable i2c master
sendW[0] = 0x24
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#user control addr, disable i2c modes and fifo
sendW[0] = 0x6A
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#reset fifo and dmp
sendW[1] = 0x0C
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
pyb.delay(100)
#config addr, set low pass filter 188hz
sendW[0] = 0x1A
sendW[1] = 0x01
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#sample rate divider addr, set 1khz
sendW[0] = 0x19
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#gyro cfg addr, max sensitivity
sendW[0] = 0x1B
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#accel cfg addr, max sensitivity
sendW[0] = 0x1C
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
gyroSense = 131#LSB,deg,sec
accelSense = 16384#LSB,g
#user control addr, disable i2c modes and fifo
#enable fifo
sendW[0] = 0x6A
sendW[1] = 0x40
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
print('\nAccumulating 40 samples...')
#user control addr, enable fifo
sendW[0] = 0x6A
sendW[1] = 0x40
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#fifo addr, enable gyro + accel fifo
sendW[0] = 0x23
sendW[1] = 0x78
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#accumulate 40 samples in 40 milliseconds, 480 bytes
pyb.delay(40)
#fifo addr, disable gyro + accel fifo
sendW[0] = 0x23
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
print('Done accumulating 40 samples!')
#fifo hi-count addr, read fifo
sendR[0] = 0x72 | 0x80
cs_spi[0].low()
for i in range(2):
#spi.send(0x00)
#spi.recv(recvRs) - the ff. errors so 'recvRo' is a temporary container
spi.send_recv(sendR, recvRo)
recvRs = recvRo[0]
cs_spi[0].high()
fifo_cnt = recvRs[0] << 8 | recvRs[1]
packet_cnt = fifo_cnt/12
print('\n--Raw result of samples--')
print('fifo cnt: ', fifo_cnt)
print('packet cnt: ', packet_cnt, '\n')
temp = bytearray(2)
#whoami
sendW[0] = 0x75 | 0x80
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
spi.recv(temp)
cs_spi[0].high()
print ('\nWho am I dev1: ', temp, ', I should be 0x71 -> 113 or 0x68 -> 104\n')
I am so beginner when it comes to embedded systems. I want to learn how to program them and a lot referred me to python since prototyping is fast and codes are simple to understand. I now know the basics of Python and I do like its straight-forwardness. I'm currently programming a Pyboard v1.1 and i now know the syntax on SPI also.
Now, i have my SPI device; it is a MPU9250 and I can't see python tutorial with it regarding SPI - all i2c. This leads me to reading internally the libraries of the SPI for MPU 9250 and done some coding like setting/writing modes then fetching raw/unprocessed gyro + accelerometer data and who_am_i of it. Now, when I'm going to test it out via interactive or script mode programming on python, i get data but all returns 0 or 0 > data. I do print the results and view them via python run by terminal/command line.
so far, i have tried (4) MPU9250 sensors and they always output 0x00 or 0 in whoami, (fifo count) sampling also of gyro and accelerometer is always 1. I have check my connections/wires and all are on their correct places:
MPU -> Pyboard:
SDA -> MOSI
ADO -> MISO
SCL -> SCK
nCS -> CS (GPIO)
Result of my simulation.
I don't have any oscilloscopes or logic analyzers as others suggest me to check it using those
I'll attach the code that I am using and THIS is reference (it's a github spi mpu9250 library, you can check its other files on that site also) I am decoding, what I'm after is the acquisition of initial raw data samples upon start up w/o processing them to real values and the who_am_i operation. The code is straight-forward where i didn't even create a separate file/library to handle spi transmission so you'll see a lot of redundant spi transmission codes.
I hope you can help me, Thanks
EDIT: Somehow I can't attach files (e.g. txt or py extension, always saying invalid extension). Here's the code below:
# main.py -- put your code here!
import pyb
from pyb import SPI
from pyb import Pin
#spi operation
print('\nSPI Pyboard v1.1 Test\n')
print('\nPowering up...')
#wait for power up mpu9250
pyb.delay(500)
print('done!')
#int_spi = Pin('Y11', Pin.IN, Pin.PULL_UP)
cs_spi1 = Pin('Y11', Pin.OUT_PP)
cs_spi2 = Pin('Y9', Pin.OUT_PP)
cs_spi = (cs_spi1, cs_spi2)
cs_spi[1].high()
cs_spi[0].high()
#based on datasheet, baudrate is exception
spi = SPI(1, SPI.MASTER, baudrate=115200, polarity=1, phase=1, firstbit=SPI.MSB)
sendW = bytearray(2)#for write operation (w/data)
sendR = bytearray(1)#for read operation
recvRo = bytearray(1)#for read operation, temporary data container
recvRs = bytearray(12)#for read operation, data container
#pwr mgmt1 addr, reset device
sendW[0] = 0x6B
sendW[1] = 0x80
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
pyb.delay(200)
print('\nReset device1 success!')
#auto select clock source, gyro or internal
sendW[1] = 0x01
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#pwr mgmt2 addr
sendW[0] = 0x6C
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
pyb.delay(400)
#int addr, disable all interrupt
sendW[0] = 0x38
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#fifo addr, disable all fifo
sendW[0] = 0x23
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#pwr mgmt1 addr, turn on clock source internal
sendW[0] = 0x6B
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#i2c enable addr, disable i2c master
sendW[0] = 0x24
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#user control addr, disable i2c modes and fifo
sendW[0] = 0x6A
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#reset fifo and dmp
sendW[1] = 0x0C
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
pyb.delay(100)
#config addr, set low pass filter 188hz
sendW[0] = 0x1A
sendW[1] = 0x01
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#sample rate divider addr, set 1khz
sendW[0] = 0x19
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#gyro cfg addr, max sensitivity
sendW[0] = 0x1B
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#accel cfg addr, max sensitivity
sendW[0] = 0x1C
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
gyroSense = 131#LSB,deg,sec
accelSense = 16384#LSB,g
#user control addr, disable i2c modes and fifo
#enable fifo
sendW[0] = 0x6A
sendW[1] = 0x40
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
print('\nAccumulating 40 samples...')
#user control addr, enable fifo
sendW[0] = 0x6A
sendW[1] = 0x40
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#fifo addr, enable gyro + accel fifo
sendW[0] = 0x23
sendW[1] = 0x78
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
#accumulate 40 samples in 40 milliseconds, 480 bytes
pyb.delay(40)
#fifo addr, disable gyro + accel fifo
sendW[0] = 0x23
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
cs_spi[0].high()
print('Done accumulating 40 samples!')
#fifo hi-count addr, read fifo
sendR[0] = 0x72 | 0x80
cs_spi[0].low()
for i in range(2):
#spi.send(0x00)
#spi.recv(recvRs) - the ff. errors so 'recvRo' is a temporary container
spi.send_recv(sendR, recvRo)
recvRs = recvRo[0]
cs_spi[0].high()
fifo_cnt = recvRs[0] << 8 | recvRs[1]
packet_cnt = fifo_cnt/12
print('\n--Raw result of samples--')
print('fifo cnt: ', fifo_cnt)
print('packet cnt: ', packet_cnt, '\n')
temp = bytearray(2)
#whoami
sendW[0] = 0x75 | 0x80
sendW[1] = 0x00
cs_spi[0].low()
spi.send(sendW)
spi.recv(temp)
cs_spi[0].high()
print ('\nWho am I dev1: ', temp, ', I should be 0x71 -> 113 or 0x68 -> 104\n')