Jan 26, 2021
10:17 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jan 26, 2021
10:17 PM
Hi everyone,
I tried replicating "https://jimmyutterstrom.com/blog/2015/07/12/psoc-tutorial-adafruit-lsm303-magnetometer-compass-modul... onto PSoC5LP.
I got readings from the compass module, but it is always the same value and does not change while the PSoC plugged in.
When i remove and plug in the PSoC again, the heading value changes to what is expected but it does not update when i move the compass along. I feel like there's something wrong with the I2C communication, that the value is not being updated. Any help / guidance on how to solve this issue is greatly appreciated.
#include <project.h> #include <math.h> #include <stdio.h> #define LSM303_ADDRESS_ACCEL (0x32 >> 1) #define LSM303_ADDRESS_MAG (0x3C >> 1) #define LSM303_REGISTER_ACCEL_CTRL_REG1_A 0x20 #define LSM303_REGISTER_MAG_MR_REG_M 0x02 #define LSM303_REGISTER_MAG_OUT_X_H_M 0x03 #define LSM303_REGISTER_ACCEL_OUT_X_L_A 0x28 typedef struct Vector3{ int x; int y; int z; } Vector3; void LSM303_Init() { //Start the I2C component. LSM303_I2C_Start(); /*------------ Accelerometer ------------*/ //Send start command for write mode. LSM303_I2C_MasterSendStart(LSM303_ADDRESS_ACCEL, LSM303_I2C_WRITE_XFER_MODE); //Specify which register we want to write to. //This register is written to for enabling x, y and z //output as well as setting datarate and powermode. LSM303_I2C_MasterWriteByte(LSM303_REGISTER_ACCEL_CTRL_REG1_A); //Set the required bits in the register. LSM303_I2C_MasterWriteByte(0x27u); /*------------ Magnetometer ------------*/ //This register is written to for setting data output rates //and controlling measurement flow. LSM303_I2C_MasterWriteByte(LSM303_REGISTER_MAG_MR_REG_M); LSM303_I2C_MasterWriteByte(0x00u); LSM303_I2C_MasterSendStop(); } void LSM303_ReadMag(Vector3 *magData) { uint8 data[6]; //Prepare the module for magnetometer output. LSM303_I2C_MasterSendStart(LSM303_ADDRESS_MAG, LSM303_I2C_WRITE_XFER_MODE); LSM303_I2C_MasterWriteByte(LSM303_REGISTER_MAG_OUT_X_H_M); LSM303_I2C_MasterSendStop(); //-- //Start the communication in read mode. LSM303_I2C_MasterSendStart(LSM303_ADDRESS_MAG, LSM303_I2C_READ_XFER_MODE); //Read databytes. data[0] = LSM303_I2C_MasterReadByte(LSM303_I2C_ACK_DATA); data[1] = LSM303_I2C_MasterReadByte(LSM303_I2C_ACK_DATA); data[2] = LSM303_I2C_MasterReadByte(LSM303_I2C_ACK_DATA); data[3] = LSM303_I2C_MasterReadByte(LSM303_I2C_ACK_DATA); data[4] = LSM303_I2C_MasterReadByte(LSM303_I2C_ACK_DATA); //Notice that we are here using "NAK_DATA". It's to tell the //LSM303 that we're done and don't want to read anymore data. data[5] = LSM303_I2C_MasterReadByte(LSM303_I2C_NAK_DATA); //Put together the different data bytes to form complete //integers for storing the output values. magData->x = (int16_t)(data[1] | (data[0] << 8)); magData->y = (int16_t)(data[5] | (data[4] << 8)); magData->z = (int16_t)(data[3] | (data[2] << 8)); LSM303_I2C_MasterSendStop(); } int main() { Vector3 magData; char output[4]; //String for storing uart output. PC_UART_Start(); LSM303_Init(); for(;;) { LSM303_ReadMag(&magData); //Calculate heading using arctan on the Y and X vectors. //And convert from radians to degrees. float h = (atan2(magData.y, magData.x) * 180.0) / 3.14159265359; //Map the value to comply with the standard system where the heading //is specified as an angle between 0 - 360 degrees. if(h < 0) { h = 360 + h; } //Output the heading through our UART component. sprintf(output, "%i\r\n", (int)(h+0.5)); PC_UART_PutString(output); //Update heading at 1 Hz CyDelay(1000); } } /* [] END OF FILE */
Labels
- Labels:
-
PSOC5 LP MCU
1 Reply