I cannot use I2C in Keil Studio

We are in the process of migrating from mbed os2 to mbed os6.
I tried to get the values from the BMX055 using I2C and output them on my laptop via serial communication. However, the values are not output. I have confirmed that serial communication is working properly. I am having trouble because there is no error message.
If you have any ideas, please let me know.

The environment we are using is baremetal with Mbed OS6

Hello,

please be so kind fill a name of your target.

BR, Jan

thank you for replying Jan .

I am trying to use the BMX055 9-axis sensor module. I am going to get acceleration and angular velocity information from it.

I am not a good English speaker, so maybe this is not what you are replying to.

Hello,

I understand what BMX055 is, but…

  • what MCU do you use?
  • link to your library for BMX055?

BR, Jan

What Mbed board are you using? Also, are you using a library to communicate with the BMX055? Could you post the more detail about the code that you tried?

Same below in Japanese v

どのmbedターゲットを使っていますか。そして、BMX055と連絡するためのライブラリーを使っていますか?試したプログラムを詳しく教えてください。

#include"mbed.h"

//ポート設定
BufferedSerial uart_usb(USBTX, USBRX,115200); //USB接続
DigitalOut led1(LED1); //ボード上のLED
I2C i2c(PB_9, PB_8); //ジャイロ、加速度センサ

//=========================================================
//ジャイロ加速度センサ設定
int sample_num = 100;
float meas_interval = 0.01;
float theta_mean;
float theta_variance;
float theta_dot_mean;
float theta_dot_variance;

//=========================================================

//=========================================================
// I2C common functions
//=========================================================
//i2c write function
void i2c_mem_write(int device_address, int mem_address, int mem_data)
{
int device_address_temp = device_address<<1;
device_address_temp = device_address_temp & 0xfe;

i2c.start();
i2c.write(device_address_temp);
i2c.write(mem_address);
i2c.write(mem_data);
i2c.stop();
return;

}

//i2c read function
int i2c_mem_read(int device_address, int mem_address)
{
int device_address_temp = device_address<<1;
int device_address_temp_w = device_address_temp & 0xfe;
int device_address_temp_r = device_address_temp | 0x01;

i2c.start();
i2c.write(device_address_temp_w);
i2c.write(mem_address);
i2c.write(device_address_temp_r);
int data = i2c.read(0);
i2c.stop();
return data;

}

//=========================================================
// Accelerometer (BMX055)
//=========================================================
//get data
float get_acc_data()
{
//read ACCD_Y_LSB registor (0x04)
int y_temp_L = i2c_mem_read(0x19, 0x04);
y_temp_L = y_temp_L >> 4;
y_temp_L = y_temp_L & 0x0f;

//read RATE_Y_MSB registor (0x05)
int y_temp_H = i2c_mem_read(0x19, 0x05);

//calculate Y acceleration
int y_data = y_temp_L + 16 * y_temp_H;
if(y_data > 2047)
{
    y_data = -1 * (4096 - y_data);
}

//-----------------------------------------------------
//read ACCD_Z_LSB registor (0x06)
int z_temp_L = i2c_mem_read(0x19, 0x06);
z_temp_L = z_temp_L >> 4;
z_temp_L = z_temp_L & 0x0f;

//read RATE_Z_MSB registor (0x07)
int z_temp_H = i2c_mem_read(0x19, 0x07);

//calculate Z acceleration
int z_data = z_temp_L + 16 * z_temp_H;
if(z_data > 2047)
{
    z_data = -1 * (4096 - z_data);
}

//-----------------------------------------------------
//calculate theta
float theta_deg = atan( float(y_data) / float(z_data) );
return (float)theta_deg * 57.29578f;   //degree

}

//statistical data of accelerometer
void acc_init()
{
//initialize ACC register 0x0F (range)
//Full scale = +/- 2 G
i2c_mem_write(0x19, 0x0f, 0x03);

//initialize ACC register 0x10 (band width)
//Filter bandwidth = 1000 Hz
i2c_mem_write(0x19, 0x10, 0x0f);

//get data
float theta_array[sample_num];
for(int i=0; i<sample_num; i++)
{
    theta_array[i] = get_acc_data();
    wait_us( meas_interval );
}

//calculate mean
theta_mean = 0;
for(int i=0; i<sample_num; i++)
{
    theta_mean += theta_array[i];
}
theta_mean /= sample_num;

//calculate variance
float temp;
theta_variance = 0;
for(int i=0; i<sample_num; i++)
{
    temp = theta_array[i] - theta_mean;
    theta_variance += temp*temp;
}
theta_variance /= sample_num;
return;

}

//=========================================================
// Gyroscope (BMX055)
//=========================================================
//get data
float get_gyro_data()
{
//read RATE_X_LSB registor (0x02)
int x_temp_L = i2c_mem_read(0x69, 0x02);
//read RATE_X_MSB registor
int x_temp_H = i2c_mem_read(0x69, 0x03);

//calculate X angular ratio
int x_data = x_temp_L + 256 * x_temp_H;
if(x_data > 32767)
{
    x_data = -1 * (65536 - x_data);
}
x_data = -1 * x_data;
// +1000 (deg/sec) / 2^15 = 0.0305176
return float(x_data) * -0.0305176f; // deg/sec

}

//statistical data of gyro
void gyro_init()
{
//initialize Gyro register 0x0F (range)
//Full scale = +/- 1000 deg/s
i2c_mem_write(0x69, 0x0f, 0x01);

//initialize Gyro register 0x10 (band width)
//Data rate = 1000 Hz, Filter bandwidth = 116 Hz
i2c_mem_write(0x69, 0x10, 0x02);

//get data
float theta_dot_array[sample_num];
for(int i=0;i<sample_num;i++)
{
    theta_dot_array[i] = get_gyro_data();
    wait_us(meas_interval);
}

//calculate mean
theta_dot_mean = 0;
for(int i=0;i<sample_num;i++)
{
    theta_dot_mean += theta_dot_array[i];
}
theta_dot_mean /= sample_num;

//calculate variance
float temp;
theta_dot_variance = 0;
for(int i=0; i<sample_num; i++)
{
    temp = theta_dot_array[i] - theta_dot_mean;
    theta_dot_variance += temp*temp;
}
theta_dot_variance /= sample_num;
return;

}

int main()
{

int num = 1 ;

//-------------------------------------------
//I2C initialization
//-------------------------------------------
i2c.frequency(400000); //400 kHz

//UART initialization
//uart_usb.baud(115200); //115.2 kbps
uart_usb.set_format(8, BufferedSerial::None, 1);
printf(“==角度==角速度==\n”);

//-------------------------------------------
//Accelerometer & Gyro initialization
//-------------------------------------------
//センサの初期化
acc_init();
gyro_init();

while(1)
{

printf("%f , %f\n", get_acc_data(), get_gyro_data() );

}

}

Sorry for the delay. I had an exam and had to get used to it for a while.
I have posted the program.
The board used is NUCLEO-F401RE.
This works on OS5.

Hmm, you might have to use a logic analyzer to see what is getting output over the I2C bus, it’s hard to say from this code (looks correct). What Mbed version are you using? On STM32 devices, the single-byte I2C functions were quite badly broken until Mbed 6.17 or so.

Same below in Japanese v

妙だなあ、プログラムが正しそうと思う。問題を発見するように、ロジアナを付けたほうがいいと思う。ところで、どのmbedのバージョンを使っているか?6.17以下なら、STM32ターゲットのI2C HALがだいぶ壊れていた。

Thanks for checking the program.
I use OS6.13. I did not know that I2C was broken.
Thanks for letting me know. By the way, which is the best choice for the latest version of the OS?
I’ll try OS 6.17.0 for now.
Let me know if other ones are better.
image

Avoid to use versions with -rcx sufix, that are Release Candidates before pure 6.17 was released.

BR, Jan