Duda mantener valores al quitar corriente

Buenos a todos,
Estoy haciendo un programa para poder controlar una suspensión neumática , controlando las 4 suspensiones con dos pulsadores, uno para subir y otro para bajar. Soy muy novato en esto y casi todo lo hago con "if" ya que no domino otras funciones. Hasta ahora lo he estado controlando con Arduino pero con un programa muy "manual". Ahora he puesto sensores de presión y quiero automatizarlo... Adjunto la idea de código que tengo (los que domináis os van a doler los ojos... Se que es un poco pesado pero creo que puede funcionar. Lo que me surgen varias dudas:

La primera es que haciéndolo así, cada vez que apague y vuelva a encender el coche, la variable NIVEL volverá a 0. por lo tanto cunado presione para subir, aunque este en el nivel 3 físicamente, Arduino estar en el 0 y me pasara a nivel 1 en vez de nivel 4. ¿Cómo podría hacer que guarde el ultimo valor que tenia antes de apagar ?
Por otro lado, quizás es una pregunta muy tonta , pero si pongo int NIVEL = 1 , ¿¿como sabe Arduino que es el valor numérico 1 ( o 2 , 3 , 500... ) y no que le estoy asignando esa variable al pin 1 ?? ¿o es que hay que hacerlo de maneras distintas y lo estoy haciendo mal?
El código seguro que aun tiene errores, no lo he probado , solo era para mostrar la idea que tengo y que se vean las dudas.
(si alguna alma caritativa quiere simplificarlo con alguna otra opción que no sea el if, será muy bien venida)

void setup(){
  pinMode(4, INPUT);  //pulsador subir
  pinMode(5, INPUT);   // pulsador bajar
  pinMode(A1, INPUT);  // sensor presion 1
  pinMode(A2, INPUT);  // sensor presion 2
  pinMode(A3, INPUT);  // sensor presion 3
  pinMode(A4, INPUT);  // sensor presion 4
  pinMode(6, OUTPUT);  //electrovalvula subir 1
  pinMode(7, OUTPUT);  //electrovalvula subir 2
  pinMode(8, OUTPUT);  //electrovalvula subir 3
  pinMode(9, OUTPUT);  //electrovalvula subir 4
  pinMode(10, OUTPUT);  //electrovalvula bajar 1
  pinMode(11, OUTPUT);  //electrovalvula bajar 2
  pinMode(12, OUTPUT);  //electrovalvula bajar 3
  pinMode(13, OUTPUT);  //electrovalvula bajar 4

  
  int NIVEL = 0
  int VALOR = 0

  int S1N1 = 200  //valor sensor presion asignado para nivel 1 (no tienen porque ser el mismo en las 4 suspensiones. se aaran pruevas para asignar el valor correcto en cada una) 
  int S2N1 = 200
  int S3N1 = 200
  int S4N1 = 200
  
  int S1N2 = 300  //valor sensor presion asignado para nivel 2  
  int S2N2 = 300
  int S3N2 = 300
  int S4N2 = 300

  int S1N3 = 400  //valor sensor presion asignado para nivel 3  
  int S2N3 = 400
  int S3N3 = 400
  int S4N3 = 400


  int S1N4 = 500  //valor sensor presion asignado para nivel 4  
  int S2N4 = 500
  int S3N4 = 500
  int S4N4 = 500



  digitalWrite (6 , HIGH)   // cerrar todas las electrovalvulas al encender
  digitalWrite (7 , HIGH)
  digitalWrite (8 , HIGH)
  digitalWrite (9 , HIGH)
  digitalWrite (10 , HIGH)
  digitalWrite (11 , HIGH)
  digitalWrite (12 , HIGH)
  digitalWrite (13 , HIGH)


  
  
}

void loop() 
{
  if ( digitalRead (4 , HIGH))  //  PULSO PARA SUBIR
    {
      NIVEL ++1;
      VALOR = 1;
      
    }
    
  if ( digitalRead (5, HIGH))  //  PULSO PARA BAJAR
    {
      NIVEL --1;
      VALOR = 1;
      
    }
  
// AMORTIGUADOR 1 , NIVEL 1:

  if ( NIVEL == 1 && (AnalogRead (A1 < S1N1) && VALOR = 1)  // Subir
   {
      digitalWrite(6,LOW); // activar rele electrovalvula subuir suspension 1
   }

  
if ( NIVEL == 1 && (AnalogRead (A1 > S1N1) && VALOR = 1)    //Bajar
   {
      digitalWrite(10,LOW); // activar rele electrovalvula bajar suspension 1
   }

  
if ( NIVEL == 1 && (AnalogRead (A1 = S1N1) && VALOR = 1)    //Parar 
   {
      digitalWrite(6,HIGH); // desactivar rele electrovalvula
      digitalWrite(10,HIGH);
   }

// REPETIR CODIGO PARA CADA SUSPENSION


// PARAR TODOS: (Para que durante la marcha con los cambios de presion por el movimiento no este abriendo y cerrando las valvulas) :

 if ( NIVEL == 1 && (AnalogRead (A1 = S1N1) && (AnalogRead (A2 = S2N1) &&(AnalogRead (A3 = S3N1) && (AnalogRead (A4 = S4N1) && VALOR = 1)  
   {
     digitalWrite(6,HIGH);
     digitalWrite (7 , HIGH)
     digitalWrite (8 , HIGH)
     digitalWrite (9 , HIGH)
     digitalWrite (10 , HIGH)
     digitalWrite (11 , HIGH)
     digitalWrite (12 , HIGH)
     digitalWrite (13 , HIGH)
     VALOR = 0;
   }



// REPETIR TODO PARA CADA NIVEL

}

Muchísimas gracias de antemano y saludos.

Hola @MARTIARACIL, bienvenido al foro Arduino en Español.
Voy a responder tus consultas paulatinamente.

  1. Lo primero tiene que ver con las convenciónes usadas en programación.
    Las variables se escriben con minúsculas y constantes con mayúsculas pero no todo mezclado.
    Recuerda esto.

  2. Las lecturas de sensores analógicos no requieren la predefinición con pinMode del tipo

pinMode(A1, INPUT);  // sensor presion 1
  pinMode(A2, INPUT);  // sensor presion 2
  pinMode(A3, INPUT);  // sensor presion 3
  pinMode(A4, INPUT);  // sensor presion 4

Simplemente no pongas nada en estos 4 casos y funcionará sin problemas.

  1. Para guardar datos en los Arduinos se dispone de un espacio en EEPROM, hay 4 formas de usarla, dos para lectura y dos para escritura.
    Esta el método viejo y el nuevo. El viejo solo guardaba bytes y todo lo que no era bytes había que transformarlo para su almacenamiento o lectura
    Entonces vino el método presente que es EEPROM.get para leer y EEPROM.put para escribir
    en ambos casos se requiere de una dirección y de la variable que se va a guardar
    por ejemplo
    Si quieres guarda un valor de presion cuya variable se llama presion1 y fue definida asi
float presion1 = 2.34;

la guardas con

EEPROM.put(direccion, presion1);

Esto guarda presion1 a partir de la dirección X que empieza por 0 y termina en lo que de el máximo del arduino que estas usando. O sea que debiste haber indicado

int dirección = 0;

el tema es que si quieres guardar otro valor, debes reservar los lugares utilizados por la variable presion1.
Y cuantos son? Gran pregunta.

Los microcontroladores o mejor dicho el C de éstos disponen de un comando que te devuelve el tamaño en bytes que ocupa una variable
si usas sizeof(presion1) esto te dará un valor que es 4 (no importa pero es bueno saberlo). Un float ocupa 4 bytes.
El tema es que si deseas usar la dirección siguiente reservando los lugares de presion1 y por ejemplo quisieras almacenar presion2 de nuevo como otro float simplemente haces esto.

direccion += sizeof(presion1);

Observa que he hecho.. el += es lo mismo que si pusiera

direccion = direccion + sizeof(presion1);

es la forma elegante o simplificada de hacer o escribir lo mismo usando menos tipeo.
Pero lo destacable es que en sizeof() no pongo la variable que voy a guardar sino la anterior, la que guardé porque podría haber almacenado un entero, que ocupa 2 bytes o un byte que solo ocupa 1 y entonces no estaría ocupando eficientemente el espacio de la EEPROM.

Ahora miraré tu código y te haré comentarios mas allá del tema de minúsculas y mayúsculas.

  1. Análisis de tu programa.

4.1) Esto esta mal

if ( digitalRead (4 , HIGH))  //  PULSO PARA SUBIR
   {
     nivel ++1;
     valor = 1;
    
   }

se usa if (digitalRead (4 )) y en lo personal **NO conviene ** que no lo consultes así pero ya lo hablaremos.
Dentro del if tienes varios erroes, si lo preguntas de este modo en cada ciclo del loop se incrementará nivel en 1 unidad , mas alla que nivel ++ 1 no es la forma correcta. La forma correcta es

nivel++;

mi consejo es que hagas esto y mas si se trata de pulsadores.
lees el valor y lo comparas con el valor anterior, y buscas siempre el flanco, si en tu caso se trata de un flanco de subida o sea el valor anterior será 0 y pasas a 1 cuando presionas.
las variables que use deben estar definidas como globales antes del setup()

  estado1 = digitalRead(4);
   if (estado1 && !estado1Ant) {
       nivel++;
       valor = 1;     
   }
   estado1Ant = estado1;

estas dos variables estado1 y estado1Ant definidas como bool antes del setup llevan los valores presentes y anterior y cuando preguntas en el condicional if, consultas por esto

Pasó el pulsador de 0 a 1? El estado anterior es el 0 que esta en estado1Ant
El estado actual es 1 que es el reportado por estado1.

Esto en forma elegante

if (estado1 && !estado1Ant) {

es lo mismo que esto

if (estado1 == HIGH && estado1Ant == LOW) {

y además estado1Ant == LOW puede expresarse solo como !estado1Ant porque el ! es un negador
Niego el valor que tenga estado1Ant.

Sigo mas tarde.

Ostia no esperaba una respuesta así … INCREIBLE! muchísimas gracias!

Me lo leeré atentamente cunado tenga un ratillo, cogeré apuntes.. y casi casi que volveré a empezar de cero ..

Por cierto, me recomiendas algún sitio concreto de tutoriales en español que estén bien explicados? pdf... video... me da igual. En ingles se que hay mucha info en esta web pero al final entre que me cuesta el ingles y que me cuesta entender la programación ...

De verdad, muchísimas gracias!

Si claro que lo hay. Hay cientos de tutoriales en Indice de temas tutoriales o incluso la misma sección llamada Documentación y Tutoriales.
También hay muchos tutoriales en Youtube.

Solo busca Arduino LoQueTeInterese y tendras tu respuesta.

buenas a todos, tras darle muchas vueltas he hecho esto ... Espero que no este todo mal...

  int nivel;
  int valor;
  int memoria;
  int estado1;
  int estado1Ant; //estados pulsador 1 (subir)
  int estado2;
  int estado2Ant; //estados pulsador 2 (bajar)

  int a1n1= 200;  //valor sensor presion asignado para amortiguador 1 nivel 1 
  int a2n1= 200;  //valor sensor presion asignado para amortiguador 2 nivel 1
  int a3n1= 200;
  int a4n1 = 200;




void setup(){


  pinMode(4, INPUT);  //pulsador subir
  pinMode(5, INPUT);   // pulsador bajar
  pinMode(A1, INPUT);  // sensor presion 1 NO NECESARIO DECLARARLO
  pinMode(A2, INPUT);  // sensor presion 2 NO NECESARIO DECLARARLO
  pinMode(A3, INPUT);  // sensor presion 3 NO NECESARIO DECLARARLO
  pinMode(A4, INPUT);  // sensor presion 4 NO NECESARIO DECLARARLO
  pinMode(6, OUTPUT);  //electrovalvula subir 1
  pinMode(7, OUTPUT);  //electrovalvula subir 2
  pinMode(8, OUTPUT);  //electrovalvula subir 3
  pinMode(9, OUTPUT);  //electrovalvula subir 4
  pinMode(10, OUTPUT);  //electrovalvula bajar 1
  pinMode(11, OUTPUT);  //electrovalvula bajar 2
  pinMode(12, OUTPUT);  //electrovalvula bajar 3
  pinMode(13, OUTPUT);  //electrovalvula bajar 4



  digitalWrite (6 , HIGH);   // cerrar todas las electrovalvulas al encender
  digitalWrite (7 , HIGH);
  digitalWrite (8 , HIGH);
  digitalWrite (9 , HIGH);
  digitalWrite (10 , HIGH);
  digitalWrite (11 , HIGH);
  digitalWrite (12 , HIGH);
  digitalWrite (13 , HIGH);


  EEPROM.get( memoria , nivel);

 
}

void loop() 
{
  estado1 = digitalRead (4)

   if (estado1 && !estado1Ant) {
       nivel++;
       valor = 1;     
   }
   estado1Ant = estado1;
   
 EEPROM.put( memoria , nivel);  //Grabamos valor del nivel

  estado2 = digitalRead (5)

   if (estado2 && !estado2Ant) {
       nivel--;
       valor = 1;     
   }
   estado2Ant = estado2;
   
 EEPROM.put( memoria , nivel);  //Grabamos valor del nivel
      
    }
  

// AMORTIGUADOR 1 , NIVEL 1:

  if ( nivel == 1 && analogRead (A1 < a1n1) && valor == 1)  // Subir
   {
      digitalWrite(6,LOW); // activar rele electrovalvula subuir suspension 1
   }

  
  if ( nivel == 1 && analogRead (A1 > a1n1) && valor == 1)    //Bajar
   {
      digitalWrite(10,LOW); // activar rele electrovalvula bajar suspension 1
   }

  
  if ( NIVEL == 1 && analogRead (A1 = a1N1) && valor == 1)    //Parar 
   {
      digitalWrite(6,HIGH); // desactivar rele electrovalvula
      digitalWrite(10,HIGH);
   }

// REPETIR CODIGO PARA CADA AMORTIGUADOR 




 if ( nivel== 1 && (analogRead (A1 = a1n1 && (analogRead (A2 = a2n1) &&(analogRead (A3 = a3n1) && (analogRead (A4 = a4n1) && valor = 1)   / PARAR TODOS: (Para que durante la marcha con los cambios de presion por el movimiento no este abriendo y cerrando las valvulas) :
   {
     digitalWrite(6,HIGH);
     digitalWrite (7 , HIGH);
     digitalWrite (8 , HIGH);
     digitalWrite (9 , HIGH);
     digitalWrite (10 , HIGH);
     digitalWrite (11 , HIGH);
     digitalWrite (12 , HIGH);
     digitalWrite (13 , HIGH);
     nivel= 0;
   }                                    /



// REPETIR TODO PARA CADA NIVEL

}

El tema del estado y estadoAnt no lo tengo muy claro la verdad.... Además, ¿tendría que poner algún delay para que no me suba varios niveles "de golpe?
Muchas gracias por la paciencia!

Esto funciona asi.. y no he leído bien tu respuesta pero como dices que el tema estado y estadoAnt no lo terminas de entender te daré mi respuesta y luego te remitiré a un tutorial muy bien hecho de victorjam.

 estado1 = digitalRead (4)

   if (estado1 && !estado1Ant) {
       nivel++;
       valor = 1;     
   }
   estado1Ant = estado1;

Este es un método simple para usar con pulsadores de los pequeños, si usas pulsadores grandes del tipo industrial no uses este método porque rebotan. De hecho todos lo hacen pero los pequeños muy poco.
Casi nunca debo usar rutina antirebotes.

Las variables estado1, estado1Ant se definen como boolean o sea solo toman estados 1/0 o true/false lo mismo que HIGH y LOW.

Entonces lees el estado con

estado1 = digitalRead (4);

a esta linea le falta el; no olvides la sintaxis correcta o tendrás errores por todos lados.
digitalRead(4) lee el estado del pin digital 4 que definiste previamente como

pinMode(4, INPUT);

Esto hace que el pin quede sujeto a como conectaste el pulsador al pin?
Si usas una resistencia pull-up o sea resistencia a VCC o pull-down resistencia a GND.

De acuerdo a esto, será tu estado NORMAL y tu estado PULSADO o PRESIONADO.
Supongamos que lo hiciste bien, y bien como sería? un Pull-DOWN o sea resistencia conectada a masa.

aca ves a la derecha el método pull-down. El switch siempre esta a GND y eso es lo que lees con digitalRead(4) si no lo pulsas. Lees un LOW
de modo que el estadoAnt es LOW casi siempre.

Cuando presiones, digitalRead(4) cambia a HIGH, porque si miras, queda el pin unido a VCC. Entonces como estado es HIGH y estadoAnt es LOW (olvida el 1 de estado1 porque hablo de manera genérica), tienes en tu consulta

if (estado1 && !estado1Ant) {

que es lo mismo que

if (estado1 == HIGH && estado1Ant == LOW) {

Solo para que lo vayas asimilando una situación del tipo estado1Ant == LOW es lo mismo que poner
!estado1Ant o sea, el operador ! niega el estado de estado1Ant

Dicho de otro modo. Si solo tuvieras estado1Ant debes imaginar que el estado posible es VERDADERO y si le pones un negador ! entonces se transforma en estado1Ant == LOW

La comparación de las dos situaciones resulta en esperar el cambio en el flanco de LOW a HIGH en el pulsador.
Siempre esta en LOW hasta que presionas. Cuando presionas pasa a HIGH
Esto

if (estado1 && !estado1Ant)

justamente es una forma de preguntar, pasó el pulsador de LOW a HIGH? Si, pasó cada vez que presionas el pulsador y su conexión es pull-down, si fuera pull-up tendrías que preguntar a la inversa.

Este método permite que con cada pulsación se preste atención a lo que el condicional tiene y no actúa mas, y es la gran diferencia a simplemente preguntar

if (estado1==HIGH)

que es lo mismo que preguntar

if (estado1)

Si solo preguntaras así, cada vez que el loop da un ciclo incrementas tu contador y eso se vuelve una locura en tu programa.

Ojalá haya sido clara, la explicación.

¿tendría que poner algún delay para que no me suba varios niveles "de golpe?

Creo haber sido claro que solo funciona una vez, no necesitas delay(). Eso es para la mala programación como cuando solo preguntas por su estado y no cuando preguntas por el flanco.

Buenas tardes, con lo que me comentasteis anteriormente y cosas que he ido aprendiendo en tutoriales, parece que tengo el codigo bastante avanzado. A parte de los dos pulsadores, he instalado un modulo bluetoth y he creado una app .

Ahora tengo 3 opciones para actuar :

  1. modo completamente manual des de la app, con lo que activo y desactivo reles usando :
if ( Serial.available() > 0)
  {
    estado = Serial.read();
  }
  switch ( estado)
  {

    case 'a':
      digitalWrite(6, LOW);
      break;

Con una letra para cada rele. Esto fnciona a la perfeccion.

  1. Seleccionando con 4 pulsadores de la app uno de los 4 niveles , usando la misma estructura que en la anterior. Aqui por eso ya entran en juego los sensores de presion:
if ( Serial.available() > 0)
  {
    estado = Serial.read();
  }
  switch ( estado)
  {
    case 'm':
      nivel = 1;
      valor = 1;
      break;

    case 'n':
      nivel = 2;
      valor = 1;
      break;

    case 'o':
      nivel = 3;
      valor = 1;
      break;


    case 'p':
      nivel = 4;
      valor = 1;
      break;
}

if ( nivel == 1 && analogRead(A1) < adn1 && valor == 1 ) // Subir
  {
    digitalWrite(6, LOW);
    digitalWrite(7, LOW); // activar reles electrovalvulas subuir suspension delantera
  }

  if ( nivel == 1 && analogRead(A1) > adn1 && valor == 1 ) // Subir
  {
    digitalWrite(10, LOW);
    digitalWrite(11, LOW); // activar reles electrovalvulas bajar suspension delantera
  }

  if ( nivel == 1 && analogRead(A1) == adn1 && valor == 1)   //Parar
  {
    digitalWrite(6, HIGH); // desactivar reles electrovalvulas delanetras
    digitalWrite(7, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(11, HIGH);
    valor = 0
  }

Adjunto solo un trozo , ya que es donde creo que esta el problema. para todos los demás amortiguadores y niveles se repite la misma estructura.
El valor adn1 lo tengo definido como variable antes de nada con el valor que me aparece en pantalla con el Serial.print .
Esto ya no me funciona, i es que no me respeta el < y > , ya que me activa ambos relés , tanto de subir como de bajar y le da igual la presión.

¿Qué estoy haciendo mal?

  1. Aun no tengo las resistencias para reducir el voltaje de los pulsadores que al venir del coche va a 12v(14v) , pero supongo que me pasara lo mismo que en el caso anterior.
    En este caso he usado la estructura que me explicasteis mas arriba.

Si hace falta me lo decís y pongo el código entero, pero es bastante largo.
una vez mas, muchísimas gracias!! Gracias a vosotros cada día me esta enganchando mas esto de programar :slight_smile:

Sobre la (3), los pulsadores no tienes que conectarlos a 12V, los conectas a 5V provenientes del arduino.

Sobre la (2), yo haría

...
if(nivel == 1 && valor == 1) {
  if(analogRead(A1) < adn1){
  ...
  }
 if(analogRead(A1) > adn1) {
  ...
 }
 etc...

Buenas tardes otra vez,
Con respecto a lo de los pulsadores, aprovecho los que van en el tablero de origen, y la alimentación de ellos viene del coche a 12V ya que los usa para algo de otra centralita. Así que me toca reducir el voltaje de la señal antes de entrar a arduino.

En relación a la modificación del código que me comentáis, la verdad que me ha quedado mucho mas simple de lo que lo tenia, pero me sigue sin funcionar.
Al pulsar el botón de NIVEL 1 (por ejemplo) de la app , me acciona TODOS los relés , tanto de subir como de bajar.

Adjunto todo el código a ver si veis alfo que se me escapa o es que simplemente la estructura de IF no es la correcta...

int nivel;
int valor;

int memoria;

bool estado1;
bool estado1Ant;
bool estado2;
bool estado2Ant;

int estado = 0;

int adn1 = 200;
int atn1 = 200;

int adn2 = 250;
int atn2 = 250;

int adn3 = 300;
int atn3 = 300;

int adn4 = 350;
int atn4 = 350;

#include <EEPROM.h>

void setup()
{

  Serial.begin(9600);

  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);

  digitalWrite (6, HIGH);
  digitalWrite (7, HIGH);
  digitalWrite (8, HIGH);
  digitalWrite (9, HIGH);
  digitalWrite (10, HIGH);
  digitalWrite (11, HIGH);
  digitalWrite (12, HIGH);
  digitalWrite (13, HIGH);

  estado1Ant = LOW;
  estado1 = LOW;

  estado2Ant = LOW;
  estado2 = LOW;

  valor=0;


  EEPROM.get( memoria , nivel);

}

void loop()
{
  if ( Serial.available() > 0)
  {
    estado = Serial.read();
  }
  switch ( estado)
  {

    case 'a':
      digitalWrite(6, LOW);
      break;
    case 'b':
      digitalWrite(6, HIGH);
      digitalWrite(10, HIGH);
      break;
    case 'c':
      digitalWrite(10, LOW);
      break;


    case 'd':
      digitalWrite (7, LOW);
      break;
    case 'e':
      digitalWrite (7, HIGH);
      digitalWrite (11, HIGH);
      break;
    case 'f':
      digitalWrite (11, LOW);
      break;


    case 'g':
      digitalWrite(8, LOW);
      break;
    case 'h':
      digitalWrite(8, HIGH);
      digitalWrite(12, HIGH);
      break;
    case 'i':
      digitalWrite(12, LOW);
      break;


    case 'j':
      digitalWrite(9, LOW);
      break;
    case 'k':
      digitalWrite(9, HIGH);
      digitalWrite(13, HIGH);
      break;
    case 'l':
      digitalWrite(13, LOW);
      break;



    case 'm':
      nivel = 1;
      valor = 1;
      break;

    case 'n':
      nivel = 2;
      valor = 1;
      break;

    case 'o':
      nivel = 3;
      valor = 1;
      break;


    case 'p':
      nivel = 4;
      valor = 1;
      break;

  }


//OPCION PULSADORES FISICOS: 

  estado1 = digitalRead(4);

  if (estado1 == HIGH && estado1Ant == LOW) {
    nivel++;
    valor = 1;
  }
  estado1Ant = estado1;

  EEPROM.put( memoria , nivel);

  estado2 = digitalRead(5);

  if (estado2 == HIGH && estado2Ant == LOW) {
    nivel--;
    valor = 1;
  }
  estado2Ant = estado2;

  EEPROM.put( memoria , nivel);


  //CODIGO NIVELES:

  //  NIVEL 1:

  if ( nivel == 1 && valor == 1 )
  {
    if (analogRead(A1) < adn1)
    {
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
    }
    
    if (analogRead(A1) > adn1 )
    {
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    }
    
    if ( analogRead(A1) == adn1)
    {
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH);
    }
    
    if (analogRead(A2) < atn1)
    {
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
    }
    
    if (  analogRead(A2) > atn1)
    {
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
    }
    
    if ( analogRead(A2) == atn1)
    {
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
    }
    if (analogRead(A1) == adn1 && analogRead(A2) == atn1)
  {
      digitalWrite(6, HIGH);
      digitalWrite(7 , HIGH);
      digitalWrite(8 , HIGH);
      digitalWrite(9 , HIGH);
      digitalWrite(10 , HIGH);
      digitalWrite(11 , HIGH);
      digitalWrite(12 , HIGH);
      digitalWrite(13 , HIGH);
      valor = 0;
    }

  }


    //  NIVEL 2:

  if ( nivel == 2 && valor == 1 )
  {
    if (analogRead(A1) < adn2)
    {
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
    }
    
    if (analogRead(A1) > adn1 )
    {
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    }
    
    if ( analogRead(A1) == adn2)
    {
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH);
    }
    
    if (analogRead(A2) < atn2)
    {
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
    }
    
    if (  analogRead(A2) > atn2)
    {
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
    }
    
    if ( analogRead(A2) == atn2)
    {
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
    }
    if (analogRead(A1) == adn2 && analogRead(A2) == atn2)
  {
      digitalWrite(6, HIGH);
      digitalWrite(7 , HIGH);
      digitalWrite(8 , HIGH);
      digitalWrite(9 , HIGH);
      digitalWrite(10 , HIGH);
      digitalWrite(11 , HIGH);
      digitalWrite(12 , HIGH);
      digitalWrite(13 , HIGH);
      valor = 0;
    }

  }

    //  NIVEL 3:

  if ( nivel == 3 && valor == 1 )
  {
    if (analogRead(A1) < adn3)
    {
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
    }
    
    if (analogRead(A1) > adn3 )
    {
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    }
    
    if ( analogRead(A1) == adn3)
    {
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH);
    }
    
    if (analogRead(A2) < atn3)
    {
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
    }
    
    if (  analogRead(A2) > atn3)
    {
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
    }
    
    if ( analogRead(A2) == atn1)
    {
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
    }
    if (analogRead(A1) == adn3 && analogRead(A2) == atn3)
  {
      digitalWrite(6, HIGH);
      digitalWrite(7 , HIGH);
      digitalWrite(8 , HIGH);
      digitalWrite(9 , HIGH);
      digitalWrite(10 , HIGH);
      digitalWrite(11 , HIGH);
      digitalWrite(12 , HIGH);
      digitalWrite(13 , HIGH);
      valor = 0;
    }

  }

    //  NIVEL 4:

  if ( nivel == 4 && valor == 1 )
  {
    if (analogRead(A1) < adn4)
    {
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
    }
    
    if (analogRead(A1) > adn4 )
    {
      digitalWrite(10, LOW);
      digitalWrite(11, LOW);
    }
    
    if ( analogRead(A1) == adn4)
    {
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(11, HIGH);
    }
    
    if (analogRead(A2) < atn4)
    {
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
    }
    
    if (  analogRead(A2) > atn4)
    {
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
    }
    
    if ( analogRead(A2) == atn4)
    {
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(12, HIGH);
      digitalWrite(13, HIGH);
    }
    if (analogRead(A1) == adn4 && analogRead(A2) == atn4)
  {
      digitalWrite(6, HIGH);
      digitalWrite(7 , HIGH);
      digitalWrite(8 , HIGH);
      digitalWrite(9 , HIGH);
      digitalWrite(10 , HIGH);
      digitalWrite(11 , HIGH);
      digitalWrite(12 , HIGH);
      digitalWrite(13 , HIGH);
      valor = 0;
    }

  }


}

Muchas gracias por la ayuda!!

Hola otra vez, he probado de poner los if directamente dentro del case , por probar, y me hace lo mismo.

También he probado de darle a los niveles des de diferentes posiciones, es decir darle en manual para que suba la presión y luego probar de darle a los niveles automáticos. y hace cosas muuy raras. depende la presion y del nivel, o activa todos tanto de subir como de bajar, en otros todos los de subir y la mitad de bajar a la vez, en otros si que lo hace medio bien , hasta que llega a un valor que ya empieza a hacer cosas raras...

Alguna idea??

Gracias de antemano!

Bueno, ya va ir avanzando el código.
He visto esto

estado1 = digitalRead(4);

pero no veo que definas a 4 como INPUT por lo tanto jamás a funcionar
Tampoco lo haces con el pin 5 que son aparentemente tus dos pines digitales.

debes indicarlo en el setup() asi

pinmode(4, INPUT);
Esta configuración vale para PULL-UP o PULL-DOWN
o

pinmode(4, INPUT_PULLUP);

donde le dices que el pin siempre esta viendo un HIGH y espera un LOW

De todas formas el problema no viene de eso, ya que de momento lo estoy probando solo des de los botones de la app …
He cambiado el código varias veces pero siempre acabo en ultima instancia con *if... ( if...**case "a"... **. // if....else... // if...if....) *.
Mi sospecha es que al poner < , > y = en cada if, como procesa tan rápido llega un punto que va mas rápido el programa que los relés físicos , se cumplen los 3 if i se queda en bucle activando tanto los relés de subir como los de bajar. ¿¿Puede ser??
Llevo días dándole vueltas pero no se me ocurre como solucionarlo... ya que si pongo un *delay() * imagino que me trabajara a "golpes". :confused:
Como siempre muchísimas gracias por vuestra ayuda!

Espero que no uses mucho tu programa porque acabo de descubrir esto

EEPROM.put( memoria , nivel);

que va destruir en muy poco tiempo tu EEPROM

La EEPROM no se usa asi de seguido.
Asi que por favor, deja de correr ese código o vas a tener que apuntar a otra dirección porque la dirección que usas quedará inservible.
La EEPROM tiene una vida util de 100.000 escrituras puede que algo mas, he leido de alquien que hizo un ensayo destructivo y llego a 5 veces ese valor pero eso pasa de vez en cuando, no es definitivo.

Lo mejor es que reconsideres el uso de esas linéas (estan repetidas) de código.

Si la rutina con la que incrementas o decrementas nivel esta bien hecha entonces solo cuando termines de pulsar sería convenientes que salves el valor y una vez. No con cada cambio.
Incluso poniendola dentro de la que sube nivel o de la que lo decrementa es mucho mejor de lo que haces ahora.
Lo habitual es tener un boton que sube, otro que baja y un tercero que es quien da la orden de guardar.

No estoy entendiendo mucho tu código pero me surgen un par de preguntas.
¿Cuando apagas el auto, la suspensión baja, sube o queda donde la pusiste?
Suponiendo que quede en su ultima posición ¿no puedes leer los sensores de presión al encender para saber en que nivel está y te ahorras tener que guardar los valores?

Ostras de eso no tenia ni idea... ¿Así seria correcto no?

estado1 = digitalRead(4);

  if (estado1 == HIGH && estado1Ant == LOW) {
    nivel1++;
    valor = 1;
    EEPROM.put( memoria1 , nivel1);

  }
  estado1Ant = estado1;

De todas formas todo el trozo de código de los pulsadores manuales y guardado en la memoria lo tengo como texto , y estoy trabajando solo des de la app , con un pulsador para cada nivel que manda un carácter y uso un case("X") para cada posición . Para simplificarlo un poco y conseguir al menos que vaya de un nivel al otro.

En cuanto a lo de leer los sensores de presión para saber el nivel que esta, no me gusta porque el coche es un 4x4, y siempre anda por montaña. Por lo que ,si por ejemplo, lo paro en medio de un camino con muchas regatas, al volver a encender las presiones serán muy dispares, ya que una rueda quizás esta dentro de la regata sin peso y la otra aguantado casi todo el peso .

La idea es que solo se regule cuando yo le de al botón (físico o a través de la app) , en sitios lo mas nivelado posible.

gatul:
No estoy entendiendo mucho tu código pero me surgen un par de preguntas.

Lo que me dices que no estas entendiendo , lo veo normal, es mi primer código "de verdad" y voy muy perdido.

Es objetivo de lo que tendría que hacer es : si presiono para subir, suma 1 al nivel , lee la presión (es diferente en cada suspensión ya que delante tiene mas peso que atrás. de momento lo he simplificado con dos presiones, delante i detrás) . Si la presión es inferior a la asignada, entonces activa el relé (LOW) .Al llegar a la presión asignada se para y ya no tiene que hacer nada mas. si vuelvo a presionar subir, se repite pero con la presión del próximo nivel. Si presiono bajar hace lo mismo per restando 1 al nivel.

Seguro que hay alguna manera mucho mas simple y efectiva pero de momento no he dado con ella.

Gracias a los dos por los comentarios. Se agradece muchísimo.

Entiendo que entonces solo puedes regular la suspensión en el llano.
La regulas y ya queda así a menos que vuelvas a pulsar un botón para volver a regular.
Ahora me voy haciendo una idea más armada. :wink:

Se me ocurrió, para no quemar innecesariamente la eeprom (y como alternativa a usar otro pulsador) podrías leer el estado de la alimentación mediante algún pin (si te queda alguno disponible) y guardar los datos en eeprom solo al momento de apagar el vehículo.
Algo así

Cuando lees LOW en el pin (Dx en el esquema) inmediatamente guardas los datos (incluso podría usarse una interrupción si el pin lo permite).
Con una variable de control podrías incluso guardar solo si hubo modificaciones.
El condensador mantendría la alimentación el tiempo suficiente para guardar los datos.

Aunque esto

MARTIARACIL:
Ostras de eso no tenia ni idea... ¿Así seria correcto no?

estado1 = digitalRead(4);

if (estado1 == HIGH && estado1Ant == LOW) {
    nivel1++;
    valor = 1;
    EEPROM.put( memoria1 , nivel1);

}
  estado1Ant = estado1;

esta mucho mejor y en parte es lo que te sugería, también algo como un 3er botón que confirme la configuración a aguardar o un pulsado largo o lo que sugiere @gatul con un detector de apagado del Arduino/encendido del auto son soluciones mucho mejores.

Ejemplo de esto es que si cambiaras 30 valores por decir algo, son 30 grabaciones, claro que hablamos de 100mil y seguramente no llegues nunca pero, es un momento en que debes respetar este tipo de cosas o no quejarte en unos años por un fallo que te costará reconocer que ocurre.

Muchas gracias a los dos, al final después de darle muchas vueltas lo tengo funcionando.
Por lo que hace al tema del guardado de valores lo tengo hecho de momento como puse, para no modificar hardware. dudo que nunca llegue a los 100mil ni si quiera a los mil....

Y referente al tema de que hacia un poco lo que le daba la gana con los relés, a parte de que cambie un poco el código para separar completamente las delanteras y traseras, el problema era "mecánico" . No se muy bien porque, en el momento de meter o quitar presión los valores que marca no son los reales de la suspensión.

Ej. presión estable marca 400. mientras mete presión sube a 500 i al parar se estabiliza en 430. Mientras bajo marca 100 i al parar y estabilizar marca los 400.

De momento lo he solucionado poniendo para cada posición 3 valores , el estable, el de bajada (-XX) i el de subida (+YY).. no se si vosotros con mas experiencia sabéis como solucionarlo de manera mas fiable y sencilla.

Como siempre muchas gracias.!

Como los valores en un AD no son estables, no sirve poner condiciones estrictas como que cuando algo sea igual a X hago tal cosa, eso solo te conduce a fracaso o comportamientos indeseados.
Otra cosa es que debes usar histéresis. O sea, si el sensor supera un valor activas un RELE pero si caer del valor consultado no lo apaga. Debe ir mas abajo de un valor de histéresis que asegurar que el RELE no se va a prender y apagar en el entorno del valor de control.

Y asi con todo.

Respecto del tema EEPROM se me acaba de ocurrir algo mas que podría achicar el abuso de escrituras.
Una especie de tiempo de cambios que establezca cuando guardar el dato.
Estamos de acuerdo que todo cambio de tus valores debe ser almacenado pero cúando hacerlo? Si lo haces con cada cambio digamos que estamos grabando situaciones parciales que no son importantes pero... que tal si con cada cambio inicias un temporizador y este temporizador solo espera a que no haya mas cambios y cuando eso pase aún cuando luego lo vuelvas a cambiar, guardará mucho menos datos.

Solo para que lo imagines. Quieres guardar 50. Y estabas en 0.
Con el método actual guardarás 50 valores pero si depende de un timer que le dice.. no guardo a menos que se superen 5 segundos.... todos los valores se irán reservando y cuando por 5 segundos no hagas mas cambios entonces lo almacena.
Creo que es lo mejor que se puede hacer con 2 botones, o bien, de nuevo se me ocurre algo mas.
Y si se guarda el dato presionando los dos simultáneamente?

Tienes entonces dos métodos posibles.