1 2 Previous Next 22 Replies Latest reply on Oct 17, 2015 2:23 AM by user_1377889

    I2C for HMC5883L compass

    niharika.bhargava
              I am trying to use the PSoC as the master to communicate with the compass to get values for x, y and z axis and display them on the LCD screen. I have set the I2C component to master mode as Fixed Function. SDA is connected to P12[5] and SCL to P12[4]. I get the same values 127 32 9 displayed on the screen regardless of the orientation of the compass. The code is as follows: #include        #include          #include            #define SLAVE_ADD 0x1E #define Config_Reg_A 0x00 #define Config_Reg_B 0x01 #define Mode_Reg 0x02 #define X_MSB_Reg 0x03 #define X_LSB_Reg 0x04 #define Z_MSB_Reg 0x05 #define Z_LSB_Reg 0x06 #define Y_MSB_Reg 0x07 #define Y_LSB_Reg 0x08 #define Status_Reg 0x09 #define ID_Reg_A 0x0A #define ID_Reg_B 0x0B #define ID_Reg_C 0x0C void compass_init(); void main() { LCD_Char_1_Start(); I2C_Compass_Start(); /* Send 9 clocks on SCL line in order to unlock any possible freeze of connected devices on the I2C bus */ I2C_Compass_MasterSendStart(0xFF, I2C_Compass_READ_XFER_MODE); I2C_Compass_MasterSendStop(); compass_init(); CyDelay(6); uint8 x=0, y=0, z=0; // 3-axis Magnetometer Raw sensor values while(1){ uint8 send_data[] = {X_MSB_Reg}; uint8 *setup = send_data; I2C_Compass_MasterWriteBuf(SLAVE_ADD, setup, 1u,I2C_Compass_MODE_COMPLETE_XFER); uint8 rec_data[6]; uint8 *read = rec_data; I2C_Compass_MasterReadBuf(SLAVE_ADD, read, 6u, I2C_Compass_MODE_COMPLETE_XFER); LCD_Char_1_PrintInt8(rec_data[0]); x = rec_data[0]<<8 | rec_data[1]; y = rec_data[2]<<8 | rec_data[3]; z = rec_data[4]<<8 | rec_data[5]; LCD_Char_1_PrintNumber(x); LCD_Char_1_PutChar(' '); LCD_Char_1_PrintNumber(y); LCD_Char_1_PutChar(' '); LCD_Char_1_PrintNumber(z); CyDelay(1500); LCD_Char_1_ClearDisplay(); CyDelay(1500); void compass_init() { uint8 send_data[] = {Mode_Reg, Config_Reg_A}; uint8 *setup = send_data; I2C_Compass_MasterWriteBuf(SLAVE_ADD, setup, 2u,I2C_Compass_MODE_COMPLETE_XFER); }              
        • 1. Re: I2C for HMC5883L compass
          user_1377889

          Welcome in the forum!

             

          Please do not try to post code-snippets but attach a completre project archive, so we all can have a look at all of your settings.  To do so, use
          Creator->File->Create Workspace Bundle (minimal)
          and attach the resulting file. A link to the datasheet of the compass would be helpful, so we must not search for it.



          Bob
           

          • 2. Re: I2C for HMC5883L compass
            niharika.bhargava
                    Yeah sorry about that. Please find the file attached   
            • 3. Re: I2C for HMC5883L compass
              user_1377889

              You did not enable global interrupts which is requred for the I2C-component to function properly..

                 

                      uint8 send_data[] = {X_MSB_Reg};
                      uint8 *setup = send_data;
                      I2C_Compass_MasterWriteBuf(SLAVE_ADD, setup, 1u,I2C_Compass_MODE_COMPLETE_XFER);
              This sequence can be done easier, since in C-language an array is a pointer to its data. So you might write

                 

                      uint8 send_data[] = {X_MSB_Reg};
                      I2C_Compass_MasterWriteBuf(SLAVE_ADD, send_data, 1u,I2C_Compass_MODE_COMPLETE_XFER);

                 

              thus saving an additional variable and its initialization.

                 

              Sometimes it is requred to address an I2C-slave with a sequence of

                 

              MasterSendStart();  //Initializing a read register sequence

                 

              MasterWriteByte(); // Register to read

                 

              MasterSendRestart(); // Switch to reading now

                 

              MasterReadByte(); // Get register value, could be repeated, some devices allow for that

                 

              MasterSendStop(); // End the transmission

                 


              Happy coding

                 

              Bob

              • 4. Re: I2C for HMC5883L compass
                user_14586677

                There is a fairly good ap note here and some examples.

                   

                 

                   

                www.dropbox.com/s/1s8u0uurlhw0nbs/I2C%20Ap%20Notes.zip

                   

                 

                   

                Regrds, Dana.

                • 5. Re: I2C for HMC5883L compass
                  jorden.luke

                  I have been working with the PSOC for some time. I really like them and find the very useful. The issue I have them is I have always had problems with the I2C. I am trying to use the this same sensor. I have the interrupts enable. I have connected it to a logic analyzer and I can see that when I make the function call MasterSendStart(); It is sending out the data that  I would expect. I am even seeing the Ack. The problem that I am having is with the next line which is I2C_MasterWriteByte(byte); it just hangs up in here and never continues. Any hints?

                  • 6. Re: I2C for HMC5883L compass
                    user_1377889

                    Welcome in the forum!

                       

                    Can you post your complete project, so that we all can have a look at all of your settings? To do so, use
                    Creator->File->Create Workspace Bundle (minimal)
                    and attach the resulting file.

                       

                    MasterSendStart() returned a value, was it != zero? Same for MasterSendByte(), what was returned.

                       

                    What is your environment? Cypress Kit?? Self-made pcb???

                       

                    I2C terminated correctly? Connections checked twice?

                       

                    Bob

                    • 7. Re: I2C for HMC5883L compass
                      user_14586677

                      Here is a PSOC 4 solution you could possibly adapt -

                         

                       

                         

                      https://github.com/EmbeddedSam/PSoC-4-Compass-Sensor

                         

                       

                         

                      Regards, Dana.

                      • 8. Re: I2C for HMC5883L compass
                        jorden.luke

                        I am using the FreeSoC2 Development Board - PSoC5LP https://www.sparkfun.com/products/13229. I can't see what is being returned in the status it doesn't come up in the locals when I am am running it in the debugger. I have checked the connections many of time. It works with an Arduino I set up just to test the sensor. I can also see the data that I expect on a logic analyzer when this line of code is executed: I2C_MasterSendStart(HMC5883L_ADDRESS, I2C_WRITE_XFER_MODE). I have uploaded the file. The main function I have been debugging is HMC5883L_Config(). I do have uart that I was using for debuging. 

                        • 9. Re: I2C for HMC5883L compass
                          user_1377889

                          First I see that the pin connected to sda is not configured correctly. Datasheet states:

                             

                          sda – In/Out
                          Serial data (SDA) is the I2C data signal. It is a bidirectional data signal used to transmit or receive all bus data. The pin connected to sda should be configured as Open-Drain-Drives-Low.

                             

                          Usually reading from an I2C-device is done in one transaction, in your case like

                             

                              I2C_MasterSendStart(HMC5883L_ADDRESS, I2C_WRITE_XFER_MODE);
                              I2C_MasterWriteByte(array[0]);
                              I2C_MasterWriteByte(array[1]);

                             

                           
                              I2C_MasterSendRestart(HMC5883L_ADDRESS, I2C_READ_XFER_MODE);
                              array[0] = I2C_MasterReadByte(I2C_ACK_DATA);
                              array[1] = I2C_MasterReadByte(I2C_ACK_DATA);
                              array[2] = I2C_MasterReadByte(I2C_ACK_DATA);
                              array[3] = I2C_MasterReadByte(I2C_ACK_DATA);
                              array[4] = I2C_MasterReadByte(I2C_ACK_DATA);
                              array[5] = I2C_MasterReadByte(I2C_NAK_DATA); // Signal LAST BYTE to read
                              I2C_MasterSendStop();

                             

                           

                             

                          Additionally I would suggest to check the returned values of SendStart() etc which are ment to indicate any errors occured.

                             

                           

                             

                          Bob

                          • 10. Re: I2C for HMC5883L compass
                            jorden.luke

                            Bob,
                            I don't know where you saw that configuration but as I am looking at mine it is configured like you said. No I didn't change it. See the screen shot that I have attached

                               

                               

                            Other than checking that what you said  I feel I have all ready been work with. In the config function I guess I don't need to stop it and start it again to set up the next set or regs.

                               

                            Thanks,

                               

                            Jorden Luke

                               

                            • 11. Re: I2C for HMC5883L compass
                              jorden.luke

                              I have found out that after I do my status = I2C_MasterSendStart(HMC5883L_ADDRESS, I2C_WRITE_XFER_MODE); I get 3 returned. Which I understand to be a the last bite got Nacked. Which means to say that the address got Naked because that is the only thing i sent right?

                              • 12. Re: I2C for HMC5883L compass
                                jorden.luke

                                Ok I looked into the spark fun board was not giving enough output on 3.3v line to make it the sensor work. I had to make some modifications to the board as prescribe on their website and now it isn't nacking. It still doesn't work fully but I think that is to pour choice with pointers I will continue to fix it on my own. Thanks for you help.

                                   

                                Jorden Luke

                                • 13. Re: I2C for HMC5883L compass
                                  tmahfuz1993_1434601

                                  So has anyone solved the problem for the magnetometer. I cannot solve it. Infact I dont Know how to start. Any help would be greatly appreciated. Thanks

                                  • 14. Re: I2C for HMC5883L compass
                                    tmahfuz1993_1434601

                                    So has anyone been able to solve the problem for the compass and I2C. I am currently working on it and i dont know where to start. I read the datasheet but I m still confused. Any help would be greatly appreciated. Thanks

                                    1 2 Previous Next