5 votos

El proyecto ATTiny se reinicia al conectar el teléfono

Proyecto

Todavía no tengo mucha experiencia con la electrónica y la programación de microcontroladores. Recientemente (por accidente) compré un par de microcontroladores ATTiny13A, suponiendo que podría programarlos con el IDE de Arduino.

Debido a la poca memoria de estas cosas, decidí hacer un proyecto sencillo: una luz de lectura que se apaga automáticamente. Y decidí utilizar AVR Studio (6.0) en lugar del IDE de Arduino.

El circuito es bastante sencillo, creo. Dos botones para añadir media hora de luz, y otro para apagar las luces inmediatamente. Todo se alimenta de una varilla de pared USB, que suministra alrededor de 5V (5,2, he medido).

He simplificado el led. De hecho son 2 leds (al principio pensaba en 3) y las resistencias correspondientes, por lo que también he añadido la resistencia. También he omitido las conexiones al programador AVR, ya que no son relevantes para el circuito en sí.

schematic

simular este circuito - Esquema creado con CircuitLab

La luz funciona como se supone que debe hacerlo. Arde durante 3 segundos cuando la conecto. Puedo encenderla y apagarla. Y cuando la enciendo, arde durante una media hora antes de apagarse sola. Si sé de antemano que quiero tener más de media hora de luz, puedo pulsar el botón varias veces, para obtener N veces media hora.

Hasta aquí todo bien.

Problema: reinicios no deseados

Ahora el problema es que parece ser bastante sensible a los picos o caídas. Tengo una varilla de pared con dos conexiones. Cuando la luz nocturna está conectada en una de ellas, y yo conecto mi teléfono en la otra, la luz nocturna se reinicia, encendiéndose durante tres segundos y luego se apaga. Esto también ocurre la mayoría de las veces cuando desenchufo el teléfono. No importa si la luz estaba encendida o apagada cuando lo hago.

Así que mi pregunta principal es, ¿Cómo puedo solucionar estos reinicios? ? También estoy abierto a otros consejos.

Voy a pegar el programa aquí para que sirva de referencia también. Creo que no es relevante, pero intenté usar interrupciones y tener el controlador en modo de reposo la mayor parte del tiempo, así que lo publicaré de todos modos, por si contiene información vital.

/*
 * NachtLampje.c
 *
 * Created: 22-10-2014 19:46:50
 *  Author: GolezTrol
 */ 

#define F_CPU 1200000UL // Sets up the default speed for delay.h 

#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/wdt.h>

volatile int seconds = 3;
int secondsInc = 1800;

void setupLed() {
    DDRB = 1<<DDB0;
}

void updateLed() {
    // Blink for a moment when we're at 15 seconds, so user might prolong.
    if (seconds > 0 && seconds != 15)
        PORTB |= 1<<PB0;
    else
        PORTB &= ~(1<<PB0);
}

void setTimer(int state) {
    if (state) {
        WDTCR |= (1<<WDP2) | (1<<WDP1); // 1sec
        WDTCR |= (1<<WDTIE); // Enable watchdog timer interrupts
    }       
    else {
        WDTCR &= ~(1<<WDTIE); // Disable watchdog timer interrupts
    }   
}

ISR(WDT_vect) {
    // Timer interrupt
    if (seconds == 0) 
      return;

    if (--seconds == 0) {
        setTimer(0);
    }   
    updateLed();
}

ISR(PCINT0_vect){
    // Button interrupt

    // Button 1 = PB3 = Add half an hour of light.
    if (~PINB & 0x08) {
        seconds += secondsInc;
    }

    // Button 2 = PB 4 = Turn off the lights
    if (~PINB & 0x10) {
        seconds = 0;
    }

    // Enable timer, if necessary
    setTimer(seconds > 0);

    // Update the led.
    updateLed();
}

int main(void) {
    setupLed();

    updateLed();

    setTimer(seconds > 0);

    GIMSK = 0b00100000;    // turns on pin change interrupts
    PCMSK = 0b00011000;    // turn on interrupts on pins PB3 and PB4

    sei(); // Enable global interrupts

    // Use the Power Down sleep mode
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);

    for (;;) {
        sleep_mode();   // go to sleep and wait for interrupt...
    }
}

1 votos

0 votos

No estoy seguro de que esté relacionado con el problema que reportas, pero en tu esquema falta una resistencia limitadora de corriente en la base del transistor en el pin 5 de la MCU. ¿Está ahí en el circuito y te lo perdiste al capturar el esquema?

6 votos

Observo la importante omisión de cualquier condensador de desacoplamiento en ese esquema. ¿Los has omitido a propósito, o realmente no tienes ninguno?

3voto

Simon Puntos 365

Lo más probable es que tengas una caída de tensión al conectar o desconectar el teléfono. Siempre debes añadir algo de capacitancia entre VCC y GND para que el circuito sea menos propenso a las caídas de tensión. Intenta añadir dos condensadores en paralelo: 10uF (electrolítico) y 100nF (de cerámica o lámina). Ten en cuenta la polaridad del electrolítico. Si esto no ayuda, intenta añadir más condensadores en paralelo.

Y, sí, el transistor debe tener al menos una resistencia de base de 10 ohmios.

Editar: Para los MCUs de Atmel, los valores correctos de los condensadores se pueden encontrar en la hoja de datos o en los diseños de referencia.

Pero: Quizá sean aún más importantes las parásitas (ESR, resistencia en serie equivalente). Asegúrate de colocar una tapa de baja ESR (cerámica) lo más cerca posible de los pines de alimentación del MCU. En general, cuanto más grande sea la tapa, más ESR tendrá. 100nF es un valor que se suele utilizar cerca de los pines de alimentación (nivel de chip), mientras que 10uF o 4,7uF se suelen utilizar para amortiguar partes enteras del circuito (nivel de subcircuito).

Para tu circuito es ciertamente suficiente añadir dos 100nF en paralelo a los pines de alimentación.

0 votos

Gracias por su respuesta. Se agradece. Su consejo es lo que entendí de los comentarios también. ¿Puedes decirme cómo puedo encontrar los valores adecuados para esos condensadores? El ensayo y error no parece ser una buena manera de obtenerlos. Además, ¿la elección de un valor incorrecto puede dañar mi circuito de alguna manera?

2voto

Dennis Puntos 6

Yo empezaría con un cap de cerámica de 100nF lo más cerca posible de los pines Vcc y GND. Esta es una recomendación general para Atmel uC para hacer frente a pequeñas caídas de tensión y picos.

Como segundo paso, añade ese electrolítico en algún lugar de la línea de alimentación (no tiene que estar muy cerca del chip). Puedes empezar con algo en el rango de 10-100uF y elegir uno apropiado para la calidad de tu fuente de alimentación de pared. Esto es puramente experimental.

En general, cuanto más grande sea el tapón que añadas, más resistente será tu circuito a las pérdidas de potencia, pero más largo será el tiempo de desconexión cuando saques el enchufe.

Sugerencia: Los tapones de 100uF, 47uF y otros similares se pueden recuperar gratuitamente de las placas base de los PC, los televisores y otros aparatos electrónicos de sobremesa.

0voto

Mike Henry Puntos 111

Por favor, lea los circuitos POR (Power On Reset) para las CPUs basadas en Atmel, página 6

http://www.atmel.com/Images/Atmel-2521-AVR-Hardware-Design-Considerations_ApplicationNote_AVR042.pdf

Para proteger la línea de RESET de más ruido, conecte un condensador desde la patilla de RESET a tierra. Esto no es directamente necesario ya que el regulador dispone internamente de un filtro de paso bajo para eliminar los picos y ruidos que podrían causar el reinicio. El uso de un condensador extra es una protección adicional. Sin embargo, este condensador extra no puede ser utilizado cuando se usa DebugWIRE o PDI.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X