Skip to content

Commit

Permalink
add notes on PWM
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Jun 2, 2024
1 parent 148477b commit 20b40c1
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
72 changes: 72 additions & 0 deletions examples/AS5600_pwm_test/AS5600_pwm_test.ino
Original file line number Diff line number Diff line change
@@ -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 --
41 changes: 41 additions & 0 deletions notes_on_PWM.md
Original file line number Diff line number Diff line change
@@ -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


0 comments on commit 20b40c1

Please sign in to comment.