Soy un programador y no tengo experiencia con arduino ni con ningún microcontrolador. Especialmente el aspecto técnico.
Soldé una Matriz Led RGB 6x8 y uso modulación codificada en binario enlace Mezclar los colores.
Los Leds están controlados por 4 74hc595 shiftregisters. Básicamente, muevo los bits para controlar el realmente rápido durante una interrupción del temporizador.
Ahora quiero influir en el color de los leds mediante la medición de las frecuencias de sonido con un Electret micrófono breakout board . Para lograr una detección de frecuencia rápida, utilizo una técnica que se describe aquí enlace .
Se basa en interrupciones ADC.
Ambas mejoras funcionan solas, pero cuando intento unir el código, se rompe.
El temporizador y el ADC se inicializan así:
cli(); //stop all interrupts
/////////////////////
//initialize TIMER//
////////////////////
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 1; // compare match register
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= ((1<<CS21)|(1<<CS20)) ;
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
//////////////////
//initialize ADC//
//////////////////
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS1); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
//ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
sei(); //start all interrupts
Entonces, mi pregunta es: ¿es posible usar esas interrupciones juntas? ¿Y cómo tengo que configurarlos para que funcione? ¿O es un callejón sin salida?
EDIT La interrupción del temporizador:
ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
zaehlbit <<=1;
//reset timercompare and zaehlbit
if( zaehlbit == 0 ) {
OCR1A= 1;
zaehlbit = 1;
}
//latch low
bitClear(PORTB, latchPinPORTB);
//red
for (int i=0; i<8; i++){
// clock low
bitClear(PORTB, clockPinPORTB);
//check led position and brightness
//and set Bit on Datapin if zaehlbit in Brightness
if (ledCounter&led && zaehlbit&red){
bitClear(PORTB, dataPinPORTB);
}
else {
bitSet(PORTB, dataPinPORTB);
}
// clock low (register bit)
bitSet(PORTB, clockPinPORTB);
ledCounter >>= 1;
if( ledCounter == 0 ) {
ledCounter = 128;
}
}
//shift timer compare and set timer back to generate delay (Bit Angle Modulation)
OCR1A <<= 1;
TCNT1 = 0;
}
Hago el mismo for-loop para las filas y los otros colores. Simplemente lo dejé afuera porque parecía confuso. El registro de comparación de coincidencias se desplaza hacia la izquierda durante la interrupción y el temporizador se retrasa para generar un retraso "creciente". Hay una interrupción por ciclo. Se ejecuta en un reloj / 32 tickrate
La interrupción de ADC se ve así:
ISR(ADC_vect) {//when new ADC value ready
prevData = newData;//store previous value
newData = ADCH;//get value from A0
if (newData > prevData){//if positive slope
bitSet(PORTB, ledPORTB);//set pin 12 high
}
else if (newData < prevData){
bitClear(PORTB, ledPORTB); //set pin 12 low
}
}
La interrupción de ADC se activa cada vez que un valor de A0 está listo. En el mainloop solo trato de configurar algunos leds pero no funciona.