This repository was archived by the owner on Feb 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathPWM_manual.ino
153 lines (121 loc) · 4.29 KB
/
PWM_manual.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/****************************************************************************************************************************
PWM_manual.ino
For ESP32, ESP32_S2, ESP32_S3, ESP32_C3 boards with ESP32 core v2.0.0+
Written by Khoi Hoang
Built by Khoi Hoang https://github.com/khoih-prog/ESP32_FastPWM
Licensed under MIT license
This is pure hardware-based PWM
*****************************************************************************************************************************/
/******************************************************************************************************************************
// All GPIO pins (but GPIO34-39) can be used to generate PWM
// For ESP32, number of channels is 16, max 20-bit resolution
// For ESP32_S2, ESP32_S3, number of channels is 8
// For ESP32_C3, number of channels is 6
******************************************************************************************************************************/
#define _PWM_LOGLEVEL_ 4
#define UPDATE_INTERVAL 1000L
// Using setPWM_DCPercentage_manual if true
#define USING_DC_PERCENT true
#include "ESP32_FastPWM.h"
#if ARDUINO_ESP32C3_DEV
#define pinToUse 9
#else
#define pinToUse 16
#endif
// Max resolution is 20-bit
// Resolution 65536 (16-bit) for lower frequencies, OK @ 1K
// Resolution 4096 (12-bit) for lower frequencies, OK @ 10K
// Resolution 1024 (10-bit) for higher frequencies, OK @ 50K
// Resolution 256 ( 8-bit)for higher frequencies, OK @ 100K, 200K
// Resolution 128 ( 7-bit) for higher frequencies, OK @ 500K
int PWM_resolution = 10;
ESP32_FAST_PWM* PWM_Instance;
float frequency = 1000.0f;
#if USING_DC_PERCENT
float dutycyclePercent = 0.0f;
float DCStepPercent = 5.0f;
#else
uint16_t dutycycle = 0;
uint16_t DCStep;
#endif
// Max resolution is 20-bit
// Resolution 65536 (16-bit) for lower frequencies, OK @ 1K
// Resolution 4096 (12-bit) for lower frequencies, OK @ 10K
// Resolution 1024 (10-bit) for higher frequencies, OK @ 50K
// Resolution 256 ( 8-bit) for higher frequencies, OK @ 100K, 200K
// Resolution 128 ( 7-bit) for higher frequencies, OK @ 500K
uint8_t resolution = 16;
uint8_t channel = 0;
char dashLine[] = "=================================================================================================";
void printPWMInfo(ESP32_FAST_PWM* PWM_Instance)
{
Serial.println(dashLine);
Serial.print("Actual data: pin = ");
Serial.print(PWM_Instance->getPin());
Serial.print(", PWM DC = ");
Serial.print(PWM_Instance->getActualDutyCycle());
Serial.print(", PWMPeriod = ");
Serial.print(PWM_Instance->getPWMPeriod());
Serial.print(", PWM Freq (Hz) = ");
Serial.println(PWM_Instance->getActualFreq(), 4);
Serial.println(dashLine);
}
void setup()
{
Serial.begin(115200);
while (!Serial && millis() < 5000);
delay(100);
Serial.print(F("\nStarting PWM_manual on "));
Serial.println(ARDUINO_BOARD);
Serial.println(ESP32_FAST_PWM_VERSION);
// Create a dummy instance
// channel 0, 16-bit resolution
PWM_Instance = new ESP32_FAST_PWM(pinToUse, frequency, 0, channel, resolution);
// Default channel 0, 8-bit resolution
//PWM_Instance = new ESP32_FAST_PWM(pinToUse, frequency, 0);
if (PWM_Instance)
{
PWM_Instance->setPWM();
//printPWMInfo(PWM_Instance);
}
else
{
Serial.print(F("Stop here forever"));
while (true)
delay(10000);
}
#if !USING_DC_PERCENT
// 5% steps
DCStep = round((1 << resolution) / 20.0f);
#endif
}
void loop()
{
static unsigned long update_timeout = UPDATE_INTERVAL;
// Update DC every UPDATE_INTERVAL (1000) milliseconds
if (millis() > update_timeout)
{
#if USING_DC_PERCENT
PWM_Instance->setPWM_DCPercentage_manual(pinToUse, dutycyclePercent);
dutycyclePercent += DCStepPercent;
if (dutycyclePercent > 100.0f)
dutycyclePercent = 0.0f;
#else
if (dutycycle > (1 << resolution))
{
PWM_Instance->setPWM_manual(pinToUse, (1 << resolution));
dutycycle = 0;
}
else
{
// Funny kludge to get around ESP32 bug, adding 4 to dutycycle each loop !!!
if (dutycycle < DCStep)
dutycycle = 0;
PWM_Instance->setPWM_manual(pinToUse, dutycycle);
dutycycle += DCStep;
}
#endif
printPWMInfo(PWM_Instance);
update_timeout = millis() + UPDATE_INTERVAL;
}
}