Seeed_Arduino_AS5600
Seeed_Arduino_AS5600 copied to clipboard
Improvements to setMaxAngle() / setStartPosition() / setEndPosition()
Sorry for all the editing - changed my mind! See next comment for new versions.
Here are new versions of the set_()
and get_()
functions. Suggested improvements:
- Simplified code if no argument (-1)
- Reads back the newly set register value using
get_()
functions instead of duplicating that code in eachset_()
function - Uses new shared
writeTwoBytes()
function to write double byte i2c registers, for smaller code size and better readability - Added return value to
setConf()
, for consistency with otherset_()
functions - Fixed typo "setEndtPosition" in comment
- Simplified
getEndPosition()
- Better documentation of what happens if no function argument
- Better documentation with min/max values, and how to use start+end or start+range for scaled outputs
I don't think setMaxAngle() / getMaxAngle() are ideal function names since the MANG register doesn't set the "max angle" but rather than angular range or 'width' from the start position angle. I haven't renamed them though, just improved the documentation.
/*******************************************************
In: new angular range to set 205..4095, OR none
Out: value of angular range register
Description: sets a value in angular range register.
Must be greater than 18 degrees (204). Use with start:
start=10 deg + range=90 deg gives 10..100 degrees for
output from getScaledAngle.
If no value is provided, method will set from start
position to current position of magnet.
*******************************************************/
word AMS_5600::setMaxAngle(word newMaxAngle)
{
if (newMaxAngle == -1) newMaxAngle = getRawAngle();
writeTwoBytes(_addr_mang, newMaxAngle);
return getMaxAngle();
}
/*******************************************************
Method: getMaxAngle
In: none
Out: value of angular range register 205..4095
Description: gets value of angular range register.
*******************************************************/
word AMS_5600::getMaxAngle()
{
return readTwoBytesSeparately(_addr_mang);
}
/*******************************************************
Method: setStartPosition
In: new start angle position 0..4095, OR none
Out: value of start position register
Description: sets a value in start position register.
If no value is provided, method will set to current
position of magnet.
*******************************************************/
word AMS_5600::setStartPosition(word startAngle)
{
if (startAngle == -1) startAngle = getRawAngle();
writeTwoBytes(_addr_zpos, startAngle);
return getStartPosition();
}
/*******************************************************
Method: getStartPosition
In: none
Out: value of start position register 0..4095
Description: gets value of start position register.
*******************************************************/
word AMS_5600::getStartPosition()
{
return readTwoBytesSeparately(_addr_zpos);
}
/*******************************************************
Method: setEndPosition
In: new end angle position 0..4095, OR none
Out: value of end position register
Description: sets a value in end position register.
Use with start: start=10 deg + end=180 deg gives
10..180 degrees for output from getScaledAngle.
If no value is provided, method will set to current
position of magnet.
*******************************************************/
word AMS_5600::setEndPosition(word endAngle)
{
if (endAngle == -1) endAngle = getRawAngle();
writeTwoBytes(_addr_mpos, endAngle);
return getEndPosition();
}
/*******************************************************
Method: getEndPosition
In: none
Out: value of end position register 0..4095
Description: gets value of end position register.
*******************************************************/
word AMS_5600::getEndPosition()
{
return readTwoBytesSeparately(_addr_mpos);
}
/*******************************************************
Method: getRawAngle
In: none
Out: value of raw angle register 0..4095
Description: gets raw value of magnet position.
start, end/max angle settings do not apply.
*******************************************************/
word AMS_5600::getRawAngle()
{
return readTwoBytesTogether(_addr_raw_angle);
}
/*******************************************************
Method: getScaledAngle
In: none
Out: value of scaled angle register 0..4095
Description: gets scaled value of magnet position.
start and end/max angle settings are used to convert
a reduced range (eg, 10..100 degrees) to full 0..4095
values for greater resolution.
*******************************************************/
word AMS_5600::getScaledAngle()
{
return readTwoBytesTogether(_addr_angle);
}
/*******************************************************
Method: setConf
In: value of CONF register, see datasheet
Out: value of CONF register
Description: sets value of CONF register.
*******************************************************/
word AMS_5600::setConf(word _conf)
{
writeTwoBytes(_addr_conf, _conf);
return getConf();
}
and a new function writeTwoBytes()
:
/*******************************************************
Method: writeTwoBytes
In: address and data to write
Out: none
Description: writes two bytes to an i2c register.
*******************************************************/
void AMS_5600::writeTwoBytes(int adr_in, word dat_in)
{
writeOneByte(adr_in, highByte(dat_in));
delay(2);
writeOneByte(adr_in+1, lowByte(dat_in));
delay(2);
}
I haven't tested it, but this is a much faster way to write 2 bytes, without setting the register address separately for the high and low bytes, and without delay()
calls:
void AMS_5600::writeTwoBytes(int adr_in, word dat_in)
{
Wire.beginTransmission(_ams5600_Address);
Wire.write(adr_in);
Wire.write(highByte(dat_in));
Wire.write(lowByte(dat_in)); // automatic adr_in+1
Wire.endTransmission();
}
Sorry, if it is off topic: Arduino 1.8.19 using esp8266 complains that e.g. startAngle == -1 can never happen because word seems unsigned 16bit. In case you want change the functions.