//       (o\---/o)           
//        ( , , )
// ___,--.(_(Y)_),--.____
//|   "--"       "--"    |
//| Don't Worry Be Happy |
//| HECTOR E. VILLARREAL |
//|         2023         |
//|______________________|
//       )   |   (
//      (___,'.___) 
//CONTROL DE Aforo con pulsadores y Protothreads
//---------------------------------------------------------------------------------------------------
//Librerias
#include <LiquidCrystal.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <HTTPSRedirect.h>  //Instalar, no está en el paquete del IDE
#include <protothreads.h>  // include protothread library
//--------------------------------------------------------------
//Declaración de los PULSADORES
//--------------------------------------------------------------
int entrada=0;                   // variable entrada
int salida=0;                    // variable salida
byte Pe = 2;     //Pulsador entrada
byte Ps = 3;     //Pulsador salida
long pmpreviousMillis = 0;
//--------------------------------------------------------------
//Declaración de los LCD, led interno y BUZZER
//--------------------------------------------------------------
//Set LCD
LiquidCrystal lcd(A5, A4, A3, A2, A1, A0);  // Corresponde a (RS, EN, D4, D5, D6, D7)
int buzzer = 7;
const int ledPin = LED_BUILTIN; // led builtin

int ledState = LOW;         // ledState used to set the LED
long previousMillis = 0;
long interval = 500; // tiempo que queremos destelle el led

static struct pt pt1, pt2, pt3;  // each protothread needs one of these
//---------------------------------------------------------------------------------------------------
//--------------------------------------------------------------
//INICIALIZACION y CONFIGURACION del sistema
//--------------------------------------------------------------

void setup() {  // Set up serial interface and CAN bus interface
  Serial.begin(115200);
//--------------------------------------------------------------
//Configura primera linea LCD
lcd.begin(16, 2);   // Tipo de LCD
lcd.setCursor(0, 0); // Selecciono la Primera linea
lcd.print("Contr. Aforo 1.0"); // escribimos en la primera linea
//--------------------------------------------------------------

  PT_INIT(&pt1);  // initialise the two
  PT_INIT(&pt2);  // protothread variables
  PT_INIT(&pt3);  // protothread variables
}

/* exactly the same as the protothreadMainLoop function */
static int protothreadPulsadores(struct pt *pt) {
  PT_BEGIN(pt);
  while (1) {
//--------------------------------------------------------------
// Pulsador entrada
//--------------------------------------------------------------
  if(digitalRead(Pe)) {  // Pregunta si pulsador horario fue presionado
      //delay(100); //Anti-Rebote
      PT_SLEEP(pt, 100);  //Anti-Rebote
      entrada=entrada+1;  
  }
//--------------------------------------------------------------
// Pulsador salida
//--------------------------------------------------------------
  if(digitalRead(Ps)) {  // Pregunta si pulsador Antihorario fue presionado
      //delay(100); //Anti-Rebote
      PT_SLEEP(pt, 100);  //Anti-Rebote
      salida=salida+1;
  }
//--------------------------------------------------------------
    PT_END(pt);
  }
}
static int protothreadLcd(struct pt *pt) {
  PT_BEGIN(pt);
  while (1) {
  lcd.setCursor(0, 1);
  //Serial.print("Entrada= ");
  //Serial.println(entrada);
  lcd.print("IN=");
  lcd.print(entrada);
  //Serial.print("Salida= ");
  //Serial.println(salida);
  lcd.print(" OUT=");
  lcd.print(salida);  
  PT_END(pt);
  }
}
static int lcdLoop(struct pt *pt) {
  PT_BEGIN(pt);
  while (1) {
    //Serial.println("PROTO LOOP1");
    PT_END(pt);
  }
}

void loop() {
  Serial.println("loop ");
  protothreadPulsadores(&pt1);  // schedule the two protothreads
  protothreadLcd(&pt2); // by calling them infinitely
  lcdLoop(&pt3);
}