Skip to content

Commit

Permalink
add error handling (#56)
Browse files Browse the repository at this point in the history
- add experimental error handling
- add **int lastError()** so user can check the status of last I2C actions.
- update readme.md
- update examples
- minor edits
  • Loading branch information
RobTillaart committed Feb 10, 2024
1 parent 5134633 commit 6f05b4d
Show file tree
Hide file tree
Showing 29 changed files with 199 additions and 69 deletions.
52 changes: 43 additions & 9 deletions AS5600.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: AS56000.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.5.1
// VERSION: 0.6.0
// PURPOSE: Arduino library for AS5600 magnetic rotation meter
// DATE: 2022-05-28
// URL: https://github.com/RobTillaart/AS5600
Expand Down Expand Up @@ -509,29 +509,55 @@ int32_t AS5600::resetCumulativePosition(int32_t position)
}


int AS5600::lastError()
{
int value = _error;
_error = AS5600_OK;
return value;
}


/////////////////////////////////////////////////////////
//
// PROTECTED AS5600
//
uint8_t AS5600::readReg(uint8_t reg)
{
_error = AS5600_OK;
_wire->beginTransmission(_address);
_wire->write(reg);
_error = _wire->endTransmission();

_wire->requestFrom(_address, (uint8_t)1);
if (_wire->endTransmission() != 0)
{
_error = AS5600_ERROR_I2C_READ_0;
return 0;
}
uint8_t n = _wire->requestFrom(_address, (uint8_t)1);
if (n != 1)
{
_error = AS5600_ERROR_I2C_READ_1;
return 0;
}
uint8_t _data = _wire->read();
return _data;
}


uint16_t AS5600::readReg2(uint8_t reg)
{
_error = AS5600_OK;
_wire->beginTransmission(_address);
_wire->write(reg);
_error = _wire->endTransmission();

_wire->requestFrom(_address, (uint8_t)2);
if (_wire->endTransmission() != 0)
{
_error = AS5600_ERROR_I2C_READ_2;
return 0;
}
uint8_t n = _wire->requestFrom(_address, (uint8_t)2);
if (n != 2)
{
_error = AS5600_ERROR_I2C_READ_3;
return 0;
}
uint16_t _data = _wire->read();
_data <<= 8;
_data += _wire->read();
Expand All @@ -541,21 +567,29 @@ uint16_t AS5600::readReg2(uint8_t reg)

uint8_t AS5600::writeReg(uint8_t reg, uint8_t value)
{
_error = AS5600_OK;
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(value);
_error = _wire->endTransmission();
if (_wire->endTransmission() != 0)
{
_error = AS5600_ERROR_I2C_WRITE_0;
}
return _error;
}


uint8_t AS5600::writeReg2(uint8_t reg, uint16_t value)
{
_error = AS5600_OK;
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(value >> 8);
_wire->write(value & 0xFF);
_error = _wire->endTransmission();
if (_wire->endTransmission() != 0)
{
_error = AS5600_ERROR_I2C_WRITE_0;
}
return _error;
}

Expand Down
23 changes: 19 additions & 4 deletions AS5600.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: AS5600.h
// AUTHOR: Rob Tillaart
// VERSION: 0.5.1
// VERSION: 0.6.0
// PURPOSE: Arduino library for AS5600 magnetic rotation meter
// DATE: 2022-05-28
// URL: https://github.com/RobTillaart/AS5600
Expand All @@ -12,7 +12,8 @@
#include "Wire.h"


#define AS5600_LIB_VERSION (F("0.5.1"))
#define AS5600_LIB_VERSION (F("0.6.0"))


// default addresses
const uint8_t AS5600_DEFAULT_ADDRESS = 0x36;
Expand All @@ -36,6 +37,17 @@ const uint8_t AS5600_MODE_DEGREES = 0;
const uint8_t AS5600_MODE_RADIANS = 1;
const uint8_t AS5600_MODE_RPM = 2;


// ERROR CODES
const int AS5600_OK = 0;
const int AS5600_ERROR_I2C_READ_0 = -100;
const int AS5600_ERROR_I2C_READ_1 = -101;
const int AS5600_ERROR_I2C_READ_2 = -102;
const int AS5600_ERROR_I2C_READ_3 = -103;
const int AS5600_ERROR_I2C_WRITE_0 = -200;
const int AS5600_ERROR_I2C_WRITE_1 = -201;


// CONFIGURE CONSTANTS
// check datasheet for details

Expand Down Expand Up @@ -202,7 +214,7 @@ class AS5600
// void burnSetting();


// Experimental 0.1.2 - to be tested.
// EXPERIMENTAL 0.1.2 - to be tested.
// approximation of the angular speed in rotations per second.
// mode == 1: radians /second
// mode == 0: degrees /second (default)
Expand All @@ -220,6 +232,9 @@ class AS5600
// returns last position.
int32_t resetCumulativePosition(int32_t position = 0);

// EXPERIMENTAL 0.5.2
int lastError();


protected:
uint8_t readReg(uint8_t reg);
Expand All @@ -230,7 +245,7 @@ class AS5600
uint8_t _address = AS5600_DEFAULT_ADDRESS;
uint8_t _directionPin = 255;
uint8_t _direction = AS5600_CLOCK_WISE;
uint8_t _error = 0;
int _error = AS5600_OK;

TwoWire* _wire;

Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,20 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.6.0] - 2024-01-25
- add experimental error handling
- add **int lastError()** so user can check the status of last I2C actions.
- update readme.md
- update examples
- minor edits

----

## [0.5.1] - 2023-12-31
- fix #51, add **increaseOffset(float degrees)**
- update keywords.txt
- update readme.md (several cleanups)


## [0.5.0] - 2023-12-07
- refactor API, begin()
- update readme.md
Expand Down
87 changes: 71 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ See more in the sections Analog OUT and PWM OUT below.


##### Note: (From Zipdox2 - See issue #36)

Some AS5600 modules seem to have a resistor between **PGO** and **GND**.
This causes the AS5600 to disable the output (to use it for programming, see datasheet).
This resistor needs to be removed to use the **OUT** pin.
Expand All @@ -137,6 +138,8 @@ See **Make configuration persistent** below.

## I2C

The I2C address of the **AS5600** is always 0x36.

#### Address

| sensor | address | changeable |
Expand All @@ -150,6 +153,32 @@ The **AS5600L** supports the change of I2C address, optionally permanent.
Check the **setAddress()** function for non-permanent change.


#### I2C multiplexing

Sometimes you need to control more devices than possible with the default
address range the device provides.
This is possible with an I2C multiplexer e.g. TCA9548 which creates up
to eight channels (think of it as I2C subnets) which can use the complete
address range of the device.

Drawback of using a multiplexer is that it takes more administration in
your code e.g. which device is on which channel.
This will slow down the access, which must be taken into account when
deciding which devices are on which channel.
Also note that switching between channels will slow down other devices
too if they are behind the multiplexer.

- https://github.com/RobTillaart/TCA9548

Alternative could be the use of a AND port for the I2C clock line to prevent
the sensor from listening to signals on the I2C bus.

Finally the sensor has an analogue output **OUT**.
This output could be used to connect multiple sensors to different analogue ports of the processor.

**Warning**: If and how well this analog option works is not verified or tested.


#### Performance

| board | sensor | results | notes |
Expand Down Expand Up @@ -439,6 +468,40 @@ Please read datasheet for details.
| 6-7 | | not used | |


#### Error handling

Since 0.5.2 the library has added **experimental** error handling.
For now only lowest level I2C errors are checked for transmission errors.
Error handling might be improved upon in the future.

Note: The public functions do not act on error conditions.
This might change in the future.
So the user should check for error conditions.

```cpp
int e = lastError();
if (e != AS5600_OK)
{
// handle error
}
```


- **int lastError()** returns the last error code.
After reading the error status is cleared to **AS5600_OK**.


| Error codes | value | notes |
|:--------------------------|:-------:|:----------|
| AS5600_OK | 0 | default |
| AS5600_ERROR_I2C_READ_0 | -100 |
| AS5600_ERROR_I2C_READ_1 | -101 |
| AS5600_ERROR_I2C_READ_2 | -102 |
| AS5600_ERROR_I2C_READ_3 | -103 |
| AS5600_ERROR_I2C_WRITE_0 | -200 |
| AS5600_ERROR_I2C_WRITE_1 | -201 |


## Make configuration persistent. BURN

#### Read burn count
Expand Down Expand Up @@ -599,20 +662,6 @@ with enough precision to get the max resolution.
When PWM OUT is selected **readAngle()** will still return valid values.


## Multiplexing

The I2C address of the **AS5600** is always 0x36.

To use more than one **AS5600** on one I2C bus, one needs an I2C multiplexer,
e.g. https://github.com/RobTillaart/TCA9548.
Alternative could be the use of a AND port for the I2C clock line to prevent
the sensor from listening to signals on the I2C bus.

Finally the sensor has an analogue output **OUT**.
This output could be used to connect multiple sensors to different analogue ports of the processor.

**Warning**: If and how well this analog option works is not verified or tested.

----

## AS5600L class
Expand Down Expand Up @@ -697,17 +746,23 @@ priority is relative.
- is there improvement possible.



#### Could

- add error handling
- investigate PGO programming pin.
- check for compatible devices
- AS5200 ?
- investigate performance
- basic performance per function
- I2C improvements
- software direction

- implement extended error handling in public functions.
- will increase footprint !! how much?
- writeReg() only if readReg() is OK ==> prevent incorrect writes
- ```if (_error != 0) return false;```
- set AS5600_ERROR_PARAMETER e.g. setZPosition()
- a derived class with extended error handling?


#### Wont (unless)

Expand Down
3 changes: 2 additions & 1 deletion examples/AS5600L_set_address/AS5600L_set_address.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// FILE: AS5600L_set_address.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AS5600


#include "AS5600.h"
#include "Wire.h"


AS5600L ASL; // use default Wire

Expand Down
3 changes: 2 additions & 1 deletion examples/AS5600_I2C_frequency/AS5600_I2C_frequency.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// FILE: AS5600_I2C_frequency.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AS5600


#include "AS5600.h"
#include "Wire.h"


AS5600L as5600; // use default Wire

Expand Down
5 changes: 3 additions & 2 deletions examples/AS5600_angular_speed/AS5600_angular_speed.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// FILE: AS5600_angular_speed.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AS5600


#include "AS5600.h"
#include "Wire.h"


AS5600L as5600; // use default Wire

Expand All @@ -24,7 +25,7 @@ void setup()

Serial.println(as5600.getAddress());

// as5600.setAddress(0x40); // AS5600L only
// as5600.setAddress(0x40); // AS5600L only

int b = as5600.isConnected();
Serial.print("Connect: ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// FILE: AS5600_angular_speed_RPM.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AS5600


#include "AS5600.h"
#include "Wire.h"


AS5600 as5600; // use default Wire

Expand Down
Loading

0 comments on commit 6f05b4d

Please sign in to comment.