Despertar Arduino con interrupción por el Serial

Hi folks,

tengo una duda, que no se si es una chaladura lo que estoy diciendo o no. A ver si @Brico_Dani, @AMR, @MiguelAngelLV, @JJ_T o cualquier otr@ puede esclarecermela.

Tengo un Arduino Mega conectado por el Serial1 con una RPi en remoto. El Arduino solo se va a usar cuando la RPi le mande alguna orden, por lo demás está inactivo. Ahora mismo está en el loop con la típica función

While( Serial1.available ) {
            ...

El caso es que lleva un par de semanas rulando y me da la sensación de que el Arduino se queda más payá que pacá (no responde el mamoncete) o puede ser el conversor Serial-TTL que haya murido. Sea como sea, había pensado que no quiero el Arduino haciendo a piñon el loop todo el rato.

Estaba pensando en dormir el Arduino y que se despertase cuando le llegara algo por el Serial1. Usar algo de este estilo (gracias a BooleanBite):

#include <avr/sleep.h>

void setup() {
   Serial1.begin(9600);
   // Serial1 (RX - Pin 19) - (TX - Pin 18)
   attachInterrupt(19, serialInterrupt, CHANGE);
   //Establecemos el modo de bajo consumo
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}

void loop() {
    // Inicializamos el modo bajo consumo
    sleep_enable(); 
    // Ponemos el modo bajo consumo
    sleep_mode();   
}

// Variable para saber si se está procesando la interrupción
volatile boolean inService = false;

void serialInterrupt() {
    // Si se está procesando la interrupción, no hacer nada
    if (inService) return;

    // No se está procesando
    inService = true;
 
    // Habilitar interrupción de nuevo para permitir trabajar al Serial
    interrupts();
 
    // Esperar a que esté activo el Serial
    while(!Serial1.available());

    // Leer datos del Serial
    while(Serial1.available()){
        ...
    }
    // Lectura acabada
    inService = false;
}

Pero no se si esto es un buen uso o no.

Se que Arduino tiene una interrupción para el Serial, llamada SerialEvent (yo usaría el serialEvent1() ). Pero creo que no funciona si duermo al Arduino (aquí dejo el ejemplo del SerialEvent).

1 me gusta

[…]

Tengo un Arduino Mega conectado por el Serial1 con una RPi en remoto. El
Arduino solo se va a usar cuando la RPi le mande alguna orden, por lo
demás está inactivo. Ahora mismo está en el loop con la típica función

[…]

Estaba pensando en dormir el Arduino y que se despertase cuando le
llegara algo por el Serial1. Usar algo de este estilo (gracias a
BooleanBite):

Utilizar las interrupciones para activar algo es precisamente una de las
cosas para las que se pensaron en los microcontroladores.

Cualquier simple búsqueda por la red te habría valido:

https://searx.me/?q=wake%20up%20arduino%20serial%20interrupt&categories=general

Los dos primeros resultados tienen buena pinta.

Salud y Revolución.

Lobo.

Biba VooleanVite!!

Quizas necesites poner otro modo de Bajo Consumo; en el ejemplo lo estas poniendo set_sleep_mode(SLEEP_MODE_PWR_DOWN); en modo SLEEP_MODE_PWR_DOWN pero este modo apaga también el puerto serial por lo que no podrías activarlo por puerto serie. Hay más modos de Bajo Consumo.

En el articulo que supongo habras mirado; hay una tabla con los modos de bajo consumo. Tendría que investigar más… pero creo que con PWR_SAVE podría funcionarte; en la documentación de ATMEL seguramente podrías verlo con más detenimiento.

En esta web de Arduino (sacada gracias a las busquedas de @Razlobo :wink: ) indican que para interrupciones por Serial con Arduino dormido el modo bueno seria POWER_MODE_IDLE

1 me gusta

Entonces todo perfecto

Hola tio.
Solo una cosa. Un micro no debe sufrir “patatús” y quedarse frito ejecutando su bucle, y ,aunque poner en otros modos de consumo es buena idea si no se esta utilizando el micro a tope, quizás no solucione tu problema.
Yo, ademas de poner el modo de consumo que te permita despertar por UART, activaría también el watchdog e iría refrescándolo (lo ideal con una interrupción de un timer (asegurandote que están activas en el modo de consumo que elijas)). De esta forma tienes el micro dormidico y si se queda tostado pues reset al canto.

1 me gusta