Gadget para desconectar un ascensor

Muy buenas,

Estoy haciendo un proyecto que tiene que desconectar un ascensor a una determinada hora y dias y que lleva un menu para poder configurar la hora, los dias a desconectar, etc.

Conectare un RTC a arduino para saber la hora y el dia y segun hora y el dia conectare/desconectare el ascensor.

Lo que tiene que hacer arduino es lo siguiente:

Muestro hora y fecha
Leo Hora
Leo Dia
Si dia y hora laborables entonces //Hora desde 7.30 hasta 17.50
Desactivo Stop
Desactivo Led
Sino si hora es igual o mas grande a 17.50 y dias es laborable entonces //Empiezo proceso de desconexion
Espero puertas cerrar
Llamo planta 4
Espero ascensor llegue
Activo Stop
Activo Led
Sino //dias de fiesta o horas no laborables. Realmente este caso no se necesita porque de serie el rele de stop y el led estan activados
Activo rele Stop
Activo led

Hasta aqui todo bien. Luego pense en diseñar un menu para poder configurar la hora, fecha y dias de fiesta.

Ahora es cuando llega el problema. Yo necesito que el proceso principal (de ahora en adelante el proceso de desconexion) se ejecute siempre, pero si estoy dentro del menu y estoy esperando una entrada valida el programa se me queda parado y el proceso de desconexion no se ejecuta hasta que no se salga del bucle que espera.

Entonces empezé a buscar y vi que habia el multitasking, las interrupciones, etc. He pensado unas cuantas opciones para poder solucionar esto y lo que me gustaria es que les echarais un ojo y me dijerais que opinais (si me dais nuevos puntos de vista mejor que mejor)

Aqui pongo las opciones que se me han ocurrido (he tenido en cuenta que cuando el proceso de desconexion esta llegando a su hora no se pueda acceder al menu)

Soluciones a interferencia entre de los procesos desconexion y menu

OPCION 01: A 10 o 20 min desconexión no poder entrar en menú. Si se entra en los bucles de espera de datos a los 2 minutos se saldra automaticamente. Problema --> si voy viajando entre menús menos de dos min por cada uno puedo pasarme de la hora de desconexión

OPCION 02: Debería ser que si a las 17.50 no se ha podido iniciar lo intente cada 10 min. Tiene que haber una variable que guarde si la desconexión/conexión se ha realizado. Con esto juntamente que no se puede estar esperando una entrada mas de dos min me aseguro que el proceso de desconexión se ejecute siempre

OPCION 03: Interrupciones: creo que si la interrupción se encarga de la desconexión, mirando cada x tiempo la hora y si llega la hora se ejecuta el p desconexión. El p menú estaria en el principal. Pero esto no se como hacerlo

OPCION 04: En el bucle principal pongo condición de entrar en menú que se apriete la tecla asterisco y que no sean 10 o 20 min antes de la hora de conex/descon. En los bucles de espera de datos hago lo mismo. Si son 10 o 20 min antes se sale del bucle. Haciendo que se cierren los procesos hasta llegar al principal que entonces ira directamente al proceso desconexion

OPCION 05: En cada bucle que espere entrada de tecla se llama al proceso desconexion. Con esto me aseguro que aunque este en espera a que el usuario introduzca un dato el proceso de desconexion se lleva a cabo. Hay que tener en cuenta de que el proceso de desconexión sea autónomo (no haga falta que se le envien variables), porque sino se convierte en un lio tener que llevar las variables hasta el bucle de espera para pasárselas al proceso desconexion.

Bueno he intentado exponerlo lo más claro posible y espero que se entienda. También quiero daros las gracias por el tiempo que le dediqueis y un saludo :smiley:

Has llegado al punto que todos llegamos alguna vez ¿cómo demonios hago que el micro ejecute dos cosas a la vez?
Merecería un apartado esencial en todas las introducciones a microcontroladores.

La idea es que tienes un bucle principal de "baja prioridad" corriendo para gestionar por ej el menú.
Por otro lado tienes un conjunto de interrupciones que "interrumpen" el flujo de ese bucle para atender de forma inmediata sucesos de alta prioridad, una vez procesados, retornan al bucle principal donde lo dejaban.

es decir, mirate el ejemplo blinkwithoutdelay jeje

Muchas gracias a los dos por contestar.

Como bien dices, jray, he llegado (en un proyecto que pensaba que seria sencillito) a un apartado de nivel elevado de los micros. Me he estado mirando las interrupciones, los RTOS y la programacion cooperativa (creo que se llama así).

Estoy barajando la posibilidad de solucionar el problema de dos maneras:

Con las interrupciones, y asi aprendo sobre este tema

Controlando el tiempo de espera de entrada de datos, limitandolo a dos minutos. Entonces si son las 17.50 (que es la hora en que se tiene que iniciar el proceso de desconexion) y estoy en el menú, a los dos minutos se cerraran los bucles de esperera de datos finalizando asi el proceso del menu. Entonces el proceso de desconexion se activa si ha pasado de las 17.50. Que aunque no se active justo a las 17.50 no pasa nada. Puede ser a las 18 o a las 19. Lo critico es que se active.

Sergegsx me miro el ejemplo este qu eme comentas

Muchas graicas

Un saludo :smiley:

Yo iría a por la programación cooperativa.
Teóricamente con este método o con cualquier RTOS se crea aplicaciones con mas confiables si haces un buen estudio completo de tus funciones y los requerimientos en términos de tiempo puedes tener ticks de ?-segundos.

En esta web Telmtron tienes un ejemplo para AVR y Arduino.

Muchas gracias yOPERO, me lo miro :smiley:

erikcrane:
Ahora es cuando llega el problema. Yo necesito que el proceso principal (de ahora en adelante el proceso de desconexion) se ejecute siempre, pero si estoy dentro del menu y estoy esperando una entrada valida el programa se me queda parado y el proceso de desconexion no se ejecuta hasta que no se salga del bucle que espera.

Entonces empezé a buscar y vi que habia el multitasking, las interrupciones, etc. He pensado unas cuantas opciones para poder solucionar esto y lo que me gustaria es que les echarais un ojo y me dijerais que opinais (si me dais nuevos puntos de vista mejor que mejor)

Yo opino que os complicais en tonterias...

Como siempre, ataca el problema de la zona mas baja, tu problema es:
-"que si espera una entrada valida en el menu se queda parado" pues no esperes!

Emplea las interrupciones para detectar pulsaciones o haz un barrido cada 200ms para detectar si al estar dentro del menu ha pulsado alguna tecla. A ti te da igual que desde que pulsa la tecla pase 250ms hasta que tu lo detectes, que mas da si al final el interface humano y su interaccion es lo que mas maniobra y posibilidades te deja...

Como si tiene que esperar 1 segundo desde que pulsa la tecla a ser detectada... tu mientras ocupa el arduino en lo importante.

Con un simple circuito RC mantienes la pulsacion (la entrada a 1) aunque suelte la tecla, pero ya te digo, emplea interrupcion para eso y miesntras ves ejecutando el programa que te interesa, dedica solo x milisegundos a realizar el resto, a nivel percepcion de la persona que lo usa ni se entera.

No se si he dejado claro por donde tirar...

Tambien queda otra que parece se nos olvida cuando hablamos de varias tareas a la vez y demas...

Emplea dos micros, que un puñetero atmega 328 te cuesta menos de 3 euros, asi puedes emplear uno para una cosa y otro para otra, mas simple imposible.

¿porque la limitacion a no tener recursos, quedarte sin memoria, quedarte sin pines por menos de 3 euros que te cuesta otro micro?

Que hablamos de unidad por ascensor, no de miles de unidades...

Asi fabricas un Dual-Core XD

Heke, realmente no entiendo mucho a que te refieres. Creo que dices que haga barridos cada x milisegundos para detectar si pulsan una tecla. Sino se pulsa el proceso desconexion se sigue ejecutando y cuando se realiza la pulsación se actua en consecuencia.

No enteiendo que es un circuito RC y para que necesito mantener la pulsación:

Heke:
Con un simple circuito RC mantienes la pulsacion (la entrada a 1) aunque suelte la tecla, pero ya te digo, emplea interrupcion para eso y miesntras ves ejecutando el programa que te interesa, dedica solo x milisegundos a realizar el resto, a nivel percepcion de la persona que lo usa ni se entera.

Lo de utilizar dos atmega lo habia pensado, pero acabo de empezar con todo esto y plantearme colocar un atmega haria que el proyecto tardase aun mucho mas en acabar, pero estoy de acuerdo en que por menos de 3 euros tienes otro procesador con su memoria y es una buena solución.
Pero también creo que lo que intento hacer tampoco es tan complicado para requerir de otro procesador, pero claro eso solo es lo que creo.

Agradezco mucho tu post :smiley:

Hola,
no sé qué interfaz utilizas para configurar. Tomando como ejemplo el keypad (4x3) del Playground, yo lo enfocaría así

void loop()
{
   activar_desactivar();
   configurar();
}

Para configurar, pondría un carácter de inicio de configuración ('#'), y un carácter de final de configuración (''), de suerte que si llega un '#' entra en la rutina de configuración, y no sale de las misma hasta que llegue el ''

int configurar()
{
char key = keypad.getKey();

if (key = '#')
{
// se inician rutinas de configurar: for(;;){}
// leer todo lo que llega, configurar
// hasta que llegue el carácter ''
if(key == '
')
return 1;
}
else
return 0;
}

¿Cuánto puede tardar la configuración? Uno, dos, tres minutos? En el peor de los casos, se realizaría el activado/desactivado con tres minutos de retraso. ¿Sería crítico eso?
En la función de configuración podrías añadir una comprobación de hora, y poner un mensaje de aviso "para de configurar, que llega la hora!"

Hola,

En mi opinión, el consejo que te han dado de leer el ejemplo de blinking without delay y tratar de entenderlo, creo que buena dirección. Es la base para poder entender todo lo demás.

Al final, el control a "tiempo real" es algo relativo, ya que depende de la dinámica (inercia) de tu sistema a controlar. Si vas a controlar la temperatura de una habitación pueden pasar minutos hasta que tu control actue y no es un problema. Pero si vas a un proceso químico, pueden ser milisegundos.

Lo que te están intentando explicar, es que si tu código es suficientemente rápido como para atender a cada una de las tareas, estarás cumpliendo tus requisitos. Ten en cuenta que una pulsación de un botón dura en orden de ms, es decir, tu micro es capaz de leer el estado de esa entrada, pero también de seguir ejecutando muchas otras cosas más. A parte que siempre puedes "alargar" dichas pulsaciones como te han explicado usando hardware adicional.
Por poner un ejemplo, si una pulsación a una tecla, son XX ms, a un micro le da tiempo a hacer muchas cosas y todavía el usuario sigue con el dedo en el pulsador.

Ahora bien, para poder hacer ésto hay diferentes formas de resolverlo. Aunque usando interrupciones puede darte muchos dolores de cabeza ya que si no tienes cuidado, puedes perder el control de tu aplicación.
Si te fijas como has descrito tu aplicación, es una secuencia. Si hay cierto evento, hago una determinada acción. Hacerte un diagrama de flujo de tu aplicación, creo que te ayudará a "visualizar" tu problema. Yo usaría una máquina de estados como método de programación. Dichos eventos que has comentado (pulsación de teclas, que sea determinada hora/fecha, etc) serán los que determinen el flujo de tu programa.

Lo que quiero decir, que si tu código hace un ciclo completo (leer entradas -> realizar código -> actualizar salidas -> volver a empezar) en menos tiempo que el tiempo necesario para atender a tu tarea más rápida, no tendrás ningún problema.
Los delay() son tus peores enemigos y ninguna función que realices tiene que tener código bloqueante. Por ejemplo, quedarse esperando con código que bloquea a que el usuario pulse un botón, o que se reciba cierto caracter por al puerto serie, o enviar por puerto serie y quedarse esperando a que se envie toda la cadena (esto lo hacían antes las funciones de Arduino, pero lo han modificado desde la versión 1.0), etc.

Saludos,

Igor R.

Curro92, esto que me comentas es una opción que he tenido en cuenta. Si hago que el tiempo de espera a que el usuario es un tiempo limitado (para controlar que no se quede esperando un dato indefinidamente), cuando acabe de configurar tengo que hacer que se inicie el proceso de desconexion, siempre y cuando se haya llegado a la hora de ejecución. Pero si la hora de desconexion son las 17.50, realmente a mi no me importa que se inicie el proceso a las 18.30 (por decir una hora), siempre y cuando se inicie.

El asunto aqui es que esta solución (que es valida) no me permite aprender cosas más complicadas como los RTOS, interrupciones, etc. Siempre que hago un proyecto intento hacerlo de una manera para que pueda aprender cosas nuevas.

Igor R, he leido tus posts sobre interrupciones y multitarea. Lei uno (creo que lo escribistes en 2009) sobre como encender dos leds a diferentes frecuencias utilizando la funcion millis() y lo encontre muy muy interesante. He visto que esta función es muy potente y como bien dices me he dado cuenta que el delay() es una función que a primera vista parece muy práctica pero no la veo muy elegante para programar.

Voy a leerme con atención todo lo que me habeis comentado y intentar entenderlo todo. Y ralmente me gustaria poder programar este "gadget" de la forma más eficiente posible (dentro de unas limitaciones, claro)

Muchas gracias a todos por ir contestado :smiley:

Un saludo

Yo he diseñado un controlador que tiene una interface de usuario con una pantalla gráfica + botonera, la cual el usuario puede configurar diferentes setpoints, test, visualizar alarma, elegir de una BBDD módelos del aparato al que se le está haciendo el test, ...mientras el usuario navega por los menus, por detrás se siguen haciendo las cosas sin parar. Por eso te digo que lo que cuentas, se puede hacer sin ningun problema. En realidad hace muchas más cosas, como puede ser control de slew rates cuando cambias el target para no hacer cambios bruscos, tonos de alarma, la salida son mensajes CAN, control del disparo de una luz estroboscópica, y un largo etc (todas las tareas se realizan sin pararse cuando el usuario está navegando por el menu).

La forma que lo hice es creando una máquina de estados sencilla basada en tabla de transiciones (me cree mi propia librería para ello) la cual compartí en SECUduino/FSM Library at master · IgorReal/SECUduino · GitHub ó http://arduino.cc/forum/index.php/topic,75826.0.html
Puedes buscar más info en google : "event driven state machine".

Pero como te digo, hay muchas formas de resolver el mismo problema. Yo te cuento mi experiencia, y las ventajas que encuentro son:

  • La sencillez: no usas sistemas de otros que sean dificiles de entender y/o requieren más tiempo estudiartelos que la aplicación en sí que tienes que realizar. Por no decir la dificultad que puede tener cambiar algo.
  • Depurar es muy sencillo, por ejemplo, tengo una modificación a esa librería original para que me saque por puerto serie en el estado en el que me encuentro y el evento recibido.
  • Puedes guardar en la memoria no volatil el estado en el que te encuentras por si se va la corriente. Es muy fácil tener el control de tu aplicación de nuevo después de un "apagón".
  • Toda la lógica es una tabla de transición guardada en memoria de programa.
  • Flexibilidad: cambiar el flujo de tu programa, es simplemente cambiar dicha tabla de transiciones.
  • Leer el código aunque haya pasado mucho tiempo, es sencillo, ya que se resume en leerte la tabla de transición y luego ver lo que hace la función de cada estado.
  • Aunque la limitación es que hay que tener en cuenta que es similar a un sistema cooperativo, la función realizada en cada estado tiene que durar menos que el tiempo de refresco que necesite la tarea más rápida. Para que de tiempo a leer eventos externos -> actualizar estados -> realizar las funciones de dichos estados y volver a empezar. Aunque el flujo de tu programa no va controlado por tiempo, si no por eventos.

Saludos,

Igor R.

Muy buenas,

Igor R, como me has aconsejado estoy mirándome las maquinas de estado finito. Por lo que he visto es una solución perfecta para muchos proyectos desarrollados con microcontroladores y por lo que me dijiste para el mio también. Además me gusta porque así para hacer futuros proyectos de mayor embergadura me ira de perlas.

Por cierto buscando sobre las maquinas de estado finito me he encontrado con un término un tanto curioso, código espaguetti. Al parecer es el tipo de código que siempre he usado, plantear un problema y programar a "pelo" para ir solucionandolo. El término espaguetti se debe a algo? es que me ha parecido curioso que le llamen así y no entiendo el motivo.

Igor R estoy buscando sobre FSM y event driver machine, y cuando pongo en el google event driven machine me salen todo de resultados de QP. Por lo que he visto es un software para crear máquinas de estado para el arduino y por la de resultados que salen veo que es bastante famoso. Tu lo conoces? tienes alguna opinión sobre este software?

Tambien te queria pedir si sabes de alguna web, video, pdf, lo que sea, que expliquen como realizar de inicio a fin un proyecto en arduino con fsm, a modo de ejemplo. Es que me he estado mirando la teoria de las fsm pero no se como llevarlo al mundo arduino.

Si me puedes dirigir en la buena dirección te lo agradezco mucho

un saludo :smiley:

No he trabajado con QP. Tengo un libro por aquí de su autor que explica todas las tripas (es en C++). El problema es que necesitas tiempo para estudiartelo, ya que es como si programases en otro lenguaje de programación, con sus reglas, etc. Lo mismo que si usas un RTOS... y no tengo tiempo!! :wink:

Ya depende de lo que quieras hacer, valorar si te merece la pena usarlo...

Existen muchos ejemplos por la red. En el link que te he puesto del foro, hice 3 ejemplos usando mi librería y hay un pdf también.
Luego también puedes encontrar uno básico, es este otro que escribí de un miniprotocolo serie Tinkering with Electronics...: LINKDUINO: Linksys + Arduino + Excel-Telnet
Ten en cuenta, que hay muchas maneras de hacer tu máquina de estados. Empieza por hacerte una básica con estructuras if().
Este ejemplo no contempla que le lleguen otros caracteres entre medio, etc. Lo que hace es encender el led de la placa si le llegan el comando S1F y apagarlo si le llega S0F

//Mini protocolo serie
//Igor Real

int luz1= 13;
int el1;
int estado=0;
byte dato_recibido;

void setup() {
   pinMode(luz1, OUTPUT);
   pinMode(12, OUTPUT);
   digitalWrite(12,LOW);
   Serial.begin(9600);
}

void loop()
{
  //trama a recibir --> S1F o S0F
  //S inicio
  //1 ENCENDIDO Y 0 APAGADO
  //F fin
  while (Serial.available() > 0)
  {
    //Significa que has recibido algo y lees el primer byte
    dato_recibido=Serial.read();
    if (dato_recibido=='S' && estado==0){
      estado=1;
    }
    if (((dato_recibido=='1')||(dato_recibido=='0')) && estado==1){
      estado=2;
      if (dato_recibido=='1')  el1=1;
      if (dato_recibido=='0')  el1=0;
    }
    if (dato_recibido=='F' && estado==2){
      estado=0;
      digitalWrite(luz1,el1);
      if (el1==0)  Serial.println("APAGADO");
      if (el1==1)  Serial.println("ENCENDIDO");
    }
    
  }
}

Lo tienes que pensar así:

  • Si estoy en el estado 0 y recibo una S => voy al estado 2
  • Si estoy en el estado 2 y recibo un 1 u 0 => asigno el valor a mi variable y voy al estado 3
    ....

Luego de ahí puedes pasar a otro tipo de máquinas que están creadas con tabla de transiciones; ó hacerte que cada estado tenga condición de entrada, salida y mientras está activado; ó que se puedan realizar acciones en las transiciones, etc.... cuanto más lo compliques, te estarás creando una especie de "lenguaje de programación" nuevo, para que se me entienda, ya que tendrás que aplicar reglas a tu código para que te funcione adecuadamente.

Pensarlo para tu display+botonera, pues lo mismo... Piensa que cada estado muestras la pantalla al usuario, entonces te vas dibujando el diagrama de flujo:

  • si estoy en el menu principal, y el usuario aprieta el botón "derecho", paso al segundo menu, etc.
  • si estando en el segundo menu, deja apretado por más de 3 segundos el botón de aceptar, entonces hago ....

Esto hará que si tienes algun día que meter un menú nuevo entre medio (por poner un ejemplo), no tengas que cambiar todo tu código ó te vuelvas loco. Por ejemplo, algo típico cuando empiezas, es hacerte una variable según tus pulsaciones/submenus vas haciendo +/-1, +/-10, +/-100... según en el nivel de menu en el que te encuentras. Entonces llamás a funciones según el valor de esa variable (por ejemplo usando un select case).
Lo haces, estás todo contento, y se te ocurre que ahora entre medio de tus menús, quieres meter uno más...ohhh no!!! entonces es cuando te das cuenta que programar así es bastante ineficiente... (en mi opinión). Por no decir leer el código cuando ha pasado mucho tiempo y no te acuerdas de lo que hiciste....

Espero que te sirva,

Saludos,

Igor R.

Nota.- Lo he puesto muchas veces por el foro, pero por una más...uno de los mejores libros de microcontroladores y gratis! No es para atmel, pero es en C, así que no hay mucho problema... http://www.tte-systems.com/books/pttes

En la misma linea de lo que enseñan en el libro de TTE Systems mencionado por IgorR,
El siguiente articulo (ingles) presenta un microkernel para sistemas embebidos también en "C"

Tiene buena pinta ese artículo, yOPERO!! :wink:

Lo único que yo aconsejaría ir empezando poco a poco para "entender" los problemas y saber "identificar" tus necesidades.
Necesitas pelearte con interrupciones primero, para poder entender que puedes estar en tu rutina de mostrar algo por pantalla, y que de repente entres a tu interrupción y empieces a tener problemas....
O que eliges leer tus botones por interrupción, y un día falla la conexión (eléctricamente) siendo intermitente y estás entrando todo el rato a dicha rutina, no dejando ejecutarse el código principal si no has previsto este modo de fallo en tu código.
O entender el problema de manipular variables no atómicas => Arduino Forum
etc.

Luego así aprendes a evitar usarlas o tener mucho cuidadín...je,je,je

]:smiley:

Muy buenas,

Me he estado mirando el tema de las máquinas de estado y lo que he "sacado" es el archivo adjunto. no se si lo que he hecho es una maquina de estados, o me lo he inventado :P.

Para programarla lo estoy haciendo con switch (que no se si es correcto o no)

Agradeceria que me dijerais si estoy por bueno camino o no he entendido nada de lo que me habeis dicho.

Muchas gracias por la ayuda y un saludo

Lo he mirado rápido, pero tiene pinta que no hace lo que originalmente querías, no??

Si estás en el menu (y/o siguientes estados) no hay transición para que si es la hora XXhXX,dia D,etc haga tus acciones de desactivar,etc.
Es decir, se te quedaría bloqueado en dicho estado de muestra menu,etc sin poder desactivar o hacer lo que tienes en otras ramas.

Yo diría que te faltan transiciones en ese flujograma....no crees?

Un consejo, puedes crearte nombre de eventos cortos, para poner en tus transiciones y luego en un lateral describes lo que hace cada uno. Es más fácil de seguirlo, dibujar el diagrama y queda más limpio.
Por ejemplo: ev_pulsacion1, ev_pulsacion2, ev_alarm1,.... (ev=evento).
Y describes la lógica de cada evento en otro sitio que no sea sobre las transiciones:
ev_pulsacion1= pulsación de la tecla 1 (entrada digital 7)
ev_alarma1= Hora 7h30 && laborable && Stop
etc.

Es más, si lo programas así.... luego puedes sustituir lo que genera tu evento muy fácil!!! Yo lo hago así en mi programación, y esto me permite, por ejemplo, que mi evento pulsación tecla confirmar (ev_confirmar), pueda venir de una tecla o de un comando serie.
Para que me entiendas por dónde voy... de forma sencillísima, hago que mi programa se controle por comandos serie, por entradas digitales, o por ambos!!
Es un ejemplo, pero es para que entiendas la ventaja de pensarlo/programarlo así, que luego tus eventos son fáciles de cambiar las condiciones que lo generan, y si te has preparado el código, pues te resulta inmediato hacerlo.

Lo digo para que no hagas tu programación repetitiva con IF (RTC.hora...&& digitalread(x) { bla,bla}
Si no que leas todas tus entradas que generen eventos (RTC, entradas analógicas/digitales, serie,etc) y generes el evento/s que corresponda.
Luego en tu código sólo tienes, si estoy en (estado==5 && ev_alarma1), hago tal y cual.... Y tu ev_alarma=(RTC.hora== && digitalRead...etc.).
A parte que el mismo evento, puede ser utilizado en varias transiciones y no tienes que repetir código.
Espero que me entiedas por donde voy...

:wink:

Primero de todo muchas gracias por tus consejos. Entiendo por donde vas y ya estaba pensando en que el codigo que estoy escribiendo es muy chapucero (basicamente vos escribiendo codigo segun las necesidades) y mi idea era reescribirlo para que no fuera tan chapucero. Con esto que me dices quedará mejor y mas entendible. Gracias de nuevo XD

En lo referente al dibujo, está mal. Con lo que me has dicho me he puesto a revisar el dibujo con el codigo y he visto que he representado mal graficamente el codigo que tengo escrito.

En el loop tengo dos switchs. Un switch es el que se encarga de mirar la hora y el dia, y dependiendo de estos dos valores hace una u otra acción. Y el otro siwtch es el del menu, que segun la tecla apretada vas a una opcion u otra.

En el primer caso (el case 0 en mi codigo) del switch (que es cuando mira la hora y el dia) tambien se controla si se aprieta la tecla # (que es la que sirve para ir al menu). Si esa tecla se aprieta el siwtch del menu pasa al case encargado de mostrar el menu. (el primer case del switch del menu es de reposo, que no hace nada)

El codigo seria mas o menos asi:

void loop(){
  switch (a){
   case 0:
     leo hora y dia
     controlo si se aprieta # - si se aprieta # b = 1 sino b continua valiendo 0
     segun hora y dia cambio asigno a variable a los diferentes case
     break;
  case 1:
     cuando es la hora 7.30 y dia laborable desactivo stop
     break;
  .......
  }
  switch (b){
    case 0:
      break;
    case 1:
      muestro menu
      segun opcion me voy a un case o otro
      break;
    case 2:
      configuro hora y fecha
      break;
    .....
   }

Muchas gracias por los comentarios y por el tiempo dedicado a responder

Un saludo