Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: 1 [2]   Go Down
Author Topic: alguna idea para mejorar este codigo SOLUCIONADO  (Read 1865 times)
0 Members and 1 Guest are viewing this topic.
Málaga, Spain
Offline Offline
Edison Member
*
Karma: 41
Posts: 2182
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Pues como comentaba nayma, aparte de poder definir en vectores lo pines, en este ejemplo vamos a utilizar estructuras de datos para definir los interruptores, una matriz para definir la máquina de estados y finalmente otro vector (array) para ejecutar las acciones.

El código queda muy limpio y sencillo, la mayor parte de las cosas son declaración de tipos y variables.

Code:
#include <Arduino.h>

#define OFF            0
#define SWITCHING_ON   1
#define ON             2
#define SWITCHING_OFF  3

// Defino la estructura de datos de mi interruptor
typedef struct
{
  uint8_t  buttonPin;
  uint8_t  miEstado; 
  uint8_t  ledPin;
} t_switch;

// Variable con mis interruptores
t_switch miInterruptor[] =
  {
    // boton, estado, LED
    { 2, OFF, 13 }, 
    { 4, OFF, 12 },
    { 7, OFF, 8 }
  };

// Definir transiciones de mi maquina de estados
// ---------------------------------------------
const uint8_t maquinaInterruptor[2][4] =
{
  // Estados
  //OFF,          SWITCHING_ON, ON,            SWITCHING_OFF 
  { OFF,          ON,           ON,            SWITCHING_OFF }, // transiciones cuando boton sin pulsar
  { SWITCHING_ON, SWITCHING_ON, SWITCHING_OFF, SWITCHING_OFF }  // transiciones cuando boton pulsado
};

// Definir las acciones en cada estado
const uint8_t accion[4] = { LOW, HIGH, HIGH, LOW };

// Numero de interruptores
#define NUM_SWITCH    ( sizeof(miInterruptor)/sizeof(t_switch) )

 
void scanAndSet ( uint8_t inPin, uint8_t outPin, uint8_t &state )
{
  uint8_t nuevoEstado;
 
  // Saco mi nuevo estado, sando la lectura del boton y mi estado actual
  nuevoEstado = maquinaInterruptor[digitalRead(inPin)][state];
 
  // Si el nuevo estado es diferente del antiguo ejecuto la accion
  // en este caso actuar sobre el LED
  if ( nuevoEstado != state )
  {
    digitalWrite ( outPin, accion[nuevoEstado] );
    state = nuevoEstado;
  }
}
 
void setup()
{
  for ( uint8_t i = 0; i < NUM_SWITCH; i++ )
  {
    pinMode ( miInterruptor[i].buttonPin, INPUT );
    pinMode ( miInterruptor[i].ledPin, OUTPUT );
  }
}


void loop()
{
  for ( uint8_t i = 0; i < NUM_SWITCH; i++ )
  {
    scanAndSet ( miInterruptor[i].buttonPin, miInterruptor[i].ledPin, miInterruptor[i].miEstado );
  }
  delay ( 100 );
}
Como veis, el código que ejecuta la maquina de estados, es muy simple. Lo único que hace es cambiar, el estado (utilizando la matriz de transiciones indexada por: el estado del pin y el estado actual). Funcionaría de la siguiente forma:
Supongamos que mi estado actual es SWITCHING_ON y el botón está a low, por lo tanto: maquinaInterruptor[1][0] == ON. Mi nuevo estado sería ON, ahora compruebo si ha habido cambio de estado e indexo la acción de digitalWrite con mi acción.

Espero que os haya gustado la solución. Esta es una solución muy rápida y fácil de implementar para una máquina de estados que no cambie mucho. Para rizar el rizo, se podría haber definido unos "functores" que ejecutasen la acción del estado en vez de usar el digitalWrite tal cual.

La solución algorítmica hace exactamente lo mismo que esta. Esta es más rápida pero consume un poco más de memoria, las matrices se podrían haber definido en memoria flash con lo que habríamos ganado en RAM.

El siguiente paso sería hacer lo mismo pero orientado a objetos.

Por cierto, por la razón que sea no me ha dejado definir el nombre de los estados como un tipo enumerado, que hubiese sido lo suyo. Ha saltado con un error de compilación absurdo.
typedef enum {OFF, SWITCHING_ON, ON, SWITCHING_OFF} t_estado;
Logged

   

Madrid
Offline Offline
Sr. Member
****
Karma: 5
Posts: 481
Life isn't about finding yourself, life is about creating yourself!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@fm es un problema de arduino ide, solución chapuza crearte

Code:
//hender.h
typedef enum {OFF, SWITCHING_ON, ON, SWITCHING_OFF} t_estado;

Logged

Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

Málaga, Spain
Offline Offline
Edison Member
*
Karma: 41
Posts: 2182
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Leñe!!! Pues si que es peculiar este chisme, en la vida se me hubiese ocurrido ponerlo dentro de un fichero de cabecera  smiley-cry!
Logged

   

Pages: 1 [2]   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: