/*
___ ___ __ __ _
| __| / __| | \/ | / |
| _| \__ \ | |\/| | | |
|_| |___/ |_| |_| |_|
*/
/*
-------------------------------------------------------------------------------------------------------------------------------------
Miembros implementación:
Rosniel Isse Gonzalez 2241085
Estiven Olarte Cubides 1930581
Descripción de ejercicio, primera FSM:
• La primera FSM recibe caracteres desde el monitor serial e identifica las secuencias “A##A”,
“A##R”, “G##R” y “G##L”. Los símbolos ## deben contener números entre 0 y 9 (ej. A28R o
G36L). Al detectar una de estas secuencias, se deben activar salidas que permitan identificar la
secuencia recibida y dejar el número recibido en una variable global (ej. 28 o 36).
Se verificará conectando la placa Arduino UNO a un PC y enviando caracteres por el monitor
serial. Las salidas se verifican mediante el encendido de leds conectados a los pines de I/O de la
placa. En el monitor serial debe apreciarse el estado actual, cada que se presente un cambio de
estado y el último valor que sea recibido correctamente.
-------------------------------------------------------------------------------------------------------------------------------------
*/
/*
_ _ _ _
/_\ _ _ __ _ | | (_) ___ (_) ___
/ _ \ | ' \ / _` | | | | | (_-< | | (_-<
/_/ \_\ |_||_| \__,_| |_| |_| /__/ |_| /__/
*/
/*
Entradas: Caracteres que se enviarán desde el monitor serial.
Salidas: Leds en pines de I/O del Arduino (UNO, Devboard #1).
Aquí creo una variable global para almacenar el número detectado.
Descripción de los estados:
Se habilita la entrada por el Serial,
S1: Detecta la primera letra deben ser 'A' o 'G'.
S2: Detecta el primer número de la secuencia numeral interna.
S3: Detecta el segundo número de la secuencia numeral interna.
S4: Detecta la última letra, deben ser 'A', 'R' o 'L' y procesa la secuencia.
Salida (especificaciones): Mostrará un color determinado según la salida, al final
mostrará la secuencia completa en el monitor serial, pero solo cumplirá con
los colores si se realiza una determinada secuencia.
Color ROJO: Secuencia A##A.
Color VERDE: Secuencia A##R.
Color AZUL: Secuencia G##R.
Color VIOLETA: Secuencia G##L.
La FSM la voy a realizar en AI y la voy a representar mediante un diagrama de estados.
*/
//Librerías
#include <Arduino.h>
//Variables globales
char entradaCaracter; //Caracter de entrada, Serial.read.
String secuencia = ""; //Variable donde almaceno la secuencia.
int numeroSecuencia; //Variable donde almaceno la parte numeral de la secuencia, secuencia(1) && secuencia()2.
bool secuenciaLeds = false; //Variable de control.
const int pinRojo = 12; // Pin para el componente rojo del LED RGB.
const int pinVerde = 13; // Pin para el componente verde del LED RGB.
const int pinAzul = 11; // Pin para el componente azul del LED RGB.
//Enumeración de estados de la FSM.
enum States { S1, S2, S3, S4 };
States S = S1; //Inicio.
//FUNCIONES
/*
_____ _
| ___| _ _ _ __ ___ (_) ___ _ __ ___ ___
| |_ | | | | | '_ \ / __| | | / _ \ | '_ \ / _ \ / __|
| _| | |_| | | | | | | (__ | | | (_) | | | | | | __/ \__ \
|_| \__,_| |_| |_| \___| |_| \___/ |_| |_| \___| |___/
*/
//Encender ROJO.
void encenderRojo() {
digitalWrite(pinRojo, HIGH);
digitalWrite(pinVerde, LOW);
digitalWrite(pinAzul, LOW);
}
//Encender VERDE.
void encenderVerde() {
digitalWrite(pinRojo, LOW);
digitalWrite(pinVerde, HIGH);
digitalWrite(pinAzul, LOW);
}
//Encender AZUL.
void encenderAzul() {
digitalWrite(pinRojo, LOW);
digitalWrite(pinVerde, LOW);
digitalWrite(pinAzul, HIGH);
}
//Encender VIOLETA.
void encenderVioleta() {
digitalWrite(pinRojo, HIGH);
digitalWrite(pinVerde, LOW);
digitalWrite(pinAzul, HIGH);
}
//Apagar LED.
void apagarLED() {
digitalWrite(pinRojo, LOW);
digitalWrite(pinVerde, LOW);
digitalWrite(pinAzul, LOW);
}
//Función para limpiar BUFFER, es necesario para quitar cualquier residuo del buffer de lectura.
void limpiarBuffer() {
while (Serial.available() > 0) { //Siempre y cuando la lectura sea while(true) realizará el proceso de lectura.
Serial.read(); //Leyendo para ver si hay algo.
}
}
//Función de RESET.
void reset() {
secuencia = ""; //Limpia la secuencia.
S = S1; //Retorna a S1.
Serial.println("Estado S1, esperando:");
}
/*
___ _ _ _ ___ ___ __ __
| __| _ _ _ _ __ (_) ___ _ _ ___ ___ __| | ___ _ __ __ _ _ _ ___ (_) ___ | __| / __| | \/ |
| _| | || | | ' \ / _| | | / _ \ | ' \ / -_) (_-< / _` | / -_) | ' \ / _` | | ' \ / -_) | | / _ \ | _| \__ \ | |\/| |
|_| \_,_| |_||_| \__| |_| \___/ |_||_| \___| /__/ \__,_| \___| |_|_|_| \__,_| |_||_| \___| _/ | \___/ |_| |___/ |_| |_|
|__/
*/
//Estado 1.
void State_S1() {
apagarLED();
if (entradaCaracter == 'A' || entradaCaracter == 'G') { //Verifica la entrada, BUFFER.
secuencia += entradaCaracter; //Suma el caracter a la secuencia, secuencia = secuencia + caracter.
Serial.println(entradaCaracter);
Serial.println("Estado S1, se guardó caracter " + String(entradaCaracter) + " y la secuencia hasta este momento es: " + secuencia + ".");
S = S2; //Variable de control del Switch-case.
limpiarBuffer(); //Limpia el BUFFER.
} else if (entradaCaracter != 'A' || entradaCaracter != 'G') { //Verifica que no se cumple la condición inicial.
Serial.println("No es el caracter esperado en este estado, se mantiene en el estado S1 esperando el caracter correcto.");
limpiarBuffer(); //Limpia el BUFFER.
reset(); //Resetea, se mantiene en el mismo estado en este caso, en los próximos se devuelve a S1.
}
}
//Estado 2. Los comentarios son los mismos que en Estado 1.
void State_S2() {
if (isdigit(entradaCaracter)) {
secuencia += entradaCaracter;
Serial.println(entradaCaracter);
Serial.println("Estado S2, se guardó caracter " + String(entradaCaracter) + " y la secuencia hasta este momento es: " + secuencia + ".");
S = S3;
limpiarBuffer();
} else if (!isdigit(entradaCaracter)) {
Serial.println("No es el dígito esperado en este estado, y por lo tanto no cumple la secuencia. Se reinicia y vuelve al Estado S1.");
limpiarBuffer();
reset();
}
}
//Estado 3. Los comentarios son los mismos que en Estado 2.
void State_S3() {
if (isdigit(entradaCaracter)) {
secuencia += entradaCaracter;
Serial.println(entradaCaracter);
Serial.println("Estado S3, se guardó caracter " + String(entradaCaracter) + " y la secuencia hasta este momento es: " + secuencia + ".");
S = S4;
limpiarBuffer();
} else if (!isdigit(entradaCaracter)) {
Serial.println("No es el dígito esperado en este estado, y por lo tanto no cumple la secuencia. Se reinicia y vuelve al Estado S1.");
limpiarBuffer();
reset();
}
}
//Estado 4.
void State_S4() {
if (entradaCaracter == 'A' || entradaCaracter == 'R' || entradaCaracter == 'L') { //Verifica la entrada, BUFFER.
secuencia += entradaCaracter; //Suma el caracter a la secuencia, secuencia = secuencia + caracter.
Serial.println("Estado S4, se guardó " + String(entradaCaracter) + " y la secuencia completa es: " + secuencia);
numeroSecuencia = secuencia.substring(1, 3).toInt(); //Aquí usa substring para buscar los caracteres en la posición 1 y 3.
Serial.println("Número detectado: " + String(numeroSecuencia));
if (secuencia[0] == 'A' && secuencia[3] == 'A') {
encenderRojo(); //Salida con la secuencia A##A.
Serial.println("Salida " + secuencia + ", led encendido ROJO.");
secuenciaLeds = true; //Se activa la variable de control, si es una secuencia con aviso led es verdadero.
} else if (secuencia[0] == 'A' && secuencia[3] == 'R') {
encenderVerde(); //Salida con la secuencia A##R.
Serial.println("Salida " + secuencia + ", led encendido VERDE.");
secuenciaLeds = true; //Se activa la variable de control, si es una secuencia con aviso led es verdadero.
} else if (secuencia[0] == 'G' && secuencia[3] == 'R') {
encenderAzul(); //Salida con la secuencia G##R.
Serial.println("Salida " + secuencia + ", led encendido AZUL.");
secuenciaLeds = true; //Se activa la variable de control, si es una secuencia con aviso led es verdadero.
} else if (secuencia[0] == 'G' && secuencia[3] == 'L') {
encenderVioleta(); //Salida con la secuencia G##L.
Serial.println("Salida " + secuencia + ", led encendido VIOLETA.");
secuenciaLeds = true; //Se activa la variable de control, si es una secuencia con aviso led es verdadero.
} else if (secuenciaLeds = false) {
apagarLED();
}
limpiarBuffer();
Serial.println("Se cumplió la FSM, se reinicia la FSM determinista.");
reset();
} else if (entradaCaracter != 'A' || entradaCaracter != 'R' || entradaCaracter != 'L') { //Verifica que no se cumple la condición inicial.
Serial.println("No es el caracter esperado en este estado, y por lo tanto no cumple la secuencia. Se reinicia y vuelve al Estado S1.");
limpiarBuffer();
reset();
}
}
/*
__ __ ___ ___ ____ ____ _____ _____ _ _ ____
\ \ / / / _ \ |_ _| | _ \ / ___| | ____| |_ _| | | | | | _ \
\ \ / / | | | | | | | | | | \___ \ | _| | | | | | | | |_) |
\ V / | |_| | | | | |_| | ___) | | |___ | | | |_| | | __/
\_/ \___/ |___| |____/ |____/ |_____| |_| \___/ |_|
*/
void setup() {
Serial.begin(9600);
pinMode(pinRojo, OUTPUT);
pinMode(pinVerde, OUTPUT);
pinMode(pinAzul, OUTPUT);
}
/*
__ __ ___ ___ ____ _ ___ ___ ____
\ \ / / / _ \ |_ _| | _ \ | | / _ \ / _ \ | _ \
\ \ / / | | | | | | | | | | | | | | | | | | | | | |_) |
\ V / | |_| | | | | |_| | | |___ | |_| | | |_| | | __/
\_/ \___/ |___| |____/ |_____| \___/ \___/ |_|
*/
void loop() {
if (Serial.available() > 0) {
entradaCaracter = Serial.read();
switch (S) {
case S1:
State_S1();
break;
case S2:
State_S2();
break;
case S3:
State_S3();
break;
case S4:
State_S4();
break;
}
}
}