I've been looking for a solution for this problem for quite a time I tried different I2C libraries; like,
I2C master library using hardware TWI interface * Author: Peter Fleury
But the same problem, I think my problem is in the HMC5883L_my library.
Update: I have to mention that I'm including I2C_TWSR_Check();
function to check the status of the I2C operations success in the HMC5883L library in int16_t data_read (int16_t *results_ptr);
function, and as a result I get a successful operations all the time. But, the problem is when the serial monitor of the Arduino IDE is open and I'm watching the values and moving the module with different vectors, as soon as x-axis changes from -ve to +ve values, the serial monitor stops and I have to close it and open it again.
#include <avr/io.h>
#include <Arduino.h>
#include "HMC5883L_my.h"
#include "I2C.h"
int16_t results[3];
void HMC5883L_init (void)
{
I2C_start(HMC5883L_write);
I2C_tx(Configuration_Register_A);
I2C_tx(0x78);
I2C_tx(0x20);
I2C_tx(0x00);
I2C_stop();
}
int16_t data_read (int16_t *results_ptr)
{
uint16_t lsb,msb;
int16_t status_of_process = 0;
I2C_start(HMC5883L_write);
I2C_TWSR_Check();
I2C_tx(Data_Output_X_MSB_Register);
I2C_TWSR_Check();
I2C_stop();
I2C_start(HMC5883L_read);
I2C_TWSR_Check();
msb = I2C_rx();
lsb = I2C_rx();
I2C_TWSR_Check();
results[0] = msb << 8 | lsb;
Serial.print("x-axis = ");
Serial.println(results[0]);
msb = I2C_rx();
lsb = I2C_rx();
I2C_TWSR_Check();
results[1] = msb << 8 | lsb;
Serial.print("z-axis = ");
Serial.println(results[1]);
msb = I2C_rx();
lsb = I2C_rx();
I2C_TWSR_Check();
results[2] = msb << 8 | lsb;
Serial.print("y-axis = ");
Serial.println(results[2]);
I2C_TWSR_Check();
I2C_stop();
Serial.println();
return status_of_process;
}
void HMC5883L_read_reg (uint8_t reg)
{
uint8_t reg_dat;
I2C_start(HMC5883L_write);
I2C_tx(reg);
I2C_start(HMC5883L_read);
reg_dat = I2C_rx();
I2C_stop();
Serial.println(reg_dat);
}
As you can see I put I2C_TWSR_Check();
after each I2C operation to see if there's any problem during read operation but I can't see any problem when the module stops reading if x-axis value get to positive region.
This is my I2C library but I don't think there's a serious problem with it because it worked with other I2C modules without any problem.
/*
* I2C_Library.c
*
* Created: 6/6/2017 12:34:39 AM
* Author : wolfrose
*/
#include <avr/io.h>
#include <Arduino.h>
#include "I2C.h"
void I2C_init(void)
{
//set SCL to 100kHz
TWSR = 0x00;
TWBR = 0x48;
//enable TWI
TWCR = (1<<TWEN);
}
void I2C_start(uint8_t address)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
TWDR = address;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
}
void I2C_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
void I2C_tx(uint8_t data)
{
TWDR = data;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
}
uint8_t I2C_rx(void)
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
return TWDR;
}
void I2C_TWSR_Check(void)
{
uint8_t Status;
Status = TWSR & 0xF8;
switch(Status)
{
/////////////// MASTER TRANSMITTER //////////////
case 0x08:
Serial.println("Start is OK");
break;
case 0x10:
Serial.println("Re start");
break;
case 0x18:
Serial.println("SLA+W OK ACK");
break;
case 0x20:
Serial.println("SLA+W no ACK");
break;
case 0x28:
Serial.println("data TX OK ACK");
break;
case 0x30:
Serial.println("data TX OK no ACK");
break;
case 0x38: // arbitration lost in SLA+W or data TX
Serial.println("arbitration lost in SLA+W or data TX");
break;
/////////////// MASTER RECEIVER //////////////
case 0x40:
Serial.println("SLA+R OK ACK");
break;
case 0x48:
Serial.println("SLA+R OK NO ACK");
break;
case 0x50:
Serial.println("data RX OK ACK");
break;
case 0x58:
Serial.println("data RX OK NO ACK");
break;
default:
Serial.println("Error");
break;
}
}
I2C_TWSR_Check()
function after each communication is complete, you should be seeing the output from this:Serial.println("SLA+R OK ACK");
all the time there is a successful receive communication and the output from this:Serial.println("data TX OK ACK");
all the time there is a successful transmit communication. Your question does not mention this output. please apply an EDIT to update