如何通过python的smbus i2c接口与MC3416xPJ通信?

时间:2019-05-05 00:02:04

标签: python raspberry-pi3 sensor i2c smbus

我的问题是关于如何在RaspberryPi上通过python的i2c接口smbus连接磁传感器MMC3416xPJ。我已经按照传感器的数据表(https://www.memsic.com/userfiles/files/Datasheets/Magnetic-Sensors-Datasheets/MMC3416xPJ_Rev_C_2013_10_30.pdf)在ATMega微控制器中用C实现了正在运行的i2c通信。但是,此代码在某些位置需要i2c“首次启动”和“重复启动”功能。例如,“ get_data”函数看起来像附加的:

error_code = i2c_first_start(address | I2C_WRITE);

if(error_code != I2C_SUCCEED){return error_code;}

error_code = i2c_write(MMC3416xPJ_CONTROL_0);

if(error_code != I2C_SUCCEED){return error_code;}

...

我已经尝试使用RPi的i2cdetect和i2cset命令来连接传感器。有趣的是(奇怪的),“ sudo i2cdetect-y 1”指向十六进制地址0x61。虽然,传感器(MMC34160PJ)的写地址应改为0b01100000(0x60)。有没有人已经尝试在python中使用此传感器或类似传感器?

提前谢谢!

请附上要在python中实现的代码:

error_code = i2c_first_start(address | I2C_WRITE);              // FIRST START 0x60 | 0x00 = 0x60 "I want to write"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_write(MMC3416xPJ_CONTROL_0);               // 0x07 "I am interested in control register"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_write( (1<<MMC3416xPJ_CONTROL_0_TAKEMEASUREMENT) );    // 0x01 "I want to set bit to start measurement"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_repeated_start(address | I2C_WRITE);           // REPEATED START 0x60 | 0x00 = 0x60 "I want to write again"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_write(MMC3416xPJ_STATUS);              // 0x06 "I am interested in status register"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_repeated_start(address | I2C_READ);            // REPEATED START 0x60 | 0x01 = 0x61 "I want to read"
if(error_code != I2C_SUCCEED){return error_code;}
while(1){
    error_code = i2c_read_nack(&data);              // READ (NOT ACKNOWLEDGE)
    if(error_code != I2C_SUCCEED){return error_code;}
    if (data & (1<<MMC3416xPJ_STATUS_MEAS_DONE))            // data & 0x01 "Is measurement already done?"
    break;
};
error_code = i2c_repeated_start(address | I2C_WRITE);           // REPEATED START 0x60 | 0x00 = 0x60 "I want to write again"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_write(MMC3416xPJ_XOUT_LOW);                // 0x00 "I am interested in measurement data register"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_repeated_start(address | I2C_READ);            // 0x60 | 0x01 = 0x61 "I want to read again"
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_read_ack(&data_x_low);                 // READ (ACKNOWLEDGE) BYTE 0
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_read_ack(&data_x_high);                // READ (ACKNOWLEDGE) BYTE 1
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_read_ack(&data_y_low);                 // READ (ACKNOWLEDGE) BYTE 2
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_read_ack(&data_y_high);                // READ (ACKNOWLEDGE) BYTE 3
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_read_ack(&data_z_low);                 // READ (ACKNOWLEDGE) BYTE 4
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_read_nack(&data_z_high);               // READ (ACKNOWLEDGE) BYTE 5
if(error_code != I2C_SUCCEED){return error_code;}
error_code = i2c_stop();                        // STOP
if(error_code != I2C_SUCCEED){return error_code;}
data_x_16bit = (int16_t) ( ((data_x_high << 8) | data_x_low ) );
data_y_16bit = (int16_t) ( ((data_y_high << 8) | data_y_low ) );
data_z_16bit = (int16_t) ( ((data_z_high << 8) | data_z_low ) );
data_x_16bit -= 32768;
data_y_16bit -= 32768;
data_z_16bit -= 32768;

我认为前三个发送行应该以某种方式看起来与此类似,但它不起作用:

import smbus
bus = smbus.SMBus(1)
bus.write_byte_data(0x60, 0x07, 0x01)  # Send 0x01 (TAKEMEASUREMENT) to 0x07 (Control 0 register) to address 0x60 (0b01100000) of MMC3416{0}PJ.

结果始终为Errno 121-与使用write_data,write_byte_data,write_word_data或其他方法无关...

0 个答案:

没有答案