Hello,
I'm just trying to learn things about programming core libraries.
My reasons to investigate and try to learn from core libraries are:
- Passion and curiosity for for learning how to program the internal hardware
- Developing my experience in programming, time after time because my first time I started to get into studying the code libraries, I didn't know pretty much things about; for example, program control, FSM, ISR control .. etc.
- Improve my programming skills in writing device drivers; because if I got something I need to program and didn't find some meaningful libraries on the web, then I can program my own library. And this reason is one of the most important reasons.
=================================================================
My first time learning how to do core libraries like; twi, spi, uart .. etc. I now wrote these libraries in the most basic form, taking the basic functions from the Atmega328 datasheet. At that time I thought that's pretty much about it. And didn't understand why the premium libraries are much more complex and there is a lot of data flow management and program flags control.
Basically, my I2C library works OK, but if something goes wrong in the program, then there's no management in my code to restart the initialization of i2c bus.
There are still a lot of things to learn about, especially in this library.
=================================================================
My question now, is that I copied the utility/twi, changed the extension of the source file to .cpp and copied the whole library and put it in Arduino/libraries, and tried to run one basic program to get data from HMC5883L, but the code didn't work. But it's working with my i2c library.
I know that I should use the Wire.h library but I wanted to know why I can't use the twi.h library and use it?
So, I don't know what's wrong with it. The code takes one arbitrary value and put it in the serial monitor only one time, there's no continuous reading from the HMC5883L.
This is my code:
#include "twi.h"
////////////////////////////////////////////////////////////////////////////////////
// HMC5883L
//#define HMC5883L 0x1E
#define HMC5883L_READ 0X3D
#define HMC5883L_WRITE 0X3C
#define CONFIGURATION_REGISTER_A 0X00 //Read/Write
#define CONFIGURATION_REGISTER_B 0X01 //Read/Write
#define MODE_REGISTER 0X02 //Read/Write
#define DATA_OUTPUT_X_MSB_REGISTER 0X03 //Read
#define DATA_OUTPUT_X_LSB_REGISTER 0X04 //Read
#define DATA_OUTPUT_Z_MSB_REGISTER 0X05 //Read
#define DATA_OUTPUT_Z_LSB_REGISTER 0X06 //Read
#define DATA_OUTPUT_Y_MSB_REGISTER 0X07 //Read
#define DATA_OUTPUT_Y_LSB_REGISTER 0X08 //Read
#define STATUS_REGISTER 0X09 //Read
#define IDENTIFICATION_REGISTER_A 0X10 //Read
#define IDENTIFICATION_REGISTER_B 0X11 //Read
#define IDENTIFICATION_REGISTER_C 0X12 //Read
#define DECLINATION_ANGLE 3.46
void hmc5883l_init (void);
void data_read (uint8_t *dat);
void hmc5883l_print_serial(void);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
twi_init(); // frequency is already set by default to 100k
twi_setFrequency(100000); // if you want to set it to different speed
}
void loop() {
// put your main code here, to run repeatedly:
hmc5883l_print_serial();
}
void hmc5883l_init(void){
uint8_t HMC5883L_ini[4] = {CONFIGURATION_REGISTER_A,0x78,0x20,0x00};
twi_writeTo(HMC5883L_WRITE,HMC5883L_ini,4,1,1);
}
void data_read(uint8_t *dat){
bool write_res,read_res;
uint8_t op_x_msb[] = {0X03};
write_res = twi_writeTo(HMC5883L_WRITE,op_x_msb,1,1,0);
read_res = twi_readFrom(HMC5883L_READ, dat, 6, 1);
}
void hmc5883l_print_serial(void){
int16_t x,z,y;
uint8_t data[6];
float heading,heading_in_degrees,declination_angle_YANBU;
data_read(data);
x = data[0] << 8 | data[1];
z = data[2] << 8 | data[3];
y = data[4] << 8 | data[5];
heading = atan2(y,x);
declination_angle_YANBU = ((3.0 + (52.0 / 60.0)) / (180 / M_PI)); // in yanbu city it's
heading += declination_angle_YANBU;
// Correct for heading < 0deg and heading > 360deg
if (heading < 0){
heading += 2 * PI;
}
if (heading > 2 * PI){
heading -= 2 * PI;
}
heading_in_degrees = heading * 180 / M_PI;
Serial.println(heading_in_degrees);
}