Interruptor infrarrojo

Hace tiempo que tengo una silla con LEDs que funciona con una batería externa. Esta opera a 5V, consumiendo entre 1 y 2 amperios. La compra venia recomendada de una batería externa de 10,000mAh, dando aproximadamente unas 6h de uso.
El problema es que cuando la silla está apagada consume 190mA. Esto significa que la batería completamente cargada tardaría unos 2 días en descargarse sin hacer absolutamente nada (y creo que eso es mejorable).

Mi idea es usar un Arduino, sensor de IR y un transistor para que solo cuando encienda la silla el Arduino deje pasar corriente (mediante el transistor).

Considerando que quiero usar el mínimo consumo posible he pensado en usar un Arduino Nano dormido y despertarlo cuando detecte señal del IR. Nunca he trabajado con interrupciones (para despertar un microcontrolador) ni con los modos de dormido. He leído que el power-down es el que menos consume pero no se si me sirve (¿recomendaciones?).
Para el transistor he pensado usar este circuito, que por lo que dicen soporta 2A a 5V.

¿Creéis que merece la pena tirar adelante con el proyecto? Remarco el factor que si al final consumo más de 190mA no consigo nada (si puede consumir uA mientras no uso IR mejor).

¡Claro que puede valer la pena!

Justamente hace unos días estuve haciendo pruebas al respecto, más abajo amplío.

Primero un comentario sobre la placa: te va a convenir eliminar el LED "power" de la placa para reducir el consumo a lo mínimo, sino te va a consumir unos 6 mA.
En el Nano, fácilmente puedes cortar la pista entre el LED y su resistencia asociada, entra justo la hoja de una trincheta o cutter, según como la llames (y si algún día lo quieres restaurar, con una gota de estaño quedaría como nuevo). También puedes desoldarlo, va en gustos y práctica.
Sería esta:

En lo que estuve trabajando fue en una placa que pondré en mi auto pero que tiene que estar siempre alimentada, por ello la necesidad de bajar el consumo durmiendo al Nano.
La idea es despertarlo de dos formas, por la pulsación de un botón del volante (trabajará un tiempo y lo vuelvo a "dormir") o detectando cuando el auto está en contacto (trabaja normalmente).

La forma de despertarlo es mediante una interrupcion hardware en el pin 2, asociado a INT0, conectado a la llave de encendido del auto y para dormirlo testeo el estado del mismo pin.
O sea, en este caso, mientras el pin esté en HIGH (está en contacto), se ejecuta el código normalmente. Cuando el pin está en LOW (apagué el auto) entra en modo power_down hasta que el pin vuelva a estar HIGH (lo que generará la interrupción que lo "despierta" y es la parte que te puede servir) o hasta que pulse el botón.

Como le desconecto el LED PWR, uso el LED del pin 13 (LED_BUILTIN) como indicador de encendido (puedes no usarlo para ganar unos 5 mA)

Te dejo el código que estoy usando, lo "limpié" lo más posible para que lo puedas adaptar a tu proyecto, si te sirve.
Vas a ver que defino una variable keypwr_flag, yo la necesito porque como dije antes lo despierto tambien por medio de un botón (que usa el pin 3 asociado a INT1), entonces necesito discriminar qué lo despertó. La dejé por si te es útil pero puedes eliminarla tranquilamente.
Así mismo yo leo el estado del contacto del auto, en tu caso leerías el sensor, tal vez necesites adaptar el nivel de disparo (o sea, lo que en mi caso es HIGH en el tuyo puede ser LOW según lo que envíe tu sensor).

#include <avr/sleep.h>

const byte PIN_KEYPWR = 2;
const byte PIN_RELAY = 9;
volatile bool keypwr_flag = false;

// *****
// el resto de tus definiciones acá
// *****

// Servicio de Interrupcion 0
void keyPwr_ISR() { // INT0
  sleep_disable();
  detachInterrupt(digitalPinToInterrupt(PIN_KEYPWR));
  keypwr_flag = true;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  pinMode(PIN_RELAY, OUTPUT);
  digitalWrite(PIN_RELAY, HIGH);

// *****
// el resto de tu setup
// va aca
// *****

// *** solo para debug ***
  Serial.begin(9600);
// ***
}

void loop() {
  static bool keypower = false; 
  keypower = digitalRead(PIN_KEYPWR);  // Lee estado llave
  if(keypower) {
// *****
// todo lo que tenga que hacer "despierto"
// va aca
// *****
  }
  else { // entrar en sleep
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(PIN_RELAY, LOW);
// preparar sleep
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    noInterrupts();
    EIFR = bit(INTF0); // IMPORTANTE! limpia interrupcion pendiente (si hubiera)
    attachInterrupt(digitalPinToInterrupt(PIN_KEYPWR), keyPwr_ISR, CHANGE);
    sleep_enable();    
    interrupts();

// *** solo para debug ***
    Serial.println("A dormir!...");
    Serial.flush();
// ***

    sleep_cpu(); // *** dormir! ***

// sale de sleep
    digitalWrite(LED_BUILTIN, HIGH);
    digitalWrite(PIN_RELAY, HIGH); 
    detachInterrupt(digitalPinToInterrupt(PIN_MODEBTN));

// *** solo para debug ***
    Serial.print("Despierto!...");
    Serial.flush();
// ***

    keypwr_flag = false;
  }  
}

PIN_RELAY es la salida al MOSFET (todavía no me había decidido a usar relé o transistor cuando escribí el código :wink: )

Edito: Disparo la interrupción por cambio de estado (CHANGE) porque estoy seguro que siempre será por un HIGH (ya que lo duermo cuando es LOW), fijate si tienes que cambiar el modo de disparo en tu proyecto. Es importante (te lo indiqué en el código) limpiar el flag de interrupción antes de hacer attachInterrupt (se me disparaba 2 veces si no lo hacía, sin importar el modo de disparo que usase; encontré la explicación y la solución en el foro de Nick Gammon).

Espero te sirva.
Saludos

Moderador:
Hola, bienvenido al foro Arduino.
En la sección proyectos tienes estos dos hilos que debiste haber leído antes de postear

Como tu consulta es para otra sección lo muevo a Hardware.
El primer enlace no funciona, revísalo por favor.
El segundo enlace estaba bien pero cuando se trata de imágenes es mas fácil agregar el enlace usando la etiqueta de imagen para que el post sea mas descriptivo. Por eso lo edité en ese punto.
Normas del foro

Muchas gracias por el comentario, seguro que podré apañármelas con eso.
Hace unos días estuve mirando el tema de despertar en interrupciones y mencionaban un problema: si la interrupción ocurre antes del 'sleep_cpu' el microcontrolador permanecía durmiendo para siempre. Es una pena que haya perdido la página donde lo vi, ¿sabes si tu código tiene el mismo problema?

Edit: he encontrado la página. Para solucionarlo usaban el sleep_enable() y sleep_disable(), que ya estas usando.

Está probadísimo, anda sin problemas.
Saludos