add notes on PWM

This commit is contained in:
Rob Tillaart 2024-06-02 12:40:40 +02:00
parent 4c14007319
commit 3360ecdaaf
2 changed files with 113 additions and 0 deletions

View File

@ -0,0 +1,72 @@
//
// FILE: AS5600_pwm_test.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AS5600
// https://forum.arduino.cc/t/questions-using-the-as5600-in-pwm-mode/1266957/3
//
// monitor the PWM output to determine the angle
// not tested with hardware yet
int PWMpin = 7;
long fullPeriod = 0;
float measureAngle()
{
// 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);
fullPeriod = micros() - rise;
float bitTime = fullPeriod / 4351.0;
float dataPeriod = highPeriod - 128 * bitTime;
float angle = 360.0 * dataPeriod / (4095 * bitTime);
return angle;
}
//float testMath(uint32_t fullPeriod, uint32_t highPeriod)
//{
// float bitTime = fullPeriod / 4351.0;
// float dataPeriod = highPeriod - 128 * bitTime;
// float angle = 360.0 * dataPeriod / (4095 * bitTime);
// return angle;
//}
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
pinMode(PWMpin, INPUT_PULLUP);
// // test code
// for (int pwm = 0; pwm < 4096; pwm++)
// {
// Serial.println(testMath(4351, 128 + pwm), 2);
// }
}
void loop()
{
float angle = measureAngle();
Serial.println(angle, 1); // print with 1 decimal
delay(1000);
}
// -- END OF FILE --

View File

@ -0,0 +1,41 @@
## notes on PWM
#### Description
If you do not know the PWM frequency you can determine the angle
with PWM in the following way.
In one period there are 4351 bits (128 + 4095 + 128)
These come typically in one pulse like
```
00001111111111111111111111111111111111100000000
HEADER DATA POSTLOW
```
#### Step 1
Determine the duration of one cycle by measuring the time between two RISING edges.
Lets call this time FULLSCALE == 4351 bits.
Then the time for one bit BITTIME = round(FULLSCALE / 4351.0);
#### Step 2
Measure the duration of the HIGHPERIOD == HEADER + DATA
We know the HEADER is 128 bits and FULLSCALE = 4351 bits.
DATAPERIOD = HIGHPERIOD - 128 \* BITTIME
ANGLE = 360 \* DATAPERIOD / (4095 \* BITTIME)
Code: AS5600_pwm_test.ino
#### Related
https://github.com/RobTillaart/AS5600
https://forum.arduino.cc/t/questions-using-the-as5600-in-pwm-mode/1266957/3