#include <LiquidCrystal.h>
#include <AccelStepper.h>
int dire = 1; // Sentido del Motor
char cable[4] = "A30";
char bobina[3] = "S";
char* tcable[6] = {"A30", "B50", "C60", "RP37", "RP47", "CUS"};
int ptcable = 0;
char* tbobina[5] = {"S", "M", "L", "XL", "C"};
int ptbobina = 0;
float velocidad=10.0; // Velocidad en mm/sg inicial
int vel_hom=1000; // Velocidad para el Homming en pasos (25mm/sg)
int anchobob=50; // Ancho de la Bobina (mm)
int vueltas =0 ; //Nº de vueltas
bool swState = HIGH; //Variable para control de seleción del Encoder
bool swLast = HIGH; //Variable para control de seleción del Encoder
bool menu = HIGH; // En High estomos en navegacion. LOW modificando alguna posición
int lastClk = LOW; // Variable para el control del sentido del encoder
byte sentido=0; //Nos indica el sentido del Encoder: 0=Nada 1=Derecha 2=Izquierda
bool modorun =LOW; //Indica si estamos en modo Run
bool wait_motor = LOW; //Swicht por effecto Hall en eje de motor de recogida
int previus_pos; // Posicion previa del carro
float RotaryTime1; //Retraso entre pulsacion
float RotaryTime=0; //Retraso entre rotacion
float RotaryTime2=0; //Retraso entre pulsacion
float time_vuelta=0; // Variable del tiempor entre vueltas
int posm=0; // Posicion del cursor en el Menu Principal
#define ENCODER_CLK 37// Pin Clk del Encoder ***31**37**
#define ENCODER_DT 35 // Pin de Datos Encoder ***33***35**
#define X_MIN 3 // Pin del Principio de Carrera
#define HALL 2 // Pin swicth hall para atender el funcionamiento del motor de la bobina (3 permite interrupcion)
int offset = 40; // Offset del cero
#define SELECT_BUTTON 31 // Pin del Select del Encoder **35**31**
#define buzzer 33// Pin del buzzer ***37**33**
//#define Kill_PIN 37
////////////////////MOTOR PAP////////////////////////////////
// Motor con Half Step 1/2 400 pasos/vuelta //
// Husillo T8 de paso 8mm -> 500 pasos -> 100mm //
// Motor con Half Step 1/8 1600 pasos/vuelta //
// Rueda de 20 dientes -> 40 pasos -> 1 mm -> Factor 40 //
//
#define DIR A1// 28//A1 /EJE X
#define STEP A0// 26//A0
#define ENABLE 38// 24//38
//#define DIR 28//A1 //EXTRUSOR
//#define STEP 26//A0
//#define ENABLE 24//38
#define motorInterfaceType 1
AccelStepper miMotor = AccelStepper(motorInterfaceType, STEP, DIR);
LiquidCrystal lcd(16, 17, 23, 25, 27, 29); // Configuro el LCD
void setup() {
Serial.begin(9600);
pinMode(ENCODER_CLK, INPUT_PULLUP);
pinMode(ENCODER_DT, INPUT_PULLUP);
pinMode(SELECT_BUTTON, INPUT_PULLUP);
pinMode(buzzer, OUTPUT); // Set buzzer
pinMode(X_MIN, INPUT_PULLUP); // SWITCH MINIMO HOME
pinMode(HALL, INPUT_PULLUP); // SWITCH HALL para supervision de movimiento en motor bobina
// Motor
pinMode(DIR, OUTPUT);
pinMode(STEP, OUTPUT);
pinMode(ENABLE, OUTPUT);
miMotor.setAcceleration(5000);
miMotor.setMaxSpeed(3000);//Equivalente a 75mm/sg
miMotor.setSpeed(velocidad*40);
digitalWrite(ENABLE, HIGH); // Deshabilito el motor
lcd.begin(20, 4); // Configuro el LCD a 20x4 carac.
// Represento la pantalla principal
lcd.setCursor(0, 0); lcd.print("[ BOBINADORA TC ]");
lcd.setCursor(0, 1); lcd.print((char) 126); lcd.print("Vel= mm/s");
lcd.setCursor(11-(String(velocidad).length()), 1);lcd.print(velocidad);
lcd.setCursor(1, 2); lcd.print("Ancho Bob= mm");
lcd.setCursor(15- (String(anchobob).length()), 2);lcd.print(anchobob);
lcd.setCursor(1, 3); lcd.print("CONFIG HOME RUN");
//lcd.setCursor(0, 3); lcd.print("T= s V= P= mm");
}
void loop() {
if (modorun == false) { // Si no estamos en modo RUN
digitalWrite(ENABLE, HIGH); //Libero al Motor /// posiblemente debere quitarlo
byte boton=0; /// NAVEGANDO POR MENU
boton = encoder(); // Saber el sentido de Encoder (0=Nada 1=Der 2=Izq)
//Serial.println(boton);
if (menu == true) { // Si estamos en modo navegación
switch (boton) {
case 1: // Giro a derecha
if (posm <4){posm++;} // Incremento el puntero del menu si es menor a 4
else {posm=0;} // Si superamos el valor 4 lo ponemos a cero
mnp_cursor (posm); // Llamamos a la rutina de indicar la posicion (->) en el menu
break;
case 2:
if (posm >0){posm--;}
else {posm=4;}
mnp_cursor (posm);
break;
}
}
else { ///// Estamos dentro de MODIFICAR una opcion en el menú
switch (boton) { // Verificamos si giramos el Encoder
case 1: // En caso de girar a DER con el encoder
if (posm == 0) { // Si estamos en la posicion de Velocidad
velocidad=velocidad+0.1;
lcd.setCursor(6, 1); lcd.print(" ");
lcd.setCursor(11-(String(velocidad).length()), 1);lcd.print(velocidad);
//lcd.setCursor(7, 0);lcd.print(velocidad);
// Serial.print("Vel:");
// Serial.println(velocidad);
}
if (posm == 1) { // Si estamos en la posicion de Bobina
anchobob=anchobob+1;
lcd.setCursor(12, 2); lcd.print(" ");
lcd.setCursor(15- (String(anchobob).length()), 2);lcd.print(anchobob);
//lcd.setCursor(12, 1);lcd.print(anchobob);
}
break;
case 2: // En caso de girar a DER con el encoder
if (posm == 0) { // Si estamos en la posicion de Velocidad
velocidad=velocidad-0.1;
lcd.setCursor(6, 1); lcd.print(" ");
lcd.setCursor(11-(String(velocidad).length()), 1);lcd.print(velocidad);
// lcd.setCursor(7, 0);lcd.print(velocidad);
// Serial.print("Vel:");
// Serial.println(velocidad);
}
if (posm == 1) { // Si estamos en la posicion de Bobina
anchobob=anchobob-1;
lcd.setCursor(12, 2); lcd.print(" ");
lcd.setCursor(15- (String(anchobob).length()), 2);lcd.print(anchobob);
}
break;
}
}
}
else { //Nos encontramos en MODO RUN
//
if (wait_motor == true){ // Esperamos que el sensor Hall habilite la interrupcion por movimiento del motor
// deshabilitar la interripcion HaLL
//wait_motor =true;
if (digitalRead(ENABLE)==HIGH) { // Acabo de habilatar el Hall y esto se ejecutara solo 1 vez y al principio
detachInterrupt(digitalPinToInterrupt(HALL));// Dehabilito la interrupcio y vamos al Vaiven
time_vuelta= millis();//PONGO EL CONTAdor a cero de la velocidad de vuelta
lcd.setCursor(0, 0); lcd.print("*** BOBINANDO ***");
lcd.setCursor(0, 3); lcd.print("T= s V= P= mm");
}
/// Podemos modificar la velocidad en run
byte boton=0; /// NAVEGANDO POR MENU
boton = encoder(); // Llamamos a la subrutina de lectura del Encoder
switch (boton) { // Verificamos si giramos el Encoder en modo RUN para variar la velocidad
case 1: // En caso de girar a DER con el encoder
velocidad=velocidad+0.1;
lcd.setCursor(6, 1); lcd.print(" ");
lcd.setCursor(11-(String(velocidad).length()), 1);lcd.print(velocidad,2);
break;
case 2: // En caso de girar a DER con el encoder
velocidad=velocidad-0.1;
lcd.setCursor(6, 1); lcd.print(" ");
lcd.setCursor(11-(String(velocidad).length()), 1);lcd.print(velocidad,2);
break;
}
///////**********
vaiven(); //empezamos a realizar el vaiven
}
else {
lcd.setCursor(0, 3); lcd.print(">Esperando Arranque<");
}
}
swState = digitalRead(SELECT_BUTTON); /// Click Encoder
//RotaryTime1 = millis();
if ((swState == LOW) && (swLast == HIGH)) {
RotaryTime1 = millis();
if (RotaryTime1 - RotaryTime2 > 1000) {
// Serial.println("Rotary pressed");
tone(buzzer, 2000,150); // Send 0.3KHz sound signal...
// delay(5); // ...for sec
// noTone(buzzer);
// miMotor.setSpeed(velocidad * dire);
//dire = dire * (-1);
// delay(100);//debounce
menu = !menu; // Nos adentramos dentro de opcion menu
byte lcd_carac_i = (menu==0)*62+(menu==1)*32; // Caracter "<" o " "
byte lcd_carac_f = (menu==0)*60+(menu==1)*32; // Caracter ">" o " "
if (posm == 0) { // pulsamos sobre Velocidad
lcd.setCursor(5, 1); lcd.print((char) (lcd_carac_i ));
lcd.setCursor(11, 1); lcd.print((char) (lcd_carac_f ));
Serial.println("Estas en Velocidad");
}
if (posm == 1) { // pulsamos sobre Ancho Bobina
Serial.println("Estas en longitud bobina");
lcd.setCursor(11, 2); lcd.print((char) (lcd_carac_i));
lcd.setCursor(15, 2); lcd.print((char) (lcd_carac_f));
}
if (posm == 2) {// Estamos sobre Config
lcd.clear();
lcd.setCursor(0, 0); lcd.print("[ CONFIGURACI0N ]");
lcd.setCursor(0, 1); lcd.print(" Offset: mm");
lcd.setCursor(0, 2); lcd.print(" Ancho: mm");
lcd.setCursor(1, 3); lcd.print("GUARDAR SALIR");
menu = !menu; ; // quito el modo menu
}
if (posm == 3) { // Estamos en HOMING
Serial.println("Estas en Homming");
lcd.setCursor(8, 3); lcd.print((char) (lcd_carac_i));
lcd.setCursor(13, 3); lcd.print((char) (lcd_carac_f));
lcd.setCursor(0, 3); lcd.print(" Homming..... "); //
homming(); // Realizamos el Homming
lcd.clear();
lcd.setCursor(0, 0); lcd.print("[ HOMMING ]");
lcd.setCursor(0, 1); lcd.print(" Offset: mm");
lcd.setCursor(0, 2); lcd.print(" Ancho: mm");
lcd.setCursor(1, 3); lcd.print("GUARDAR SALIR");
//lcd.setCursor(0, 3); lcd.print(" CONFIG HOME RUN");
//menu = !menu; ; // quito el modo menu
}
if (posm == 4) {
Serial.println("Estas en run");
lcd.setCursor(15, 3); lcd.print((char) (lcd_carac_i));
lcd.setCursor(19, 3); lcd.print((char) (lcd_carac_f));
wait_motor = false; // Hasta que no verifiquemos movimiento en el motor por interrupcion
attachInterrupt(digitalPinToInterrupt(HALL), Mov_Motor, RISING); // Habilito la interrupcion a la espera de ver motor arrnacado
modorun=!modorun;
lcd.setCursor(0, 3); lcd.print(" CONFIG HOME RUN");
lcd.setCursor(0, 0); lcd.print("[ BOBINADORA TC ]");
vueltas=0; // Pongo el contador a cero
}
mnp_cursor((menu==1)*(posm-99)+99);
//Serial.println(((menu==1)*(posm-99)));
}
RotaryTime2 = millis();
} ///retardo
//RotaryTime2 = millis();
swLast = swState;
}
/// Indicacion cursor en Menu Principal (posicion "posm")
void mnp_cursor (int posicion) {
//lcd.blink();
lcd.setCursor(0, 1); lcd.print((char) 32);
lcd.setCursor(0, 2); lcd.print((char) 32);
lcd.setCursor(0, 3); lcd.print((char) 32);
lcd.setCursor(8, 3); lcd.print((char) 32);
lcd.setCursor(15, 3); lcd.print((char) 32);
//lcd.setCursor(15, 3); lcd.print((char) 32);
switch (posicion) {
case 0:
lcd.setCursor(0, 1); lcd.print((char) 126);
break;
case 1:
lcd.setCursor(0, 2); lcd.print((char) 126);
break;
case 2:
lcd.setCursor(0, 3); lcd.print((char) 126);
break;
case 3:
lcd.setCursor(8, 3); lcd.print((char) 126);
break;
case 4:
lcd.setCursor(15, 3); lcd.print((char) 126);
break;
}
}
/// Lectura del Encoder /////////
byte encoder(){
byte sentido=0;
int newClk = digitalRead(ENCODER_CLK);
int dtValue = digitalRead(ENCODER_DT);
//**
//RotaryTime1 = millis();
if (millis() - RotaryTime > 20) {
// Serial.println("Ya puede leer");
//**
//if (newClk != lastClk ) {
if (newClk == LOW && lastClk == HIGH ) {
// There was a change on the CLK pin
//lastClk = newClk;
//int dtValue = digitalRead(ENCODER_DT);
//if (newClk == LOW && dtValue == HIGH) { // DERECHA
if (dtValue == HIGH) { // DERECHA
sentido=1;
// Serial.println("Rotated clockwise ⏩");
}
if (dtValue== LOW) { // IZQUIERDA
// else {
sentido=2;
// Serial.println("Rotated counterclockwise ⏪");
}
RotaryTime = millis();
}
}
// }
lastClk = newClk;
return sentido;
}
void homming(){ // Vamos a realizar el Homming
digitalWrite(ENABLE, LOW); //Habilito al Motor
miMotor.setSpeed(-vel_hom);
//Serial.println("Estamos en Homming");
//Serial.println(digitalRead(X_MIN));
while(digitalRead(X_MIN) == LOW) { // En Bucle hasta que no lleguemos al fina de carrera
//lcd.setCursor(0, 0); lcd.print(digitalRead(X_MIN));
//Serial.println(digitalRead(X_MIN));
//lcd.setCursor(17- (String(miMotor.currentPosition()).length()), 3);lcd.print(miMotor.currentPosition());
// miMotor.setSpeed(velocidad*(-1));
miMotor.runSpeed(); // A correr
}
miMotor.setCurrentPosition (0); /// Grabamos la posicion Inicial
miMotor.setSpeed(vel_hom); // Configuramos la velocidad de Homming
miMotor.moveTo(offset*40); // Desplazamos hasta el offset
while(miMotor.currentPosition() != offset*40) { // vamos hasta el offfset
miMotor.run();
}
miMotor.setCurrentPosition (0); // este es el cero
digitalWrite(ENABLE, HIGH); //Deshabilito al Motor
}
void vaiven (){ //// MODO VAIVENNNNNN
digitalWrite(ENABLE, LOW); // Habilito el Motor
if ((miMotor.currentPosition() > anchobob*40)&& (dire =1)) {
dire=-1;
vueltas=vueltas+1;
lcd.setCursor(2, 3); lcd.print(" "); //borro
lcd.setCursor(2, 4); lcd.print(anchobob/((millis()-time_vuelta)/1000),2);
time_vuelta= millis();
lcd.setCursor(12-(String(vueltas).length()), 3); lcd.print(vueltas);
}
if ((miMotor.currentPosition() < 0)&& (dire =-1)) {
dire=1;
vueltas=vueltas+1;
lcd.setCursor(2, 3); lcd.print(" "); //borro
lcd.setCursor(2, 4); lcd.print(anchobob/((millis()-time_vuelta)/1000),2);
time_vuelta= millis();
lcd.setCursor(12-(String(vueltas).length()), 3); lcd.print(vueltas);
}
miMotor.setSpeed(velocidad*40*dire);
miMotor.runSpeed();
if ((( (miMotor.currentPosition())/40) != previus_pos)) { // si hay de paso 1 mm
lcd.setCursor(15, 3); lcd.print(" "); // Borro el primer digito en descenso
lcd.setCursor(18-(String(miMotor.currentPosition()/40).length()), 3); lcd.print(miMotor.currentPosition()/40);
previus_pos=( (miMotor.currentPosition())/40);
//Serial.println(miMotor.currentPosition()/40);
//Serial.println(1/((millis()-time_vuelta)/1000));
}
//lcd.setCursor(12-(String(vueltas).length()), 3); lcd.print(vueltas);
//lcd.setCursor(2, 3); lcd.print(" "); //borro
//lcd.setCursor(2, 4); lcd.print(anchobob/((millis()-time_vuelta)/1000));
}
void Mov_Motor() { /// Interrupcion en caso de ver movimiento en motor principal
wait_motor =true; // Habilito la variable para poder bobinar
//lcd.setCursor(0, 2); lcd.print("*** Bobinando ***");//NO lo puedo poner en el tratamiento de la interrupcion
//Serial.println("Interrupción!! Efecto HALLLL");
//detachInterrupt(digitalPinToInterrupt(HALL));
}