Setting custom pwm sequence

Hi, I am trying to create a custom PWM sequence for Arduino Uno pin 6 PWM output:

The PWM frequency is 62.5kHz and duty cycle should be 50%. I am using the following code, but cannot get the starting at 300us pin high followed by 3 pulses at 62.5kHz followed by the pin being high forever.

Currently, I get 3 pulses at 62.5kHz at the beginning (rather than a 300us or in the case I have implemented in code, a 100ms high output followed by the pulse) and after delay the pulse continues forever

This is the code I am running:

int outputPin = 6;

void setup(){
  pinMode(outputPin, OUTPUT);
  setPwmFrequency(6, 1);
  // delay(1000);
  analogWrite(outputPin, 255);
  delay(100);
  
  // analogWrite(outputPin, 0);
  // delayMicroseconds(10);
  // digitalWrite(outputPin, HIGH);
}

void loop(){
  for(int i=0; i<3; i++){
    analogWrite(outputPin, 127);
    // delay(100);
  }
  exit(0);
}

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x07; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

What could be going wrong that I cannot see my expected behavior?

What comes out of that code?
Not being 200% expert this sounds strange. From what is that 300 uS counted? Why involve PWM? It makes no sense just sending a few pulses.

Please give us the big picture showing why this? No helper like spending time finding a solution to Your question just to hear the next day: "It doesn't work".

If this sequence can be blocking, you may want to consider using

 __builtin_avr_delay_cycles ( );

https://forum.arduino.cc/t/causing-a-delay-while-in-an-interrupt/358488/3

You're not really trying to generate a pwm signal so much as you are trying to generate 3 pulses. A pwm signal is continuous. It doesn't stop after only 3 pules. Why not simply do this:

digitalWrite(PIN, LOW);
delayMicroseconds(300);
digitalWrite(PIN, HIGH);
delayMicroseconds(300);
digitalWrite(PIN, LOW);

etc, etc. That would be a lot simpler than trying to generate a PWM signal for 3 pulses.

beat me to it, although I was suggesting using micros() for timing.

while the OP COULD use a for() loop its hardly worth it for three pulses - unless thats just an example.

I'm not a big fan of blocking code either, since it usually causes problems with most systems, especially anything with wifi. But 300us is so fast, that blocking isn't blocking for long.

Currently my code does the following:


so no dc bias for 300us and and infinite sequence of 62.5khz pulse after 3 pulses. The 3 pulse is an example, I will need a maximum pulse count of 40 pulses for my application used to adjust voltage on a inverting boost.

Does this create one 62.5kHz pulse?

No just get a 80ms pulse:

Did you replace each instance of PIN with outputPin to write to pin 6?

Yes actually I tried putting in setup() but in loop() works fine

But goes on forever

int pulse= HIGH;
if (pulse) {
digitalWrite(PIN, HIGH);
delayMicroseconds(300);
digitalWrite(PIN, LOW);
delayMicroseconds(8);
digitalWrite(PIN, HIGH);
delayMicroseconds(8);
digitalWrite(PIN, LOW);
delayMicroseconds(8);
digitalWrite(PIN, HIGH);
pulse=LOW;
}

Add your pulses to this profile

If you are trying to generate a set of 3 pulses at different times, it would be easier to put that into it's own function and call it from whereever you are triggering it from.

SPI ...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.