Thanks for clarifying,
I have made a test sketch to time how long it takes for every angle pull request using the 3 diffrent output modes.
For some reason l2c is not working, i can't get the sensor to connect.
I had already written another program to edit the configs of the sensor and that worked perfectly, but now that i'm using your library it seems i can't connect with l2c and i have no idea why, I already tried adding 2 pull up resistors(5K) from vcc to both sda and scl lines but this doesn't help.
Below is the program i wrote to test how long it takes to get the angle from the sensor with varying settings, i feel this is an important detaill to take into account when writing fast paced programs where timing is very important, feel free to optimise/correct it and add it to your library examples.
There also seems to be a problem with the pwmmeasure function, but i'm pretty sure thats because I2C isn't working though and therefore i cant change the output mode.
Do you know what i'm missing here why l2c isnt working? i'm using the arduino Mega on 5V.
The program stops after the analog testing no matter what i try, these are the serial output results:
AS5600_output_speedtest.ino
00:52:10.498 -> AS5600_LIB_VERSION: 0.6.1
00:52:10.498 -> Connect: 0
00:52:11.514 -> [Analog] - 0 224µs to retrieve angle: 230.50 angle in register: 0
00:52:11.715 -> [Analog] - 1 124µs to retrieve angle: 230.50 angle in register: 0
.
.
.
00:52:31.315 -> [Analog] - 98 128µs to retrieve angle: 358.94 angle in register: 0
00:52:31.489 -> [Analog] - 99 128µs to retrieve angle: 358.94 angle in register: 0
00:52:31.532 ->
00:52:31.532 ->
00:52:31.532 ->
00:52:31.532 -> finished ANALOG ANGLE timing, avarage query time(µs): 127
00:52:31.532 -> Fastest: 120 (3)
00:52:31.532 -> Slowest: 224 (1)
00:52:31.532 ->
00:52:31.532 ->
00:52:31.532 ->
00:52:31.721 -> as5600 not connected
00:52:31.721 -> Connect: 0
the program: (Check later post for updated version, this is off)
//
// FILE: AS5600_output_speedtest.ino
// AUTHOR: Pollyscracker
// PURPOSE: demo/testing
// URL: https://github.com/RobTillaart/AS5600
//
// Examples may use AS5600 or AS5600L devices.
// Check if your sensor matches the one used in the example.
// Optionally adjust the code.
#include <Arduino_BuiltIn.h>
#include <AS5600.h>
#include <Wire.h>
int iQueryN = 100; // amount of times to request the angle per outputmode (minimum total process time per mode: iQueryN * delay(200)(at the end of the loop)
int Directionpin = 4; // sensor input, connect to dir of the sensor
int Analogpin = A7; // sensor output, connect to both pins
int PWMpin = 7; // sensor output, connect to both pins
// Set false if your microcontroller or setup works with 12Bit ADC conversion
// for use with Analog output only
bool b10BitADC = true;
AS5600L as5600; // use default Wire
bool bOutmodeAnal = false;
bool bOutmodePWM = false;
bool bHighFreq = false;
bool bOutmodeReg = false;
bool bOutmodeRegRaw = false;
int iQcount = 0;
int iNmax = 0;
int iNmin = 0;
unsigned long ulStartTime = 0UL;
unsigned long ulTempTime = 0UL;
float fAngle = 0;
unsigned long ulAvarageTime = 0;
int iLongest = 0;
int iShortest = 2147483647;
int b = 0;
void setup()
{
Serial.begin(460800);
while(!Serial);
Serial.println(__FILE__);
Serial.print("AS5600_LIB_VERSION: ");
Serial.println(AS5600_LIB_VERSION);
//delay(1000);
Wire.begin();
//while(! Wire) Serial.print("0");
as5600.begin(); // set direction pin or leave blank when tied directly to gnd or vcc
//while(! as5600) Serial.print("1");
as5600.setDirection(AS5600_CLOCK_WISE); // default, just be explicit.
as5600.setOutputMode(AS5600_OUTMODE_ANALOG_100);
b = as5600.isConnected();
Serial.print("Connect: ");
Serial.println(b);
if(as5600.detectMagnet())
{
Serial.print("Magnet detected, AGC: "); Serial.print(as5600.readAGC()); Serial.println("\t(Optimal value: 255/2 for 5V mcu's, 128/2 for 3V3 mcu's)");
} else {
if(as5600.magnetTooStrong()) Serial.println("Magnet to strong/close to sensor.");
if(as5600.magnetTooWeak()) Serial.println("Magnet to weak/far from sensor.");
}
//////////////////////////////////////////////////////
// Configs that can influence the pull/call times
/*const uint8_t AS5600_POWERMODE_NOMINAL = 0;
const uint8_t AS5600_POWERMODE_LOW1 = 1;
const uint8_t AS5600_POWERMODE_LOW2 = 2;
const uint8_t AS5600_POWERMODE_LOW3 = 3;*/
as5600.setPowerMode(0);
/*const uint8_t AS5600_HYST_OFF = 0;
const uint8_t AS5600_HYST_LSB1 = 1;
const uint8_t AS5600_HYST_LSB2 = 2;
const uint8_t AS5600_HYST_LSB3 = 3; */
as5600.setHysteresis(0);
/*const uint8_t AS5600_SLOW_FILT_16X = 0;
const uint8_t AS5600_SLOW_FILT_8X = 1;
const uint8_t AS5600_SLOW_FILT_4X = 2;
const uint8_t AS5600_SLOW_FILT_2X = 3;*/
as5600.setSlowFilter(0);
/*const uint8_t AS5600_FAST_FILT_NONE = 0;
const uint8_t AS5600_FAST_FILT_LSB6 = 1;
const uint8_t AS5600_FAST_FILT_LSB7 = 2;
const uint8_t AS5600_FAST_FILT_LSB9 = 3;
const uint8_t AS5600_FAST_FILT_LSB18 = 4;
const uint8_t AS5600_FAST_FILT_LSB21 = 5;
const uint8_t AS5600_FAST_FILT_LSB24 = 6;
const uint8_t AS5600_FAST_FILT_LSB10 = 7;*/
as5600.setFastFilter(0);
delay(1000);
}
float measurePWMAngle()
{
// wait for LOW
while (digitalRead(PWMpin) == HIGH);
// wait for HIGH
while (digitalRead(PWMpin) == LOW);
uint32_t rise = micros();
// wait for LOW
while (digitalRead(PWMpin) == HIGH);
uint32_t highPeriod = micros() - rise;
// wait for HIGH
while (digitalRead(PWMpin) == LOW);
uint32_t fullPeriod = micros() - rise;
float bitTime = fullPeriod / 4351.0;
float dataPeriod = highPeriod - 128 * bitTime;
float angle = 360.0 * dataPeriod / (4095 * bitTime);
return angle;
}
float measureAnalAngle()
{
float angle = 0.0;
uint16_t rawangle = analogRead(Analogpin);
if(b10BitADC) angle = 360.0/1023 * rawangle;
else angle = 360.0/4095 * rawangle;
return angle;
}
void loop()
{
if( !bOutmodeAnal)
{
if(iQcount == 0)
{
as5600.setOutputMode(AS5600_OUTMODE_ANALOG_100);
delay(10);
}
if( iQcount < iQueryN)
{
ulStartTime = micros();
fAngle = measureAnalAngle();
ulTempTime = (micros()-ulStartTime);
Serial.print("[Analog] - "); Serial.print(iQcount); Serial.print(" \t"); Serial.print(ulTempTime); Serial.print("µs to retrieve angle: "); Serial.print(fAngle); Serial.print("\tangle in register: "); Serial.println(as5600.readAngle());
if( ulTempTime > iLongest ) { iLongest = ulTempTime; iNmax++; }
if( ulTempTime < iShortest) { iShortest = ulTempTime; iNmin++; }
ulAvarageTime += ulTempTime;
iQcount++;
if( iQcount == iQueryN )
{
ulAvarageTime = ulAvarageTime/iQcount;
Serial.println("\n");
Serial.println();
Serial.print("finished ANALOG ANGLE timing, avarage query time(µs): ");Serial.println(ulAvarageTime);
Serial.print("Fastest: "); Serial.print(iShortest); Serial.print(" ("); Serial.print(iNmin); Serial.println(")");
Serial.print("Slowest: "); Serial.print(iLongest); Serial.print(" ("); Serial.print(iNmax); Serial.println(")");
Serial.println("\n");
Serial.println();
// Set output mode to PWM
as5600.setOutputMode(AS5600_OUTMODE_PWM);
as5600.setPWMFrequency(AS5600_PWM_115);
bOutmodeAnal = true;
bOutmodePWM = false;
bHighFreq = false;
iQcount = 0;
iShortest = 2147483647;
iLongest = 0;
iNmax = 0;
iNmin = 0;
ulAvarageTime = 0UL;
}
}
}
else if(!bOutmodePWM)
{
if(iQcount == 0)
{
if( !b )
{
Serial.println("as5600 not connected");
as5600.begin();
b = as5600.isConnected();
Serial.print("Connect: ");
Serial.println(b);
}
// Set output mode to PWM
as5600.setOutputMode(AS5600_OUTMODE_PWM);
if( !bHighFreq ) as5600.setPWMFrequency(AS5600_PWM_115);
else as5600.setPWMFrequency(AS5600_PWM_920);
delay(10);
}
if( iQcount < iQueryN)
{
uint16_t preangle = as5600.readAngle();
ulStartTime = micros();
fAngle = measurePWMAngle();
ulTempTime = (micros()-ulStartTime);
Serial.print("[PWM] - "); Serial.print(iQcount); Serial.print(" \t"); Serial.print(ulTempTime); Serial.print("µs to retrieve angle: "); Serial.print(fAngle); Serial.print("\tPRE-call angle from register: "); Serial.print(preangle); Serial.print("\tPOST-call angle from register: "); Serial.println(as5600.readAngle());
if( ulTempTime > iLongest ) { iLongest = ulTempTime; iNmax++; }
if( ulTempTime < iShortest) { iShortest = ulTempTime; iNmin++; }
ulAvarageTime += ulTempTime;
iQcount++;
if( iQcount == iQueryN )
{
ulAvarageTime = ulAvarageTime/iQcount;
Serial.println("\n");
Serial.println();
if( !bHighFreq ) {
Serial.print("finished PWM ANGLE timing at lowest frequency (115Hz), avarage query time(µs): ");Serial.println(ulAvarageTime);
Serial.print("Fastest: "); Serial.print(iShortest); Serial.print(" ("); Serial.print(iNmin); Serial.println(")");
Serial.print("Slowest: "); Serial.print(iLongest); Serial.print(" ("); Serial.print(iNmax); Serial.println(")");
bHighFreq = true;
} else {
Serial.print("finished PWM ANGLE timing at highest frequency (920Hz), avarage query time(µs): ");Serial.println(ulAvarageTime);
Serial.print("Fastest: "); Serial.print(iShortest); Serial.print(" ("); Serial.print(iNmin); Serial.println(")");
Serial.print("Slowest: "); Serial.print(iLongest); Serial.print(" ("); Serial.print(iNmax); Serial.println(")");
bOutmodePWM = true;
bOutmodeReg = false;
bOutmodeRegRaw = false;
}
Serial.println();
Serial.println();
iQcount = 0;
iShortest = 2147483647;
iLongest = 0;
ulAvarageTime = 0UL;
iNmax = 0;
iNmin = 0;
}
}
}
else if(!bOutmodeRegRaw) {
if( iQcount < iQueryN)
{
if( !bOutmodeReg )
{
ulStartTime = micros();
fAngle = as5600.readAngle();
} else {
ulStartTime = micros();
fAngle = as5600.rawAngle() * AS5600_RAW_TO_DEGREES;
}
ulTempTime = (micros()-ulStartTime);
if( ulTempTime > iLongest ) { iLongest = ulTempTime; iNmax++; }
if( ulTempTime < iShortest) { iShortest = ulTempTime; iNmin++; }
ulAvarageTime += ulTempTime;
iQcount++;
if( iQcount == iQueryN )
{
ulAvarageTime = ulAvarageTime/iQcount;
Serial.println();
Serial.println();
if( !bOutmodeReg ) {
bOutmodeReg = true;
Serial.print("finished register read ANGLE timing, avarage query time: ");Serial.println(ulAvarageTime);
Serial.print("Fastest: "); Serial.print(iShortest); Serial.print(" ("); Serial.print(iNmin); Serial.println(")");
Serial.print("Slowest: "); Serial.print(iLongest); Serial.print(" ("); Serial.print(iNmax); Serial.println(")");
}
else if(!bOutmodeRegRaw) {
bOutmodeRegRaw = true;
Serial.print("finished register read RAW ANGLE timing, avarage query time: ");Serial.println(ulAvarageTime);
Serial.print("Fastest: "); Serial.print(iShortest); Serial.print(" ("); Serial.print(iNmin); Serial.println(")");
Serial.print("Slowest: "); Serial.print(iLongest); Serial.print(" ("); Serial.print(iNmax); Serial.println(")");
bOutmodeAnal = false;
bOutmodePWM = false;
bHighFreq = false;
}
Serial.println();
Serial.println();
iQcount = 0;
iShortest = 2147483647;
iLongest = 0;
ulAvarageTime = 0UL;
iNmax = 0;
iNmin = 0;
}
}
}
delay(200);
}