Skip to content

Instantly share code, notes, and snippets.

@magnomp
Created July 8, 2013 22:54
Show Gist options
  • Save magnomp/5953179 to your computer and use it in GitHub Desktop.
Save magnomp/5953179 to your computer and use it in GitHub Desktop.
Sketch para Arduino para geração de 8 sinais de audio em 8 pinos, cada um seguindo um padrão especifico de pulsos (um pulso no canal 1, dois pulsos no canal 2, etc). As bibliotecas de audio para Arduino têm a limitação de permitir gerar apenas um tom em um dado instante, ou quando muito tantos tons quanto forem os timers de hardware disponíveis …
#include <TimerOne.h>
#define FREQUENCIA 110 // hz
#define TEMPO_TOCANDO 200 // ms
#define TEMPO_PAUSA_CURTA 200 // ms
#define TEMPO_PAUSA_LONGA 1000 // ms
#define TOCANDO 0
#define PAUSA_CURTA 1
#define PAUSA_LONGA 2
#define PERIODO_TIMER (1000000/(FREQUENCIA*2))
#define CICLOS_TOCANDO (TEMPO_TOCANDO*1000L)/PERIODO_TIMER
#define CICLOS_PAUSA_CURTA ((TEMPO_PAUSA_CURTA*1000L)/PERIODO_TIMER)
#define CICLOS_PAUSA_LONGA ((TEMPO_PAUSA_LONGA*1000L)/PERIODO_TIMER)
typedef struct {
byte estado;
byte contador;
byte pulsos;
} Canal;
volatile byte estado = 0x00;
volatile Canal canais[8];
void interrupt() {
estado = ~estado;
byte mascara_tocando = 0;
for (int i = 0; i < 8; ++i) {
++canais[i].contador;
if ((canais[i].estado == TOCANDO) && (canais[i].contador == CICLOS_TOCANDO)) {
++canais[i].pulsos;
canais[i].contador = 0;
canais[i].estado = canais[i].pulsos == (i + 1)?PAUSA_LONGA:PAUSA_CURTA;
}
else if ((canais[i].estado == PAUSA_CURTA) && (canais[i].contador == CICLOS_PAUSA_CURTA)) {
canais[i].estado = TOCANDO;
canais[i].contador = 0;
}
if ((canais[i].estado == PAUSA_LONGA) && (canais[i].contador == CICLOS_PAUSA_LONGA)) {
canais[i].estado = TOCANDO;
canais[i].contador = 0;
canais[i].pulsos = 0;
}
if (canais[i].estado == TOCANDO)
mascara_tocando |= 1 << i;
}
PORTD = estado & mascara_tocando;
}
void setup() {
/* Serial.begin(9600);
Serial.println("Constantes");
Serial.print("PERIODO_TIMER = ");
Serial.println(PERIODO_TIMER);
Serial.print("CICLOS_TOCANDO = ");
Serial.println(CICLOS_TOCANDO);
Serial.print("CICLOS_PAUSA_CURTA = ");
Serial.println(CICLOS_PAUSA_CURTA);
Serial.print("CICLOS_PAUSA_LONGA = ");
Serial.println(CICLOS_PAUSA_LONGA); */
DDRD = 0xFF;
memset((void *)&canais, '\0', sizeof(Canal)*8);
Timer1.initialize(PERIODO_TIMER);
Timer1.attachInterrupt(interrupt);
}
void loop() {
}
@magnomp
Copy link
Author

magnomp commented Jul 8, 2013

Este código foi feito para gerar os sinais nos pinos correspondentes a PORTD do microcontrolador, que no caso do Arduino UNO são os pinos 1..8 (sim, se perde a comunicação serial. No meu caso não fez falta, mas o código pode ser adaptado para utilizar outros pinos)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment