//sistema de flats/darks y Bahtinov para telescopio: 2 tapas movidas por motores diferentes.
// El relé es para encender el panel de flats, y la sonda para tener una referencia
// de temperatura.
// Son 2 motores 28-BYJ de 5v y su driver ULN2003, alimentados por usb 5v
// La idea es mandar unas "letras-acciones" via serial para controlarlo en remoto, y la
// opción de la botonera para su uso directo-esporádico (y añadiendo un lcd )
//IMPORTANTE: cambiar lineas 53 y 54 en función del desplazamiento que se quiera.
//IMPORTANTE: al enchufar el sistema, si pulsas los botones de flats/bahtinov, su acción
//inicial es SIEMPRE cerrarlos; si estaban ya cerrados, puedes forzar/romper el sistema.
//los botones están en pruebas, la version de python y su ejecutable funcina ok
//el relé es de estado sólido, uno normal fallaba a veces por voltaje
// en pruebas v2.0
#include <Button.h>
#include <AccelStepper.h>
#include <Stepper.h>
#include <DHT.h>
#include <Adafruit_GFX.h> //Liberia para gráficos
#include <Adafruit_SSD1306.h> //Liberia para Oleds monocromáticos basados en controladores SSD1306
/*Se declara el pin de reset, este es requerido por el constructor de la librería SSD1306
*para definir el tipo de OLED y la comunicación I2C en los (pines SDA, SCL)*/
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_RESET);
/*Se define una condición para saber si en la librería esta definida la altura de 32 de lo contrario
*no dejara compilar el código hasta que se cambie la altura correcta desde la librería*/
#if (SSD1306_LCDHEIGHT != 32)
#error("Altura incorrecta, cambie en la librería de Adafruit_SSD1306.h!");
#endif
Button Flats(A0);
Button Mascara(A1);
Button Luz(A2);
Button LeerTemp(2);
int rele=3; //para el rele
int option; //para mandar mensajes
#define DHTTYPE DHT22 // modelo sonda
const int DHTPin = 4; // pin de conexion sonda
DHT dht(DHTPin, DHTTYPE);
// Pines de los 2 motores
#define IN1 12
#define IN2 11
#define IN3 10
#define IN4 9
#define IN5 8
#define IN6 7
#define IN7 6
#define IN8 5
// STEPS DEL GIRO y sus pines . Revisarlo al montar.
const int stepsPerRevolution1 = 1340; //flats en mi sistema 1340
const int stepsPerRevolution2 = 1550; //bahtinov en mi sistema 1550
AccelStepper MotorFlats(AccelStepper::FULL4WIRE, IN1, IN3, IN2, IN4);
AccelStepper MotorMascara(AccelStepper::FULL4WIRE, IN5, IN7, IN6, IN8);
int controlBoton = 0; //para las 2 acciones al pulsar botones
void apagado() // Apaga bobinados del motor, por revisar, no funciona
{
digitalWrite (12, LOW);
digitalWrite (11, LOW);
digitalWrite (10, LOW);
digitalWrite (9, LOW);
digitalWrite (8, LOW);
digitalWrite (7, LOW);
digitalWrite (6, LOW);
digitalWrite (5, LOW);
}
void setup() {
Serial.println("DHTxx test!");
dht.begin();
pinMode(A0, INPUT_PULLUP); // boton Flats
pinMode(A1, INPUT_PULLUP); // boton Mascara
pinMode(A2, INPUT_PULLUP); // boton Luz
pinMode(2, INPUT_PULLUP); // boton leer temperatura
pinMode(3, OUTPUT); // rele
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// VELOCIDAD DE CADA MOTOR
MotorMascara.setMaxSpeed(500);
MotorMascara.setAcceleration(20);
MotorMascara.setSpeed(100);
MotorFlats.setMaxSpeed(500);
MotorFlats.setAcceleration(20);
MotorFlats.setSpeed(100);
Serial.begin(9600);
}
void leer_oled() {
display.clearDisplay(); //Borra el buffer
display.setTextSize(1); //Establece el tamaño de fuente, admite tamaños de 1 a 8
display.setTextColor(WHITE); //Establece el color
display.setCursor(35,10); //Establecer las coordenadas para mostrar la posición del texto
//display.println("HOLA");
display.setCursor(20,20); //Establecer las coordenadas para mostrar la posición del texto
//display.println("MUNDO");
//display.display(); //Muestra el texto
}
void loop() {
leer_oled();
float h = dht.readHumidity(); //
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("fallo al leer sensor dht!");
return;
}
// MOTOR 1
if (Flats.pressed()) {
controlBoton = 1 - controlBoton;
Serial.println(controlBoton ? "Boton ON" : "Boton OFF");
if (controlBoton) {
Serial.println("poniendo flats");
MotorFlats.move(-stepsPerRevolution1 );
MotorFlats.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,0);
display.println("flats Puesta");
display.display();
}
else {
Serial.println("retirando flats");
MotorFlats.move(stepsPerRevolution1 );
MotorFlats.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,0);
display.println("Bahtinov flats");
display.display();
}
}
// MOTOR 2
if (Mascara.pressed()) {
controlBoton = 1 - controlBoton;
Serial.println(controlBoton ? "Boton ON" : "Boton OFF");
if (controlBoton) {
Serial.println("poniendo bahtinov");
MotorMascara.move(stepsPerRevolution2 );
MotorMascara.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,10);
display.println("Bahtinov Puesto");
display.display();
}
else {
Serial.println("retirando bahtinov");
MotorMascara.move(-stepsPerRevolution2 );
MotorMascara.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,10);
display.println("Bahtinov Quitado");
display.display();
}
}
// RELE PARA LUZ ON/OFF
if (Luz.pressed()) {
controlBoton = 1 - controlBoton;
Serial.println(controlBoton ? "Boton ON" : "Boton OFF");
if (controlBoton) {
Serial.println("luz on");
digitalWrite(rele, HIGH);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,15);
display.println("luz ON");
display.display();
}
else {
Serial.println("luz off");
digitalWrite(rele, LOW);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,15);
display.println("luz OFF");
display.display();
}
}
// SENSOR TEMPERATURA Y HUMEDAD
if (LeerTemp.pressed()){
Serial.print("Humed: ");
Serial.print(h);
Serial.print("Temp: ");
Serial.println(t);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,7);
display.print("Temp: ");
display.print(t);
display.setCursor(25,17);
display.print("Humed: ");
display.print(h);
display.display();
}
// ENVIAR TEXTO via serial PARA EJECUTAR las ACCIONES en remoto
if (Serial.available()>0){
option=Serial.read();
if(option=='a') {
Serial.println("quitar flats");
MotorFlats.move(stepsPerRevolution1 );
MotorFlats.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,0);
display.println("Flats Puesto");
display.display();
}
if(option=='b') {
Serial.println("poner flats");
MotorFlats.move(-stepsPerRevolution1 );
MotorFlats.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,0);
display.println("Flats Quitado");
display.display();
}
if(option=='c') {
Serial.println("quitando bahtinov");
MotorMascara.move(-stepsPerRevolution2 );
MotorMascara.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,10);
display.println("Bahtinov Quitado");
display.display();
}
if(option=='d') {
Serial.println("poniendo bahtinov");
MotorMascara.move(stepsPerRevolution2 );
MotorMascara.runToPosition();
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,10);
display.println("Bahtinov Puesto");
display.display();
}
if(option=='e') {
Serial.println("luz on");
digitalWrite(rele, HIGH);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,15);
display.println("luz ON");
display.display();
}
if(option=='f') {
Serial.println("luz off");
digitalWrite(rele, LOW);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(25,15);
display.println("luz OFF");
display.display();
}
if(option=='g') {
Serial.print("Humed: ");
Serial.print(h);
Serial.print("Temp: ");
Serial.println(t);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(20,10);
display.print("Temp: ");
display.print(t);
display.setCursor(20,25);
display.print("Humed: ");
display.print(h);
display.display();
}
}
}