AskSin++
As5600.h
1 //- -----------------------------------------------------------------------------------------------------------------------
2 // AskSin++
3 // 2020-01-03 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
4 //- -----------------------------------------------------------------------------------------------------------------------
5 // Datasheet:
6 // https://ams.com/documents/20143/36005/AS5600_DS000365_5-00.pdf
7 
8 #ifndef SENSORS_AS5600_H_
9 #define SENSORS_AS5600_H_
10 
11 #include <Wire.h>
12 
13 #define AS5600ADDRESS 0x36
14 #define ZMCOADDRESS 0x00
15 #define ZPOSADDRESSMSB 0x01
16 #define ZPOSADDRESSLSB 0x02
17 #define MPOSADDRESSMSB 0x03
18 #define MPOSADDRESSLSB 0x04
19 #define MANGADDRESSMSB 0x05
20 #define MANGADDRESSLSB 0x06
21 #define CONFADDRESSMSB 0x07
22 #define CONFADDRESSLSB 0x08
23 #define RAWANGLEADDRESSMSB 0x0C
24 #define RAWANGLEADDRESSLSB 0x0D
25 #define ANGLEADDRESSMSB 0x0E
26 #define ANGLEADDRESSLSB 0x0F
27 #define STATUSADDRESS 0x0B
28 #define AGCADDRESS 0x1A
29 #define MAGNITUDEADDRESSMSB 0x1B
30 #define MAGNITUDEADDRESSLSB 0x1C
31 #define BURNADDRESS 0xFF
32 
33 namespace as {
34 
35 enum AS5600PowerMode {NOM = 0, LPM1, LPM2, LPM3 };
36 
37 template <uint8_t pmode = NOM>
38 class As5600 {
39 
40 private:
41  uint16_t _angle;
42  int16_t _raw;
43  bool _present;
44  uint8_t _status;
45 
46  int _readSingleByte(uint8_t adr) {
47  Wire.beginTransmission(AS5600ADDRESS);
48  Wire.write(adr);
49  Wire.endTransmission();
50  delay(2);
51  Wire.requestFrom(AS5600ADDRESS, 1);
52 
53  int ret = -1;
54  if(Wire.available() <=1) {
55  ret = Wire.read();
56  }
57 
58  return ret;
59  }
60 
61  int _readTwoBytes(uint8_t regMSB, uint8_t regLSB)
62  {
63  uint8_t _lsb = 0;
64  uint8_t _msb = 0;
65 
66  _msb = _readSingleByte(regMSB);
67  _lsb = _readSingleByte(regLSB);
68 
69  return (_msb << 8) | _lsb;
70  }
71 
72 
73  void _writeSingleByte(int adr_in, int dat_in)
74  {
75  Wire.beginTransmission(AS5600ADDRESS);
76  Wire.write(adr_in);
77  Wire.write(dat_in);
78  Wire.endTransmission();
79  }
80 
81 public:
82 
83  As5600 () : _angle(0), _raw(0), _present(false), _status(0) {}
84 
85  uint8_t getConfigLo() {
86  return _readSingleByte(CONFADDRESSLSB);
87  }
88 
89  uint8_t getConfigHi() {
90  return _readSingleByte(CONFADDRESSMSB);
91  }
92 
93  void setPowerMode(uint8_t pm){
94  if (pm <= LPM3) {
95  uint8_t config = _readSingleByte(CONFADDRESSLSB);
96  config &= ~((1 << 0) | (1 << 1));
97  config |= pm;
98  _writeSingleByte(CONFADDRESSLSB, config);
99  } else {
100  DPRINTLN(F("setPowerMode failed: wrong mode"));
101  }
102  }
103 
104  void setWatchDog(bool state) {
105  uint8_t config = _readSingleByte(CONFADDRESSMSB);
106  config &= ~(1 << 5);
107  if (state) config |= 0x20;
108  _writeSingleByte(CONFADDRESSMSB, config);
109  }
110 
111  uint8_t getStatus() {
112  return _readSingleByte(STATUSADDRESS) & 0b00111000;
113  }
114 
115  uint8_t getAGC() {
116  return _readSingleByte(AGCADDRESS);
117  }
118 
119  void init () {
120  Wire.begin();
121 
122  uint8_t status = getStatus();
123  uint8_t agc = getAGC();
124 
125  if (status == 0x20) {
126  _present=true;
127  setPowerMode(pmode);
128  //setWatchDog(true);
129  DPRINT(F("AS5600 OK. AGC: "));DDEC(agc);DPRINT(F(", CONFIG Lo: 0x"));DHEX(getConfigLo());DPRINT(", Hi: 0x");DHEXLN(getConfigHi());
130  } else {
131  DPRINT(F("AS5600 FAILURE. AGC: "));DDEC(agc);DPRINT(F(", Status: 0x"));DHEXLN(status);
132  //0x08 = no Magnet detected, magnet too strong, AGC minimum gain overflow
133  //0x10 = no Magnet detected, magnet too weak, AGC maximum gain overflow
134  //0x28 = Magnet detected, magnet too strong
135  //0x30 = Magnet detected, magnet too weak
136  //0x38 = no sensor
137  }
138  }
139 
140  void measure () {
141  _status = getStatus();
142  _present = (_status == 0x20);
143 
144  if (_present) {
145  _raw = _readTwoBytes(RAWANGLEADDRESSMSB, RAWANGLEADDRESSLSB);
146  _angle = (_raw > -1) ? map(_raw, 0, 4096, 0, 359) : 0xFFFF;
147  }
148  }
149 
150  uint16_t angle () { return _angle; }
151  int16_t raw () { return _raw; }
152  uint8_t status() { return _status ;}
153 };
154 
155 }
156 
157 
158 
159 #endif /* SENSORS_AS5600_H_ */
as::As5600
Definition: As5600.h:38