Unable to communicate correctly with the GY-521
Posted: Tue May 19, 2020 5:04 am
I am trying to read some registers from the GY521, which has multiple accelerometers and gyroscopes. Bascially, I am using I2C to read the data from it, but it is not responding back, I am wondering, why?
It is not fried because I have tried it with Arduino Uno and it was working perfectly. And, I have read the AC voltage from the SDA and SCL pins which is getting me something at least. Why am I reading AC voltage? because the AC is about pulses, the same concept applies here, if I get something on the multimeter, means there are some pulses coming out from the SDA and SCL pins. I don't know when to choose between the "ACK" or "NACK" for the GY-521. I have tried it on 400kHz and 100kHz, same results, noting that they both work with the GY-521.
The code:
It is not fried because I have tried it with Arduino Uno and it was working perfectly. And, I have read the AC voltage from the SDA and SCL pins which is getting me something at least. Why am I reading AC voltage? because the AC is about pulses, the same concept applies here, if I get something on the multimeter, means there are some pulses coming out from the SDA and SCL pins. I don't know when to choose between the "ACK" or "NACK" for the GY-521. I have tried it on 400kHz and 100kHz, same results, noting that they both work with the GY-521.
The code:
Code: Select all
#include <driver/i2c.h>
#include <esp_event.h>
#define MPU6050_SDA 21
#define MPU6050_SCL 22
#define MPU6050_ADDRESS 0b1101000
#define MPU6050_RESET_REGISTER 0x6B
#define MPU6050_DISABLE_TEMP_SENSOR 0b0001000
#define MPU6050_RESET_COMMAND 0b1001000 // the last bit is for reset and the middle one for temp sensor disable
#define MPU6050_ACCEL_CONFIG_REGISTER 0x1C
#define MPU6050_GYRO_CONFIG_REGISTER 0x1B
#define MPU6050_X_ACCEL_OUTPUT_REGISTER 0x3B
#define MPU6050_X_GYRO_OUTPUT_REGISTER 0x43
#define CONVERT_RAW_ACCEL_TO_ACCEL_OF_2G(rawAccel) rawAccel/16384
#define CONVERT_RAW_ACCEL_TO_ACCEL_OF_4G(rawAccel) rawAccel/8192
#define CONVERT_RAW_ACCEL_TO_ACCEL_OF_8G(rawAccel) rawAccel/4096
#define CONVERT_RAW_ACCEL_TO_ACCEL_OF_16G(rawAccel) rawAccel/2048
void sendMessageToMPU(us registerNumber, us command, us write, us* const readBuffer, size_t readBufferSize) {
i2c_cmd_handle_t cmdHandler = i2c_cmd_link_create();
i2c_master_start(cmdHandler);
i2c_master_write_byte(cmdHandler, (MPU6050_ADDRESS << 1) | !write, 1);
printf("[Master] The address of the MPU was sent with command of %s to send %d\n", !write ? "Reading" : "Writing", command);
i2c_master_write_byte(cmdHandler, registerNumber, 1);
if (write) {
i2c_master_write_byte(cmdHandler, command, 1);
} else {
i2c_master_read(cmdHandler, readBuffer, readBufferSize, I2C_MASTER_ACK);
}
i2c_master_stop(cmdHandler);
i2c_master_cmd_begin(I2C_NUM_0, cmdHandler, pdMS_TO_TICKS(5));
i2c_cmd_link_delete(cmdHandler);
}
void initMaster() {
i2c_config_t MPUConfig;
MPUConfig.mode = I2C_MODE_MASTER;
MPUConfig.master.clk_speed = 400000;
MPUConfig.sda_io_num = (gpio_num_t)MPU6050_SDA;
MPUConfig.scl_io_num = (gpio_num_t)MPU6050_SCL;
MPUConfig.scl_pullup_en = (gpio_pullup_t)1;
MPUConfig.sda_pullup_en = (gpio_pullup_t)1;
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &MPUConfig));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0));
sendMessageToMPU(MPU6050_ACCEL_CONFIG_REGISTER, 0, 1, 0, 0);
sendMessageToMPU(MPU6050_GYRO_CONFIG_REGISTER, 0, 1, 0, 0);
}
void setup(void);
void loop(void);
void app_main() {
setup();
for (; ;) {
loop();
}
}
void setup() {
initMaster();
}
void loop() {
unsigned short* xAccelPtr = (unsigned short*)malloc(2);
MPU_Operations::sendMessageToMPU(MPU6050_X_ACCEL_OUTPUT_REGISTER, 0, 0, (us*)xAccelPtr, 2);
printf("X Accel: %d\n", CONVERT_RAW_ACCEL_TO_ACCEL_OF_2G(*xAccelPtr));
printf("\n\n");
delete xAccelPtr;
vTaskDelay(pdMS_TO_TICKS(1000));
}