/*
* Trama 1. Control de salidas de Relé para el microPLC - arduino
*
* Descripción: Control de los relés de salida de la placa microPLC mediante códigos enviados
* desde el terminal serie. Mediante RS-232 con el adaptador USB del arduino.
*
* Autor: Juan Carlos Sande
* Fecha: 08-10-2024
* Versión: 1.0
*/
//verde pin 8 out1
//verde pin 9 out2
//rojo pin 10 out3
// Asignación de Pins a Salidas digitales
#define Out_1 8
#define Out_2 9
#define Out_3 10
#define Out_4 11
// Pins de entrada (están ordenados de forma decreciente por necesidades del PCB)
#define In_1 2
#define In_2 3
#define In_3 4
#define In_4 5
// Librerías
//#include "microPLC.h"
#include <string.h>
//#include <Servo.h>
#include <TimerOne.h>
//*******************************************************
//Variables de eventos
bool Evento_TV_S1;
bool Evento_TA_S1;
bool Evento_TR_S1;
//*******************************************************
//Variables de estados
byte estado_semaforo_S1;
#define estado_verde 1
#define estado_ambar 2
#define estado_rojo 3
//Tiempos para cada semaforo
#define tiempo_verde_S1 10
#define tiempo_ambar_S1 2
#define tiempo_rojo_S1 6
// Funciones prototipo
void getInputs(void);
void setOutputs(void);
//Funciones semaforo
void tiempo_1seg(void);
void modo_verde_S1(void);
void modo_ambar_S1(void);
void modo_rojo_S1(void);
//********************************
void Menu(void);
unsigned char GetCode(void);
void Cmd(void);
void Pulsador_01(void);
void Pulsador_02(void);
void Motor(void);
// Variables globales
int variable_tiempo;
//Definición de las variables de trabajo
bool s1,s2,s3,s4; // Entradas del MicroPLC
bool k1,k2,k3,k4; // Salidas del MicroPLC
bool estadoPulsador_01=true;
bool estadoPulsador_02=true;
void setup()
{
// Iniciar las comunicaciones en serie
Serial.begin(9600);
// Establecer los pins de salida de los relés
pinMode(Out_1, OUTPUT);
pinMode(Out_2, OUTPUT);
pinMode(Out_3, OUTPUT);
pinMode(Out_4, OUTPUT);
// Establecer los pins de entradas digitales optoacopladas
pinMode(In_1, INPUT);
pinMode(In_2, INPUT);
pinMode(In_3, INPUT);
pinMode(In_4, INPUT);
// Inicio del primer estado
k1=0;
k2=0;
k3=0;
Timer1.initialize(1000000);//configuracion de timer1 para que dispare cada 1000000 microsegundo (1 segundo)
Timer1.attachInterrupt (tiempo_1seg); // llamada a la funcion tiempo_1seg para que se dispare cada segundo
Timer1.stop(); // parada del tiempo1 para que no empieze a contar de inicio.
// inicio del semaforo con la luz verde
estado_semaforo_S1 = estado_verde;
modo_verde_S1();
variable_tiempo = tiempo_verde_S1; // asignacion del tiempo del semaforo verde
Timer1.start(); // inicio del temporizador
// Mostrar el menu de información
Menu();
}
/* loop
* Programa principal
*/
void loop(){
getInputs(); // Leer las entradas digitales
Pulsador_01(); // Ejecuta acciones segun estado pulsador 1
Pulsador_02(); // Ejecuta acciones segun estado pulsador 2
//-------- Trama --------
// Si se ha recibido algún carácter
if (Serial.available()) {
// Leer los caracteres recibidos
Cmd();
}
//1.- USO DE RECURSOS
//2.- ANTENCION DE EVENTOS
if (Evento_TV_S1){
Evento_TV_S1=false;
//Que hacer con el evento de culminacion del tiempo verde
estado_semaforo_S1 = estado_ambar;
modo_ambar_S1();
variable_tiempo = tiempo_ambar_S1;
Timer1.start();
}
if (Evento_TA_S1){
Evento_TA_S1=false;
//Que hacer con el evento de culminacion del tiempo ambar
estado_semaforo_S1 = estado_rojo;
modo_rojo_S1();
variable_tiempo = tiempo_rojo_S1;
Timer1.start();
}
if (Evento_TR_S1){
Evento_TR_S1=false;
//Que hacer con el evento de culminacion del tiempo rojo
estado_semaforo_S1 = estado_verde;
modo_verde_S1();
variable_tiempo = tiempo_verde_S1;
Timer1.start();
}
setOutputs(); // Activar las salidas
delay(1);// CicloScan + 1ms, retardo para anti-rebotes
}
/* Menu
* Información con los comandos programados
*/
void Menu(void){
Serial.println("Frame: <cmd> <parametro> ");
Serial.println("cmd: <p>Paro");
Serial.println(" <m> Marcha");
Serial.println("parametro: <1..4> Rele");
}
void Cmd(void){
// Verificar si hay datos disponibles en el Monitor Serie
if (Serial.available() > 0) {
// Leer el comando del Monitor Serie
String comando = Serial.readStringUntil('\n');
comando.trim(); // Eliminar espacios en blanco
// Encender LEDs
if (comando == "m1"||comando == "M1") {
k1=1;
Serial.println("k1=1");
} else if (comando == "m2") {
k2=1;
Serial.println("k2=1");
} else if (comando == "m3") {
k3=1;
Serial.println("k3=1");
} else if (comando == "m4") {
k4=1;
Serial.println("k4=1");
}
// Apagar LEDs
else if (comando == "p1") {
k1=0;
Serial.println("k1=0");
} else if (comando == "p2") {
k2=0;
Serial.println("k2=0");
} else if (comando == "p3") {
k3=0;
Serial.println("k3=0");
} else if (comando == "p4") {
k4=0;
Serial.println("k4=0");
}
}
}
/* GetInputs
* Lee el estado de la entrada indicada en el parámetro y lo asigna invertido a las variables de trabajo
*/
void getInputs(void){
s1=digitalRead(In_1);
s2=digitalRead(In_2);
s3=digitalRead(In_3);
s4=digitalRead(In_4);
}
/* setOutputs
* Asigna el estado de las variables de trabajo a las salidas digitales
*/
void setOutputs(void){
digitalWrite(Out_1, k1);
digitalWrite(Out_2, k2);
digitalWrite(Out_3, k3);
digitalWrite(Out_4, k4);
}
/* Pulsador_01
* Ejecuta entrada a traves del pulsador 01
*/
void Pulsador_01(void){
if (s1==1 && estadoPulsador_01==true){
estadoPulsador_01=false;
k1=!k1;//K1 valdra lo contrario de como este cada vez que pasa por esta linea si es TRUE pasa a FALSE o viceversa.
Serial.println("Pulsador_01=On");
}
else if (s1==0 && estadoPulsador_01==false){
estadoPulsador_01=true;
//k1=0;
Serial.println("Pulsador_01=Off");
}
}
/* Pulsador_02
* Ejecuta entrada a traves del pulsador 01
*/
void Pulsador_02(void){
if (s2==1 && estadoPulsador_02==true){
estadoPulsador_02=false;
k2=1;
Serial.println("Pulsador_02=On");
}
else if (s2==0 && estadoPulsador_02==false){
estadoPulsador_02=true;
k2=0;
Serial.println("Pulsador_02=Off");
}
}
void tiempo_1seg(void){
variable_tiempo--;//Se resta un segundo cada vez
if (variable_tiempo<=0){
if(estado_semaforo_S1==estado_verde){
//Lanzar estado de culminacion de Tiempo Verde
Timer1.stop();
Evento_TV_S1=true;
}
if(estado_semaforo_S1==estado_ambar){
//Lanzar estado de culminacion de Tiempo Ambar
Timer1.stop();
Evento_TA_S1=true;
}
if(estado_semaforo_S1==estado_rojo){
//Lanzar estado de culminacion de Tiempo Rojo
Timer1.stop();
Evento_TR_S1=true;
}
}
}
void modo_verde_S1(void){
k1=1; //verde
k2=0;
k3=0;
}
void modo_ambar_S1(void){
k1=0;
k2=1; //ambar
k3=0;
}
void modo_rojo_S1(void){
k1=0;
k2=0;
k3=1; //rojo
}