Ayuda para control de compresores y cambiar maestro.

Hola a todo el mundo!

Soy nuevo en el foro y en el mundo de arduino, solo he programado plcs y esto se me queda un poco grande por ahora, voy a empezar a recibir cursos de arduino como lenguaje y programación pero necesito ayuda para un proyecto, os lo explico.

El proyecto en si es controlar una sala de compresores de aire, cada compresor consta de un sensor temperatura y un sensor de presión en común en el calderín, todos estos adaptados para que funcione con arduino.

Procesos:

1 - Cuando la presión sea menor a 7,5 bares entra a funcionar el compresor 1, si después de un tiempo la presión es menor a 7,5 entrará el compresor 2, después de otro tiempo si la presión sigue estando menor a 7,5 bares entrará el compresor 3. (hasta ahí si soy capaz de programarlo)

2 - Si los tres compresores estuvieran funcionando un tiempo a determinar y la presión es menor a 7,5 bares pararía los compresores (que sería por rotura de tubería de la instalación)

3 - como veis el compresor 1 sería el maestro en realizar el empiece de los procesos y para que no sufra tanto desgaste sería que cada 200 horas cambiara de maestro, por ejemplo cuando el compresor 1 ha estado 200 horas de maestro cambiará al compresor 2 empezando el proceso en el compresor 2 y así con el compresor 3.

El control de temperatura sería por avería, cuando un compresor supere 82 ºC pararía dicho compresor y saltaría una avería.

Como veis esto me queda un poco grande a la hora de programar y ect ya que hasta ahora solo consigo programar y hacer funcionar el paso 1 ya que cuando aplico el paso 2 se me queda el compresor 1 encendido aunque le cambia las variables en un if en el loop.

A ver si alguien me pudiera ayudar o que código haríais para el manejo de este proceso.

Gracias de antemano, un saludo!

Hola, bienvenido!!!
Te voy a recomendar que hagas los cursos tutoriales que estan en documentación, los dos primeros links son de 8 clases cada uno. Solo para que refuerces tus conocimientos de arduino.
Los que hemos trabajado con PLC tenemos algunas costumbres que acá no existen. Las cosas no estan tan servidas y hay que trabajar un poquito mas.

Una de las clases es sobre millis()
millis() es una función que te da un valor unsigned long en milisegundos contados desde que arrancas el arduino.
Por ende, no guarda relación con ninguna hora, pero si sirve para la medicíón de tiempos. Claro que si cortas energía pierdes todo lo que venias acumulando.
Asi que yo usaria un RTC, y el recomendado es el DS3231 o no… ahora que lo pienso mejor tal vez no haga falta. Ya retomaré esto.
Siguiendo con la idea,
Punto 2. Los tres compresores funcionan un tiempo Tx y la presion es menor a 7.5bares detienes los compresores.
Si esto lo implementas con millis() es muy fácil. Lee el ejemplo BlinkWithoutDelay.ino que usa esta función.
Pero básicamente haces asi

// defines un variable unsigned long
unsigned long t_start;


// en el loop en alguna parte estará esto


if (millis()-t_start>INTERVALO && Presion<7.50) {
   digitalWrite(PinComp1, LOW);
   digitalWrite(PinComp2, LOW);
   digitalWrite(PinComp3, LOW);

 }

Bien, aunque eso luce bien, falta decirle a t_start = millis(); en el momento que tu enciendas los compresores e inicies la cuenta que terminara cuando la diferencia entre millis() y t_start supere INTERVALO.
Se entiende?
Punto3.
Puedes llevar una variable x cada compresor mas otra extra para contabilizar arranque y parada

unsigned long TONCompresor1 = 0; // tiempo en milisegundos de Compresor 1
unsigned long TONCompresor2 = 0; // tiempo en milisegundos de Compresor 2
unsigned long TONCompresor3 = 0; // tiempo en milisegundos de Compresor 3



unsigned long TempCompresor1 = 0; 
unsigned long TempCompresor2 = 0; 
unsigned long TempCompresor3 = 0;

De nuevo, cuando enciendas cada compresor harás
TempCompresor1 = milllis();
Lo mismo para Comp2 y 3
Cuando detengas un compresor haras

TONCompresor1 += millis()-TempCompresor1;

Que hace esta ultima instrucción?
TONCOmpresor1 valia 0.
TempCompresor1 la inicializaste conlos milisegundos que llevaba el arduino al momento en que encendiste el Compresor1 y cuando lo detengas calculas los milisegundos que estuvo ON como millis() - TempCompresor1 y se lo sumas a TONCompresor1 sin perder el valor que ya pudiera tener acumulado.

Espero lo comprendas. Es lo mismo que con el PLC pero escrito en C.
Obviamente falta… asi que ese TONCompresor1 debes compararlo con 20036001000 (200 hs expresadas en miliseg).

if (TONCOmpresor1 > 720000000UL) {
 // Cambias de bomba
}

Bueno tienes bastante para unir y trabajar.
esos valores tan grandes mejor crearlos al comienzo de este modo
#define 200HORAS 20036001000 // 200 horas expresadas en milisegundos
Y luego lo usas asi

if (TONCOmpresor1 > 200HORAS) {
 // Cambias de bomba
}

A ver como resulta.

waa, mil gracias surbyte por tu explicaciones, es un poco engorroso venir de programar plc y empezar con esto teniendo las funcionalidades del los plc en la cabeza, como dije estoy un poco verde en arduino y sobre todo en este lenguaje programación pero no me voy a dar por vencido.

Me he leído bien los tutoriales que me has propuesto pero creo que para mi proyecto y con la basica formación que dispongo se me va a poner cuesta arriba pero lo voy a intentar.

A ver si saco un poco de tiempo y me pongo al lío e iré comentando como va.

De nuevo mil gracias. un saludo

Hola,

Me gustaría hacer un comentario sobre este tema:

Sé más de programación “convencional” que de PLC’s, pero sé lo suficiente (de PLC’s) como para saber que no es tan fácil con arduino (como diría surbyte, hay facilidades que ‘acá’ no están tan servidas).

Efectivamente se puede programar la sala de compresores como dice surbyte. Yo, si tuviera que hacerlo, lo haría con un “automata de estados” (no me sentiría seguro si lo hiciese con un método, digamos, “lineal”).

Por último; ojo con esta aplicación: una sobrepresión puede ser peligrosa (por muchas válvulas de seguridad que haya). Yo duplicaría algunas de las seguridades con un circuito totalmente ajeno al arduino (por ejemplo: la parada de los compresores con un presostato independiente -y no sólo esto-).

Saludos a todos.

(Estoy deseando que más gente opine sobre este tema -autómata-).

vffgaston muy buen comentario!!! Y ya que estamos... agrega un watchdog.. cuando termines todo, hablamos del tema watchdog, no sea cosa que por ruido electrico se tilde tu arduiino y se queme un compresor.

agrega un watchdog.

Por ejemplo

Comparto con vffgaston la programación de maquinas de estados. Te dejo dos links FSM Library y Arduino finite state machine library. Ambas tienen ejemplos, pero verás como cambia el enfoque de lo que pretendes hacer. Entiendo que lucirá hasta mas complicado en un comienzo pero apóyate en los ejemplos y verás que podrás resolverlo.

Buenas compañeros.

Iré comentando a lo que me habeis respondido.

vffgaston: (no me sentiría seguro si lo hiciese con un método, digamos, "lineal").

Antes esta sala se controlaba con un plc de forma lineal hasta que este con una subida de tensión dijo ciao, por lo que no habría problema a la hora de hacerlo linealmente.

vffgaston: Por último; ojo con esta aplicación: una sobrepresión puede ser peligrosa (por muchas válvulas de seguridad que haya). Yo duplicaría algunas de las seguridades con un circuito totalmente ajeno al arduino (por ejemplo: la parada de los compresores con un presostato independiente -y no sólo esto-).

Cada compresor tiene su placa con su controlador ajeno a la instalación controlando su presión, temperatura, alarmas ect. Estos están puesto en manuales y se le envía la señal de arranque o parada desde plc o en este caso desde arduino, pero si por ejemplo hubiera una sobrepresión en uno de los compresores este pararía y avisaría en su placa de una avería.

surbyte: Comparto con vffgaston la programación de maquinas de estados. Te dejo dos links FSM Library y Arduino finite state machine library. Ambas tienen ejemplos, pero verás como cambia el enfoque de lo que pretendes hacer. Entiendo que lucirá hasta mas complicado en un comienzo pero apóyate en los ejemplos y verás que podrás resolverlo.

Lo he estado mirando por encima y no tiene mala pinta pero como os dije soy demasiado novato y me gustaría empezar la casa por el tejado.

Bueno lo que he pensado es empezar este proyecto intentando controlar cada compresor con un arduino(no conectados entre si,serían individuales) eliminando las placas de casa, ya que voy a necesitar varias señales como temperatura y las horas para el mantenimiento para el arduino del control principal, ¿como lo veis?

PD. Este proyecto es de uso y mérito personal no profesional, mi familia tiene una fabrica de ensamblaje de cajas de cartón y la sala de compresores es de ahí.(también decir que ahora mismo como están configurados "en autónomos" la sala funciona bien, el fin de este proyecto es para un rendimiento mayor de los compresores).

Un saludo arduineros.

Bien, comienza haciendo algo y luego si lo requiere lo iremos mejorando. PLEASE no uses delay, si quieres no perderte de nada. Mira el tutorial de millis(), mira el ejemplo BlinkWithoutDelay un ejemplo que acabo de escribirle a alguien que queria hacer que titile algo pero sin DETENER la secuencia del programa,

Esta es una rutina que envía un número por un par de 74HC595, que encienden una barrra de leds. La barra encenderá leds de acuerdo a una secuencia específica.. que no viene al caso pero imagina que enciende 1 luego 2 luego 3 mantiene 3 y termina bajando a 2 a 1 y aca lo que quiero mostrarte, el ultimo titila, No te marees por lo que pondré porque son chips de registro de desplazamiento que ya conoces por el PLC.

void displayConBlink(unsigned int numero){
                
    LowByte = numero & 0x00ff;
    HighByte = (numero & 0xff00)>>8;
    
    switch (estado) {
        case 0: 
                digitalWrite(pinLatch, LOW);
                shiftOut(pinDatos, pinReloj, MSBFIRST, HighByte);       
                shiftOut(pinDatos, pinReloj, MSBFIRST, LowByte);        
                digitalWrite(pinLatch, HIGH);
                if (millis() - tstart > INTERVALO) {
                    tstart = millis();
                    estado = 1;
                }
                break;
        case 1: 
                digitalWrite(pinLatch, LOW);
                shiftOut(pinDatos, pinReloj, MSBFIRST, 0x00);   // digitOne unidades
                shiftOut(pinDatos, pinReloj, MSBFIRST, 0x00);        //digitOne decenas
                digitalWrite(pinLatch, HIGH);
                
                if (millis() - tstart > INTERVALO) {
                    estado = 0;
                    tstart = millis();
                }
                break;
        default:
                break;
    }
}

La rutina recibe un número 14 o 15. No me complique mucho pero mira el switch case que es lo que interesa. estado es la variable que controla que hara. Esta por defecto en 0. Cuando ejecuta el case 0: envia algo en bits a los 595's y luego te encuentras con

if (millis() - tstart > INTERVALO) {
   estado = 1;
   tstart = millis();
}

millis() es una función que lleva los milisegundos desde que encendimos el Arduino. tstart tiene el valor de millis() en algun momento que INICIO el timer INTERVALO en este caso vale 500 mseg o sea que busco un parpadeo de 0.5 seg ON y luego OFF y asi. pero hecho de este modo, cuando cumplo 500 mseg, ajusto tstart con el nuevo valor de millis() y lo mas importante ajusto estado =1 lo que en el siguiente ciclo hara que pase al segundo case 1: Esta es la manera estilo máquina de estados que uso millis() y tengo un programa que fluye sin DEMORAS.

Espero se vea la idea.

Antes esta sala se controlaba con un plc de forma lineal hasta que este con una subida de tensión dijo ciao, por lo que no habría problema a la hora de hacerlo linealmente.

El término "lineal" lo empleamos aquí (espero que surbyte está de acuerdo) para designar lo métodos convencionales de programar (eso suponiendo que haya metodos "convencionales" de programar: todos los programadores creemos que somos una suerte de "artistas" inimitables . . . ). Un PLC no te deja que lo programes "de forma lineal".

Cuando el proceso a programar tiene mucha interactividad (en este caso hay que estar pendiente de si el(los) presostato(s) marca(n) más o menos de los dos o tres niveles de presión que controlan los arranques y paradas de los compresores; hay que estar pendientes de los termostatos; de las eventuales ordenes de los operadores humanos, etcétera . . .) y, además, la respuesta del sistema NO es la misma a los eventos exteriores, si no que depende de lo que haya pasado hasta ese momento (estado de sistema), la cosa se complica.

Insisto en que, al memos a mi, programar una cosa de esta complejidad me resulta imposible por los métodos convencionles (alguna vez que por pereza -preparar lo que hace falta para hacerlo con un autómata de estados es un coñazo-, he empezado por lo tradicional -y lo he ido complicando- un programa que aparentemente se podía elaborar por el método convencional he terminado haciéndolo con un autómata; si se ha seguido la norma de estilo que invita a dividir el código en rutinas (funciones, subfunciones, todo viene a ser lo mismo, al menos para lo que nos ocupa), resulta relativamente fácil.

En tu caso, si la sala de compresores funciona con lo que tienes, yo empezaría -quizá- por monitorizarla: horas de funcionamiento (lo más fácil) por compresor; gráfico de funcionamiento de cada compresor (se empieza a complicar); gráfico de presiones - tiempo (se complica más). Cuando hayas sido capaz de lo anterior, entonces control de UN compresor (sustituyendo el suyo: palabras mayores) y, por fin, control de la sala completa (aquí hay que "atarse los machos").

Saludos

Quizás tenga yo el termino lineal equivocado, quizas sea por que no he tocado nunca programación.

He estado haciendo algo a ver como lo veis, primero os explicaré como es el funcionamiento de los compresores que aquí tenemos ya que no son comunes, son compresores de 50 CV y de tornillo.
se componen de tres partes una el motor, otra es la cabeza de aspiracion, la cabeza de aspiracion solo puede funcionar y dejar de funcionar mientras el motor esta arrancado y por ultimo el tornillo.

Al pulsar marcha arranca el motor del compresor(si la presion es menor a x bares, si no estará en espera), espera x segundos y entra la cabeza de aspiracion, cuando ha llegado a la consigna seleccionada de presion deja de funcionar la cabeza de aspiracion y se queda el motor solo durante x segundos, si antes de esos x segundos la presion baja de una consigna minima vuelve a entrar la cabeza de aspiracion y así en cadena, si en esos x segundos no baja de la consigna minima de presion se parará el motor y esperará a que haya demanda de presion.

Aquí os dejo el código a ver como lo veis.

int motor = 22;
int cabezaspi = 26;
int pulsadorON = 50;
int pulsadorOFF = 52;
int setaemerg = 53;
int sensorTemperatura = A0;
int sensorPresion = A1;
int estado = 0;
int emergencia = 0;
int resetemerg = 51;

long tempmotor = 5000; // consigna desde que pulsas hasta que para si no hay demanda.
long tiempo = 0;  //tiempo cuando se inicia arduino
long tiempON =0;  // almacenaje del tiempo cuando pulsas on.
long sumaton =0;  // suma entre entre tiempON y consigna de tiempo para hacer diferencia.

////variables tiempo on cabeza de aspiración.
long tempcabeza = 5000; // tiempo desde que empiez el motor hasta que arranca la cabeza de aspiracion.
long tempcabezaVON = 5000; // tiempo que espera 
long tiempONcab = 0;
long sumaONcab = 0;
////////////////////

////variables tiempo off cabeza de aspiración.
long tiempOFFcab = 0;
long sumaOFFcab = 0;
////////////////////////////////

//variables presion y temperatura
float temperatura = 0; // variable para temperatura
float presion = 0; // variable para presión
///////////////////////////////////

void setup() {


  pinMode (motor, OUTPUT);
  pinMode (cabezaspi, OUTPUT);
  pinMode (pulsadorON, INPUT);
  pinMode (pulsadorOFF, INPUT);
  pinMode (sensorTemperatura, INPUT);
  pinMode (sensorPresion, INPUT);
  pinMode (setaemerg, INPUT);
  pinMode (resetemerg, INPUT);

}

void loop() {

   tiempo = millis();
   
   temperatura = (5.0 * analogRead(sensorTemperatura)*100.0)/1023.0; //calculo para grados del sensor TMP36GZ.
   presion = (5.0 * analogRead(sensorPresion)*100.0)/1023.0; // este valor es para simular, ya que no he probado aun el sensor de presion

   if (temperatura >= 82){ // temperatura maxima del compresor, sería una alarma si se llegara a esa temperatura.
    emergencia = 1;
    estado = 0;
   }
   if (presion >= 400){ //presion maxima de la instalacion, sería una alarma si se llegara a esa presión.
    emergencia = 2;
    estado = 0;
   }
   if (digitalRead (setaemerg) == HIGH){
    emergencia = 3;
    estado = 0;
   }
  if (digitalRead(pulsadorON)== HIGH, emergencia == 0){
    estado=1;
  }
  
  if (digitalRead(pulsadorOFF)== HIGH){ si se pulsa off pasa a estado 5 y despues de estar funcionando solo el motor x segunos se parará
    digitalWrite(cabezaspi, LOW);
    tiempONcab = tiempo;
    sumaONcab = tiempONcab + tempcabeza;
    estado = 5; 
  }
  
  switch (estado){ // estado parado.
    case 0:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    break;

    case 1: // si la presion es menor a una consigna y la temperatura menor a otra consigna, pasa a estado 2.
    if (presion < 300, temperatura<82){ // esta consigna de presion debe ser modificable, seria la presion minima que puede haber en la isntalación.
    tiempONcab = tiempo;
    sumaONcab = tiempONcab + tempcabeza;
    estado=2;   
    }
    break;

    case 2: // arranca motor y cuando el tiempo sea la suma pasa a estado 3.
    digitalWrite (motor, HIGH);
    if (tiempo == sumaONcab){
     estado=3;
    }
    break;

    case 3: // se pone en marcha la cabeza de aspiración conjunto con el motor.
    digitalWrite (motor,HIGH);
    digitalWrite (cabezaspi,HIGH);
    if (presion >= 300){ // si la presion llega hasta la consigna maxima, parará la cabeza de aspi y pasara a estado 4.
      digitalWrite (cabezaspi,HIGH);
      tiempOFFcab = tiempo;
      sumaOFFcab = tiempOFFcab + tempcabezaVON;
      estado = 4;
    }
    break;

    case 4: // solo se queda en marcha el motor por si hubiera una demanda de aire.
    digitalWrite (motor,HIGH);
    if (tiempo == sumaOFFcab){ // si la presion de consigna ha bajado volverá a estado 3.
      if (presion < 200){
        estado = 3;
      }
      if (presion>=300){ // si la presion no se modifica en esos x segundos pasará a estado 1 = espera.
        estado = 1;
      }  
    }
    break;

    case 5:
    if (tiempo == sumaONcab){
      digitalWrite (motor, LOW);
      estado = 0;
    }
  }
  switch (emergencia){
    case 0:
    break;
    case 1:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    if (digitalRead (resetemerg)==HIGH){
      emergencia = 0;
      estado = 0;
    }
    case 2://///////////////////////////hago varios estados por que en pantalla saldria cual seria cada emergencia
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    if (digitalRead (resetemerg) == HIGH){
      emergencia = 0;
      estado = 0;
    }
    break;
    
    case 3:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    
    if (digitalRead (resetemerg) == HIGH){
      emergencia = 0;
      estado = 0;
    }
    break;
  }
}

PD. acepto cualquier crítica.

Saludos.

Buenas, he simulado mi codigo y en principio el switch case de estado se va directamente a estado 2 sin tocar nada, los tiempos de retardo con millis no me funcionan y la verdad no se que es lo que hago mal, me vendria bien una ayudita pleasee!!

Hola,

Había perdido yo este hilo . . . .

Ahora no puedo, pero esta tarde lo echo un vistazo con calma.

La intorducción de la variable "estado" y el uso del "switch case" va por dónde yo indicaba (autómata de estados). Yo lo programo de una forma algo más sofisticada (que al principio es un coñazo pero después es mucho más cómodo) pero no importa tanto. Lo importante es la filosofía del diseño del flujo del programa.

Para analizar este tipo de estructuras se usa un diagrama característico que, al menos a mí, me ayuda muchísimo con el diseño; aquí tienes ejemplos:

https://www.google.es/search?q=diagrama+de+estados+y+transiciones&rlz=1C1VFKB_enES643ES644&tbm=isch&tbo=u&source=univ&sa=X&ved=0CB0QsARqFQoTCP3208eo7MgCFUJ9GgodbGEIJg&biw=1330&bih=947

No me extrañaría que, si lo estudias un poco, veas que tu caso se puede representar por un gráfico como este; si es el caso te aconsejo que lo hagas; te ayudará muchísimo y nos ayudará a los que intentamos echarte una mano.

Saludos

Este se parece a lo tuyo

Hola,

He estado echando un vistazo al código:

1) Formalmente (comentarios, nombre de variables, estructura) no tiene mala pinta (yo pongo muchísimos más comentarios; de hecho no guardo otra documentación del programa que los comentarios- y el programa propiamente dicho, claro-).

2) Es muy difícil seguir la lógica. Yo sería incapaz de depurar este programa ni aunque lo hubiera hecho yo. Quizá con el gráfico que te sugiero sería más fácil.

3) Esta condición "if (tiempo == sumaONcab)" ¿no es difícil que se cumpla?: actualizas "tiempo" al comienzo de cada "loop()", con lo que irá a saltos.

Saludos

Bueno la misma opinión que vffgaston en general. 1. Al comienzo un cambio menor.. por si el programa crece. No hace falta que definas como int los pines que vas a usar. o usas #define ETIQUETA pin o usas

const byte motor                = 22;
const byte cabezaspi            = 26;
const byte pulsadorON           = 50;
const byte pulsadorOFF          = 52;
const byte setaemerg            = 53;
const byte sensorTemperatura            = A0;
const byte sensorPresion        = A1;

como yo te he modificado.

  1. Tampoco esta nada mal, pero solo para saber tu código del loop lees dos variables analógicas
temperatura = (5.0 * analogRead(sensorTemperatura)*100.0)/1023.0;       //calculo para grados del sensor TMP36GZ.

Recuerda que si la temperatura varia tendrás algunos comportamientos anómalos. Un promedio movil sería buena alternativa pero eso es para resolver en la práctica. Si la lectura es estable olvida este comentaio.

  1. Coincido con el punto 3 de vffgaston cambia esa linea a
if (tiempo >= sumaONcab)

Para terminar te diré que lo has hecho de una forma que no es la que yo hubiera hecho pero no luce mal. Has organizado todo en sensores que se actualizan y determinan acciones usando dos switch-case. A mi me parece que esta bien. Salvo la cuestion del punto 3 que puede no cumplirse estrictamente a menos que >= sea una opción lo demás esta OK.

Recuerda que si la temperatura varia tendrás algunos comportamientos anómalos. Un promedio movil sería buena alternativa pero eso es para resolver en la práctica. Si la lectura es estable olvida este comentaio.

Absolutamente: cualquier perturbación de origen electromagnético (y los arranques/paradas de un compresor tienen su aquel) puede producir lecturas espúreas. Es importantísimo no dar una lectura por buena si no se repite dentro de un intervalo razonable en un tiempo razonable (o, como dice surbyte, la media de varias consecutivas; yo prefiero el otro método pero es más difícil de programar. El de las medias puede valer de momento).

Por cierto: como están cableados los sensores hasta el arduino. ¿Tienes algo en medio -amplificadores, etc . .-?

Saludos

Buenas

He estado ausente por aquí por falta de tiempo, pero me he puesto al día rápidamente,
como me habéis dicho, el fallo era poner el ==, ya que con >= los tiempos funcionan bien.

He intentado hacer el diagrama de estados y transiciones pero me quedo a mitad ya que desconozco como se hacen, pero aun así lo intentare.

Hasta ahora simulando me hace casi todo bien y hay errores que no se por que me pasan por mucho que le de vueltas al código, puede que no me haya explicado bien,

Al encender arduino la variable estado se encuentra en 0, a la espera de pulsar ON para que pase a estado 1:

    case 0:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    if (digitalRead(pulsadorON) && HIGH){
    estado=1;
    }
    break;

En estado 1, que es el estado de espera, si la presión no es menor a la consigna mínima de la instalación no hace nada, si fuera menor, haría la suma del tiempo con la consigna de tiempo a la que entraría la cabeza de aspiración y pasaría a estado 2:

    case 1:
    if (presion < 100, temperatura<82){ 
    tiempONcab = tiempo;
    sumaONcab = tiempONcab + tempcabeza;
    estado=2;   
    }
    break;

En estado 2 arranca el motor y temporiza en esta caso 5" y pasaría a estado 3:

    case 2: // arranca motor y cuando el tiempo sea la suma pasa a estado 3.
    digitalWrite (motor, HIGH);
    if (tiempo >= sumaONcab){
     estado=3;
    }
    break;

En estado 3 se pone en marcha también la cabeza de aspiración hasta que llegue a la consigna maxima de la instalación. Cuando llegue a la consigna máxima parará la cabeza de aspiración y hara la suma de del tiempo con la consigna del tiempo de espera para no tener que volver a rrancar el motor de nuevo.

    case 3: // se pone en marcha la cabeza de aspiración conjunto con el motor.
    digitalWrite (motor,HIGH);
    digitalWrite (cabezaspi,HIGH);
    if (presion >= 350){ // si se cumple, para cabezaspi, hace la suma y pasa a estado 4.
      digitalWrite (cabezaspi,LOW);
      tiempOFFcab = tiempo;
      sumaOFFcab = tiempOFFcab + tempcabezaVON;
      estado = 4;
    }
    break;

En el estado 4 pararía la cabeza de aspiración y esperaría un tiempo determinado, en este caso 5" antes de parar el motor por si hubiera demanda de aire y así no habría que volver a arrancar el motor pasando a estado 3. Si en ese tiempo no llega a la consigna mínima, pararía el motor y volvería a estado 1 de espera. (en este estado = 4, cuando lo simulo bajando la presión por debajo de la consigna mínima vuelve a estado numero 3 haciéndolo bien, pero si si mantengo la presión por encima o igual a la máxima hace un bucle infinito entre estado pasando por estado 1 hasta el 4, y nunca me para el motor, he pensado en ponerle un else if en vez del if).

    case 4: // solo se queda en marcha el motor por si hubiera una demanda de aire.
    digitalWrite (motor,HIGH);
    if (tiempo >= sumaOFFcab){ // si la presion de consigna ha bajado volverá a estado 3.
      if (presion < 100){
        estado = 3;
      }
      if (presion>=350){ // si la presion no se modifica en esos x segundos pasará a estado 1 = espera.
        digitalWrite (motor,LOW);
        estado = 1;
      }  
    }
    break;

Haber si consigo hacer el diagrama de estado y transiciones del compresor y lo cuelgo para que os pueda aclarar mas.

Un saludo compañeros.

Vale , olvidad lo de antes creo que ya lo tengo. He simulado varias veces y comprobando por el serial y por lo pronto todo bien, a ver como lo veis:

const byte motor = 2;
const byte cabezaspi = 3;
const byte pulsadorON = 4;
const byte pulsadorOFF = 5;
const byte setaemerg = 6;
const byte resetemerg = 7;
const byte sensorTemperatura = A0;
const byte sensorPresion = A1;

int estado = 0;
int emergencia = 0;


long tempmotor = 5000; // consigna desde que pulsas hasta que para si no hay demanda.
long tiempo = 0;  //tiempo cuando se inicia arduino
long tiempON =0;  // almacenaje del tiempo cuando pulsas on.
long sumaton =0;  // suma entre entre tiempON y consigna de tiempo para hacer diferencia.

////variables tiempo on cabeza de aspiración.
long tempcabeza = 5000; // tiempo desde que empiez el motor hasta que arranca la cabeza de aspiracion.
long tempcabezaVON = 5000; // tiempo que espera 
long tiempONcab = 0;
long sumaONcab = 0;
////////////////////

////variables tiempo off cabeza de aspiración.
long tiempOFFcab = 0;
long sumaOFFcab = 0;
////////////////////////////////

//variables presion y temperatura
float temperatura = 0; // variable para temperatura
float presion = 0; // variable para presión
///////////////////////////////////

void setup() {


  pinMode (motor, OUTPUT);
  pinMode (cabezaspi, OUTPUT);
  pinMode (pulsadorON, INPUT);
  pinMode (pulsadorOFF, INPUT);
  pinMode (sensorTemperatura, INPUT);
  pinMode (sensorPresion, INPUT);
  pinMode (setaemerg, INPUT);
  pinMode (resetemerg, INPUT);
  Serial.begin(9600);

}

void loop() {

   tiempo = millis();
   
   temperatura = (5.0 * analogRead(sensorTemperatura)*100.0)/1023.0; //calculo para grados del sensor TMP36GZ.
   presion = (5.0 * analogRead(sensorPresion)*100.0)/1023.0; // este valor es para simular, ya que no he probado aun el sensor de presion
   Serial.print ("tiempo ");
   Serial.println (tiempo);
   Serial.print ("Presion  ");
   Serial.println (presion);
   Serial.print ("estado");
   Serial.println (estado);
   Serial.print ("emergencia");
   Serial.println (emergencia);
   

   if (temperatura >= 82){ // temperatura maxima del compresor, sería una alarma si se llegara a esa temperatura.
    emergencia = 1;
    estado = 0;
   }
   if (presion >= 490){ //presion maxima de la instalacion, sería una alarma si se llegara a esa presión.
    emergencia = 2;
    estado = 0;
   }
   if (digitalRead (setaemerg) == HIGH){
    emergencia = 3;
    estado = 0;
   }
   if (estado == 3){//si se pulsa off pasa a estado 5 y despues de estar funcionando solo el motor x segunos se parará.
    if (digitalRead(pulsadorOFF) == HIGH){
     digitalWrite(cabezaspi, LOW);
     tiempONcab = tiempo;
     sumaONcab = tiempONcab + tempcabeza;
     estado = 5;
    }
   }

  switch (estado){ // estado parado.
    case 0:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    if (digitalRead(pulsadorON) && HIGH){
    estado=1;
    }
    break;

    case 1: // si la presion es menor a una consigna y la temperatura menor a otra consigna, pasa a estado 2.
      if (digitalRead(pulsadorOFF)== HIGH){
        estado=0;
      }
    if (presion <= 100){ // esta consigna de presion debe ser modificable, seria la presion minima que puede haber en la isntalación.
    tiempONcab = tiempo;
    sumaONcab = tiempONcab + tempcabeza;
    estado=2;   
    }
    break;

    case 2: // arranca motor y cuando el tiempo sea la suma pasa a estado 3.
      if (digitalRead(pulsadorOFF)== HIGH){
        digitalWrite (motor, LOW);
        estado=0;
      }
    digitalWrite (motor, HIGH);
    if (tiempo >= sumaONcab){
     estado=3;
    }
    break;

    case 3: // se pone en marcha la cabeza de aspiración conjunto con el motor.

    digitalWrite (motor,HIGH);
    digitalWrite (cabezaspi,HIGH);
    
    if (presion >= 350){ // si la presion llega hasta la consigna maxima, parará la cabeza de aspi y pasara a estado 4.
      digitalWrite (cabezaspi,LOW);
      tiempOFFcab = tiempo;
      sumaOFFcab = tiempOFFcab + tempcabezaVON;
      estado = 4;
    }

    break;

    case 4: // solo se queda en marcha el motor por si hubiera una demanda de aire.
    if (digitalRead(pulsadorOFF)== HIGH){
      digitalWrite (motor,LOW);
      estado=0;
    }
    digitalWrite (motor,HIGH);
    if (tiempo >= sumaOFFcab){ // si la presion de consigna ha bajado volverá a estado 3.
      if (presion <= 100){
        estado = 3;
      }
      if (presion>= 350){
        digitalWrite (motor,LOW);
        estado = 1;     
      }
    }
    break;

    case 5:
    if (tiempo >= sumaONcab){
      digitalWrite (motor, LOW);
      estado = 0;
    }
}
  switch (emergencia){
    case 0:
    break;
    case 1:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    if (digitalRead (resetemerg)==HIGH){
      emergencia = 0;
      estado = 0;
    }
    case 2://///////////////////////////hago varios estados por que en pantalla saldria cual seria cada emergencia
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    if (digitalRead (resetemerg) == HIGH){
      emergencia = 0;
      estado = 0;
    }
    break;
    
    case 3:
    digitalWrite (motor,LOW);
    digitalWrite (cabezaspi,LOW);
    
    if (digitalRead (resetemerg) == HIGH){
      emergencia = 0;
      estado = 0;
    }
    break;
  }
}

Por cierto Surbyte ¿como se haría el muestreo de la señal para que si me da una señal mal no la detecte como buena?

Saludos máquinas.

Por cierto Surbyte ¿como se haría el muestreo de la señal para que si me da una señal mal no la detecte como buena?

¿Cuántas son continuas -analógicas- y cuántas ON-OFF?