Pages: 1 [2] 3   Go Down
Author Topic: Máquina de estados: Librería FSM  (Read 10008 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
No he fallado. Acabo de encontrar 10 mil maneras que no funcionan. Thomas Edison
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

 smiley-eek ole!
Logged

Algunas personas sueñan con grandes logros, mientras que otros no duermen cumpliéndolos.

http://diagnostican.blogspot.com

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

Tengo un link que explica ambos, (en ingles)

http://www.stateworks.com/active/download/TN10-Moore-Or-Mealy-Model.pdf

Es sobre un microondas y se ve las diferencias de ambos.
Cual es mejor? la moraleja de este documento dice que ninguno pero ambos juntos.
« Last Edit: October 20, 2011, 07:48:26 am by yOPERO » Logged

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

     

[SOLUCIONADO]

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A nivel de cómputo son igual de potentes.

Si quereís demostración matemática, la teoría de automatas dice:
http://es.scribd.com/doc/54703356/24/Equivalencia-de-Maquinas-de-Mealy-y-Maquinas-de-Moore

Si no os quereís leer el rollo, al final:
Una maquina mealy es equivalente a una Moore y viceversa.

Al final, la elección entre un tipo de diseño Moore o Mealy es más bien a qué esté acostumbrado el desarrollador. Si:
Para ti una transición entre estados implica un cambio en la salida. Elige Mealy

Para ti un estado implica una salida . Elige Moore.

Saludos,
Aritz R
Logged


0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Acabo de hacerme un programita rápido usando mi librería FSM. Se trata de medir el tiempo de 0 a 100 kph en el coche, recogiendo la velocidad del bus CAN.... un quema embragues!!

Es un todo en uno!!

- Tiene como utilizar filtros hardware para el bus CAN con nuestra librería.
- Como ir cambiando de menus en el LCD según eventos
- Programación mediante Máquina de estados.






El programa es tán sencillo como:

Code:
// -------------------------------------------------------------------------------------
// SECUduino: Chrono 0 to 100 kph
// By Igor Real
// 22/10/2011
// -------------------------------------------------------------------------------------

#include <FSM.h>
#include <LiquidCrystal.h>
#include <CAN.h>
#include "myStates.h"

#define delayShowData  7000

//VARIABLES
unsigned char myEvent;
char myByteRec;
unsigned long my0to100;
unsigned long t0;
unsigned long t_prev;
float Speed;
char bUpdateLCD;

LiquidCrystal LCD(13,12, 11, 10, 9, 8, 7);

void setup()
{
  
  LCD.begin(20,4);
  bUpdateLCD=1;
  
  CAN.begin(100);
  uint16_t  Filters[6];
  uint16_t Masks[2];
  Masks[0]=0x3FF;
  Masks[1]=0x3FF;
  Filters[0]=0x351;  //Buffer0
  Filters[2]=0x351;  //Buffer1
  CAN.SetFilters(Filters,Masks);  //Only messages with ID=0x351 are allowed in both Rx buffers
  
  FSM.begin(FSM_NextState,nStateMachine,FSM_State,nStateFcn,STATE1);
}

void loop()
{
  ReadEvents();
  FSM.Update();
}


void ReadEvents(void)
{
  
  if (CAN.CheckNew() )
  {
    CAN.ReadFromDevice(&CAN_RxMsg);
    Speed=0.005*(256*CAN_RxMsg.data[2]+CAN_RxMsg.data[1]);
    LCD.setCursor(0,1);
    LCD.print("Speed= ");
    LCD.print((int)Speed);
  }
  
  if (Speed<=0){
    FSM.AddEvent(EV_Stop);
  }else if (Speed>=100){
    FSM.AddEvent(EV_100);
  }else if ( (Speed>0) && (Speed<100) ){
    FSM.AddEvent(EV_Start);
    bUpdateLCD=1;
  }
  
}

void func1(void)
{
  if (bUpdateLCD)
  {  
    LCD.clear();
    LCD.setCursor(0,0);
    LCD.print("  *- SECUduino -*");
  
    LCD.setCursor(0,2);
    LCD.print("State 1");
    
    bUpdateLCD=0;
  }
}

void func2(void)
{
  t0=millis();
  LCD.setCursor(0,2);
  LCD.print("State 2");
  FSM.AddEvent(0);
}

void func3(void)
{
  LCD.setCursor(0,2);
  LCD.print("State 3");
}

void func4(void)
{
  my0to100=millis()-t0;
  t_prev=millis();
  LCD.setCursor(0,2);
  LCD.print("State 4");
  
  LCD.setCursor(0,3);
  LCD.print((float)my0to100/(float)1000.0);
  LCD.print(" s");
  
  while(millis()-t_prev<=delayShowData);
  FSM.AddEvent(EV_Wait);  
}

Las estructuras usadas son:

Code:
const FSMClass::FSM_State_t FSM_State[] PROGMEM= {
// STATE,STATE_FUNC
{STATE1,func1},
{STATE2,func2},
{STATE3,func3},
{STATE4,func4},
};

const FSMClass::FSM_NextState_t FSM_NextState[] PROGMEM= {
// STATE,EVENT,NEXT_STATE
{STATE1,EV_Start,STATE2},
{STATE2,0,STATE3},
{STATE3,EV_100,STATE4},
{STATE3,EV_Stop,STATE1},
{STATE4,EV_Wait,STATE1},
};




Cuando vaya al coche, grabaré otro video....


 smiley-twist

« Last Edit: October 22, 2011, 06:17:11 am by Igor R » Logged


0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1414
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

menuda aceleracion Igor !! hahaha
como te dije ya implemente la funcion 0 a 100 pero sin estados y me funciono de maravilla, pero creo que con tu codigo es tambien muy claro.
me sirve de mucho el ejemplo, sobre todo para el tema de mascaras.
a ver si encuentro tiempo y lo pruebo.
genial trabajo Igor.
Logged

* Si preguntas, pon el código de tu programa, hace mucho mas fácil ayudarte. Y me ahorro un mensaje pidiendo que lo hagas.
* Si consigues solucionar tu problema, dedica unos minutos a explicar en tu post como lo conseguiste para beneficio de todos.
* Cambia el 'Subject' de tu hilo y añade 'SOLUCIONADO' cuando hayas llegado a una solución al problema que planteaste.
* Utiliza un 'Subject' para tu hilo que explique de que va el hilo.
Si estas empezando:
* Comienza a usar Arduino
* Guías de iniciación a Arduino
* Ejemplos
* Referencia del Lenguaje
* Conceptos básicos
Guia de usuario de arduino
Tutoriales en Ingles
Si necesitas que alguien te escriba el código: http://www.freelancer.com/  o esta  http://www.guru.com/

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfecto!  Pon tu código por aquí y así hay dos enfoques diferentes de un mismo problema.

smiley-wink
Logged


0
Offline Offline
Edison Member
*
Karma: 17
Posts: 1414
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no puedo poner toooooodo el codigo porque es enorme, a ver si saco un rato y extraigo el codigo y creo un miniprograma que solo haga eso, mientras tanto...

Code:
  void performance_accel(){
       
      if (OBD_DATA == true)
        {
          unsigned long elapse_time;
          elapse_time = millis() - start_time_elapse;
          /*
          Serial.print("Last speed: ");        Serial.print(last_SPEED_rx_data); 
          Serial.print("\tCurrent speed: ");   Serial.print(SPEED_rx_data);
          Serial.print("\tStart Millis: ");    Serial.print(start_time_elapse);
          Serial.print("\tCurrent Millis: ");    Serial.print(millis());
          Serial.print("\tElapse Millis: ");   Serial.print(elapse_time);
          Serial.println();
          */
          // performance_status = 0 -> ready to start test (0 kmh)
          // performance_status = 1 -> test started...reading (V > 0 kmh y < 100 y no han habido deceleraciones)
          // performance_status = 2 -> test aborted por deceleracion  o   test finalizado, esperando V = 0 kmh
         
          // Check if car is stopped
          if ( SPEED_rx_data == 0)
          {
            start_time_elapse = millis();
            performance_status = 0; // ready to start test
          }
         
         
          // READY TO START TEST -           
          if ( (performance_status == 0) && (SPEED_rx_data > 0) )
                {
                    performance_status = 1;  // test started...recording
                    Serial.println("Performance timing STARTED !!!");
                }

         
          // RUNNING -
          if (  (performance_status == 1)    &&    (SPEED_rx_data >= 100)    )
          {
                Serial.print("Performance timing COMPLETED"); Serial.print(" Time: "); Serial.println(elapse_time);
                  if (elapse_time < best_0_to_100)
                      {
                          Serial.println(" ******* NEW PERFORMANCE RECORD ***** ");
                          best_0_to_100 = elapse_time;
                      }
                performance_status = 2;
          }
         
         
          // RUNNING - Stop the test if deceleration before 100 kmh
          if (    (performance_status == 1)    &&    (SPEED_rx_data < last_SPEED_rx_data)    )
          {
              Serial.println("Performance timing STOPPED");
              performance_status = 2;
          }
         
        } // end if obd = true
       
      }


como he dicho luego lo pulo un poco y que quede mas presentable
Logged

* Si preguntas, pon el código de tu programa, hace mucho mas fácil ayudarte. Y me ahorro un mensaje pidiendo que lo hagas.
* Si consigues solucionar tu problema, dedica unos minutos a explicar en tu post como lo conseguiste para beneficio de todos.
* Cambia el 'Subject' de tu hilo y añade 'SOLUCIONADO' cuando hayas llegado a una solución al problema que planteaste.
* Utiliza un 'Subject' para tu hilo que explique de que va el hilo.
Si estas empezando:
* Comienza a usar Arduino
* Guías de iniciación a Arduino
* Ejemplos
* Referencia del Lenguaje
* Conceptos básicos
Guia de usuario de arduino
Tutoriales en Ingles
Si necesitas que alguien te escriba el código: http://www.freelancer.com/  o esta  http://www.guru.com/

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ja,ja,ja. Está muy bien! Lo has creado con una máquina de estados.... tu performance_status no es más que una variable con el estado actual.
Hay muchas maneras de hacerlo: con if, con switch, con lockup tables, etc.


smiley-wink

« Last Edit: October 22, 2011, 09:22:39 am by Igor R » Logged


0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Alguno podría indicarme si la máquina de estados es mas potente que el Grafcet.

El concepto es similar. Me acuerdo que cuando me explicaron Grafcet, como teníamos autómatas Omron que sólo tenía lenguaje ladder, nos dibujabamos el diagrama a mano y lo programábamos con biestables, que los usábamos para simular cada estado.

Me refiero con ésto, que al final que si Petri, Grafcet, UML, Mealy, Moore, etc son conceptos similares. Tampoco soy un experto, pero al final me parece un poco todo lo mismo. Actualmente me toca mirarme bastante código escrito en Stateflow (+ Simulink) de Matlab, y es más de lo mismo...

La librería FSM, simplemente es un paso más a tener un switch gigante, ya que en modo look up table, te queda más limpio y fácil de leer. Es una librería  bastante básica... podrías ir ampliando cosillas ( un buen libro gratuito http://www.tte-systems.com/books/pttes ).

Quote
Has hecho algo con QP¿
No. Alguna vez he intentado leer algún capítulo de su libro, pero no aguanto más de 5 min...es un somnífero cojonudo!!  smiley-wink

« Last Edit: October 24, 2011, 03:30:54 am by Igor R » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A mi me cuesta un poco digerir bien todo esto.

 - He estado viendo el código que puso Igor R al principio del hilo, me refiero a FSM_v5.pde, y veo, entre otras, una linea que no entiendo: 
mynumber=mynumber*10+(myByteRec-0x30);
Perdonad mi ignorancia, pero no entiendo esa expresión, concretamente los de multiplicar por 10 y lo de 0x30, pues lo que yo pondría sería: mynumber=mynumber+myByteRec

 . Refiriéndote a ese código, cita "El número debe ser enviado entre SxxxxE, donde S es de start y E de end. xxxx es un número (unsigned long)". Pero, si además de recoger el valor del sensor quisiera recoger otro tipo de valores o el valor de otros sensores, ¿habría que definir otra estructura de datos como, p.e., AxxxxB?

Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hola,

mynumber=mynumber*10+(myByteRec-0x30);

El 0x30 es porque usando el terminal serie de Arduino, estas recibiendo los datos en ASCII. Es decir, un cero es 0x30, un uno es 0x31, etc  Es decir, con la operacion (myByteRec-0x30) tienes tu numero decimal de 0 a 9.
Luego, acerca de por que multiplicas x10 lo que tenias.... Estas recibiendo los numeros en ASCII, es decir te llegan  diferentes bytes (uno por cada caracter). Por lo que si mandas un 123, te llega "1" "2" y "3". Si solo los sumas, seria un 6 (previa conversion de Ascii a decimal).

Puedes ampliar el programa como quieras para recibir varias cosas separadas por coma, por otro caracter o por lo que quieras.... ese codigo es solo un ejemplo.


Salu2


Igor


Nota- ordenador ingles, ni acentos ni enyes.
« Last Edit: November 08, 2011, 06:30:06 pm by Igor R » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Gracias Igor R, la rutina que yo empleaba sumaba los caracteres,  y no sus valores, y después convertía la cadena en valor. Supongo que el resultado es el mismo. Pero aplicando tu expresión el código es interpreta mas fácilemente.

Por lo que me comentas, veo que el envio de datos en serie no tiene una programación standar, o sea, que el código que recibe el dato estará en función del código que los manda. Yo ya he conseguido hacer gráficos en processing con datos enviados en serie desde arduino, pero mis conocimientos son muy básicos, sin embargo creo que existen programas generadores de gráficos que también guardan los datos en ficheros.  En este último caso, solo podremos enviar los datos si están correctamente "empaquetados" para un uso particular, ¿no?. ¿Existen diferencias en la forma de enviar datos a estos programas?¿podrías recomendar alguno? (mejor si son gratuitos)

Solo decir que mi interés es hacer un código propio, pero viendo como trabajan los demás voy enterándome de las cosas.
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Puedes usar KST, mira esto que escribi => http://real2electronics.blogspot.com/2011/09/arduino-adc-muestreo-alta-velocidad.html

Logged


Barcelona
Offline Offline
Jr. Member
**
Karma: 0
Posts: 67
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

buenas tardes a todos!!

he estado instalando el nuevo ide de arduino 1.0 y las libreeias con las que trasteo y cuando intento cargar un ejemplo (FSM_V5) me sale un error.
a que puede ser devido??

os dejo el error que os comento


* 010.JPG (80.68 KB, 406x480 - viewed 44 times.)
Logged

0
Offline Offline
Edison Member
*
Karma: 16
Posts: 1579
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hola,
Estoy con el movil,pero en plan rápido busca la modificación q hay q hacer a las librerias para el Uno. Simplemente es un include,ya q han cambiado el nombre del fichero.
Salu2
Logged


Pages: 1 [2] 3   Go Up
Jump to: