Struggling to get this generating the correct PWM.
I need to drive an LED at 10MHz with 50% Duty Cycle
with a 2ms ON and 48ms OFF (total cycle for this 50ms)
Want it to run in the second processor so can constantly run in the background.
The 2nd LED is just to show the main loop is running.
Any help appreciated getting this working and also if possible explanation on how the end result is achieved.
//
//
// The LED flashing pin
#define LED0 17
#define LED1 16
int PWM_FREQUENCY = 10000; // this variable is used to define the time period
int PWM_CHANNEL = 0; // this variable is used to select the channel number
int PWM_RESOUTION = 8; // this will define the resolution of the signal which is 8 in this case
int dutyCycle = 127; // it will define the width of signal or also the one time
// We need to create a task (object)
TaskHandle_t Task0;
void setup()
{
Serial.begin(115200);
Serial.println("Setup started.");
pinMode(LED1, OUTPUT);
ledcSetup(PWM_CHANNEL, PWM_FREQUENCY, PWM_RESOUTION);
ledcAttachPin(LED0, PWM_CHANNEL);
xTaskCreatePinnedToCore(
loop0, /* Function to implement the task */
"Task0", /* Name of the task */
1000, /* Stack size in words */
NULL, /* Task input parameter */
0, /* Priority of the task */
&Task0, /* Task handle. */
0); /* Core where the task should run */
Serial.println("Setup completed.");
}
// This is a new loop (any name will do) for our new task
void loop0(void * parameter) {
// It must run forever, so this is the construct
for (;;) {
// Just put your code here as you would do for the std loop()
Serial.print("Running on core: ");
Serial.println(xPortGetCoreID());
ledcWrite(PWM_CHANNEL, 50);
delay(2);
ledcWrite(PWM_CHANNEL, 0);
delay(48);
}
}
void loop()
{
// If you don't put this in the original loop, NOTHING happens
digitalWrite(LED1, HIGH);
delay(1000);
digitalWrite(LED1, LOW);
delay(1000);
}
a 50% duty cycle of a 10 MHz signal would be 50 nanosec on and 50 nano sec off.
2 ms on and 48 msec off would be 4% duty cycle of a 20 Hz signal
but why do you care what the frequency is for controlling an LED? have you tried controlling the brightness of an LED on a PWM pin by just setting it using analogWrite ()? full on is 255. 4% is ~10
Im driving an LED driver and the LED is IR for a project I'm doing.
These are the requirements to drive the LED. I'm learning as i go with this but don't quite get how the frequency, and the on off durations work in conjunction with the frequency.
When i test this and adjust the code to do a 2ms on 2ms off with 100% duty the 2ms is actually about 2.9 when measured on oscilloscope.
it's not obvious what your needs are. what is the receiver of the IR pulse?
PWM of an LED is typically used to control the perceived brightness of a visible LED. But in your case, you may need a periodic IR pulse of some specific duration and it may be better to state your requirement that way rather than as a duty-cycle
The receiver needs this pattern an frequency to detect the transmitted IR signal. sort of light barrier. Once the barrier is broken the other part of the circuit will drive a GPIO pin to either high or low depending on is state. the duty cycle is the LED is being overdriven to provide the range and not have the LED on fully. I originally had this circuit done externally and used a simple microcontroller. I want to make this more of an IOT project with wifi and web console.
Finally!
You scope shots explained what you did a poor job of doing in text. You want a 10KHz carrier gated by 2ms ON + 48 ms OFF pulses. The ESP32 can do this in hardware check out its RMT Peripheral.
Thought I would do a quick update. The code suggested by jimLee worked fine and now tested with the actual circuit board. Thanks for the help guys, much appreciated./
As noted in Post #16, the ESP32's RMT peripheral can do all this in hardware without any software intervention once it's configured. In fact, the example code below even deletes the looptask: