- Edited
Hi everyone,
I'm trying to read data with a Bela mini from a IIS3DWB accelerometer and save it in a bin file so that I can analyze the signal on Matlab. The sensor has an output data rate of 26667 Hz and I'd like to exploit the whole bandwidth but I'm unsuccessful. At the moment I'm using hard SPI on pins P2.25-27-29-31 correctly configured through SSH connection and this library:[https://github.com/jeremiahrose/Bela/tree/SPI/libraries/SPI]
I'm using 44100Hz sample rate and calling the auxiliary task for the reading once every 2 audio samples.
Since I'm not getting timestamps for the readings from the sensor I'm calling the file1.log every audio sample, assuming that each reading will be repeated 2 times and that the time distance between one sample and the other is 1/44100 seconds. This is the code (simplified for better reading):
#include <Bela.h>
#include <stdio.h>
#include <stdlib.h>
#include <Spi.h>
#include <libraries/WriteFile/WriteFile.h>
#define IIS3DWB_PIN_CTRL 0x02
#define IIS3DWB_FIFO_CTRL1 0x07
//............. just a bunch of define, one for each register
#define IIS3DWB_FIFO_DATA_OUT_Z_H 0x7E
// Create a separate thread to poll Spi from
AuxiliaryTask SpiTask;
void readSpi(void*); // Function to be called by the thread
int readInterval = 22050;// How often readSpi() is run (in Hz)
int readCount = 0; // Used for scheduling, do not change
int readIntervalSamples; // How many samples between, do not change
Spi exampleDevice;
WriteFile file1;
int exampleOutput;
// IIS3DBW functions
unsigned char readByte (unsigned char reg){
exampleDevice.setup({
.device = "/dev/spidev2.1", // Device to open
.speed = 10000000, // Clock speed in Hz
.delay = 5, // Delay after last transfer before deselecting the device
.numBits = 8, // No. of bits per transaction word
.mode = Spi::MODE0 // Spi mode
});
unsigned char Rx; // Buffer to send
exampleDevice.single_transfer((reg & 0x7F) | 0x80);
Rx=exampleDevice.single_transfer(0x00);
return Rx;
}
void readBytes (unsigned char reg, unsigned char count, unsigned char * dest){
exampleDevice.setup({
.device = "/dev/spidev2.1", // Device to open
.speed = 10000000, // Clock speed in Hz
.delay = 5, // Delay after last transfer before deselecting the device
.numBits = 8, // No. of bits per transaction word
.mode = Spi::MODE0 // Spi mode
});
exampleDevice.single_transfer((reg & 0x7F) | 0x80);
for (unsigned char ii = 0; ii < count; ii++){
dest[ii] = exampleDevice.single_transfer(0x00);
}
}
void writeByte (unsigned char reg, unsigned char value){
exampleDevice.setup({
.device = "/dev/spidev2.1", // Device to open
.speed = 10000000, // Clock speed in Hz
.delay = 5, // Delay after last transfer before deselecting the device
.numBits = 8, // No. of bits per transaction word
.mode = Spi::MODE0 // Spi mode
});
exampleDevice.single_transfer(reg & 0x7F);
exampleDevice.single_transfer(value);
}
int16_t readAccelDataAxis(char axis)
{
unsigned char rawData[2]; // x/y/z accel register data stored here
switch (axis)
{
case 'x':
rawData[0]=readByte(IIS3DWB_OUTX_L_XL); // Read the 2 raw accel data registers into data array
rawData[1]=readByte(IIS3DWB_OUTX_H_XL);
break;
case 'y':
rawData[0]=readByte(IIS3DWB_OUTY_L_XL); // Read the 2 raw accel data registers into data array
rawData[1]=readByte(IIS3DWB_OUTY_H_XL);
break;
case 'z':
rawData[0]=readByte(IIS3DWB_OUTZ_L_XL); // Read the 2 raw accel data registers into data array
rawData[1]=readByte(IIS3DWB_OUTZ_H_XL);
break;
}
return (int16_t)((int16_t)rawData[1] << 8) | rawData[0] ; // Turn the MSB and LSB into a signed 16-bit value
}
void init(int Ascale)
{
writeByte(IIS3DWB_COUNTER_BDR_REG1, 0x00); // enable latched data ready interrupt
// mask data ready until filter settle complete (bit 3 == 1), disable I2C (bit 2 == 1)
writeByte(IIS3DWB_CTRL4_C, 0x08 | 0x04);
writeByte(IIS3DWB_CTRL1_XL, 0xA0 | Ascale << 2); // set accel full scale and enable accel
}
void reset()
{
writeByte(IIS3DWB_CTRL1_XL, 0x00); // set accel to power down mode
unsigned char temp = readByte(IIS3DWB_CTRL3_C);
writeByte(IIS3DWB_CTRL3_C, temp | 0x01); // Set bit 0 to 1 to reset IIS3DWB
usleep(1000); // Wait for all registers to reset
}
// end of IIS3DBW functions
bool setup(BelaContext *context, void *userData)
{
reset();
init(0x02); // configure IIS3DWB
// Set up auxiliary task to read Spi outside of the real-time audio thread:
SpiTask = Bela_createAuxiliaryTask(readSpi, 99, "bela-Spi");
readIntervalSamples = context->audioSampleRate / readInterval;
file1.setup("out.bin");
file1.setEchoInterval(10000);
file1.setFileType(kBinary);
file1.setFormat("binary: %.0f\n");
return true;
}
void render(BelaContext *context, void *userData)
{
for(unsigned int n = 0; n < context->audioFrames; n++) {
// Schedule auxiliary task for Spi readings
if(++readCount >= readIntervalSamples) {
readCount = 0;
Bela_scheduleAuxiliaryTask(SpiTask);
}
// use Spi output for whatever you need here
file1.log(exampleOutput);
}
}
// Auxiliary task to read Spi
void readSpi(void*){
int16_t prova;
prova=readAccelDataAxis('x');
exampleOutput = prova;
}
void cleanup(BelaContext *context, void *userData){
}