8 bit clock signal in esp32

#include <Arduino.h>
#include "esp32-hal-timer.h"
hw_timer_t * timer = NULL;
short counter = 0;
const int clockPin = 18;  // GPIO pin for clock output
void onTimer()
 {
    digitalWrite(clockPin,HIGH);  // Toggle clockPin HIGH or LOW
    delayMicroseconds(1);
    digitalWrite(clockPin,LOW);
    delayMicroseconds(3);
    counter++;

    if (counter >= 8) 
    {
      digitalWrite(clockPin,HIGH);  // Toggle clockPin HIGH or LOW
      delayMicroseconds(5);
      digitalWrite(clockPin,LOW);
      delayMicroseconds(3);
      counter = 0;  // Reset counter after 8 pulses
    }
 }
 void setup() 
{
    pinMode(clockPin, OUTPUT);

    // Create hardware timer
    timer = timerBegin(263.1);  // Timer 0, divider 8 (10 microsecond tick)
    timerAttachInterrupt(timer, onTimer);  // Attach callback function
}
void loop() {
    // Your main code here (if any)
}

I am not able to generate a 8 bit clock signal in esp32.

arduino IDE ESP32 board version is 3.0.2

Exactly which ESP32 board do you have

Is it actually a Nano ESP32 or is it a generic ESP32 board ?

Is it related to this

and your other 4 topics on the same subject?

generic ESP32 board

I am new to arduino forum.
I did not have idea and created new topic everytime i made changes in the code.
now I understood how to use forum

#include <Arduino.h>
#include "esp32-hal-timer.h"

hw_timer_t * timer = NULL;
const int outputPin = 18;  // GPIO pin for output
const int highTimeMicros = 1;  // High time in microseconds
const int periodMicros = 4;  // Total period in microseconds

void IRAM_ATTR onTimer() {
  static int cycleCount = 0;

  if (cycleCount < (highTimeMicros / 2)) {
    digitalWrite(outputPin, HIGH);
  } else {
    digitalWrite(outputPin, LOW);
  }

  cycleCount++;
  if (cycleCount >= periodMicros) {
    cycleCount = 0;
  }
}

void setup() {
  pinMode(outputPin, OUTPUT);

  // Create hardware timer
  timer = timerBegin(0, 80, true);  // Timer 0, 80 prescaler (1 tick = 1 microsecond), count up
  timerAttachInterrupt(timer, &onTimer, true);  // Attach callback function

  // Set the interrupt period in microseconds for 4 microseconds time period
  timerAlarmWrite(timer, periodMicros, true);  // Total period

  // Enable the timer
  timerAlarmEnable(timer);
}

void loop() {
  // Your main code here (if any)
}

i am not able to get the output in the oscilloscope

@jim-p can you please look into this as it has no errors while compiling

Your topic has been moved from the Nano ESP32 category of the forum to a more generic category

In your post #1 you have

    timerAttachInterrupt(timer, onTimer);  // Attach callback function

It should be

    timerAttachInterrupt(timer, &onTimer);  // Attach callback function

You stated you are using ESP32 core 3.0.2 which implies the code in post #6 will not work (does it compile?)

I have not run your sketch (post #1, it does compile) and did not try to analyze it. I always used the Alarm function to generate interrupts.

@Willem43
can you share me a sample code of alarm so that i can understand.

#include <Arduino.h>
#include <driver/ledc.h>

#define pwmPin 18

int pwmCounter = 0;

void IRAM_ATTR pwmcount() 
{

  pwmCounter++;

  if (pwmCounter >= 7)
  {
    ledcWrite(pwmPin, 255);     
    delayMicroseconds(5);
    ledcWrite(pwmPin, 67);
    // ledcWrite(LEDC_CHANNEL,0 );
    // delayMicroseconds(3);
    pwmCounter=0;
    
  }
}



void setup() 
{
  Serial.begin(115200);

  // Configure LED PWM channel
  // ledcSetup(LEDC_CHANNEL, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
  ledcAttachChannel(pwmPin,250000, 8,0);

  
  // Attach the channel to the GPIO to be controlled  
  attachInterrupt(pwmPin, &pwmcount, RISING);

    // Square wave generation
   ledcWrite(pwmPin, 67);   // 65 corresponds to 25% duty cycle (fully on)
}

void loop()
{


}

I have used PWM to generate a clock,but in the 8 bit . i want 5 microseconds on period then 3 microseconds off period then again continue the previous pulse.

here i a getting 9 microseconds on period.
can you please go through it.
@jim-p
@Willem43

Sorry to saying this, but you are liar.
You said the same thing 5 days ago, but still opening a new threads for your every new post.

What is the "263.1" in the parameters? Is this code compiled? I didn't find anything similar in the esp32-hal-timer.h file

@mega-29
Can you clearly state what you are trying to achieve ? What for do you need these timers and PWM? Describe your project in general.

@b707
Why are you seeing post#1, while the latest is post#10

@mega-29. I cannot help with your latest code - post #10.

I am pretty new to the ESP32 series. I am using a S3. I am also using version 3.0.2 of the ESP32 core and your latest code is for version 2.x.x, I cannot compile.

Just for your information. I played a bit with your code in your OP and after making some changes found a problem. You are using delays in the interrupt handler (always a bad idea). If you are clocking with 10us period and have a total delay in the handler of more than that (your 8th pulse takes it to 12us) my ESP32 crashes and reboots. If I remove the 3us delay in the "if {}" part it sort of works but is rather unstable. Removing all delays makes it a lot better.

Always remember interrupts routines are supposed to be fast, that means no unnecessary delays.

You problem in the latest could also be that. You are clocking at 4us (if I understand correctly) and delaying for 5us or more in the interrupt handler you are going to have problems - it will not work.

Hope that helps.

@Willem43
I have updated the version to 3.0.2

There are few things you have not told us yet.

  1. You did not mention the board you are using except saying "esp32". So I assume just that.
  2. You never really told us what you are trying to achieve, unless I missed it.

I have not used LEDC before so I tried some things just learning what can be done. Using your code in post #10 I commented out "attachInterrup" in setup() and attempted to first get a PWM signal on pin 18. I do not know whether my S3 is slower than a ESP32 but it messaged unable to assign "ledcSetup", so no output.

After some messing around I found I needed to lower the resolution to 7 bits and it worked generating a pwm at 4us (at duty cycle set to 32 it showed 25%). I then enable "attachInterrupt" and got a mess.

I changed your code to show 7 bits at 1us followed by a single 8th at 100 duty cycle (eliminating the delays). I did not use the full 128 to allow a small gap before the next 4us pulse.

However, I could not get a clean sequence at 4us. It seems the rest of the code in the interrupt routine is too slow to keep up. If I change the frequency to 150000 it does what I would expect. That is a cycle time of about 6.7us. My system will not go faster and still work correctly. I did find at 150000 I could up the resolution to 8 bits and it still works.

I do not think for this type of pulse train that LEDC is the correct route. It will be better to do it directly using a timer. The overhead added by LEDC is unnecessary.

My final version of your code is below.

#include <driver/ledc.h>

#define pwmPin 18

int pwmCounter = 0;
bool intSet = false;

void IRAM_ATTR pwmcount() {
  intSet = true;
  pwmCounter++;

  if (pwmCounter == 7) {
    ledcWrite(pwmPin, 200);     //255);     
//    delayMicroseconds(2);
//    ledcWrite(pwmPin, 32);
    // ledcWrite(LEDC_CHANNEL,0 );
    // delayMicroseconds(3);
    //pwmCounter = 0;
  }

  if (pwmCounter > 7) {
      ledcWrite(pwmPin, 64);
      pwmCounter = 0;
  }
}

void setup() {
  Serial0.begin(115200);    // Using Serial0 for the UART port
  while ( !Serial0 ) {
    delay(10);
  }

  // Configure LED PWM channel
  // ledcSetup(LEDC_CHANNEL, LEDC_BASE_FREQ, LEDC_TIMER_BIT);
//  bool success = ledcAttachChannel(pwmPin,250000,8,0);
  bool success = ledcAttach(pwmPin,150000,8);    //150000,7);
  if ( !success ) {
    Serial0.println("Could not attach LEDC");
  }
  
  // Attach the channel to the GPIO to be controlled  
  attachInterrupt(pwmPin, &pwmcount, RISING);

    // Square wave generation
  ledcWrite(pwmPin, 64);   // 65 corresponds to 25% duty cycle (fully on)

  Serial0.println("Setup done");
}

void loop() {

}

I just commented out what I did not use.

Here is a scope trace of the output. The cycle time measurement is between the cursors.

That was quite fun.

Sorry I'm using version 2

@mega-29 ,
I see you have had several topic asking the same question:

And you have been warned not to keep creating new topics with the same question. As you have clearly ignored the warning I am giving you a 2 day rest from the forum. I am leaving this topic open so people can continue to help you. If you continue to create new topics with the same question you risk a longer ban or a permanent ban.

For reference, the other topics (that I have managed to find) are:

Please, don't ask the same question in multiple topics and, if you have several related questions keep the in the same topic as the details of one question help answer other questions if they are closely related.

You can find the forum guide here:

Thank you