#include <Wire.h>
#include <DAC7574.h>
typedef enum{
ouput45 = 0b00,
ouput90 = 0b01,
ouputRotab = 0b10,
autre = 0b11
}OutputType;
//DAC
#define DAC_ADDRESS 0x4C
//Inclino
#define INC_ADDRESS 0x68
#define ACC_CONF 0x20 //Page 91
#define GYR_CONF 0x21 //Page 93
#define CMD 0x7E //Page 65
/*! Earth's gravity in m/s^2 */
#define GRAVITY_EARTH (9.80665f)
uint16_t x, y, z;
uint16_t gyr_x, gyr_y, gyr_z;
uint16_t gyro_angle_x, gyro_angle_y, gyro_angle_z;
uint16_t combined_x, combined_y, combined_z;
float roll, pitch, yaw = 0.f;
uint16_t temperature = 0;
float temperatureInDegree = 0.f;
//DAC
DAC7574 dac;
float angle45 = 0;
float angle45f = 0;
double xAngle = 0;
float angle90 = 0;
float angle90f = 0;
uint32_t analogAngle45 = 0;
uint32_t analogAngle90 = 0;
int angle_90 = 180;
int outputMaxValue90 = 3680; //3600
int outputMinValue90 = 395; //395
float angle_45_min = -51.f;
float angle_45_max = 51.f;
float angle_45 = abs(angle_45_min) + abs(angle_45_max);
///int outputMaxValue45 = 3725;//3844; //3807; //3600
///int outputMinValue45 = 232;//241; //234; //395
int outputMaxValue45 = 3725;
int outputMinValue45 = 232;
float analogMiddle45 = (outputMaxValue45-outputMinValue45)*0.5 + outputMinValue45;
float analogMiddle90 = (outputMaxValue90-outputMinValue90)*0.5 + outputMinValue90;
unsigned long timer = 0;
int divider = 1;
float print_ms = 200;
void setup(void) {
Serial.begin(115200);
//Accelerometer
Wire.begin();
//Wire.setClock(400000); // I2C Fast Mode (400kHz)
timer = millis();
print_ms = millis();
softReset();
/*
* Acc_Conf P.91
* ODR: 0x000B -> 800Hz
* range: 0x0000 -> 2G
* filtering: 0x0000 -> ODR/2
* average: 0x0600 -> 64 sample
* mode: 0x7000 -> High
* Total: 0x760B
* 0111000000001011
*/
writeRegister16(ACC_CONF,0x760B);//Setting accelerometer
/*
* Gyr_Conf P.93
* mode: 0x7000 -> High
* average: 0x0600 -> 64
* filtering: 0x0000 -> ODR/2
* range: 0x0000 -> 125kdps
* ODR: 0x000B -> 800Hz
* Total: 0x760B
*/
writeRegister16(GYR_CONF,0x760B);//Setting gyroscope
delay(50);
//DAC
dac.begin(DAC_ADDRESS);
}
void softReset(){
writeRegister16(CMD, 0xDEAF);
delay(50);
}
void loop() {
static float deltat = 0; //loop time in seconds
static unsigned long now = 0, last = 0; //micros() timers
if(readRegister16(0x02) == 0x00) {
//Read ChipID
//Serial.print("ChipID:");
//Serial.print(readRegister16(0x00));
convertToAngle();
if(millis() - print_ms > 0){
print_ms = millis();
//*
Serial.print("x:");
Serial.print(x);
Serial.print(" \ty:");
Serial.print(y);
Serial.print(" \tz:");
Serial.print(z);
Serial.print(" \tangle45f:");
Serial.print(angle45f);
//*/
Serial.println();
}
}
//Write to DAC
dac.setVoltage(analogAngle45, ouput45);
dac.setVoltage(analogAngle90, ouput90);
}
//Write data in 16 bits
void writeRegister16(uint16_t reg, uint16_t value) {
Wire.beginTransmission(INC_ADDRESS);
Wire.write(reg);
//Low
Wire.write((uint16_t)value & 0xff);
//High
Wire.write((uint16_t)value >> 8);
Wire.endTransmission();
}
//Read data in 16 bits
uint16_t readRegister16(uint8_t reg) {
Wire.beginTransmission(INC_ADDRESS);
Wire.write(reg);
Wire.endTransmission(false);
int n = Wire.requestFrom(INC_ADDRESS, 4);
uint16_t data[20];
int i =0;
while(Wire.available()){
data[i] = Wire.read();
i++;
}
return (data[3] | data[2] << 8);
}
//Read all axis
void readAllAccel() {
Wire.beginTransmission(INC_ADDRESS);
Wire.write(0x03);
Wire.endTransmission();
Wire.requestFrom(INC_ADDRESS, 16);
uint16_t data[16];
int i =0;
while(Wire.available()){
data[i] = Wire.read();
i++;
}
//Offset = 2 because the 2 first bytes are dummy (useless)
int offset = 2;
//*
x = ((uint16_t) (data[offset + 1] << 8 | (uint16_t) data[offset + 0])); //0x03
y = ((uint16_t) (data[offset + 3] << 8 | (uint16_t) data[offset + 2])); //0x04
z = ((uint16_t) (data[offset + 5] << 8 | (uint16_t) data[offset + 4])); //0x05
//*/
gyr_x = ((uint16_t) data[offset + 7] << 8 | (uint16_t) data[offset + 6]); //0x06
gyr_y = ((uint16_t) data[offset + 9] << 8 | (uint16_t) data[offset + 8]); //0x07
gyr_z = ((uint16_t) data[offset + 11] << 8 | (uint16_t) data[offset + 10]); //0x08
temperature = ((uint16_t) data[offset + 13] << 8 | (uint16_t) data[offset + 12]); //0x09
}
void convertToAngle(){
double offsetAngle = 1.00; //Arround 6% less (ex: 42° for 45°)
analogAngle45 = 0;
analogAngle90 = 0;
divider = 50;
for(int i = 0; i < divider; i++){
readAllAccel(); // read all accelerometer/gyroscope/temperature data
angle45f = (atan2(-(double)lsb_to_mps2(x, 2, 16),(double)lsb_to_mps2(z, 2, 16) )*180/PI)*offsetAngle;
angle90f = (atan2(-(double)lsb_to_mps2(y, 2, 16),(double)lsb_to_mps2(z, 2, 16) )*180/PI)*offsetAngle;
//*
if(angle45f >= angle_45_max){ //angle_45*0.51){
angle45f = angle_45_max;
}else if (angle45f <= angle_45_min){ //-angle_45*0.5){
angle45f = angle_45_min;
}//*/
if(angle90f > angle_90*0.5){
angle90f = angle_90*0.5;
}else if (angle90f < -angle_90*0.5){
angle90f = -angle_90*0.5;
}
//Analog: 3725 | 1960 | 232
// Réel: 3806 | 2001 | 234
float angleToAnalog45 = (outputMaxValue45 - outputMinValue45)/(angle_45);// 17.805/° pour 90°; 35.61/° pour 45°
float angleToAnalog90 = (outputMaxValue90 - outputMinValue90)/(angle_90);// 17.805/° pour 90°; 35.61/° pour 45°
float correctif = 0.06f;
float smoother45 = angle45f*(1-correctif) + angle45f*correctif;
float smoother90 = angle90f*(1-correctif) + angle90f*correctif;
analogAngle45 += ((smoother45 * angleToAnalog45) + analogMiddle45);//
analogAngle90 += ((smoother90 * angleToAnalog90) + analogMiddle90);//
//analogAngle45 += ((angle45f * angleToAnalog45) + analogMiddle45);//
//analogAngle90 += ((angle90f * angleToAnalog90) + analogMiddle90);//
}
analogAngle45 = analogAngle45/divider;
analogAngle90 = analogAngle90/divider;
}
/*!
* @brief This function converts lsb to meter per second squared for 16 bit accelerometer at
* range 2G, 4G, 8G or 16G.
*/
static float lsb_to_mps2(int16_t val, int8_t g_range, uint8_t bit_width){
double power = 2;
float half_scale = (float)((pow((double)power, (double)bit_width) / 2.0f));
return (GRAVITY_EARTH * val * g_range) / half_scale;
}
I'm also using a DAC with I²C communication but I've tried without it and nothing changed.
Do you know how can I get the full output from 0 to 65535 for every axis/data ?
Thanks for your help ! 🙏