Al utilizar TimerThree das a entender que estamos trabajando en Arduino Mega.
Para poder generar dos señales distintas y de diferente (hasta variable) frecuencia; preferiría también utilizar el TimerOne. Los timer 1 y 3 dispararán la interrupción; mientras que el 0 o 2 generarán las señales (¡aprovecha que son de 8 bits!). Si no necesitas de millis, delay y micros, sería de utilizar el timer0 (pines 4 y 13) para las señales; caso contrario, sería con el timer2 (pines 9 y 10).
Deshabilitar estas tres funciones sería de considerar; de hacerlo se evitan posibles desfases de la señal en altas frecuencias.
Si me preguntas a mi; yo lo haría así:
#include <TimerThree.h>
#include <TimerOne.h>
//#define USAR_T2 // Descomenta para usar el timer2 (pines 9 y 10) y así mantener a millis, delay y micros.
const byte seno[] = {128, 146, 163, 181, 197, 211, 224, 235, 244, 250, 254, 255,
254, 250, 244, 236, 225, 212, 197, 181, 164, 147, 128, 110, 92, 75, 59, 45, 32, 20,
12, 5, 1, 0, 1, 4, 10, 19, 30, 42, 57, 73, 90, 108};
byte senoContador = 0;
byte trianContador = 0;
boolean descontando = false;
void setup()
{
#ifdef USAR_T2
TCCR2A = B10100011;
TCCR2B = 1;
#else
TIMSK0 = 0; // Deshabilita el funcionamiento de millis, delay y micros
TCCR0A = B10100011;
TCCR0B = 1; // Esto aceleraría los contadores de millis, delay y micros
#endif
Timer3.initialize(40);
Timer3.attachInterrupt(funcionTrian);
Timer1.initialize(40);
Timer1.attachInterrupt(funcionSeno);
// Frecuencia (en hertz) de la ondas: (1 / (m * t)) * 1000000
// t: tiempo (periodo) en microsegundos.
// m: cantidad de muestras que componen la onda. La senoidal se compone de 44; la triangular de 511.
}
void funcionSeno() // Max freq: 22.7 KHz
{
// Onda senoidal en el pin 13 (timer0), o 10 (timer2)
#ifdef USAR_T2
OCR2A = seno[senoContador++];
#else
OCR0A = seno[senoContador++];
#endif
if (senoContador == sizeof(seno)) senoContador = 0;
}
void funcionTrian() { // Max freq: 1.95 KHz; a menos que incrementemos el factor de subida
// Onda triangular en el pin 4 (timer0), o 9 (timer2)
if (descontando) {
#ifdef USAR_T2
OCR2B = --trianContador;
#else
OCR0B = --trianContador;
#endif
if (!trianContador) descontando = false;
} else {
#ifdef USAR_T2
OCR2B = ++trianContador;
#else
OCR0B = ++trianContador;
#endif
if (trianContador == 0xFF) descontando = true;
}
}
void loop() {
}
PD: ojo a lo que se dice sobre la onda triangular:
// Max freq: 1.95 KHz; a menos que incrementemos el factor de subida
Si 2 KHz son insuficientes; entonces habrá que incrementar más el contador por interrupción.