user26743: I, at the moment am trying to come up with a simple way where I can program an Arduino to provide a step signal with a given frequency, at a specific time. 
The frequency has to be ramped up, and within a time duration of 10 seconds shall the frequency go from 0 Hz to 48000 Hz.  
How do I ensure both the specific time of when the frequency occurs, and the specific frequency of the step signal?
Signal has to be used to driver a stepper motor. 
Edit: Code current: 
So i currently wrote this piece of code: 
int timestep = 1;
while(1)
{
  unsigned long startTime = millis()
  while(startTime != 500)
  {  
    digitalWrite(step_pin,LOW);
    delayMicroseconds(208/timestep);
    digitalWrite(step_pin,HIGH);
    delayMicroseconds(208/timestep);
  }  

  timestep++;
}

For each 0.5s should the frequency be doubled..  would this work?
Edit 2.0: 
I made an new implementation using @EdgarBonet 's answer, and with the help of Timer1 library that arduino provide (I guess?).
.h file
#ifndef stepper_motor_h
#define stepper_motor_h

#include "Arduino.h"
#include <TimerOne.h>

#define step_pin  13
#define dir_pin   12
#define en_pin    11
#define max_step  200

 class stepper_motor
{
  public:
    stepper_motor();
    void step_pwm();
    static void callback();
    TimerOne timer1;
  private:
    //uint32_t period;
    bool alive_bool;    
    //int step_count;
    bool position_bool;
};


#endif

.cpp file
#include "stepper_motor.h"

int step_count = 0;
uint32_t period = 40825UL << 16; // 20412,5 us fixed point arithmetic time = 0

stepper_motor::stepper_motor()
{
  //pinMode(BUILTIN_LED,OUTPUT);
  pinMode(step_pin, OUTPUT);
  pinMode(dir_pin, OUTPUT);
  pinMode(en_pin, OUTPUT);
  alive_bool = true;
  position_bool = false;
  step_count = 0;

}

static void stepper_motor::callback()
{
  if (step_count < 240)
  {
    uint32_t new_period = sqrt(2 * step_count / 4.8);
    period -= new_period; 
    step_count++;
  }
  else
  {
    return;
  }
}


void stepper_motor::step_pwm()
{

  digitalWrite(en_pin, HIGH);

  delay(0.005);

  digitalWrite(dir_pin, HIGH);
  //LOW  - Move towards the sensor
  //HIGH -  Move away from the sensor

  delay(0.005);

  timer1.initialize(period);
  timer1.attachInterrupt(callback);
  timer1.pwm(step_pin, 512);


}


user7508: Generating a linear frequency ramp with accurate timings is not an easy
task. I am providing here only a partial answer, where I first go
through the math of the problem, then give some ideas for the
implementation.
The math
We are dealing with a frequency-modulated signal, with the frequency
ramping linearly from f = 0 at t = 0 up to a
maximum f = fM at
t = tM. Specifically, we have
fM = 48 kHz and
tM = 10 s.
Then, the instantaneous frequency is
f(t) = a t
where a = fM/tM = 4.8
kHz/s is the “acceleration” of the pulsed signal.
Let's define the “integrated frequency” as
n(t) = ∫ f(t) dt = a t²/2
This quantity can be interpreted as the number of cycles completed at
time t, except that it is a continuous variable. The first cycle
starts when n = 0 and ends when n = 1, the next
cycle starts when n = 1 and ends when n = 2, and
so on. The output signal would be high when the fractional part of n
is between 0.25 and 0.75 (or maybe between 0 and 0.5, depending on your
choice of initial phase).
From here, we can calculate at what time each cycle should start:
t(n) = √(2 n/a)
and, by successive differences, the length of each cycle:
n       0     1       2       3      ... 239,998    239,999    240,000
t       0     20,412  28,868  35,355 ... 9,999,958  9,999,979  10,000,000
length   20,412   8,455   6,488      ...        20.833     20.833
diff          -11,957 -1,967  -1,018 ...            -0.000043
approx        +81,650 -1,408  -913   ...            -0.000043

In the table above, all times are in microseconds. The lines are:

t: time
length: length of one cycle
diff: difference between lengths of successive cycles
approx: approximated formula for that difference

The columns are staggered because each cycles spans the duration between
two successive values of t, and duration differences are computed
between successive cycles. The approximated formula is based on the
Taylor expansion:
T(n+1) − T(n) ≈ dT/dn + 1/2 d²T/dn² = −aT³(1 − 3/2 aT²)
where T = 1/f, the instantaneous period, approximates the
length of one cycle. The approximation is not good for the very first
cycles, but it converges pretty fast to the correct value.
Implementation
I did not write an implementation, so I am giving here only some ideas
on how to do it.
I would use Timer 1 of the Arduino Uno, in one of the modes that allows
frequency-modulation, i.e. a PWM mode where the counter TOP is set by a
register (mode 8, 9, 10, 11, 14 or 15). I would set the prescaler to 8
in order to allow for the maximum required period length. The period
resolution would then be:

8 CPU cycles = 0.5 µs in modes 14 or 15 (fast PWM)
16 CPU cyels = 1 µs in the other modes

It could be noted that single-cycle resolution is possible with the
prescaler set to 1, but the first 5 cycles are too long for this
setting. Maybe the prescaler could be changed after the fifth cycle, but
it would be tricky to do so without any glitch.
The timer overflow interrupt would fire at the end of each cycle, and
it's ISR (namely TIMER1_OVF_vect) would be responsible for updating
the timer period in order to make the next cycle shorter than the one
just elapsed. It would do something like
period -= delta(period);

The period should be computed with 32-bit arithmetic, because the
changes get tiny by the end of the ramp. Only the 16 most
significant bits of the computed period would actually be written to the
timer register. The delta() function should be inlined and fast. I may
try the approximation from the previous section implemented in
fixed-point. Or maybe just a table lookup using only the most
significant bits of the period as an index, with the table in PROGMEM.
For details on how to actually program the timer, see
the datasheet of the ATmega328P, section 16.

Update: The following algorithm seems to work well. At least in
simulation, I did not put it inside an ISR. It assumes fast PWM, i.e. a
0.5 µs timer resolution. It remembers the current value of delta
and divides it by 2 each time the period falls below some threshold. The
computed f(t) is almost as smooth as you can expect given the
limited resolution of the timer.
uint32_t period = 40825UL << 16;  // 1st cycle is 20412.5 us
void update_period()  // should be in ISR(TIMER1_OVF_vect)
{
    static const uint16_t thresholds[] = {
            17633, 13309, 10229, 7954, 6230, 4905, 3873, 3063,
            2426, 1923, 1525, 1211, 960, 762, 605, 480, 381,
            302, 240, 190, 151, 120, 95, 76, 60, 48};
    static uint16_t threshold = 29000;
    static uint8_t index = 0;
    static uint32_t delta = 6UL << 27;

    uint16_t period_h = period >> 16;
    if (period_h <= 42) return;  // final frequency achieved
    if (period_h < threshold) {
        threshold = thresholds[index++];
        delta >>= 1;
    }
    period -= delta;
    // set the timer period register to (period >> 16) - 1.
}


user3917: As mentioned in comments and other answers, using timer 1 for hardware-timed bit toggling is likely to produce better results than code using delays based on calls like delayMicroseconds(), primarily because of overhead causing poor resolution or jitter.
Using timer 1 in a PWM mode offers an advantage: loading of the OCR1A register is double buffered in PWM modes.  This makes it possible to smoothly transition from one frequency to another without glitches due to setup delays.  The code shown below (program freqSweep.ino) illustrates one way of steadily ramping the period of a waveform.  The initial count, delta count, and number of steps parameters ic, dc, ns also are double buffered, with the first set loaded via rampInit (), and new sets loaded opportunely from time to time via rampNext ().
In operation, the ramper causes timer 1 to produce a waveform with half cycles of lengths ic, ic+dc, ic+2dc, ... ic+(ns-1)dc.  That is, it generates ns steps of varying lengths, using timer 1 interrupts to trigger its execution in the background.  While the ISR produces a ramp of cycles, the user's loop() code can be computing parameters for the next ramp.  Note, if dc>0, periods grow larger so the frequency ramp descends.  If dc<0, periods grow smaller so the frequency ramp ascends. If dc==0, the ramp is flat.  Note, ic and dc are 32-bit fixed-point numbers, with 16 binary places.  Thus, while hardware only generates time intervals with integral numbers of cycles, the ramper software works with fractional values, so dc can have values like 0.5, 3.375, .076171875 (39/512) etc.
By generating a seamless series of small ramps, one can accurately approximate larger patterns of frequency ramps.  For example, to generate a frequency-linear ramp from say 100 Hz up to 48 KHz in 10 seconds, one might divide that time into 100 parts.  If f(t) denotes the frequency desired at time t, one would then (for each 0.1 second time step) compute half-periods p and q corresponding to frequencies f(t) and f(t+0.1).  About n = 0.1*f(t+0.05) cycles are available in 0.1 seconds for frequencies between f(t) and f(t+0.1), or about ns = 2*n half-cycles.  Choose dc = (q-p)/ns [using 32:16 fixed point arithmetic, and noting that dc can be negative] to smoothly ramp from frequency f(t) to f(t+0.1) in ns steps that take about 0.1 seconds total.  0.1 seconds, or 100 ms, is enough time to calculate and load a new set of parameters.  See program comments (under the heading General form of use of ramper) re computing parameters.
Here is the example program:
// Sweep a frequency, on dig. pin 7, PD7 - jw 27 Sep 2016
#include <Streaming.h>

enum { outpin=7, mOutpin=1<<7 }; // Arduino dig. pin# & its bit mask
void setup() {
  pinMode(outpin, OUTPUT);
}

long RAMdcl, RAMdcn;    // dc is signed to allow ramps up or down
unsigned long RAMicl, RAMicn; 
unsigned int RAMnsl, RAMnsn;
volatile unsigned int RAMrampsDone; // Number of ramps done so far
volatile byte RAMsendPars;  // Flag is 1 when ok to send params

void rampInit(unsigned long ic0, unsigned long dc0, unsigned long ns0, byte clockSource) {
  /* clockSource should be a 3-bit number, from 0 to 5:
   ..Bits.. ....Effect....   [See Table 16-5, p. 134 in specs]
    0 0 0   No clock source (Timer/Counter stopped).
    0 0 1   IOclock / 1    (No prescaling)
    0 1 0   IOclock / 8    (From prescaler)
    0 1 1   IOclock / 64   (From prescaler)
    1 0 0   IOclock / 256  (From prescaler)
    1 0 1   IOclock / 1024 (From prescaler)
  */
  TIMSK1 = 0;           // Turn off timer 1 interrupts
  // ic and dc (initial count and delta count) values
  // are 32:16 fixed point values; ie with 16 binary places.
  RAMicl = RAMicn = ic0;
  RAMdcl = RAMdcn = dc0;    // Set initial param values
  RAMnsl = RAMnsn = ns0;
  RAMrampsDone = 0;     // No ramps done yet
  RAMsendPars = 1;      // Next param set can load

    // Set timer 1 to Fast Pwm mode with OC1A (dig pin 9) toggling
  TCNT1 = 0;           // Zero the counter
  TCCR1A = 1<<WGM11 | 1<<WGM10; // for Fast Pwm with TOP from OCR1A
  OCR1A = (uint16_t)(RAMicl >> 16); // Initial TOP = integer part of icl
  TCCR1B = 1<<WGM13 | 1<<WGM12 | // for Fast Pwm with TOP from OCR1A
           clockSource;    // Start timer 1 with selected prescale
  TIMSK1 = 1<<TOIE1;       // Enable timer 1 overflow interrupt at TOP
}

// timer 1 overflow interrupt handler
ISR(TIMER1_OVF_vect) {
  OCR1A = (uint16_t)(RAMicl >> 16); // Update TOP with integer part of ic
  PIND = mOutpin;         // Toggle the output pin, eg dig pin 7, PD7
  // (Output bits toggle when a 1 is written to their input port bit)

  RAMicl += (unsigned long)RAMdcl;  // dc is signed but we need bare bits 
  --RAMnsl;
  if (!RAMnsl) {        // Go on to next section?
    RAMicl = RAMicn;
    RAMdcl = RAMdcn;        // Set next param values
    RAMnsl = RAMnsn;
    ++RAMrampsDone;     // We are in the last half cycle of section
    RAMsendPars = 1;        // Ready for next param set
  }
}

// rampNext() busy-waits until it can load new param values
void rampNext (unsigned long ic, unsigned long dc, unsigned int ns) {
  while (!RAMsendPars) {}
  RAMsendPars = 0;
  RAMicn = ic;
  RAMdcn = dc;      // Set next param values
  RAMnsn = ns;
}

// rampStop() stops the ramp-processor, right now
void  rampStop() {
  TIMSK1 = 0;           // Turn off timer 1 interrupts
  RAMrampsDone = RAMsendPars = 0;
  digitalWrite(outpin, LOW);    // Turn off output bit
}

/*
  // General form of use of ramper:
  ...
  rampInit(icj, dcj, nsj, scaleBy1);  // Send first param set
  for (byte j=0; j<rampSections; ++j) {
    // Compute next param set ...
    icj = ...
    dcj = ...
    nsj = ...
    // Do other stuff here
    // ...
    // rampNext will busy-wait while sendPars is clear
    rampNext (icj, dcj, nsj);
  }
  // Busy-wait while last ramp finishes
  while (RAMrampsDone <= rampSections) {}
  rampStop();       // Stop the ramp-processor
*/

// Example: Play a sound with 5 ramp parts in loop(), with brief pauses
void loop() {
  enum { scaleBy1=1};
  unsigned long icj, dcj;       // My ramp param calc vars
  unsigned int nsj=1000;        // # of steps per ramp
  icj = ((unsigned long)1600)<<16;  // ic = initial count
  dcj = ((unsigned long)1)<<16;     // dc = step size
  nsj = 5000;
  rampInit (icj*3, dcj/2, nsj, scaleBy1);
  rampNext (icj, dcj, nsj/3);
  rampNext (icj*2, -dcj, nsj/2);
  rampNext (icj*2, -dcj, nsj/2);
  rampNext (icj, dcj, nsj/3);
  while (RAMrampsDone < 5) {};
  rampStop();           // Stop the ramp-processor
  delay(2500);          // silence-separator
}


26743: <p>I, at the moment am trying to come up with a simple way where I can program an Arduino to provide a step signal with a given frequency, at a specific time. </p>

<p>The frequency has to be ramped up, and within a time duration of 10 seconds shall the frequency go from 0 Hz to 48000 Hz.  </p>

<p>How do I ensure both the specific time of when the frequency occurs, and the specific frequency of the step signal?</p>

<p>Signal has to be used to driver a stepper motor. </p>

<p><strong>Edit: Code current:</strong> </p>

<p>So i currently wrote this piece of code: </p>

<pre><code>int timestep = 1;
while(1)
{
  unsigned long startTime = millis()
  while(startTime != 500)
  {  
    digitalWrite(step_pin,LOW);
    delayMicroseconds(208/timestep);
    digitalWrite(step_pin,HIGH);
    delayMicroseconds(208/timestep);
  }  

  timestep++;
}
</code></pre>

<p>For each 0.5s should the frequency be doubled..  would this work?</p>

<p><strong>Edit 2.0:</strong> </p>

<p>I made an new implementation using @EdgarBonet 's answer, and with the help of Timer1 <a href="https://code.google.com/archive/p/arduino-timerone/downloads" rel="nofollow">library</a> that arduino provide (I guess?).</p>

<p>.h file</p>

<pre><code>#ifndef stepper_motor_h
#define stepper_motor_h

#include "Arduino.h"
#include &lt;TimerOne.h&gt;

#define step_pin  13
#define dir_pin   12
#define en_pin    11
#define max_step  200

 class stepper_motor
{
  public:
    stepper_motor();
    void step_pwm();
    static void callback();
    TimerOne timer1;
  private:
    //uint32_t period;
    bool alive_bool;    
    //int step_count;
    bool position_bool;
};


#endif
</code></pre>

<p>.cpp file</p>

<pre><code>#include "stepper_motor.h"

int step_count = 0;
uint32_t period = 40825UL &lt;&lt; 16; // 20412,5 us fixed point arithmetic time = 0

stepper_motor::stepper_motor()
{
  //pinMode(BUILTIN_LED,OUTPUT);
  pinMode(step_pin, OUTPUT);
  pinMode(dir_pin, OUTPUT);
  pinMode(en_pin, OUTPUT);
  alive_bool = true;
  position_bool = false;
  step_count = 0;

}

static void stepper_motor::callback()
{
  if (step_count &lt; 240)
  {
    uint32_t new_period = sqrt(2 * step_count / 4.8);
    period -= new_period; 
    step_count++;
  }
  else
  {
    return;
  }
}


void stepper_motor::step_pwm()
{

  digitalWrite(en_pin, HIGH);

  delay(0.005);

  digitalWrite(dir_pin, HIGH);
  //LOW  - Move towards the sensor
  //HIGH -  Move away from the sensor

  delay(0.005);

  timer1.initialize(period);
  timer1.attachInterrupt(callback);
  timer1.pwm(step_pin, 512);


}
</code></pre>
 7508: <p>Generating a linear frequency ramp with accurate timings is not an easy
task. I am providing here only a partial answer, where I first go
through the math of the problem, then give some ideas for the
implementation.</p>

<h2>The math</h2>

<p>We are dealing with a frequency-modulated signal, with the frequency
ramping linearly from <em>f</em>&nbsp;=&nbsp;0 at <em>t</em>&nbsp;=&nbsp;0 up to a
maximum <em>f</em>&nbsp;=&nbsp;<em>f</em><sub>M</sub> at
<em>t</em>&nbsp;=&nbsp;<em>t</em><sub>M</sub>. Specifically, we have
<em>f</em><sub>M</sub>&nbsp;=&nbsp;48&nbsp;kHz and
<em>t</em><sub>M</sub>&nbsp;=&nbsp;10&nbsp;s.
Then, the instantaneous frequency is</p>

<p><em>f</em>(<em>t</em>)&nbsp;=&nbsp;<em>a</em> <em>t</em></p>

<p>where <em>a</em>&nbsp;=&nbsp;<em>f</em><sub>M</sub>/<em>t</em><sub>M</sub>&nbsp;=&nbsp;4.8
kHz/s is the “acceleration” of the pulsed signal.</p>

<p>Let's define the “integrated frequency” as</p>

<p><em>n</em>(<em>t</em>)&nbsp;=&nbsp;∫ <em>f</em>(<em>t</em>) dt&nbsp;=&nbsp;<em>a</em> <em>t</em>²/2</p>

<p>This quantity can be interpreted as the number of cycles completed at
time <em>t</em>, except that it is a continuous variable. The first cycle
starts when <em>n</em>&nbsp;=&nbsp;0 and ends when <em>n</em>&nbsp;=&nbsp;1, the next
cycle starts when <em>n</em>&nbsp;=&nbsp;1 and ends when <em>n</em>&nbsp;=&nbsp;2, and
so on. The output signal would be high when the fractional part of <em>n</em>
is between 0.25 and 0.75 (or maybe between 0 and 0.5, depending on your
choice of initial phase).</p>

<p>From here, we can calculate at what time each cycle should start:</p>

<p><em>t</em>(<em>n</em>)&nbsp;=&nbsp;√(2 <em>n</em>/<em>a</em>)</p>

<p>and, by successive differences, the length of each cycle:</p>

<pre><code>n       0     1       2       3      ... 239,998    239,999    240,000
t       0     20,412  28,868  35,355 ... 9,999,958  9,999,979  10,000,000
length   20,412   8,455   6,488      ...        20.833     20.833
diff          -11,957 -1,967  -1,018 ...            -0.000043
approx        +81,650 -1,408  -913   ...            -0.000043
</code></pre>

<p>In the table above, all times are in microseconds. The lines are:</p>

<ul>
<li><em>t</em>: time</li>
<li>length: length of one cycle</li>
<li>diff: difference between lengths of successive cycles</li>
<li>approx: approximated formula for that difference</li>
</ul>

<p>The columns are staggered because each cycles spans the duration between
two successive values of <em>t</em>, and duration differences are computed
between successive cycles. The approximated formula is based on the
Taylor expansion:</p>

<p>T(<em>n</em>+1) − T(<em>n</em>) ≈ dT/dn + 1/2 d²T/dn²&nbsp;=&nbsp;−aT³(1 − 3/2 aT²)</p>

<p>where T&nbsp;=&nbsp;1/<em>f</em>, the instantaneous period, approximates the
length of one cycle. The approximation is not good for the very first
cycles, but it converges pretty fast to the correct value.</p>

<h2>Implementation</h2>

<p>I did not write an implementation, so I am giving here only some ideas
on how to do it.</p>

<p>I would use Timer 1 of the Arduino Uno, in one of the modes that allows
frequency-modulation, i.e. a PWM mode where the counter TOP is set by a
register (mode 8, 9, 10, 11, 14 or 15). I would set the prescaler to 8
in order to allow for the maximum required period length. The period
resolution would then be:</p>

<ul>
<li>8 CPU cycles&nbsp;=&nbsp;0.5 µs in modes 14 or 15 (fast PWM)</li>
<li>16 CPU cyels&nbsp;=&nbsp;1 µs in the other modes</li>
</ul>

<p>It could be noted that single-cycle resolution is possible with the
prescaler set to 1, but the first 5&nbsp;cycles are too long for this
setting. Maybe the prescaler could be changed after the fifth cycle, but
it would be tricky to do so without any glitch.</p>

<p>The timer overflow interrupt would fire at the end of each cycle, and
it's ISR (namely <code>TIMER1_OVF_vect</code>) would be responsible for updating
the timer period in order to make the next cycle shorter than the one
just elapsed. It would do something like</p>

<pre><code>period -= delta(period);
</code></pre>

<p>The period should be computed with 32-bit arithmetic, because the
changes get tiny by the end of the ramp. Only the 16&nbsp;most
significant bits of the computed period would actually be written to the
timer register. The <code>delta()</code> function should be inlined and fast. I may
try the approximation from the previous section implemented in
fixed-point. Or maybe just a table lookup using only the most
significant bits of the period as an index, with the table in PROGMEM.</p>

<p>For details on how to actually program the timer, see
the <a href="http://www.atmel.com/Images/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_datasheet.pdf" rel="nofollow">datasheet of the ATmega328P</a>, section 16.</p>

<hr>

<p><strong>Update</strong>: The following algorithm seems to work well. At least in
simulation, I did not put it inside an ISR. It assumes fast PWM, i.e. a
0.5&nbsp;µs timer resolution. It remembers the current value of delta
and divides it by 2 each time the period falls below some threshold. The
computed <em>f</em>(<em>t</em>) is almost as smooth as you can expect given the
limited resolution of the timer.</p>

<pre class="lang-c++ prettyprint-override"><code>uint32_t period = 40825UL &lt;&lt; 16;  // 1st cycle is 20412.5 us
void update_period()  // should be in ISR(TIMER1_OVF_vect)
{
    static const uint16_t thresholds[] = {
            17633, 13309, 10229, 7954, 6230, 4905, 3873, 3063,
            2426, 1923, 1525, 1211, 960, 762, 605, 480, 381,
            302, 240, 190, 151, 120, 95, 76, 60, 48};
    static uint16_t threshold = 29000;
    static uint8_t index = 0;
    static uint32_t delta = 6UL &lt;&lt; 27;

    uint16_t period_h = period &gt;&gt; 16;
    if (period_h &lt;= 42) return;  // final frequency achieved
    if (period_h &lt; threshold) {
        threshold = thresholds[index++];
        delta &gt;&gt;= 1;
    }
    period -= delta;
    // set the timer period register to (period &gt;&gt; 16) - 1.
}
</code></pre>
 3917: <p>As mentioned in comments and other answers, using timer 1 for hardware-timed bit toggling is likely to produce better results than code using delays based on calls like <code>delayMicroseconds()</code>, primarily because of overhead causing poor resolution or jitter.</p>

<p>Using timer 1 in a PWM mode offers an advantage: loading of the OCR1A register is double buffered in PWM modes.  This makes it possible to smoothly transition from one frequency to another without glitches due to setup delays.  The code shown below (program <code>freqSweep.ino</code>) illustrates one way of steadily ramping the period of a waveform.  The <em>initial count, delta count</em>, and <em>number of steps</em> parameters <code>ic, dc, ns</code> also are double buffered, with the first set loaded via <code>rampInit ()</code>, and new sets loaded opportunely from time to time via <code>rampNext ()</code>.</p>

<p>In operation, the ramper causes timer 1 to produce a waveform with half cycles of lengths <code>ic, ic+dc, ic+2dc, ... ic+(ns-1)dc</code>.  That is, it generates <code>ns</code> steps of varying lengths, using timer 1 interrupts to trigger its execution in the background.  While the ISR produces a ramp of cycles, the user's <code>loop()</code> code can be computing parameters for the next ramp.  Note, if <code>dc&gt;0</code>, periods grow larger so the frequency ramp descends.  If <code>dc&lt;0</code>, periods grow smaller so the frequency ramp ascends. If <code>dc==0</code>, the ramp is flat.  Note, <code>ic</code> and <code>dc</code> are 32-bit fixed-point numbers, with 16 binary places.  Thus, while hardware only generates time intervals with integral numbers of cycles, the ramper software works with fractional values, so <code>dc</code> can have values like 0.5, 3.375, .076171875 (39/512) etc.</p>

<p>By generating a seamless series of small ramps, one can accurately approximate larger patterns of frequency ramps.  For example, to generate a frequency-linear ramp from say 100 Hz up to 48 KHz in 10 seconds, one might divide that time into 100 parts.  If f(t) denotes the frequency desired at time t, one would then (for each 0.1 second time step) compute half-periods p and q corresponding to frequencies f(t) and f(t+0.1).  About n = 0.1*f(t+0.05) cycles are available in 0.1 seconds for frequencies between f(t) and f(t+0.1), or about <code>ns</code> = 2*n half-cycles.  Choose <code>dc = (q-p)/ns</code> [using 32:16 fixed point arithmetic, and noting that <code>dc</code> can be negative] to smoothly ramp from frequency f(t) to f(t+0.1) in <code>ns</code> steps that take about 0.1 seconds total.  0.1 seconds, or 100 ms, is enough time to calculate and load a new set of parameters.  See program comments (under the heading <em>General form of use of ramper</em>) re computing parameters.</p>

<p>Here is the example program:</p>

<pre><code>// Sweep a frequency, on dig. pin 7, PD7 - jw 27 Sep 2016
#include &lt;Streaming.h&gt;

enum { outpin=7, mOutpin=1&lt;&lt;7 }; // Arduino dig. pin# &amp; its bit mask
void setup() {
  pinMode(outpin, OUTPUT);
}

long RAMdcl, RAMdcn;    // dc is signed to allow ramps up or down
unsigned long RAMicl, RAMicn; 
unsigned int RAMnsl, RAMnsn;
volatile unsigned int RAMrampsDone; // Number of ramps done so far
volatile byte RAMsendPars;  // Flag is 1 when ok to send params

void rampInit(unsigned long ic0, unsigned long dc0, unsigned long ns0, byte clockSource) {
  /* clockSource should be a 3-bit number, from 0 to 5:
   ..Bits.. ....Effect....   [See Table 16-5, p. 134 in specs]
    0 0 0   No clock source (Timer/Counter stopped).
    0 0 1   IOclock / 1    (No prescaling)
    0 1 0   IOclock / 8    (From prescaler)
    0 1 1   IOclock / 64   (From prescaler)
    1 0 0   IOclock / 256  (From prescaler)
    1 0 1   IOclock / 1024 (From prescaler)
  */
  TIMSK1 = 0;           // Turn off timer 1 interrupts
  // ic and dc (initial count and delta count) values
  // are 32:16 fixed point values; ie with 16 binary places.
  RAMicl = RAMicn = ic0;
  RAMdcl = RAMdcn = dc0;    // Set initial param values
  RAMnsl = RAMnsn = ns0;
  RAMrampsDone = 0;     // No ramps done yet
  RAMsendPars = 1;      // Next param set can load

    // Set timer 1 to Fast Pwm mode with OC1A (dig pin 9) toggling
  TCNT1 = 0;           // Zero the counter
  TCCR1A = 1&lt;&lt;WGM11 | 1&lt;&lt;WGM10; // for Fast Pwm with TOP from OCR1A
  OCR1A = (uint16_t)(RAMicl &gt;&gt; 16); // Initial TOP = integer part of icl
  TCCR1B = 1&lt;&lt;WGM13 | 1&lt;&lt;WGM12 | // for Fast Pwm with TOP from OCR1A
           clockSource;    // Start timer 1 with selected prescale
  TIMSK1 = 1&lt;&lt;TOIE1;       // Enable timer 1 overflow interrupt at TOP
}

// timer 1 overflow interrupt handler
ISR(TIMER1_OVF_vect) {
  OCR1A = (uint16_t)(RAMicl &gt;&gt; 16); // Update TOP with integer part of ic
  PIND = mOutpin;         // Toggle the output pin, eg dig pin 7, PD7
  // (Output bits toggle when a 1 is written to their input port bit)

  RAMicl += (unsigned long)RAMdcl;  // dc is signed but we need bare bits 
  --RAMnsl;
  if (!RAMnsl) {        // Go on to next section?
    RAMicl = RAMicn;
    RAMdcl = RAMdcn;        // Set next param values
    RAMnsl = RAMnsn;
    ++RAMrampsDone;     // We are in the last half cycle of section
    RAMsendPars = 1;        // Ready for next param set
  }
}

// rampNext() busy-waits until it can load new param values
void rampNext (unsigned long ic, unsigned long dc, unsigned int ns) {
  while (!RAMsendPars) {}
  RAMsendPars = 0;
  RAMicn = ic;
  RAMdcn = dc;      // Set next param values
  RAMnsn = ns;
}

// rampStop() stops the ramp-processor, right now
void  rampStop() {
  TIMSK1 = 0;           // Turn off timer 1 interrupts
  RAMrampsDone = RAMsendPars = 0;
  digitalWrite(outpin, LOW);    // Turn off output bit
}

/*
  // General form of use of ramper:
  ...
  rampInit(icj, dcj, nsj, scaleBy1);  // Send first param set
  for (byte j=0; j&lt;rampSections; ++j) {
    // Compute next param set ...
    icj = ...
    dcj = ...
    nsj = ...
    // Do other stuff here
    // ...
    // rampNext will busy-wait while sendPars is clear
    rampNext (icj, dcj, nsj);
  }
  // Busy-wait while last ramp finishes
  while (RAMrampsDone &lt;= rampSections) {}
  rampStop();       // Stop the ramp-processor
*/

// Example: Play a sound with 5 ramp parts in loop(), with brief pauses
void loop() {
  enum { scaleBy1=1};
  unsigned long icj, dcj;       // My ramp param calc vars
  unsigned int nsj=1000;        // # of steps per ramp
  icj = ((unsigned long)1600)&lt;&lt;16;  // ic = initial count
  dcj = ((unsigned long)1)&lt;&lt;16;     // dc = step size
  nsj = 5000;
  rampInit (icj*3, dcj/2, nsj, scaleBy1);
  rampNext (icj, dcj, nsj/3);
  rampNext (icj*2, -dcj, nsj/2);
  rampNext (icj*2, -dcj, nsj/2);
  rampNext (icj, dcj, nsj/3);
  while (RAMrampsDone &lt; 5) {};
  rampStop();           // Stop the ramp-processor
  delay(2500);          // silence-separator
}
</code></pre>
