I want 30Khz at 10% or 15% dutycycle... but im not sure how to do it.

Hi folks So here is my problem, i am trying to get 30khz at a 10 to 15 % duty cycle so far i have managed what i think is a 50% duty-cycle using the code below. how would i go about it i am a pity-full beginner :cold_sweat:. Thanks

int outPin = 8;

void setup() { pinMode(outPin, OUTPUT); }

void loop() { digitalWrite(outPin, HIGH); delayMicroseconds(16.6666665); digitalWrite(outPin, LOW); delayMicroseconds(16.6666665); }

delayMicroseconds cannot work with floating point numbers.

for that kind of frequency/ duty cycle you need hardware timers.

If you need something other than a 50% duty cycle, don’t make the on and off times equal. It isn’t rocket science.

PaulS:
If you need something other than a 50% duty cycle, don’t make the on and off times equal. It isn’t rocket science.

read robtillaart comment, your suggestion would not work anyway>

dived into my archive, this might work (did not test this specific version)

//
//    FILE: FreqGenerator.ino
//  AUTHOR: Rob Tillaart
//    DATE: 2013-04-13
//
// PUPROSE: FrequencyGenerator with variable dutyCycle
//
// Released to the public domain
//

#define FREQ_OUTPUT 11
#define FREQ_BUTTON 4

unsigned long cnt = 0;
unsigned long start = 0;
unsigned long freq = 10;
unsigned long ratio = 50;
unsigned long onTime = 1;
unsigned long offTime = 1;

unsigned long lastChange = 0;
int state = HIGH;

void setup()
{
  Serial.begin(115200);
  Serial.println("*  Frequency Generator 0.1 *");
  Serial.println(" ");
  Serial.println("freq: / * - + ");
  Serial.println("duty: z Z x X ");

  pinMode(FREQ_BUTTON,INPUT);
  digitalWrite(FREQ_BUTTON, HIGH); // internal pullup

  pinMode(FREQ_OUTPUT,OUTPUT);
  digitalWrite(FREQ_OUTPUT,LOW);

  freq = 1000;
  ratio = 50;

  startTimer1(320);
  setFrequency(freq, ratio);
  p();
}


void p()
{
  Serial.print(freq);
  Serial.print(" - ");
  Serial.print(ratio);  
  Serial.println("%");
}

void loop()
{
  if (Serial.available() > 0)
  {
    char c = Serial.read();

    if (c == 'm') freq = 500;
    if (c == 'M') freq = 32000;
    if (c == 'r') 
    {
      freq = 10000;
      ratio = 50;
    }
    if (c == '+') freq += 10;
    if (c == '-') freq -= 10;
    if (c == '*') freq += 100;
    if (c == '/') freq -= 100;
    if (c == 'z') ratio++;
    if (c == 'Z') ratio += 10;
    if (c == 'x') ratio--;
    if (c == 'X') ratio -= 10;

    ratio = constrain(ratio, 1, 99);    
    freq = constrain(freq, 500, 32000);
    setFrequency(freq, ratio);
    p();
  }
}


///////////////////////////////////////////////////////////////
//
// pulse handlers code - interrupt based
//

volatile unsigned int lowPeriod = 100;
volatile unsigned int highPeriod = 100;

void setFrequency(unsigned long freq, int dutyCycle)
{
  freq >>= 1;
  unsigned long period = (16000000UL + freq)/(freq << 1); // incl rounding
  lowPeriod = (period * dutyCycle)/100;
  highPeriod = period - lowPeriod;
  Serial.print(lowPeriod);
  Serial.print("\t");
  Serial.println(highPeriod);
}

enum {
  NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024 };

void stopTimer1()
{
  TCCR1A = 0; // reset timer 1
  TCCR1B = 0;
}

void startTimer1(int cc)
{
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;      	// reset counter
  OCR1A = cc;		// compare A register value; 

  // 4: CTC mode, top = OCR1A
  TCCR1A = _BV (COM1A1);  	// clear on compare
  TCCR1B = _BV (WGM12) | PRESCALE_1;  // should be PRESCALE_8 now for testing
  TIFR1 |= _BV (OCF1A);    // clear interrupt flag
  TIMSK1 = _BV (OCIE1A);   // interrupt on Compare A Match   
}

ISR(TIMER1_COMPA_vect)
{
  static bool flag = true;
  static int highBlink = 0;

  flag = !flag;
  if (flag == false) 
  {
    OCR1A = lowPeriod-1;
  }
  else
  {
    OCR1A = highPeriod-1;
  }
  highBlink = !highBlink;
  digitalWrite(FREQ_OUTPUT, highBlink);
}

uses /*-+ to set freq
uses zZ and xX to set duty cycle
use r to reset