Low frequency square wave

Hi all,

I need to generate a square wave signal in range 1 Hz - 200 Hz with 50% duty.

With library TimeOne it works fine from 1-64, doesnt from 65 to 124, and than works above 125 with more "holes"

as a workaround I'm able to fulfill the task using TimeOne for frequencies below 32 Hz and tone() for higher, but I'm interested in finding out what causes the holes.

Thanks.

Board: Arduino Uno
IDE: latest

Alex

principiante7:
Board: Arduino Uno
IDE: latest

Code:

?

if you mean to paste the source ?

well it's just

TimerOne t;
t.initialize

then on loop()

if ( freq > 31 ) // do through tone()
else // do through t.pwm

because t.pwm(9, 16666) works
t.pwm(9, 13333) does not
and again
t.pwm(9, 8333) works
t.pwm(9, 9090) does not

etc

so as a workaround for freq < 32 I call t.pwm and for higher tone() and this works fine just I'm looking to figure out what prevents timerone to perform in the whole range

principiante7:
?

if you mean to paste the source ?

...

I'm sure he meant like you were instructed to do in the stickies that you read before posting your question.
How to use this forum - please read.
Read this before posting a programming question ...

Why not use the Arduino micros() function? A simple example:

// type a frequency from 1 to 200 in top of serial monitor and hit [ENTER]

unsigned long cycleStart, period = 100000UL, onTime = period / 2;
const byte outPin = 13; // built in LED but could be any digital pin

void setup()
{
  Serial.begin(9600);
  pinMode(outPin, OUTPUT);
}
void loop()
{
  digitalWrite(outPin, micros() - cycleStart < onTime);
  if(micros() - cycleStart > period) // restart timer
    cycleStart += period; 
  // if there's any serial available, read it:
  if (Serial.available() > 0)
  {
    // look for the next valid integer in the incoming serial stream:
    int freq  = Serial.parseInt();
    freq = constrain(freq, 1, 200);
    period = 1000000 / freq; // 1 million / freq
    onTime = period / 2; // duty cycle (100 / 2 = 50)
    cycleStart = micros();
    Serial.println(freq);
  }
}

tone() generates a square wave.

yes but tone() has a limitation: can't operate below 31 Hz

so i tried timerone and worked but with a bug until I did

#include <TimerOne.h>
#include <LiquidCrystal_I2C.h>

TimerOne t;
LiquidCrystal_I2C lcd(0x3f, 16, 2);
int f = 0;

void setup()
{ 
  pinMode(9, OUTPUT);
  t.initialize(1000000); 
  lcd.begin();
  lcd.backlight();
}


void loop()
{

  f = map(analogRead(A0), 0, 1023, 1, 200);
  double period = (1.0 / f) * 1000000;

  if (f > 31)
  {
    t.stop();
    t.disablePwm(9);
    tone(9, f);
  }
  else
  {
    t.pwm(9, 512);
    t.setPeriod(period);
  }

  lcd.setCursor(0, 0);
  lcd.print(f);
  lcd.print(" Hz ");

}

and it works, but guessed why timerone silences from >60 Hz to 120 Hz and then works again

so the question is : did anyone experience issues using timerOne lib ? or i'm the lucky one 'cause i can accept current solution but i'm still curious ^^

principiante7:
so the question is : did anyone experience issues using timerOne lib ? or i'm the lucky one 'cause i can accept current solution but i'm still curious ^^

have you tried using timer interrupts; accessing the registers directly without the library?

i'll give it a ride, thx for the advice yet the task is already accomplished what's left is just curiosity

outsider:
...

this works fine but only if i dont use LCD

just one more question
I now need to connect this audio output to a line-in input

is this correct ?
Pin9 --///-- 1 K Ohm --||-- 47 nF --> to line-in and gnd to gnd

is 1 K Ohm enough or should be more ?
is 47 nF capacitor good or should be raised to 10 uF

many thx