In this tutorial, I am going to show how to control state of Finite State Machine via webpage. As an example, I am going to show how to control LED according to Finite State Machine model.

Demonstration




First of all, let’s think about real-time controlling Arduino via webpage:

Advantage: remotely and real-time controlling Arduino without developing and installing any special software and works on variety Operating System (Android, iOS, Windows…) as long as it installed a web browser.

Disadvantage: need to have knowledge of web programming

Solution: PHPoC Shield for Arduino has a built-in Web Server and some pre-programmed web application, allowing user to remotely control and monitoring Arduino via Webpage without requiring any knowledge of web programming. See more at https://www.hackster.io/phpoc_man/ar...bsocket-056f16

The pre-programmed web application I used in this project is “Web Remote Control / Push”.
User interface is like below:

Click image for larger version  Name:	state_machine_ui.jpg Views:	1 Size:	23.4 KB ID:	598

When websocket connection is established, if a button is pressed or released, Web Application sends a command to Arduino. For example, when button A is pressed and released, ‘A’ and ‘a’ command is sent to Arduino, respectively.
There are 3 LEDs (Red, Green, Yellow) in this project. I use three button A, B, C to turn on/off these LEDs. When a button is pressed, the current LED is blinked in short time and turned off, new LED corresponding to this button is turned on.

State machine diagram is shown as below.

Click image for larger version  Name:	state_machine.png Views:	1 Size:	11.4 KB ID:	599



Things Used In This Project
  • Arduino Uno.
  • PHPoC Shield for Arduino.
  • 7v Green LED, Red LED and Yellow LED.
  • 3 Relays


Click image for larger version  Name:	state_machine_wiring.PNG Views:	1 Size:	416.7 KB ID:	600



Source Code.

I made two pieces of codes with the same functionality. The first one is normal code. The other is State Machine code.

Normal Code

Code:
/* arduino web server - remote control (push button) */

#include "SPI.h"
#include "Phpoc.h"

#define STATE_YELLOW 'A'
#define STATE_GREEN  'B'
#define STATE_RED  'C'

#define PIN_LED_YELLOW   3
#define PIN_LED_GREEN   8
#define PIN_LED_RED   9

PhpocServer server(80);

char current_led = STATE_RED;
int pins[3] = {PIN_LED_YELLOW, PIN_LED_GREEN, PIN_LED_RED};

void handleEvent(char stt);

void setup(){
 Serial.begin(9600);
 while(!Serial)
  ;

 Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
 //Phpoc.begin();

 server.beginWebSocket("remote_push");

 Serial.print("WebSocket server address : ");
 Serial.println(Phpoc.localIP());

 pinMode(PIN_LED_YELLOW, OUTPUT);
 pinMode(PIN_LED_GREEN, OUTPUT);
 pinMode(PIN_LED_RED, OUTPUT);

 digitalWrite(PIN_LED_RED, HIGH);

}

void loop() {
 //Wait for a new client:
 PhpocClient client = server.available();

 if (client) {
  if (client.available() > 0) {
   //Read the bytes incoming from the client:
   char event = client.read();
   if(event == 'A' || event == 'B' || event == 'C')
    if(event != current_led)
     handleEvent(event);
  }
 }
}

void handleEvent(char event){

 for(int i = 0; i < 5; i++){
  digitalWrite(pins[current_led - 'A'], (i%2));
  delay(100);
 }
 //Turn on green led
 digitalWrite(pins[event - 'A'], HIGH);

 // update current state
 current_led = event;
}




Finite State Machine Code

Code:
/* arduino web server - remote control (push button) */

#include "SPI.h"
#include "Phpoc.h"

#define STATE_YELLOW 'A'
#define STATE_GREEN  'B'
#define STATE_RED  'C'

#define PIN_LED_YELLOW   3
#define PIN_LED_GREEN   8
#define PIN_LED_RED   9

PhpocServer server(80);

char fsm_state = STATE_RED;

void FSMEvent(char stt);

void setup(){
 Serial.begin(9600);
 while(!Serial)
  ;

 Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
 //Phpoc.begin();

 server.beginWebSocket("remote_push");

 Serial.print("WebSocket server address : ");
 Serial.println(Phpoc.localIP());

 pinMode(PIN_LED_YELLOW, OUTPUT);
 pinMode(PIN_LED_GREEN, OUTPUT);
 pinMode(PIN_LED_RED, OUTPUT);

 digitalWrite(PIN_LED_RED, HIGH);
}

void loop() {
 //Wait for a new client:
 PhpocClient client = server.available();

 if (client) {
  if (client.available() > 0) {
   //Read the bytes incoming from the client:
   char event = client.read();
   if(event == 'A' || event == 'B' || event == 'C')
    if(event != fsm_state)
     FSMEvent(event);
  }
 }
}

void FSMEvent(char event){

 //Action is taken based on current state and event
 switch(fsm_state){
  case STATE_YELLOW:

   if(event == STATE_GREEN){
    //Blink yellow led in a second and then turn off
    for(int i = 0; i < 5; i++){
     digitalWrite(PIN_LED_YELLOW, (i%2));
     delay(100);
    }
    //Turn on green led
    digitalWrite(PIN_LED_GREEN, HIGH);
   }
   else if(event == STATE_RED){
    //Blink yellow led in a second and then turn off
    for(int i = 0; i < 5; i++){
     digitalWrite(PIN_LED_YELLOW, (i%2));
     delay(100);
    }
    //Turn on red led
    digitalWrite(PIN_LED_RED, HIGH);
   }

   break;

  case STATE_GREEN:

   if(event == STATE_YELLOW){
    //Blink green led in a second and then turn off
    for(int i = 0; i < 5; i++){
     digitalWrite(PIN_LED_GREEN, (i%2));
     delay(100);
    }
    //Turn on yellow led
    digitalWrite(PIN_LED_YELLOW, HIGH);
   }
   else if(event == STATE_RED){
    //Blink green led in a second and then turn off
    for(int i = 0; i < 5; i++){
     digitalWrite(PIN_LED_GREEN, (i%2));
     delay(100);
    }
    //Turn on red led
    digitalWrite(PIN_LED_RED, HIGH);
   }

   break;

  case STATE_RED:

   if(event == STATE_YELLOW){
    //Blink red led in a second and then turn off
    for(int i = 0; i < 5; i++){
     digitalWrite(PIN_LED_RED, (i%2));
     delay(100);
    }
    //Turn on yellow led
    digitalWrite(PIN_LED_YELLOW, HIGH);
   }
   else if(event == STATE_GREEN){
    //Blink red led in a second and then turn off
    for(int i = 0; i < 5; i++){
     digitalWrite(PIN_LED_RED, (i%2));
     delay(100);
    }
    //Turn on green led
    digitalWrite(PIN_LED_GREEN, HIGH);
   }

   break;
 }

 // update current state
 fsm_state = event;
}