Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Controlar motor PaP desde LCD
#1
Buenas a todos,

La idea es poder hacer un proyecto donde desde un LCD, pueda crear un menú, e introducir los datos para poder controlar un motor PaP.

Soy principiante y me he lanzado al vacío, pero no se si esto me superará.

De momento tengo la idea bastante clara y voy a ver si siy capaz de llevarlo adelante.

La idea del menú en poder controlar:

.- MODO (Automático/Manual) (Tipo los home que hacemos en las impresoras, por programa, o hacer los movimiento poco a poco.
.- DIRECCIÓN (Izquierda o Derecha).
.- ACELERACIÓN/DECELERACIÓN progresiva. (Poder seleccionar SI/NO, para la marcha o el paro)
.- VELOCIDAD (rpm)

De momento lo que hecho, ha sido poner varios pulsadores y llevarlos a una entrada analógica, donde leo los valores que me da cada pulsador y así se el que tengo pulsado.

Ahora lo que quiero es poder crearme un menú en el LCD, y poder seleccionar los menús y valores. Aunque esto me está costando, ya que me lio bastante en el código.

Os iré colocando los códigos y montajes en (Fritzing), para que vayáis opinando.
Citar
#2
Os pongo el código que he utilizado para leer el valor en la entrada analógica:

Código:
/*
  Codigo utilizado para calibrar el valor de array de los botones
  leyendo el valor en Arduino con un LCD
*/


  #include <LiquidCrystal.h>
  LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  
  const int analogInPin = A0;    //Ponemos el valor de la A0 en la variable
  
/*
  adc_key basado en el valor medido con resistencias varias
  adc_key_val[5]={right, up, down, left, select};
*/

  int adc_key_val[5]={50, 200, 400, 600, 800};
  
  int NUM_KEYS = 5;
  int adc_key_in;
  int key=-1;
  int oldkey=-1;
  
  //Nombre de Botones para el lcd
  
  const int BT_RIGHT = 0;
  const int BT_UP = 1;
  const int BT_DOWN = 2;
  const int BT_LEFT = 3;
  const int BT_SELECT = 4;
  
  int sensorValue = 0;    //valor leido de la entrada A0
  
  void setup() {
    lcd.begin(16, 2);
  }
  
  void loop() {
    //Imprimir resultados en el display LCD
    if(!(get_key()==-1)){
      sensorValue = analogRead(analogInPin);
      
      switch(get_key()){
      case BT_RIGHT :
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Boton detectado");
        lcd.setCursor(0,1);
        lcd.print("1");
        delay(10);
        break;
      case BT_UP :
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Boton detectado");
        lcd.setCursor(0,1);
        lcd.print("2");
        delay(10);
        break;
       case BT_DOWN :
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Boton detectado");
        lcd.setCursor(0,1);
        lcd.print("3");
        delay(10);
        break;
       case BT_LEFT :
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Boton detectado");
        lcd.setCursor(0,1);
        lcd.print("4");
        delay(10);
        break;
       case BT_SELECT :
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Boton detectado");
        lcd.setCursor(0,1);
        lcd.print("5");
        delay(10);
        break;
        
      default:
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Boton NO detectado");
        lcd.setCursor(0,1);
        lcd.print(sensorValue);
      }
    }
        delay(100);
    }
    //get key
      boolean isPressed(int button){
        
        if(get_key()== button) return true;
        return false;
      }
     //Convierte ADC valor a número de key
       int get_key()
       {
        
        int input = analogRead(analogInPin);
        int k;
        for(k = 0; k<NUM_KEYS; k++)
        {
          if(input<adc_key_val[k])
          {
            return k;
          }
        }
        if(k>=NUM_KEYS)
          k=-1;    //Tecla presionada no valida
          
          return k;
       }

Me ha costando un poco aclararme con el array y la forma de poner la alimentación, ya que cambia todo. Probaba con un Shield de LCD, y me funcionaba bien y lo hacía con el montaje que tengo hecho y no daba ni una. Pero todo estaba en donde ponía Vcc y GND en el circuito.

Una vez que me funciona bien, y se que botón estoy pulsando en cada momento, voy a pasar a los menús.

PD: El codigo no es mio del todo, ya que he ido uniendo diferentes que he encontrado por Internet y adaptándolos a mi.
Citar
#3
El tema de poner un array de interruptores esta bien pensado, pero si te sobran patas del micro yo los pondria separados, es una consideracion personal vamos.

Ante una supuesta variacion de tension puedes tener variaciones en la seleccion de los interruptores si no tienes el suficiente margen

Necesitaras un driver para el motor PAP, unipolar o bipolar?
Citar
#4
Hola Triggerr.

Gracias por la observación, pero me da la impresión de que no voy a andar muy sobrado de Pines, así que como vi que esta era una opción me decidí por ella. Pero si me sobran lo pensaré. Sisi3

El material de que dispongo hasta el momento, es el siguiente:

.- Arduino UNO R3
.- Display LCD 16 x 2
.- Botones y material vario.
.- Motor PaP Bipolar (Modelo VEXTA PK266-02A, 2-PHASE 1,8º/step, 2A)
.- Polea y correas dentadas T2,5 (todavía no se la relación que voy a utilizar, 3:1 o ya veremos)

Con respecto al material que tengo pedido, es:

.- Driver L298:
resim

resim

Con todo esto, espero poder tener suficiente para el montaje, y sino, ya veremos que mas hace falta. Que Rafa el de la tienda de abajo de electrónica, siempre tiene ganas de vender y soluciones para casi todo :lol:

Os sigo informando.
Citar
#5
Te hablo desde el movil y rapido, necesitas 4 pines para el PAP no? Dos para el LCD, los demas para interruptores, vas sobrado nu?

Enviado desde mi Nexus 4 mediante Tapatalk
Citar
#6
Si fuera así si, pero es que no dispongo de modulo I2C para el display. Y de momento para las pruebas me tengo que apañar con los pines.

Pero acabo de comprar uno por ebay pensando en lo que me has dicho y así me sobraran pines.

Pero por el momento donde estoy mas atascado es en el menu, que es donde me estoy liando de verdad.
Citar
#7
El tema de los menus parece trivial pero no lo es. Pero si luchas con ello pillas el tranquillo y luego van solos. Dale candela y esperamos resultados!!

Enviado desde mi Nexus 4 mediante Tapatalk
Citar
#8
Hola de nuevo a todos,

No es que a las primeras de cambio ya me retire, sino que por el trabajo he andado un poco liado y me ha tocado dejar aparcado el proyecto, pero ya estoy otra vez con ello.

Tengo tal lío en la cabeza que parece que me vaya a explotar, con respecto a los menús en LCD, y cada vez parece que me líe mas. De momento estoy intentando crearme los menús y acceder secuencialmente a ellos, pero cada vez que me creo un programa veo que no hace lo que quiero y vuelvo a empezar; habré hecho mas de 20 diferentes.

Al final he visto que existen librerías para poder crear los menús y simplificar más el trabajo, ( o complicármelo más) ya que hace que vuelva a empezar.

La librería última con la que me he puesto es "MenuBackEnd", os pongo el enlace:

http://www.arduino.cc/playground/uploads...nd_1-4.zip

Ahora voy a ver si soy capaz de aclararme, ya os voy contando.

Ya me ha llegado el driver del motor y estoy deseoso de poder empezar a jugar con el, y ver que soy capaz de controlar el motor PaP. Aunque la verdad es que ando un poco desilusionado por los pocos avances que he tenido.

Pero bueno dicen que el la sigue la consigue, así que continuara......
Citar
#9
Buenas a todos,

Tras continuar aprendiendo con arduino, y buscar por internet ejemplos y manuales. He estructurado el programa mas o menos. Os lo pongo aquí:

Cita:#include  <LiquidCrystal.h>
#include  <EEPROM.h>
#include  <Stepper.h>

#define STEPS 200 //Número de pasos por vuelta.(1.8º)

LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7); //Definimos conexiones LCD

    /*
    Ponemos nombre al motor, el número de pasos y los pins de control
    Stepper nombre motor (número de pasos por vuelta, pins de control)
    */

//Stepper stepper(STEPS, 8, 9, 10, 11);    //Definimos conexiones Motor

    /*
    Podemos utilizar el inversor HD74LS04P y sólo utilizaremos dos
    pines para el motor PaP Stepper stepper(STEPS, 8, 9)
    */

const int numeroDeMenus=5;

char tituloMenu[numeroDeMenus][16] = {
  "Select MODE ",
  "Select DIR ",
  "Select Speed",
  "Ace/Dec ",
  "START/STOP " };

int adc_key_val[5] ={50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
boolean cursorActivo=false;
boolean enMenu=false;
unsigned long time;
int x=0;
byte mode=1;
byte dir=1;
byte velocidad=1;
byte aceDec=1;
byte startStop=1;

void setup()
{
  cargarConfig();
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" FILMI_Q ");
  lcd.setCursor(0,1);
  lcd.print(" Elect. Design ");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" SLICER ");
  lcd.setCursor(0,1);
  lcd.print(" VERSION V1_0 ");
  time = millis();
 }

void loop()
{
  if (millis()-time > 7000) { // Si han pasado mas de 7 segundos salimos del menu
    if (enMenu) guardarConfig();
    enMenu = false;
    x=0;
    time = millis();
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" SLICER ");
    lcd.setCursor(0,1);
    lcd.print(" READY TO RUN ");
  }
  
  if (millis()-time > 5000) { // Si han pasado mas de 5 segundos apagamos el cursor
    lcd.noBlink();
    cursorActivo=false;
  } 

  adc_key_in = analogRead(0); // Leemos el valor de la pulsación
  key = get_key(adc_key_in);       // Obtenemos el boton pulsado

  if (key != oldkey) // Si detectamos pulsaación
   {
    delay(50); // Espera para evitar los rebotes de las pulsaciones
    adc_key_in = analogRead(0); // Leemos el valor de la pulsacion
    key = get_key(adc_key_in);     // Obtenemos el boton pulsado
    if (key != oldkey)
    {
        time = millis(); // TODO: falta la comprobacion de si se ha desbordado el tiempo
        oldkey = key;
        char accion = 0;
        if (key >= 0){ // Si se ha pulsado cualquier tecla
          lcd.blink(); // Mostramos el cursor parpadeando
          cursorActivo=true;
        }
        if ((key == 0) && (enMenu)){ // Se ha pulsado la tecla derecha
        }
        if ((key == 1) && (enMenu)) { // Se ha pulsado la tecla arriba
          accion++;
        }
        if ((key == 2) && (enMenu)) { // Se ha pulsado la tecla abajo
          accion--;
        }
        if ((key == 3) && (enMenu)) { // Se ha pulsado la tecla izquierda
          x++;
          if (x>numeroDeMenus-1) x=numeroDeMenus-5;
        }
        if (key == 4){ // Se ha pulsado la tecla de seleccion
          
        }
        enMenu = true;
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(tituloMenu[x]);
        lcd.setCursor(0,1);
        
        switch (x) {
        case 0: // Estamos en fijar MODO
          mode += accion;
            if (mode == 0) {
              lcd.print("MODE MAN");
            }
            else {
              lcd.print("MODE AUTO");
            }
            if(mode > 1) mode = 1;
          break;
          
        case 1: // Estamos en fijar DIRECCIÓN
          dir += accion;
            if (dir == 0) {
              lcd.print("LEFT");
            }
            else {
              lcd.print("RIGHT");
            }
            if(dir > 1) dir = 1;
          break;
          
        case 2: // Estamos en fijar VELOCIDAD
          velocidad += accion;
          lcd.print(velocidad);
          lcd.print("rpm");
          break;
        case 3: // Estamos en fijar ACCELERACIÓN/DECELERACIÓN
          aceDec += accion;
          if (aceDec == 0) {
              lcd.print("YES");
            }
            else {
              lcd.print("NO");
            }
            if(aceDec > 1) aceDec = 1;
          break;
          
        case 4: // Estamos en MARCHA/PARO
          startStop += accion;
          if (startStop == 0) {
              lcd.print("STOP");
            }
            else {
              lcd.print("START");
              //void motorPaP
            }
            if(startStop > 1) startStop = 1;
          break;
        
        } 
      }
   }
}


// Convertimos el valor leido en analogico 
// en un numero de boton pulsado
int get_key(unsigned int input)
  {
  int k;

  for (k = 0; k < NUM_KEYS; k++)
  {
    if (input < adc_key_val[k])
    {
      return k;
    }
  }

  if (k >= NUM_KEYS)k = -1; // Error en la lectura.
  return k;
  }


boolean cargarConfig(){
  if ((EEPROM.read(0) == 27) && (EEPROM.read(1) == 28) &&
     (EEPROM.read(2) == 13) && (EEPROM.read(3) == 18)) {
    // Comprobamos que la eeprom tenga una
    // configuracion valida con numeros concretos
    // solo cargamos el valor de la configuracion si los valores coinciden
    if (EEPROM.read(4) == EEPROM.read(5)) mode = EEPROM.read(4);
    if (EEPROM.read(6) == EEPROM.read(7)) dir = EEPROM.read(6);
    if (EEPROM.read(8) == EEPROM.read(9)) velocidad = EEPROM.read(8);
    if (EEPROM.read(10) == EEPROM.read(11)) aceDec = EEPROM.read(10);
    if (EEPROM.read(12) == EEPROM.read(13)) startStop = EEPROM.read(12);
    return true;
  }
  return false;
}

void guardarConfig(){
  EEPROM.write(0,27);
  EEPROM.write(1,28);
  EEPROM.write(2,13);
  EEPROM.write(3,18);
  // Ponemos numeros concretos en el comienzo
  // de la EEPROM para confirmar que tiene valores correctos.
  EEPROM.write(4,mode);
  EEPROM.write(5,mode); // almacenamos los valores 2 veces
  EEPROM.write(6,dir);
  EEPROM.write(7,dir); // almacenamos los valores 2 veces
  EEPROM.write(8,velocidad);
  EEPROM.write(9,velocidad); // almacenamos los valores 2 veces
  EEPROM.write(10,aceDec);
  EEPROM.write(11,aceDec); // almacenamos los valores 2 veces
  EEPROM.write(12,startStop);
  EEPROM.write(13,startStop); // almacenamos los valores 2 veces
}

De momento lo que hago es poder pasar por lo diferentes menús para poder introducir los datos y una vez introducidos, en START_STOP, hago una llamada a una función para poder poner en servicio el motor.

Decidme que os parece, las opiniones. Mucha parte de este cógigo no es mia, la he sacado de paginas de internet y la he ido adaptando. Paginas que más addelante pondré para poder dar las gracias.

A partir de ahora empezaré a desarrollar la función del motor y poder ponerlo en funcionamiento.

Espero vuestros comentarios.

Un saludo a todos.
Citar
#10
Cuando tenga un rato le echo un ojo al codigo entero, solo una cosa, cuando guardes la configuracion en la EEPROM, verifica antes si los valores que vas a guardar son iguales que los que ya tiene guardados, y si son iguales no los reguardes, ya que estas consumiendo un ciclo de la EEPROM, asi te durara mas.
Citar
#11
Ok Triggerr,

Ni tan siquiera lo habia pensado.

Gracias.
Citar
#12
Tienes el post de triggerr y su estación meteorológica por si no lo has visto y te vale para coger ideas, encoder rotatorio incluido :roto2:

No lo he visto en el post, y triggerr parece que es demasiado modesto para colgarlo, con el currazo que tiene :aplauso: :aplauso: :aplauso:



Citar
#13
Hola biketrial981,

Pues si que tienes razón, menudo trabajo el de Trigger, darle la enhorabuena por el proyecto y por toda su aportación.

Me lo he estado leyendo, sobre todo en la parte del LCD y los menús y es impresionante, además está muy bien explicado. Voy a intentar seguirlo de guia, para ver si el mio funciona. Además he comprado un encoder, para probarlo en el menú.

Hoy mismo me ha llegado las dos tarjetas I2C, que tenia pedidas para el LCD, voy a empezar a hacer las primeras pruebas y ver si soy capaz de hacer funcionar el LCD con la comunicación I2C.

Ya os voy informando.
Citar


Temas similares...
Tema Autor Respuestas Vistas Último mensaje
  CONSULTA Motor Extruder no funciona manu_ro 1 184 23-09-2019, 04:30 PM
Último mensaje: bertonic
  Controlar dos o tres cartuchos calefactores Shikva 1 415 23-09-2019, 07:23 AM
Último mensaje: bertonic
  CONTROLAR CUATRO TIRAS LED WS2812B CON ARDUINO NAVIDADES MAFALDA74 10 1,005 28-03-2019, 08:44 AM
Último mensaje: shiryou
  CONSULTA Controlar bucle con un final de carrera polu2 10 466 15-03-2019, 10:16 PM
Último mensaje: Triangulo
  CONSULTA Re: Arduino Mega, 1 servo ,1 nema, 3 motor DC carlos hop 8 866 26-09-2018, 01:30 PM
Último mensaje: Shellmer