Actualmente estoy trabajando en un marcador simple con dos pantallas de 7 segmentos, un registro de desplazamiento (74HC595N), dos transistores PNP (2N3906) y un arduino uno.
Cada pantalla de 7 segmentos es un ánodo común, sin embargo, una pantalla es Azul con un voltaje directo de ~ 3.3V, la otra pantalla es Roja y tiene un voltaje directo de ~ 2V.
Estoy utilizando resistencias limitadoras de corriente de 220 ohmios en serie con el registro de desplazamiento y los cátodos de los LED. (Sospecho que esto podría ser parte de mi problema, ya que cada pantalla tiene una caída de voltaje diferente en los LED).
Estoy intentando multiplexar las pantallas, sin embargo, estoy experimentando problemas con el efecto fantasma. Estoy usando timer1 en el arduino para facilitar este comportamiento.
He configurado el temporizador con el siguiente código:
// Setup TIMER2
/* First disable the timer overflow interrupt while we're configuring */
TIMSK2 &= ~(1<<TOIE2);
/* Configure timer2 in normal mode (pure counting, no PWM etc.) */
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
/* Select clock source: internal I/O clock */
ASSR &= ~(1<<AS2);
/* Disable Compare Match A interrupt enable (only want overflow) */
TIMSK2 &= ~(1<<OCIE2A);
/* Now configure the prescaler to CPU clock divided by 128 */
TCCR2B |= (1<<CS22) | (1<<CS20); // Set bits
TCCR2B &= ~(1<<CS21); // Clear bit
/* We need to calculate a proper value to load the timer counter.
* The following loads the value 131 into the Timer 2 counter register
* The math behind this is:
* (CPU frequency) / (prescaler value) = 125000 Hz = 8us.
* (desired period) / 8us = 125.
* MAX(uint8) + 1 - 125 = 131;
*/
/* Save value globally for later reload in ISR */
tcnt2 = 5;
/* Finally load end enable the timer */
TCNT2 = tcnt2;
TIMSK2 |= (1<<TOIE2);
En el desbordamiento del temporizador se ejecuta la siguiente función:
ISR(TIMER2_OVF_vect){
// Turn off the active display
if(active_display == 0){
digitalWrite(BLUETRANS, LOW);
}
else{
digitalWrite(REDTRANS, LOW);
}
delayMicroseconds(1000);
// Toggle Display
active_display ^= 1;
// Shift out screen bits
if(active_display == 0){
displayDigit(blueByte);
}
else{
displayDigit(redByte);
}
// Turn display back on
if(active_display == 0){
digitalWrite(BLUETRANS, HIGH);
}
else{
digitalWrite(REDTRANS, HIGH);
}
// Reload the timer
TCNT2 = tcnt2;
}
No entiendo completamente el uso de Timer2, por lo que cualquier ayuda allí sería apreciada también. Entiendo que el temporizador cuenta hasta el valor de desbordamiento especificado y luego ejecuta el ISR. Sin embargo, mis intentos de reducir la frecuencia de actualización de las dos pantallas parecen hacer que mi programa no responda.
Creo que estoy multiplexando correctamente la pantalla:
- Desactivar visualización activa
- Desplazar bits al registro de desplazamiento para otra pantalla
- Enciende otra pantalla
Desafortunadamente, parece que no puedo reducir el efecto de imagen fantasma en la pantalla roja (la imagen fantasma no parece ocurrir en la pantalla azul).
Cualquier ayuda sería muy apreciada!
Entiendo que es posible que no haya incluido toda la información relevante, ¡así que pregunte y recibirá!
¡Gracias!
EDIT 1
Gracias a Justing, ahora entiendo mucho mejor cómo funciona Timer2 en el Arduino. Gracias por eso.
Desafortunadamente, incluso a 60 Hz puedo ver un efecto de efecto fantasma significativo, junto con un destello desagradable y perceptible, ya que alterna entre las pantallas. Con mi nuevo conocimiento de Timer1, pude aumentar exitosamente la frecuencia de actualización hasta 244Hz. Mi circuito actual sigue este diseño básico:
Comoseindicóanteriormente,misresistoreslimitadoresactualessonde220ohmios.¿PodríanlosdiferentesvoltajesdeavanceentrelapantallaBLUE7-segylapantallaRED7-segestarcausandoesteproblemadefantasma?Nuevamente,elúnicodígitoqueexperimentaesteproblemaeslapantallaROJA,lapantallaconelvoltajedeavancemásbajo(2V[rojo]frentea3V[azul]).Siestaeslacausa,¿elusode8resistenciasadicionalesparalasegundapantallasolucionaríaesteproblema?Esperabapodersalirconmenosresistenciasparaahorrarmealgodesoldaduraenelfuturo,perosisolucionaesteproblemadevisualización,valdríalapena.
¿Másideaschicos?Gracias!
EDIT2
EstoypublicandomifuncióndisplayDigit:
voiddisplayDigit(bytescreen){//ShiftdataintotheshiftregisterdigitalWrite(latchPin,0);//LATCHLOWTOSHIFTshiftOut(dataPin,clockPin,MSBFIRST,screen);digitalWrite(latchPin,1);//ENABLESHIFTEDBITS}
EDIT3
¿PodríanculparmemistransistoresPNP2N3906?Meparecequemientraslostransistorespermitenquelapantallaseenciendamuyrápidamente,apagarlosseproducemuchomáslento.Permitirqueeldígitorojo"vea" el valor de los dígitos anteriores. Sin embargo, esto no explica por qué no hay imágenes fantasma en la pantalla azul. ¿Puedo "levantar" fácilmente el ánodo de la pantalla con una resistencia para ayudar al transistor en su estado de "apagado"? "Off" aquí es técnicamente Vcc (5V) debido al diseño del ánodo común. La pantalla funciona cuando el ánodo se tira a tierra.
EDICIÓN FINAL
Doy las gracias a Myforwik por proporcionar la respuesta más breve y también la más útil a mi pregunta. Mi ISR ahora se ve así:
ISR(TIMER2_OVF_vect){
// Turn off the active display
if(active_display == 0){
digitalWrite(BLUETRANS, HIGH);
}
else{
digitalWrite(REDTRANS, HIGH);
}
delayMicroseconds(1000);
// Toggle Display
active_display ^= 1;
// Shift out screen bits
if(active_display == 0){
displayDigit(blueByte);
}
else{
displayDigit(redByte);
}
// Turn display back on
if(active_display == 0){
digitalWrite(BLUETRANS, LOW);
}
else{
digitalWrite(REDTRANS, LOW);
}
// Reload the timer
TCNT2 = tcnt2;
}
Resulta que estaba pasando por alto algunas de las partes más fundamentales de mi código. Ambas pantallas estaban encendidas en un momento dado, plagándome con este problema de fantasmas que no era en absoluto un problema de fantasmas.
Muchas gracias a justing, quien proporcionó posiblemente la mejor explicación que he visto sobre cómo configurar el temporizador en el Arduino. Mike DeSimone y Oli Glaser también ayudaron mucho en la resolución de problemas de mi circuito. ¡No puedo expresarles lo mucho que aprecio su ayuda!
Si bien mi problema real fue extremadamente básico, espero que todas las respuestas que se encuentran en esta página puedan ser de utilidad para alguien, ¡en algún lugar en el futuro!
Gracias de nuevo!