Как связаться с MC3416xPJ через интерфейс smbus i2c python? - PullRequest
0 голосов
/ 05 мая 2019

Мой вопрос о том, как подключить магнитный датчик MMC3416xPJ через интерфейс sambus Python i2c на RaspberryPi.Я уже реализовал работающую связь i2c в C для микроконтроллеров ATMega, следуя спецификации датчика (https://www.memsic.com/userfiles/files/Datasheets/Magnetic-Sensors-Datasheets/MMC3416xPJ_Rev_C_2013_10_30.pdf).. Однако для этого кода требуются функции 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?

Спасибо вadvance!

Атташе, пожалуйста, найдите код, который будет реализован на 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 или whatever ...

...