RPR/02_Software/01_Arduino/main/ams_as5048b.h

151 lines
5.9 KiB
C
Raw Permalink Normal View History

/**************************************************************************/
/*!
@file ams_as5048b.h
@author SOSAndroid.fr (E. Ha.)
@section HISTORY
v1.0 - First release
v1.0.1 - Typo to allow compiling on Codebender.cc (Math.h vs math.h)
v1.0.2 - Small bug fix and improvement by @DavidHowlett
Library to interface the AS5048B magnetic rotary encoder from AMS over the I2C bus
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, SOSAndroid.fr (E. Ha.)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include <math.h>
#include <Wire.h>
#ifndef _AMS_AS5048B_H_
#define _AMS_AS5048B_H_
// OPERATIONS
#define SERIAL_DEBUG_ENABLED
#define USE_WIREBEGIN_ENABLED // to comment if Wire.begin() function is called in Setup() for instance. Usefull to manage one or several I2C devices in the same sketch
// Default addresses for AS5048B
#define AS5048_ADDRESS 0x40 // 0b10000 + ( A1 & A2 to GND)
#define AS5048B_PROG_REG 0x03
#define AS5048B_ADDR_REG 0x15
#define AS5048B_ZEROMSB_REG 0x16 //bits 0..7
#define AS5048B_ZEROLSB_REG 0x17 //bits 0..5
#define AS5048B_GAIN_REG 0xFA
#define AS5048B_DIAG_REG 0xFB
#define AS5048B_MAGNMSB_REG 0xFC //bits 0..7
#define AS5048B_MAGNLSB_REG 0xFD //bits 0..5
#define AS5048B_ANGLMSB_REG 0xFE //bits 0..7
#define AS5048B_ANGLLSB_REG 0xFF //bits 0..5
#define AS5048B_RESOLUTION 16384.0 //14 bits
// Moving Exponential Average on angle - beware heavy calculation for some Arduino boards
// This is a 1st order low pass filter
// Moving average is calculated on Sine et Cosine values of the angle to provide an extrapolated accurate angle value.
#define EXP_MOVAVG_N 5 //history length impact on moving average impact - keep in mind the moving average will be impacted by the measurement frequency too
#define EXP_MOVAVG_LOOP 1 //number of measurements before starting mobile Average - starting with a simple average - 1 allows a quick start. Value must be 1 minimum
//unit consts - just to make the units more readable
#define U_RAW 1
#define U_TRN 2
#define U_DEG 3
#define U_RAD 4
#define U_GRAD 5
#define U_MOA 6
#define U_SOA 7
#define U_MILNATO 8
#define U_MILSE 9
#define U_MILRU 10
class AMS_AS5048B {
public:
AMS_AS5048B(void);
AMS_AS5048B(uint8_t chipAddress);
void begin(void); // to init the object, must be called in the setup loop
void toggleDebug(void); // start / stop debug through serial at anytime
void setClockWise(boolean cw = true); //set clockwise counting, default is false (native sensor)
void progRegister(uint8_t regVal); //nothing so far - manipulate the OTP register
void doProg(void); //progress programming slave address OTP
void doProgZero(void); //progress programming zero position OTP
void addressRegW(uint8_t regVal); //change the chip address
uint8_t addressRegR(void); //read chip address
void setZeroReg(void); //set Zero to current angle position
void zeroRegW(uint16_t regVal); //write Zero register value
uint16_t zeroRegR(void); //read Zero register value
uint16_t angleRegR(void); //read raw value of the angle register
uint8_t diagR(void); //read diagnostic register
uint16_t magnitudeR(void); //read current magnitude
double angleR(int unit = U_RAW, boolean newVal = true); //Read current angle or get last measure with unit conversion : RAW, TRN, DEG, RAD, GRAD, MOA, SOA, MILNATO, MILSE, MILRU
uint8_t getAutoGain(void);
uint8_t getDiagReg(void);
void updateMovingAvgExp(void); //measure the current angle and feed the Exponential Moving Average calculation
double getMovingAvgExp(int unit = U_RAW); //get Exponential Moving Average calculation
void resetMovingAvgExp(void); //reset Exponential Moving Average calculation values
private:
//variables
boolean _debugFlag;
boolean _clockWise;
uint8_t _chipAddress;
uint8_t _addressRegVal;
uint16_t _zeroRegVal;
double _lastAngleRaw;
double _movingAvgExpAngle;
double _movingAvgExpSin;
double _movingAvgExpCos;
double _movingAvgExpAlpha;
int _movingAvgCountLoop;
//methods
uint8_t readReg8(uint8_t address);
uint16_t readReg16(uint8_t address); //16 bit value got from 2x8bits registers (7..0 MSB + 5..0 LSB) => 14 bits value
void writeReg(uint8_t address, uint8_t value);
double convertAngle(int unit, double angle); //RAW, TRN, DEG, RAD, GRAD, MOA, SOA, MILNATO, MILSE, MILRU
double getExpAvgRawAngle(void);
void printDebug(void);
};
#endif