//#include <LiquidCrystal_I2C.h>
//SDA pin 19 and SCL pin 23 Lolin 32 lite
#include "LiquidMenu.h"
#include "AiEsp32RotaryEncoder.h"
#include "Arduino.h"
//#include <LiquidCrystal.h>
// Uso de la libreria AI Esp32RotaryEncoder
#if defined(ESP32)
#define ROTARY_ENCODER_A_PIN 27 // Pin CLK
#define ROTARY_ENCODER_B_PIN 26 // Pin DT
#define ROTARY_ENCODER_BUTTON_PIN 25 //Pîn SW
#endif
#define ROTARY_ENCODER_VCC_PIN -1 /* 27 put -1 of Rotary encoder Vcc is connected directly to 3,3V; else you can use declared output pin for powering rotary encoder */
#define ROTARY_ENCODER_STEPS 4
AiEsp32RotaryEncoder rotaryEncoder = AiEsp32RotaryEncoder(ROTARY_ENCODER_A_PIN, ROTARY_ENCODER_B_PIN, ROTARY_ENCODER_BUTTON_PIN, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
unsigned long shortPressAfterMiliseconds = 50;
unsigned long longPressAfterMiliseconds = 500;
// int led_seleccionado = 0;
bool mode = false; // Activa el while del movimiento del motor
int x = 0; // Variable que cuenta los pasos del motor (Analizar si para a variable local)
TaskHandle_t Tarea0;
int lastvalor = 0;
int valor = 0;
int Contauxcero;
bool testcero = false;
int x1 = 0; // Variable que cuenta los ciclos del motor
int delayciclos;
int demora;
int timer = 0;
int cursorPos;
int cursorPos2 = 0;
int Contaux = 0;
unsigned long Ciclos = 0;
unsigned long Ciclos_1 = 0;
unsigned long Ciclos_2 = 0;
unsigned long tanterior;
int Cont_1 = 0;
int Cont_2 = 0;
int Cont_3 = 0;
boolean Giro = true; // Variable que indica el sentido de giro del motor
boolean auxGiro;
String Gir;
boolean a = false; // Variable para ver si se activan por ciclos o no, si es FALSE se activa (invertir eso)
boolean b = false; // Variable para ver si se activan la opcion cantidad, si es FALSE se activa (invertir eso), se usa para la opcion de solo mover izq o der.
unsigned long Pasos = 0;
bool showChar = true;
//Driver Motor Step
const int steppin = 33;
const int dirpin = 32;
//Display 16x2
LiquidCrystal_I2C lcd(0x27, 16, 2);
//const int RS = 23, EN = 22, D4 = 5, D5 = 18, D6 = 19, D7 = 21;
//LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
byte tpuntos[] = {
0b00000,
0b00000,
0b00001,
0b01000,
0b11100,
0b01001,
0b01000,
0b01100
}; // t:
byte ipuntos[] = {
0b00000,
0b00000,
0b00001,
0b01000,
0b00000,
0b01001,
0b01000,
0b01100
}; //i:
byte s[] = {
0b00000,
0b01000,
0b10011,
0b10100,
0b10010,
0b10001,
0b01110,
0b00000
}; //(s
byte paren[] = {
0b00000,
0b10000,
0b01000,
0b01000,
0b01000,
0b01000,
0b10000,
0b00000
}; // )
byte uve[]{
0b00000,
0b00000,
0b10101,
0b10100,
0b10100,
0b10101,
0b01000,
0b00000
};
byte UP[]{
0b00100,
0b01110,
0b11111,
0b00100,
0b00100,
0b00100,
0b00000,
0b00000,
};
const int Pulsa = 10;
//ENCODER
//const int outputA = 17; // CLK
//const int outputB = 16; // DT
//const int SW = 4;
int incremento = 0;
int incrementos = 0;
int aState;
int bState;
int aLastState;
//const int UPs = 16;
//const int DW = 4; // Pin del pulsador para moverse hacia abajo
int buttonUpState;
int buttonDownState;
int lastButtonUpState = LOW;
int lastButtonDownState = LOW;
unsigned long lastDebounceTimeUp = 0;
unsigned long lastDebounceTimeDown = 0;
unsigned long debounceDelay = 50;
unsigned long lastDebounceTime = 0;
//const int UPs = 16;
//unsigned long debounceDelay = 50;
//LiquidMenu
//Pantalla 1
LiquidLine linea1(1, 0, "Volumen");
LiquidLine linea2(1, 1, "Encender");
//LiquidLine linea3(1, 0, "Ciclos?");
LiquidLine linea3(1, 0, "Opciones");
//LiquidLine linea4(1, 1, "Hola a todos");
LiquidScreen pantalla1(linea1,linea2,linea3);
//Pantalla linea 1 -> Pantalla 2
LiquidLine linea1_2(1, 0, "Cantidad");
LiquidLine linea2_2(1, 1, "Repeticiones");
LiquidLine linea3_2(1, 0, "Atras");
LiquidScreen pantalla2(linea1_2,linea2_2,linea3_2);
//Pantalla linea 2 -> Pantalla 3
LiquidLine linea1_3(1, 0, "Hacia la Der.");
//LiquidLine linea2_3(1, 1, "Hacia la Izq.");
LiquidLine linea3_3(1, 1, "Atras");
LiquidScreen pantalla3(linea1_3,/*linea2_3,*/linea3_3);
//Pantalla linea 4 -> Pantalla 4
LiquidLine linea1_4(1, 0, "Opcion 1");
LiquidLine linea2_4(1, 1, "Opcion 2");
LiquidLine linea3_4(1, 1, "Atras");
LiquidScreen pantalla4(linea1_4,linea2_4,linea3_4);
LiquidMenu menu(lcd,pantalla1,pantalla2,pantalla3,pantalla4);
void IRAM_ATTR readEncoderISR(){
rotaryEncoder.readEncoder_ISR();
}
void setup() {
rotaryEncoder.begin();
rotaryEncoder.setup(readEncoderISR);
bool circleValues = false;
rotaryEncoder.setBoundaries(-10000, 10000, circleValues); //minValue, maxValue, circleValues true|false (when max go to min and vice versa)
//rotaryEncoder.disableAcceleration(); //acceleration is now enabled by default - disable if you dont need it
rotaryEncoder.setAcceleration(250); //or set the value - larger number = more accelearation; 0 or 1 means disabled acceleration
Serial.begin(115200);
pinMode(Pulsa, INPUT_PULLUP);
pinMode(steppin, OUTPUT);
pinMode(dirpin, OUTPUT);
xTaskCreatePinnedToCore(Motor, "Tarea_0", 1000, NULL, 1, &Tarea0, 0);
lcd.init();
//lcd.clear();
lcd.backlight();
menu.init();
//lcd.begin(16, 2);
lcd.createChar (0, tpuntos);
lcd.createChar (1, ipuntos);
lcd.createChar (2, s);
lcd.createChar (3, paren);
lcd.createChar (4, uve);
//tanterior = millis();
linea1.set_focusPosition(Position::LEFT);
linea2.set_focusPosition(Position::LEFT);
linea3.set_focusPosition(Position::LEFT);
linea1.attach_function(1, fn_volumen);
linea2.attach_function(1, fn_encender);
linea3.attach_function(1, fn_opciones);
menu.add_screen(pantalla1);
//---------------------------------------------
linea1_2.set_focusPosition(Position::LEFT);
linea2_2.set_focusPosition(Position::LEFT);
linea3_2.set_focusPosition(Position::LEFT);
linea1_2.attach_function(1, fn_cantidad);
linea2_2.attach_function(1, fn_ciclos);
linea3_2.attach_function(1, fn_atras);
menu.add_screen(pantalla2);
//---------------------------------------------
linea1_3.set_focusPosition(Position::LEFT);
//linea2_3.set_focusPosition(Position::LEFT);
linea3_3.set_focusPosition(Position::LEFT);
linea1_3.attach_function(1, fn_onR);
//linea2_3.attach_function(1, fn_onL);
linea3_3.attach_function(1, fn_atras);
menu.add_screen(pantalla3);
//---------------------------------------------
linea1_4.set_focusPosition(Position::LEFT);
linea2_4.set_focusPosition(Position::LEFT);
linea3_4.set_focusPosition(Position::LEFT);
linea1_4.attach_function(1, fn_opcion1);
linea2_4.attach_function(1, fn_opcion2);
linea3_4.attach_function(1, fn_atras);
menu.add_screen(pantalla4);
//---------------------------------------------
pantalla1.set_displayLineCount(2);
pantalla2.set_displayLineCount(2);
pantalla3.set_displayLineCount(2);
pantalla4.set_displayLineCount(2);
menu.set_focusedLine(0);
menu.update();
}
void rotary_loop(){
//dont print anything unless value changed
if (rotaryEncoder.encoderChanged()){
//delay(250);
valor = rotaryEncoder.readEncoder();
Serial.print("Value: ");
Serial.println(rotaryEncoder.readEncoder());
//delay(10);
if(valor - lastvalor < 0){
menu.switch_focus(false);
}
else {
menu.switch_focus(true);
}
menu.update();
//lastvalor = valor;
lastvalor = rotaryEncoder.readEncoder();
}
if (rotaryEncoder.isEncoderButtonClicked()){
menu.call_function(1); //Antigua void selectOption()
delay(500);
}
handle_rotary_button();
}
void handle_rotary_button() {
static unsigned long lastTimeButtonDown = 0;
static bool wasButtonDown = false;
bool isEncoderButtonDown = rotaryEncoder.isEncoderButtonDown();
//isEncoderButtonDown = !isEncoderButtonDown; //uncomment this line if your button is reversed
if (isEncoderButtonDown) {
Serial.print("+"); //REMOVE THIS LINE IF YOU DONT WANT TO SEE
if (!wasButtonDown) {
//start measuring
lastTimeButtonDown = millis();
}
//else we wait since button is still down
wasButtonDown = true;
return;
}
//button is up
if (wasButtonDown) {
Serial.println(""); //REMOVE THIS LINE IF YOU DONT WANT TO SEE
//click happened, lets see if it was short click, long click or just too short
if (millis() - lastTimeButtonDown >= longPressAfterMiliseconds) {
on_button_long_click();
} else if (millis() - lastTimeButtonDown >= shortPressAfterMiliseconds) {
on_button_short_click();
}
}
wasButtonDown = false;
}
void rotary_onButtonClick()
{
static unsigned long lastTimePressed = 0;
//ignore multiple press in that time milliseconds
if (millis() - lastTimePressed < 500)
{
return;
}
lastTimePressed = millis();
Serial.print("button pressed ");
Serial.print(millis());
Serial.println(" milliseconds after restart");
}
void loop() {
rotary_loop();
atrass();
}
void on_button_short_click() {
Serial.print("button SHORT press ");
Serial.print(millis());
Serial.println(" milliseconds after restart");
}
void on_button_long_click() {
Serial.print("button LONG press ");
Serial.print(millis());
Serial.println(" milliseconds after restart");
}
void Motor(void *parameter){
while(1==1){
while(mode == true && x1 < Ciclos){
for(x1 = 0; x1 < Ciclos; x1++){
delay(delayciclos);
digitalWrite(dirpin, Giro);
for(x = 0; x < Pasos; x++){
digitalWrite(steppin, HIGH);
digitalWrite(steppin, LOW);
delayMicroseconds(5000);
if(digitalRead(Pulsa) == LOW){
break;
atrass();
}
}
}
Giro = true;
}
vTaskDelay(50);
}
}
//Funciones:::::
/*void selectOption(){
if(rotaryEncoder.isEncoderButtonClicked(){
menu.call_function(1);
delay(500);
}
}*/
void fn_volumen(){
menu.change_screen(2);
menu.set_focusedLine(0);
}
void fn_encender(){
menu.change_screen(3);
menu.set_focusedLine(0);
}
void fn_opciones(){
menu.change_screen(4);
menu.set_focusedLine(0);
}
void fn_off(){
menu.change_screen(1);
menu.set_focusedLine(0);
}
void fn_atras(){
menu.change_screen(1);
menu.set_focusedLine(0);
}
void fn_onR(){
Pasos = 4294967295;
Ciclos = 4294967295;
delayciclos = 0;
Giro = true;
a = true;
b = true;
fn_ciclos();
menu.change_screen(3);
menu.set_focusedLine(0);
}
/*void fn_onL(){
Pasos = 4294967295;
Ciclos = 4294967295;
delayciclos = 0;
Giro = false;
a = true;
b = true;
fn_ciclos();
menu.change_screen(3);
menu.set_focusedLine(1);
}*/
void fn_cantidad(){
Ciclos = 1;
delayciclos = 0;
a = true;
fn_ciclos();
}
void fn_ciclos(){
lcd.clear();
Serial.print("entra a ciclos, a = " + String(a));
delay(250);
for(int i = 0; i < 2; i++){
while(rotaryEncoder.isEncoderButtonClicked() == false && a == false){
if(digitalRead(Pulsa) == LOW){
break;
atrass();
}
rotaryEncoder.setAcceleration(50);
Movement();
switch(i){
case 0:
Ciclos_1 = Contaux;
cursorPos = 11;
//lcd.setCursor(11, 0);
//lcd.print(Ciclos_1);
lcd.setCursor(11,1);
lcd.print(demora);
break;
case 1:
demora = Contaux;
lcd.setCursor(11, 0);
lcd.print(Ciclos);
cursorPos = 11;
cursorPos2 = 1;
break;
/*case 2:
Ciclos_2 = Contaux;
cursorPos = 11;
lcd.setCursor(12, 0);
lcd.print(Ciclos_1);
lcd.setCursor(11,1);
lcd.print(demora);
Serial.println("case 1");
break;*/
}
lcd.setCursor(1, 0);
lcd.write(165);
lcd.print("Repet. = ");
lcd.setCursor(1, 1);
lcd.write(165);
lcd.print("Demora = ");
lcd.setCursor(14,1);
lcd.write((byte)2);
lcd.write((byte)3);
//lcd.print("(s)");
lcd.setCursor(cursorPos, cursorPos2);
if (millis() - tanterior >= 290) {
tanterior = millis();
if (showChar) {
lcd.print(Contaux);
}
else {
lcd.print(" ");
}
showChar = !showChar;
}
Ciclos = Ciclos_1;
delayciclos = demora*1000;
}
delay(250);
Contaux = 0;
cursorPos2 = 0;
lcd.clear();
delay(100);
}
Ciclos_1 = 0; Ciclos_2 = 0;
if(b == false){
for(int i = 0; i < 3; i++){
if(digitalRead(Pulsa) == LOW){
break;
i = 2;
atrass();
}
delay(150);
while(rotaryEncoder.isEncoderButtonClicked() == false && digitalRead(Pulsa) == false){
Serial.println("aqui");
rotaryEncoder.setAcceleration(250);
Movement();
switch(i){
case 0:
Cont_1 = Contaux;
lcd.setCursor(10, 0);
lcd.print(Cont_3);
lcd.print(Cont_2);
break;
case 1:
Cont_2 = Contaux;
lcd.setCursor(10, 0);
lcd.print(Cont_3);
lcd.setCursor(12, 0);
lcd.print(Cont_1);
break;
case 2:
Cont_3 = Contaux;
lcd.setCursor(11, 0);
lcd.print(Cont_2);
lcd.print(Cont_1);
break;
/*case 3:
cursorPos2 = 1;
lcd.setCursor(10,0);
lcd.print(Pasos);
lcd.setCursor(1,1);
if(auxGiro == 1){
auxGiro = "Funca 1";
lcd.print("Funca pa un lao");
}
else{
auxGiro = "Funca 0";
lcd.print("Funca pal otro lao");
}
break;*/
}
lcd.setCursor(0, 0);
lcd.print("Cant. => ");
lcd.setCursor(14, 0);
lcd.print("ml ");
cursorPos = 12 - i;
lcd.setCursor(cursorPos, cursorPos2);
if (millis() - tanterior >= 350) {
tanterior = millis();
if (showChar) {
lcd.print(Contaux);
}
else {
lcd.print(" ");
}
showChar = !showChar;
}
}
Pasos = (Cont_1 + 10*Cont_2 + 100*Cont_3);
delay(150);
Contaux = 0;
demora = 0;
lcd.clear();
}
}
Cont_1 = 0; Cont_2 = 0; Cont_3 = 0;
cursorPos2 = 0;
x1 = 0;
a = false;
b = false;
mode = true;
proceso();
}
void fn_opcion1(){
lcd.clear();
lcd.setCursor(4, 0);
//lcd.print(cantidad);
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
delay(2000);
}
void fn_opcion2(){
lcd.print("hello, world!");
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
delay(2000);
}
void Movement(){
if (rotaryEncoder.encoderChanged()){
valor = rotaryEncoder.readEncoder();
while(testcero == false){
Contauxcero = valor;
testcero = true;
Serial.print("entra while cero");
}
if(rotaryEncoder.readEncoder() == 0){
Contauxcero = 0;
}
Contaux = abs(rotaryEncoder.readEncoder()) - Contauxcero;
auxGiro = 1;
lastvalor = rotaryEncoder.readEncoder();
lcd.clear();
}
if(Contaux < 0){
Contaux = 0;
}
/*if(Contaux > 9){
Contaux = 9;
}*/
}
void proceso(){
lcd.clear();
while(mode == true && x1 < Ciclos){
if(digitalRead(Pulsa) == LOW){
mode = false;
x1 = 0;
Pasos = 0;
Ciclos = 0;
x1 = 0;
break;
}
lcd.setCursor(0, 0);
lcd.print("R");
lcd.write((byte)0);
if(Ciclos != 4294967295){
lcd.print(Ciclos);
}
else{
lcd.print("0");
}
lcd.setCursor(6, 0);
lcd.print("R");
lcd.write((byte)1);
lcd.print(x1);
lcd.setCursor(12,0);
if(Giro == true){
lcd.print("DER");
}
else{
lcd.print("IZQ");
}
lcd.setCursor(0, 1);
lcd.print("t:" + String(delayciclos/1000));
lcd.write((byte)2);
lcd.write((byte)3);
lcd.setCursor(6, 1);
lcd.write((byte)4);
if(Pasos != 4294967295){
lcd.print(Pasos);
}
else{
lcd.print("0");
}
lcd.print("/");
lcd.print(x);
lcd.setCursor(14,1);
lcd.print("u");
if(1 < x && x < 10){
lcd.clear();
}
}
mode = false;
}
void atrass(){
if(digitalRead(Pulsa) == LOW){
Pasos = 0;
mode = false;
menu.change_screen(1);
menu.set_focusedLine(0);
digitalWrite(steppin,LOW);
}
}