Hey everyone!
Im having problems when I use the case 8 (line 653) and the case 90 (line 673 ) .
Case 8 prevents the program to start and case 90 makes that some characters of the LCD screen to blink as if there was an electrical problem.
// Objetivo :
//1 - Que el Stepper haga Home para definir el punto 0 al iniciar
//2 - Que el Stepper obedezca las indicaciones de posicion del control IR
// 2.1-OJO con definir el punto "extendido" para no alcanzarlo en el punto 2 y 3
// 2.2 - Que se prenda un LED cada vez que se recibe una senal IR del control
// 3 - Que el Stepper abra "x" pasos en la manana y cierre "x" pasos en la tarde
// 3.1 - Que hacer si no hay electricidad en el momento de activarlo y mas tarde vuelve pero ya no se movio a su hora el stepper?
// 4 - Que el Stepper se detenga al detectar obstaculo debajo de persiana??
// 5 - Que el LCD despliege las acciones del programa
// 5.1 - Posicion actual del stepper
// 5.2 - Hora
// 5.3 - Mov automatico Activado o Desactivado
// 5.4 - Establecer posiciones de Mov Auto
// 5.5 - Que se apague el lcd despues de 15 seg de inactividad
// 6 - Programaciones
// 6.1 - Que se pueda programar la hora
// 6.2 - Que se pueda programar a que hora evento amanecer y evento atardecer
// 6.3 - Que se pueda programar posicion de evento amanecer y evento atardecer
// 7 - Que el IR solo reaccione ante las teclas del control preprogramadas if (teclas control = actuar) else (no haer nada)
#include <AccelStepper.h>
// AccelStepper Setup
//AccelStepper stepperX; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
AccelStepper stepperX(1, 3, 2); // (Type of driver: with 2 pins, STEP, DIR)
// Define the Pins used
#define home_switch 5 // Pin 5 connected to Home Switch (sensor efecto Hall (magnetico))
// Stepper Travel Variables
long TravelX; // Used to store the X value entered in the Serial Monitor
int move_finished = 1; // Used to check if move is completed
long initial_homing = -1; // Used to Home Stepper at startup
//control remoto por infrarojo
#include <IRremote.h> //el ATMEGA 328 no esta en la carpeta IRTimer de esta libreria y se edito el archivo para que aceptara
//este procesador ya que solo acepta el ATMEGA 328P
//C:\Users\lapde\Documents\Arduino\libraries\IRremote\src\private\IRTimer: || defined(__AVR_ATmega328__) ||
// #ifdef F_CPU //Para Arduino NANO Chino ATMEGA 328 el reloj interno es de 8Mhz (El ATMEGA 328P 16 Mhz)
// #undef F_CPU
// #define F_CPU 8000000
// #endif
int IRpin = 6;
int dt = 500;
int lTime = 1000;
int Led1 = 13;
int led1Val;
long pos1 = 5000;
long pos2 = 30000;
long pos3 = 45000;
long pos4 = 60000;
long pos5 = 75000;
long pos6 = 90000;
long pos7 = 105000;
long pos8 = 115000;
long pos9 = 122000;
int masAbajo = 2000;
int masArriba = 2000;
int open = 0;
long closed = 124000;
//RELOJ
#include <Wire.h> // comunicacion por interfaz I2C con la librería RTClib.h
#include <RTClib.h> // Librería del reloj DS3231
RTC_DS3231 rtc; // se crea un objeto de tipo rtc
bool movAuto1 = true;
bool movAuto2 = true;
#include <LiquidCrystal_I2C.h> //Libreria del LCD con el I2C para apagar el LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
//#include <LiquidCrystal.h> //Libreria del LCD sin el I2C
// int rs = 12;
// int e = 11;
// int d4 = 10;
// int d5 = 9;
// int d6 = 8;
// int d7 = 7;
// LiquidCrystal lcd(rs, e, d4, d5, d6, d7);
// para apagar pantalla despues de 15 seg
unsigned long tiempoPrev = 0; // will store last time LED was updated
// constants won't change:
const long interval = 20; // interval at which to turn off lcd
unsigned long tiempo;
// //hay que definir los valores que arroja el control remoto aqui
// #define IR_BUTTON_1 69 //TravelX = 200
// #define IR_BUTTON_2 70 //TravelX = 400
// #define IR_BUTTON_3 71 //TravelX = 600
// #define IR_BUTTON_4 68 //TravelX = 800
// #define IR_BUTTON_5 64 //TravelX = 1000
// #define IR_BUTTON_6 67 //TravelX = 1200
// #define IR_BUTTON_7 7 //TravelX = 1400
// #define IR_BUTTON_8 21 //TravelX = 1600
// #define IR_BUTTON_9 9 //TravelX = 1800
// #define IR_BUTTON_10 25 //TravelX = 2000
// #define IR_BUTTON_MAS_ARRIBA 24 //TravelX = +200
// #define IR_BUTTON_MAS_ABAJO 82 //TravelX = -200
// #define IR_BUTTON_INICIO 8 //TravelX = 200
// #define IR_BUTTON_FINAL 90 //TravelX = 2000
// //hay que definir los valores que arroja el control remoto aqui
// asterisco * = 22
// numeral # = 13
// OK = 28
// cero 0 = 25
void setup() {
// put your setup code here, to run once:
// #ifdef F_CPU //Para Arduino NANO Chino ATMEGA 328 (No el ATMEGA 328P) el reloj interno es de 8Mhz vs 16Mhz
// #undef F_CPU // Aunque hice pruebas y no note ninguna diferencia
// #define F_CPU 8000000
// #endif
Serial.begin(9600);
lcd.begin(20, 4);
lcd.backlight();
IrReceiver.begin(IRpin);
pinMode(Led1, OUTPUT);
pinMode(home_switch, INPUT_PULLUP);
delay(5); // Wait for EasyDriver wake up
stepperX.setMaxSpeed(1000.0); // Set maximum speed value for the stepper
stepperX.setAcceleration(500.0); // Set acceleration value for the stepper
// Start Homing procedure of Stepper Motor at startup
Serial.println(" ");
Serial.print("Stepper is Homing . . . . . . ");
lcd.setCursor(0, 0);
lcd.print("Shade is homing....");
delay(1000);
while (digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is activated
stepperX.moveTo(initial_homing); // Set the position to move to
initial_homing--; // Decrease by 1 for next move if needed
stepperX.run(); // Start moving the stepper
//delay(5);
}
stepperX.setCurrentPosition(0); // Set the current position as zero for now
stepperX.setMaxSpeed(1000.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(500.0); // Set Acceleration of Stepper
initial_homing = 1;
while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
stepperX.moveTo(initial_homing);
stepperX.run();
initial_homing++;
delay(5);
}
stepperX.setCurrentPosition(0);
Serial.println("");
Serial.println("Homing Completed");
Serial.println("");
Serial.println(stepperX.currentPosition());
stepperX.setMaxSpeed(1000.0); // Set Max Speed of Stepper (Faster for regular movements)
stepperX.setAcceleration(500.0); // Set Acceleration of Stepper
lcd.setCursor(0, 0);
lcd.print("Homing Completed");
lcd.setCursor(0, 1);
lcd.print("Pos: ");
lcd.println(stepperX.currentPosition());
delay(1000);
lcd.clear();
// Print out Instructions on the Serial Monitor at Start
Serial.println("READY ");
lcd.print("Ready");
delay(1000);
lcd.clear();
if (!rtc.begin()) { // si no encuentras el rtc.begin imprimes: no encontrado
Serial.println("Modulo RTC no encontrado !");
lcd.print("Reloj no encontrado");
while (1) // 1=true por lo tanto sigues imprimiendo "no encontrado"
; //hasta que la condicion sea false
}
//Para ajustar la fecha y hora del reloj DS3231
//De esta forma se le indica cual es la fecha y hora actual
//rtc.adjust (DateTime(2023,11,28,14,34,0));
//De esta forma extrae la fecha desde la compu y solo se usa la primera vez que se conecta el modulo
// if (rtc.lostPower()) { //ajusta la hora solo si el reloj perdio energia, necesita conectar la compu para obtenerla
// rtc.adjust(DateTime(__DATE__, __TIME__));
// }
}
void loop() {
//Se prioriza al control IR por lo que todos los ciclos se ejecutan mientras el IR reciba "cero" senales
// Esta parte maneja al Stepper desde el control IR
while (IrReceiver.decode() == 0) { //Se prioriza al control IR por lo que todos los ciclos se ejecutan mientras el IR reciba "cero" senales
lcd.clear();
DateTime fecha = rtc.now();
//Timer para apagar LCD despues de 15 segundos
//lcd.Backlight(); //Prender pantalla LCD al estar el IR en espera se necesita modulo I2C
tiempo = millis() / 1000;
Serial.print("TIMER:");
Serial.println(tiempo);
if (tiempo - tiempoPrev >= interval) {
tiempoPrev = tiempo;
Serial.print("TIMER LCD:");
Serial.println(tiempo);
lcd.noBacklight(); //Para apagar la pantalla LCD se necesita modulo I2C
}
if (fecha.hour() == 7 && fecha.minute() == 30) {
if (movAuto1 == true) {
Serial.println("Moviendo a movAuto1 ");
lcd.setCursor(0, 0);
lcd.print("7:30 am Amanecer"); //Es necesario imprimir esta hora en la primera linea? La hora siempre se va a estar desplegando
lcd.setCursor(0, 1);
lcd.print("Moviendo Amanecer");
delay(1000);
stepperX.moveTo(pos9); // Posicion cortinas de la manana DEFINIR
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
delay(1000);
lcd.clear();
movAuto1 = false;
}
}
if (fecha.hour() == 18 && fecha.minute() == 30) {
if (movAuto2 == true) {
Serial.println("Moviendo a movAuto2 ");
lcd.setCursor(0, 0);
lcd.print("18:30 pm Atardecer");
lcd.setCursor(0, 1);
lcd.print("Moviendo Atardecer");
delay(1000);
stepperX.moveTo(closed); // Posicion cortinas de la tarde DEFINIR
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
delay(1000);
lcd.clear();
movAuto2 = false;
}
}
// Mostrar la fecha y hora en el monitor serial
Serial.print(fecha.day());
Serial.print("/");
Serial.print(fecha.month());
Serial.print("/");
Serial.print(fecha.year());
Serial.print(" ");
Serial.print(fecha.hour());
Serial.print(":");
Serial.print(fecha.minute());
Serial.print(":");
Serial.println(fecha.second());
// Mostrar la hora en la pantalla LCD primer renglon
lcd.setCursor(0, 0);
lcd.print(fecha.hour());
lcd.print(":");
lcd.print(fecha.minute());
lcd.print(":");
lcd.print(fecha.second());
delay(1000);
if (fecha.hour() == 2 && fecha.minute() == 00) { //aqui a las 2am se reestablecen las condiciones de true
//movtimer = true; //reactiva alarma
movAuto1 = true; //reactiva evento inicial
movAuto2 = true; //reactiva evento final
}
}
//Programa de cuando el IR recibe instrucciones
int command = IrReceiver.decodedIRData.command;
lcd.backlight(); //Prender LCD cuando recibe una senal
digitalWrite(Led1, HIGH); //Prender LED cuando recibe una senal
delay(300); //Espera 300 milisegundos a que prenda la pantalla
Serial.println(command);
lcd.setCursor(0, 1);
lcd.print("ojos");
delay(300);
lcd.clear();
Serial.print("Pos actual: ");
Serial.println(stepperX.currentPosition());
lcd.print("Pos actual: ");
lcd.println(stepperX.currentPosition());
delay(dt);
digitalWrite(Led1, LOW); //Apagar LED despues de un segundo de recibir una senal
///////////////////////////////////////////////////////////////////////////
switch (command) {
case 69:
TravelX = pos1;
Serial.println("Pos 1");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 1");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 1");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 1");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 70:
TravelX = pos2;
Serial.println("Pos 2");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 2");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 2");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 2");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 71:
TravelX = pos3;
Serial.println("Pos 3");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 3");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 3");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 3");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 68:
TravelX = pos4;
Serial.println("Pos 4");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 4");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 4");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 4");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 64:
TravelX = pos5;
Serial.println("Pos 5");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 5");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 5");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 5");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 67:
TravelX = pos6;
Serial.println("Pos 6");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 6");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 6");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 6");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 7:
TravelX = pos7;
Serial.println("Pos 7");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 7");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 7");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 7");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 21:
TravelX = pos8;
Serial.println("Pos 8");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 8");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 8");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 8");
delay(dt);
break;
///////////////////////////////////////////////////////////////////////////
case 9:
TravelX = pos9;
Serial.println("Pos 9");
lcd.setCursor(0, 1);
lcd.print("Moving to Pos 9");
delay(200);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed Pos 9");
lcd.setCursor(0, 1);
lcd.print("Completed Pos 9");
delay(dt);
break;
// //////////////////////////////////////////////////////////////////
// case 281:
// TravelX = pos9;
// Serial.print("Moving to: Pos 9");
// lcd.setCursor(0, 1);
// lcd.print("Moving to Pos 9");
// delay(200); // Wait 1 seconds before moving the Stepper
// stepperX.moveTo(TravelX);
// stepperX.runToPosition();
// Serial.print("Paso: ");
// Serial.println(stepperX.currentPosition());
// lcd.print("Paso: ");
// lcd.println(stepperX.currentPosition());
// Serial.print("Completed Pos 9");
// lcd.setCursor(0, 1);
// lcd.print("Completed Pos 9");
// break;
// //////////////////////////////////////////////////////////////////
case 24:
TravelX = masArriba;
Serial.println("Moving to: UNO ARRIBA");
lcd.setCursor(0, 1);
lcd.println("UNO ARRIBA");
delay(200); // Wait 1 seconds before moving the Stepper
if (stepperX.currentPosition() <= 2000) {
Serial.println("PERSIANA ABIERTA ");
lcd.println("PERSIANA ABIERTA");
stepperX.moveTo(0);
stepperX.runToPosition();
} // this form also works - pick your favorite!
else {
stepperX.moveTo(stepperX.currentPosition() - TravelX);
stepperX.runToPosition();
}
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Completed UNO ARRIBA");
lcd.setCursor(0, 1);
lcd.print("Complete One UP");
break;
//////////////////////////////////////////////////////////////////
case 82:
TravelX = masAbajo;
Serial.println("Moving to: UNO ABAJO");
lcd.setCursor(0, 1);
lcd.println("UNO ABAJO");
delay(200); // Wait 1 seconds before moving the Stepper
if (stepperX.currentPosition() >= 124000) {
Serial.println("PERSIANA CERRADA ");
lcd.println("PERSIANA CERRADA");
stepperX.moveTo(124000);
stepperX.runToPosition();
} // this form also works - pick your favorite!
else {
stepperX.moveTo(stepperX.currentPosition() + TravelX);
stepperX.runToPosition();
}
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
lcd.clear();
Serial.println("Complete UNO ARRIBA");
lcd.setCursor(0, 1);
lcd.print("Complete One Down");
break;
// //////////////////////////////////////////////////////////////////
//case 8:
TravelX = open;
Serial.print("Moving to: HOME");
lcd.println("Moving to: HOME");
delay(200); // Wait 1 seconds before moving the Stepper
stepperX.moveTo(TravelX);
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
Serial.print("Completed Pos HOME");
lcd.setCursor(0, 1);
lcd.print("Completed HOME");
break;
// // //////////////////////////////////////////////////////////////////
//case 90:
TravelX = closed;
Serial.println("Pressed CLOSED");
lcd.print("Moving to: CLOSED");
delay(200); // Wait 1 seconds before moving the Stepper
stepperX.moveTo(TravelX);
stepperX.runToPosition();
Serial.print("Paso: ");
Serial.println(stepperX.currentPosition());
lcd.print("Paso: ");
lcd.println(stepperX.currentPosition());
Serial.print("Completed Pos CLOSED");
lcd.setCursor(0, 1);
lcd.print("Completed CLOSED");
break;
// ///////////////////////////////////////////////////////////////////
case 0:
lcd.clear();
break;
///////////////////////////////////////////////////////////////////
// default:
// Serial.println("Button not recognized");
// break;
}
IrReceiver.resume();
}