[SOLUCIONADO] lcd + teclado y arduino mega

Hola, quiera plantearles mi problema a ver si me pueden ayudar.

Primero indicar que soy novato en esto y he ido incrementando la dificultad

primero pude escribir un texto en el lcd
segundo pude ingresar numeros desde el teclado
tercero y ahy estoy

debo ingresar un numero decimal ejemplo 35,59 en el extremo izquierdo del lcd y 38,98 en el extremo derecho, dentro de las consideraciones es que este valor decimal debo despues hacer una operacion matematica ( pero paso por paso, por ahora es ingresar este valor decimal y mostrarlo en el lcd).

Alguien me puede ayudar o indicatr donde puedo encontrar ejempo de este tipo

Juan Carlos

Estoy ocupando un arduino mega 2560
lcd keypad shield
teclado 4x4 para arduino

Nunca hay ejemplos como el que uno quiere hacer Hay sketch para manejar LCD, para usar Keypad y hasta para ingresar números. hacer lo que quieres requiere de tu ingenio.
Aqui mismo tienes ejemplos para LCD, y keypad, con ambos armas lo que quieres.

Me olvido del LCD que es fácil.
El teclado con la librería keypad tambien lo resuelves fácil.
ahora que recuerdo busca una calculadora que he visto algunas por ahi.
Calculadora hecha con arduino, hay un ejemplo de proteus que tiene una.

si no es mucha la molestia, te recuerdas del link.

ademas, se que es uso del ingenio, pero a veces uno se manea(enreda), en algo facil, y es bueno que alguien que sabe mas pueda ayudarlo u orientarlo mas aun, gracias de todas maneras, pero cuando me piden ayuda (en lo que se) soy mas concreto, por lo menos yo comparto lo que se.

Juka

Hola Junka, vamos por partes, para poner los número en el lugar de la pantalla que quieres puedes usar la función lcd.setCursor(X,Y); donde x representa la columna e y la fila de esta manera para tu números lo puedes hacer de la siguiente forma (Voy a suponer que tu pantalla es de 20x4):

lcd.setCursor(0,0) //Por defecto al encender se encuentra en esa posición
lcd.print(numero1, 2) //Para que salgan dos decimales
lcd.setCursor(15,0) //Por defecto al encender se encuentra en esa posición
lcd.print(numero2, 2) //Para que salgan dos decimales

numero1 y numero2 tienen que haber sido previamente definidos como float

Ahora, para obtener numero1 y numero2 puedes crearte una función que sea de esta forma:

floar Pasar_a_float(char cadena[]){

int i=0, exponente=-1;
float salida:

//Cálculo de la parte entera
while (cadena!='.' && i<sizeof(cadena) && cadena_>47 && cadena*<58 ){_
_salida=salida10+cadena*;
i++;
}
i++;//Para superar al punto decimal si lo hubiera
//Cálculo de la parte decimal*

while (i<sizeof(cadena) && cadena>47 && cadena*<58 ){
salida=salida+cadenapow(10,exponete);
exponente--;
}

return salida;
}
Y para poder ingresar los número lo, lo puedes hacer si quieres dentro del loop o con otra función por ejemplo, declarando una variable que char numero_char[]
int i=0;
char tecla=0;
while(tecla!='='){
tecla = keypad.getKey();
if(tecla>47 && tecla<58 || tecla =='.'){
numero_char*=tecla;*
i++;
}
}
No sé si estará bien porque lo he escrito aquí en un momento así que puede que haya escrito hasta alguna barbaridad pero creo que como ejemplo te sirve. De todas formas te recomiendo que te leas las funciones de las librerías Liquidcrystal (http://arduino.cc/en/pmwiki.php?n=Reference/LiquidCrystal) y keypad(Arduino Playground - HomePage), te pueden ayudar bastante.
Un saludo y espero haberte ayudado un poco._

Si el lcd es este:

Un ejemplo para poner esos dos números, puede ser este:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
float a = 35.59;
float b = 38.98;

void setup() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print (a);
  lcd.setCursor (11, 0);
  lcd.print(b);
}

void loop() {

}

A los prints no es necesario ponerles el número de decimales, ya que por defecto pone 2.

Creo que donde has puesto lcd.clear(); querías poner lcd.display();

Un saludo.

a ver si este codigo que encontré te da un empujón:
Esta es una calculadora con el LCD Shield
enlace esta acá

Otro codigo con Keypad

plfuertes:
Creo que donde has puesto lcd.clear(); querías poner lcd.display();

Un saludo.

Donde he puesto lcd.clear(); quería poner y he puesto lcd.clear();

Siempre hago un limpiado de pantalla antes de escribir, a no ser que quiera conservar lo que ya hay, para mover el cursor y escribir algo más en otra zona de la pantalla. Con el clear, además, sé que el cursor está en la posición 0,0 de forma que no pongo un lcd.setCursor(0,0) al imprimir el primer número.

Hola Carmeloco, lo que dices tiene sentido, pero como estás en el setup y acabas de inicializar el dilplay creo que si no pones lcd.display(); este queda apagado y no puedes escribir nada. Además de que si lo acabas de inicializar no debe haber nada y la posición del cursor debe ser la (0,0) que es la que viene por defecto.

Corrígeme si me equivoco, que soy novatillo por estos mundos y puede que diga alguna tontería, si es así dímelo y aprendo para otra vez. :slight_smile:

Un saludo.

muy agradecido por su aporte, empiezo con la programacion y les cuento

Juka

plfuertes, le agradezco su didactica explicacion pero le recuerdo que soy muy muy novato y existen algunas cosas que no entiendo, asi que le agradeceria no se moleste si las consultas son muy tontas:

he estado haciendo lo que me indica y escribo los numeros donde quiero, esto se produce cuando presiono cualquier tecla.

Pues bien viendo su ejemplos quise hacer que esos numeros (indicados por defecto) sean ingresados presionando primero la tecla *, se posicione en linea 1 columna 0, luego presionar uno despues 2 despues 8 y finalmente 9, de aqui se va ala posicionnum2 y se repite con otros numeros,

Aqui ingrese su codigo y me reclamo

Adjunto codigo

float num1;
float num2;
int tecla;
int cuadro=1;
int fila = 1;
#include <LiquidCrystal.h>
LiquidCrystal lcd(22, 23, 24, 25, 26, 27);
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns

char hexakeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {35, 34, 33, 32};
byte colPins[COLS] = {31, 30, 29,28};

//keypad customKeypad= Keypad( makeKeymap(hexakeys),rowPins,colPins,ROWS,COLS);

ME RECLAMO Y BUSCANDO HICE ESTOS CAMBIOS Y ME FUNCIONO
Keypad kpd = Keypad( makeKeymap(hexakeys), rowPins, colPins, ROWS, COLS );
void setup ()
{
lcd.begin (16,2);
lcd.setCursor(0,0);
lcd.print ("Num 1");
lcd.setCursor(11,0);
lcd.print ("Num 2");
delay (2000);

}
void loop(){

//num1=12.89;// aqui debo hacer que ingrese el num1, considerando q tendra 4 numeros (35.56), luego debe saltar a lugar donde ira num2
// como indico que se debe presionar la tecla *
int i=0;
char tecla=0;

while(tecla!='='){

tecla = keypad.getKey(); // me reclama

if(tecla>47 && tecla<58 || tecla =='.'){

numero_char=tecla;
i++;
}

}

lcd.setCursor(0,1); //Por defecto al encender se encuentra en esa posición
lcd.print(num1, 2); //Para que salgan dos decimales
num2=34.90; //idem a num1
lcd.setCursor(11,1); //Por defecto al encender se encuentra en esa posición
lcd.print(num2, 2); //Para que salgan dos decimales

}

//fuin etapa loop
}

Espero su compresión y ayuda

se me olvida consultar que significa esto

if(tecla>47 && tecla<58 || tecla =='.')

se refiere a la cantodad de numeros que se pueden presionar???

juka

Esta haciendo una validación de ingreso posibles de números por el teclado.
COmo los tiene en ASCII se leen con esos números aparentemente grandes pero simbolizan estos

Esto es lo que definió en el Keypad

{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}

lo que no veo el punto decimal que esta en la consulta del if?

if(tecla>47 && tecla<58 || tecla =='.')

plfuertes:
Hola Carmeloco, lo que dices tiene sentido, pero como estás en el setup y acabas de inicializar el dilplay creo que si no pones lcd.display(); este queda apagado y no puedes escribir nada. Además de que si lo acabas de inicializar no debe haber nada y la posición del cursor debe ser la (0,0) que es la que viene por defecto.

Corrígeme si me equivoco, que soy novatillo por estos mundos y puede que diga alguna tontería, si es así dímelo y aprendo para otra vez. :slight_smile:

Un saludo.

Está todo en el setup, porque no necesitaba que se repitiese continuamente la impresión de los números por pantalla. En el caso que yo puse, con que se haga una sola vez, era suficiente.

Lo del lcd.display, la verdad es que no hace falta para nada. Yo he hecho las pruebas con el wardware físico, especificado en mi respuesta, y funciona perfectamente.

El uso del lcd.clear, es una buena práctica (desde mi punto de vista) a usar siempre que se quiere escribir todo en la pantalla. En el caso concreto que yo he puesto, quizá no era del todo necesario, pero siempre lo pongo, para evitar errores y suciedad en el display.

Hola de nuevo, siento si durante la semana escribo menos pero ando bastante liado con la facultad.
Antes que nada decir que yo también soy nuevo, así que no te preocupes Junka que no me he molestado en ningún momento, y pido disculpas si lo ha parecido ya que yo también soy un novatillo en esto (surbyte y carmeloco saben bastante más que yo seguro).

Lo que hago con esta línea " if(tecla>47 && tecla<58 || tecla =='.')" es justamente lo que te ha dicho surbyte, y puse el ·.· porque no me percaté de que no estaba en el teclado, así que se podría eliminar. quedando de esta manera "if(tecla>47 && tecla<58)" de todas formas si lo dejas no pasa nada, sólo que esa condición no se va a dar nunca.

La representación ASCII lo que hace es asignarle a cada símbolo una secuencia de bits, puedes consultar las tablas que hay por Google. Y esa secuencia de bit pasadas a números enteros, tienen diferentes valores que también puedes consultar en dichas tablas.

No entiendo muy bien qué es lo siguiente que quieres hacer, pero me temo que no voy a poder seguir escribiendo mucho código porque como ya he dicho ando bastante liado y durante la semana aún más. Si me especificas un poco mejor lo que quieres hacer puedo intentar mirarlo en algún hueco que tenga pero no prometo nada.

Para finalizar agradecer a carmeloco la explicación, no sabía que podías encender el display sin la orden lcd.display() ya que yo no dispongo de Hardware y todo lo hago mediante simulación, y al menos a mí, si no le doy la orden se me queda apagado (Pero conserva lo que hay en él escrito si lo vuelves a encender). Sin embargo pretendo comprar el hardware cuando me asegure que todo funcione y estas diferencias entre simulación/realidad me vienen muy bien. Por otro lado decirte que a mí también me parece una buena práctica y de hecho la uso mucho, usar un clear antes de escribir ya que como bien dices, así te aseguras quitar alguna cosa que tuvieras ahí escrita evitando que se te enmarrane la pantalla.

Saludos a todos.

Gracias a todos por los comentarios, lo que llevo hasta el momento (gracias a la ayuda de Santiago Fuentes Benavides) es lo siguiente

activo el lcd y el pad, ingreso un dato en la linea 01 esto es pulsando * queda en esta posicion y puedo ingresar 4 digitos(12.98), ñuego en la posicion 8,1 e ingreso nuevamente 4 digitos, luego se debe pasar a numero (aqui tengo el problema en numeros = c.toInt();), algo se ha avanzado.
Espero me puedan ayudar
juka
#include <LiquidCrystal.h>
#include <Keypad.h>
#define N 50
const byte kROWS = 4; //four rows
const byte kCOLS = 4; //three columns
const char dROWS = 2;
const char dCOLS = 16;
const char LENGHT = 4;
char hexakeys[kROWS][kCOLS] = {

  • {'1','2','3','A'},*
  • {'4','5','6','B'},*
  • {'7','8','9','C'},*
    _ {'','0','#','D'}_
    };
    _/
    REVISA QUE ESTAS CONEXIONES ESTE DE ACUERDO AL CODIGO /_
    byte rowPins[kROWS] = {35, 34, 33, 32};
    byte colPins[kCOLS] = {31, 30, 29,28};
    LiquidCrystal lcd(22, 23, 24, 25, 26, 27);
    Keypad kpd = Keypad( makeKeymap(hexakeys), rowPins, colPins, kROWS, kCOLS );
    _char i = 0; /
    Se usa un char en vez de int para ahorrar memoria, con esto podemos usar los numeros del 0 al 255 /_
    _char num[5]; /
    Creamos un String como un arreglo de caracteres, se da un espacio extra para el caracter de fin de string '\0' /_
    int numeros[N];
    void setup () {
    lcd.begin (dCOLS, dROWS);
    lcd.setCursor(0,0);
    delay (2000);
    }
    void loop(){
    _char j; /
    Nuevamente se utiliza un char como contador /_
    _char c = kpd.getKey(); /
    se obtiene la primera pulsacion /_
    _if(c == '
    '){_
    /* Posicion del cursor (varia la fila) */
    lcd.setCursor(0, (i%dROWS));
    /* lectura de un numero */
    for(j = 0; j < LENGHT - 1 ; j++){
    c = kpd.getKey();
    num[j] = c;
    }
    //c[4] = '\0'; /* Fin de String */
    /* si se vuelve a presionar * en este ciclo se imprime en el LCD */
    if(c == '*'){
    lcd.print ("Num ");
    lcd.print (j+1, DEC);
    lcd.print (": ");
    lcd.print(num); /* lo que va despues de la coma define la base numerica (BIN = binario,OCT = octal, DEC = decimal, HEX = hexadecimal) */
    /* Se guarda lo leido como un numero entero en el arreglo numeros */
    _ numeros = c.toInt();_
    /* se aumenta en 1 unidad la fila */
    i++:
    }
    }
    }

Bueno jukaceledon, te recuerdo que debes usar tags (Nro 19) para insertar códigos en tus post. Por favor edita el anterior y usa el tag que te indico.

que tecla definiste como punto decimal? no veo que tengas una tecla para punto decimal.
Qué ocurre si quieres ingresar 3.56? No se puede.

No viste mis ejemplos de calculadoras. Había dos, uno para el LCD shield y otro para un LCD común con keypad.
tal vez un keypad diferente pero el ejemplo servía y podías comenzar desde ahi para lograr lo tuyo.
De todas formas vas en camino, aunque no comparto tu criterio de ingresar 4 digitos y no mostrarlos sino hasta que se pulse '*'

Vuelve a mirar el ejemplo keypad, te lo recomiendo

esto es lo que hace esa rutina para presentar y tener el número para operaciones de suma, resta, multiplicación y división posteriores.

  c = kpd.getKey();
  switch(c) 
  {
  case '0' ... '9': // This keeps collecting the first value until a operator is pressed "+-*/"
    lcd.setCursor(0,0);
    first = first * 10 + (c - '0');  // first esta definido como long asi que hay que modificarlo para . decimal
    lcd.print(first);
    break;
 ...................
 // siguen los demas case () break

Si usaras por ejemplo '' como punto decimal podrias agregar un case '': y incorporar el punto decimal a un first definido como float no como esta en el ejemplo.
Parte del pequeño código ue lo haria seria dividir a lo que ya tienes de first hasta que sea menor que uno por 10.
algo asi

case ´*´: 
             while (first > 1) {
                    first /= 10;        // lo divide por 10 en cada ciclo. Luego lo compara con 1, si es mayor sigue
             ]                             // si es menor sale del while
             break;                     // con esto introduces el punto decimal.

Hola surbyte, gracias por las recomendaciones y respuestas, trabaje el codigo que me indico y suprimi algunas cosas y considere ingresar el numero total (si quiero imprimir el numero 35,89) como 3589 y lo divido por 100, asi tengo el decimal 35,89, no se si estoy bien, ahora quise imprimir el numero en la segunda linea y no pude, cambie los valores en lcd.setCursor(0,2);, pero no me funciono, que puede ser, adjunto archivo

/* 
 || @version 1.0
 || @author Andrew Mascolo
 || @date May 15, 2013
 ||
 || @description
 || Simple use of keypad and LCD
*/
#include <Keypad.h>
//#include <Wire.h> 
#include <LiquidCrystal.h>
LiquidCrystal lcd(23, 22, 27, 26, 25, 24);


long first = 0;
long second = 0;
double total = 0;

char customKey;
const byte ROWS = 4;
const byte COLS = 4;

char keys[ROWS][COLS] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','*'},
  {'C','0','=','/'}
};
byte rowPins[ROWS] = {35, 34, 33, 32}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {31, 30, 29,28}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); 

void setup()
{
//  lcd.init(); // initialize the lcd 
//  lcd.backlight();
}

void loop()
{
  customKey = customKeypad.getKey();
  switch(customKey) 
  {
  case '0' ... '9': // This keeps collecting the first value until a operator is pressed "+-*/"
    lcd.setCursor(0,2);
    first = first * 10 + (customKey - '0');
    lcd.print(first);
    break;

    case '/':
    lcd.clear();
    first = (total != 0 ? total : first);
    lcd.setCursor(0,2);
    lcd.print("/");
    second = SecondNumber();
    lcd.setCursor(0,0);

    second == 0 ? lcd.print("Invalid") : total = (float)first / (float)second;

    lcd.print(total);
    first = 0, second = 0;
    break;

  case 'C':
    total = 0;
    lcd.clear();
    break;
  }
}

long SecondNumber()
{
  while( 1 )
  {
    customKey = customKeypad.getKey();
    if(customKey >= '0' && customKey <= '9')
    {
      second = second * 10 + (customKey - '0');
      lcd.setCursor(0,2);
      lcd.print(second);
    }

    if(customKey == '=') break;  //return second;
  }
 return second; 
}

Disculpen que lo realice en dos post pero estaba aprendiendo a ingresar un tags

Juka