Last active
August 27, 2020 23:00
-
-
Save matiasmicheletto/35ccac7df155f61443ba3730ba8a8d59 to your computer and use it in GitHub Desktop.
ATMega328 Arduino based dual channel variable frecuency square wave generator - Generador de onda cuadrada de frecuencia variable doble canal para Arduino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Doble generador de onda cuadrada de frecuencia variable | |
*/ | |
// Pines | |
#define T1 2 // Salida 1 | |
#define T2 3 // Salida 2 | |
// Frecuencias por defecto (Hz) | |
#define DEF_1 3 // Salida 1 | |
#define DEF_2 2 // Salida 2 | |
// Frecuencia de oscilador interno | |
#define BASE 100.16 | |
unsigned int tick1, tick2; // Contadores de pulsos del oscilador | |
unsigned int count1, count2; // Limite de cuenta | |
bool status1, status2; // Estado de salidas | |
void timerSetup(){ | |
// Inicializa el oscilador interno | |
noInterrupts(); | |
TCCR2A = 0; // Normal op. | |
TCCR2B = 0; // Normal op. | |
TCNT2 = 0; // Inicializar en 0 | |
OCR2A = (byte) (16e6/1024.0/BASE/2.0); // Registro de comparación (valor = 16MHz/Prescaler/Freq) | |
TCCR2A |= (1 << WGM21); // Modo CTC | |
TCCR2B |= (1 << CS20); // 1024 prescaler | |
TCCR2B |= (1 << CS21); // 1024 prescaler | |
TCCR2B |= (1 << CS22); // 1024 prescaler | |
TIMSK2 |= (1 << OCIE2A); // Habilitar oscilador | |
interrupts(); | |
} | |
bool togglePin(int n, bool status){ | |
// Alternar estado de salida | |
digitalWrite(n, status ? HIGH:LOW); | |
return !status; | |
} | |
void updateFreq(float fr, int *cnt, int *tck){ | |
// Actualizar el valor de frecuencia de una salida | |
if(fr > 0.0 && fr <= BASE){ | |
*cnt = (int) (BASE/fr); | |
*tck = 0; | |
printStatus(); | |
}else{ | |
printError(fr); | |
} | |
} | |
void printStatus(){ | |
// Imprime valores de frecuencia actuales | |
Serial.print("Valores actuales:\n"); | |
Serial.print("Salida 1: "); | |
Serial.print(BASE/(float)count1); | |
Serial.print(" Hz, Salida 2: "); | |
Serial.print(BASE/(float)count2); | |
Serial.print(" Hz.\n\n"); | |
} | |
void printHelp(){ | |
// Muestra las instruncciones de uso | |
Serial.print("##### Generador de frecuencia ARDUINO #####\n"); | |
Serial.print("Instrucciones de uso:\n"); | |
Serial.print("\ta\tMuestra los valores de frecuencia actuales de las salidas 1 y 2.\n"); | |
Serial.print("\th\tMuestra esta ayuda.\n"); | |
Serial.print("\ts\tConfigurar frecuencia para la salida 1. Los valores válidos pueden ser entre 0 y 100Hz. Ejemplo \"s10\" --> Salida 1 a 10Hz.\n"); | |
Serial.print("\tt\tConfigurar frecuencia para la salida 2. Los valores válidos pueden ser entre 0 y 100Hz. Ejemplo \"t0.5\" --> Salida 2 a 0.5Hz.\n\n"); | |
} | |
void printError(float fr){ | |
// Si se ingresa valor incorrecto | |
Serial.print("Error! El valor de frecuencia ingresado \""); | |
Serial.print(fr); | |
Serial.print("\" no es válido.\n\n"); | |
Serial.print("Presione \"h\" para ver la ayuda.\n\n"); | |
} | |
ISR(TIMER2_COMPA_vect){ | |
// Rutina de interrupcion del oscilador | |
tick1++; tick2++; | |
if(tick1 == count1){ | |
tick1 = 0; | |
status1 = togglePin(T1, status1); | |
} | |
if(tick2 == count2){ | |
tick2 = 0; | |
status2 = togglePin(T2, status2); | |
} | |
} | |
void serialEvent(){ | |
// Eventos de puerto serie | |
String arg; | |
float fr; | |
switch((char) Serial.read()){ | |
case 'a': // Imprimir estado | |
printStatus(); | |
break; | |
case 'h': // Imprimir ayuda | |
printHelp(); | |
break; | |
case 's': // Configurar frecuencia salida 1 | |
arg = Serial.readStringUntil('\n'); | |
fr = arg.toFloat(); | |
updateFreq(fr, &count1, &tick1); | |
break; | |
case 't': // Configurar frecuencia salida 2 | |
arg = Serial.readStringUntil('\n'); | |
fr = arg.toFloat(); | |
updateFreq(fr, &count2, &tick2); | |
break; | |
default: | |
break; | |
} | |
} | |
void setup(){ | |
Serial.begin(9600); | |
pinMode(T1, OUTPUT); | |
pinMode(T2, OUTPUT); | |
digitalWrite(T1, LOW); | |
digitalWrite(T2, LOW); | |
status1 = status2 = false; | |
tick1 = tick2 = 0; | |
count1 = (int) BASE/DEF_1; | |
count2 = (int) BASE/DEF_2; | |
timerSetup(); | |
printHelp(); | |
printStatus(); | |
} | |
void loop(){} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment