Matriz de botones

Gracias Tauro0221 por el link pero el Eset al seguir el link o intentar buscar en esa pagina manualmente el post en antivirus me bloquea el ingreso.

Amenaza: HTML/ScrInject.B troyano

a parte de eso, mi problema no es leer la matriz, mi problema es como crear el dato que necesito

MODERADOR:
no repitas lo que dice tu compañero.
Lee las normas del foro

Hi, Okay perdona pero yo no tengo problema con el link. En cuanto a las variables que debes de mandar de acuerdo a la tecla puedes hacer un for/loop que leea un array que compare con la localizacion de los caracteres que tienes que enviar de acuerda a la tecla que selecciones.

[code]


String mensage[65] = {"H0", "H02", "H03", "H04", "H05", "H06" }; 
//**********************************************************
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}
//*********************************************************
void loop() {
  // put your main code here, to run repeate
  byte key = 1; //para probar el programa cambia el numero de acuerdo a la tecla.

  for (byte cnt = 0; cnt <= 6; cnt++) {
    if (cnt = key ) //compara la tecla de la matrix con el mesaje a trasmitir.
      Serial.print("Mensaje a enviar de acuerdo al tecla de la matrix  = ");
    Serial.println(String(mensage[cnt])) ;
  }
  delay(1000);
}
//***********************************************************

[/code]

Tauro probé ese pedazo de código, funcionaria, no pude conectarlo al código de la matriz este fue mi intento:

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 5, 4}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

String mensage[65] = {"H01", "H02", "H03", "H04", "H05", "H06" };

void setup(){
  Serial.begin(9600);
}
  
void loop(){
  byte key = keypad.getKey();
  
  if (key){
    for (byte cnt = 0; cnt <= 6; cnt++) {
    if (cnt = key ) //compara la tecla de la matrix con el mesaje a trasmitir.
         Serial.println(String(mensage[cnt]));
   }
  }
}

Al presionar un botón el monitor serie solo me muestra que "algo paso", osea me tira la hora del evento pero sale en blanco, presiono los números y muestra que algo quiso llegar por el serie pero llega blanco, como si el Serial.println mandara nada... creo que algo del string eh hecho mal

saludos y gracias por responder

Hi, Perdona pero encontre dos problemas. Trata tu sketch adjunto para ver como te trabaja.

[code]
#include 
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'},
};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 5, 4}; //connect to the column pinouts of the keypad

 Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

String mensage[65] = {"H01", "H02", "H03", "H04", "H05", "H06" };

void setup(){
  Serial.begin(9600);
}

void loop(){

  byte key = keypad.getKey();
 delay(1000);
  if (key){
    for (byte cnt = 0; cnt <= 6; cnt++) {
    if (cnt == key ) //compara la tecla de la matrix con el mesaje a trasmitir.
         Serial.println(String(mensage[cnt]));
   }
  }
}

[/code]

No es mas fácil asi?

void loop(){
  byte key = keypad.getKey();

  if (key) {
      sprintf(buffer, "H0%c ", key);
      Serial.print(buffer);
  }
}

Yo no veo números mayores a 9 de modo que mantengo el H0 si hay mayores pongo un if(key>9) una cosa sino otra, lo explico como para llegar a 45.

Hola surbyte, claro eso lo puedo concatenar, sigo con el problema de poner dos cifras en la matriz:

(esto es como ejemplo, por eso pongo esta de 4x3)

char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};

pero si yo a esto: '1' le pongo '45' no me funciona y no se que modificar para que funcione.

busco, leo y trato de interpretar funciones y variables, las entiendo bien, pero se me complica relacionarlas.

lo que me respondio tauro lo probe pero el serial hace el salto de renglon pero no imprime nada

Tu error esta en como ingresas los datos. Deberías hacer algo como esto

Ingresar un dato o dos y luego cerrar dicho ingreso pulsando una tecla como # o *.

Entonces lees que ingresaste '1' y si no recibes # o * sigues acumulando.

Mira este ejemplo de una calculadora hecha con un teclado 4x4 y un Arduino. Es similar a lo que quieres hacer en el sentido de como cargar los datos. Solo presta atención a esa parte.

Disculpen el espacio de tiempo, con la pandemia tuve que irme a trabajar al campo para mantener mis ingresos, ahora volví unos días.

Surbyte, no me sirve cargar-almacenar un código y enviarlo por serial, si fuera asi los 48 botones que tengo que configura lo soluciono con una matriz de 3x4.

Lo que estoy armando es para un tablero de simulador, seria poco tedioso y menos realista que por ejemplo: para ampliar el zoom del GPS 4 veces tenga que escribir 4 veces "C"+"5"+"1"+"#(enter)"

por eso después de mis pruebas y no llegar a nada decidí consultar acá si hay manera de que en cada botón su valor sea una cadena de 3 caracteres

Lo que estoy armando es para un tablero de simulador, seria poco tedioso y menos realista que por ejemplo: para ampliar el zoom del GPS 4 veces tenga que escribir 4 veces "C"+"5"+"1"+"#(enter)"

Al menos yo no entiendo que quieres decir con esto. Entiendo que tu problema es este

Enviar códigos por puerto serie Ej: "H01" al pulsar solo una tecla de una matriz, cada botón es un código diferente "H01", "H02", y así sucesivamente, son 45 códigos en total, todos con el mismo formato una letra y un numero de dos cifras.

Te respondo que lo mejor es usar algo estilo calculadora donde los números se forma simplemente del mismo modo que los ingresamos en la calculadora. Número decena primero y unidad después seguido de un caracter del teclado que indica fin. La H o la C como mencionas no se de donde salen. Supuse que eran códigos fijos y hablaste de "H" por lo que usar "C" es lo mismo pero para cambiar de C a H entonces requieres de algo que lo haga.

En este punto me he perdido.

Tal vez sea esto lo que buscas

byte value=0;

void loop() {
  char buffer[20];
  char key = kpd.getKey();
 if (key != NO_KEY)   {
    if ( (key >= '0') && (key<= '9') )  { // si son digitos entonces los acumulo.
       value = value *10;
       value = value + key -'0';
    }
    if ( key == '#' )  {  // si presionas # termina la operacion.
      sprintf(buffer, "H02%d ", value); // solo espero 2 valores si pones mas falla esto.
      Serial.print(buffer);

      Serial.println(value);   // aca deberías usar el sprintf que te sugerí antes con value
      value=0;  // Ponego a 0 para proximo ingreso.
   }
 }
}

Surbyte justamente:

Lo que estoy armando es para un tablero de simulador, seria poco tedioso y menos realista que por ejemplo: para ampliar el zoom del GPS 4 veces tenga que escribir 4 veces "C"+"5"+"1"+"#(enter)

te lo traduzco pulsar C (el codigo lo almacena) = C pulsar 5 (el codigo lo almacena) = C5 pulsar 1 (el codigo lo almacena) = C51 pulsar # (el # hace las veces de enter ) = el codigo manda la cadena C51 por puerto serie

Eso de ahi es un ejemplo de como usaria lo que vos me propones (un código que funcione almacenando una cadena de caracteres pulsados en un teclado y después se envie por serie)

eso no me sirve... es muy engorroso para el que lo use

yo necesito que cuando pulse una tecla el arduino me mande el codigo cada tecla tiene su propia cadena.

esto es el keypad normal

char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}

en bruto esto es lo que yo necesito. (esto tiene un error obvio que es la variable tipo char, puse el recorte para demostrar otra vez lo que necesito, aun asi probe cambiarlo con String y no me funciona tampoco)

char keys[ROWS][COLS] = {
 { "H01","H02","H03","H04","H05","H06","H07","H08" },
   { "H09","H10","H11","H12","H13","H14","H15","H16" },
   { "H17","H18","H19","H20","H21","H22","H23","H24" },
   { "H25","H26","H03","H04","H05","H06","H07","H08" },
   { "H09","H10","H11","H12","H13","H14","H15","H16" },
   { "H17","H18","H19","H20","H21","H22","H23","H24" },

Entonces asumo que tenes un teclado con mas filas y columas? Ahi estas mostrando una matriz 6x8 6 filas y 8 columnas Si fuera el caso no deberías tener problema.

Pero ojo... mira como creas la matriz, dice

char keys[ROWS][COLS]

char es para caracter y tu pones ahí una cadena de caracteres de 3 bytes. Una cosa no tiene que ver con la otra. Tienes varias alternativas como por ejemplo definir un vector con tus "HXX" y que el teclado determine el ínidice de dicho vector.

O sea, tu digitas la tecla 23 y en la posicion 23 tienes "H23"

Esta es mi idea.. a ver si te sirve

#include 
// include the library code:

String datos[12] = {"H01", "H02","H03","H04","H05","H06","H07","H08","H09","H10","H11","H12"};
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  { '1','2','3' },
  { '4','5','6' },
  { '7','8','9' },
  { '*','0','#' }
};
byte rowPins[ROWS] = {  A0, A1, A2, A3}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {  2, 3, 4}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


void setup() {
  Serial.begin(9600);
  Serial.println("Demostración de teclado");
  for (int i; i<12; i++) {
      Serial.print(datos[i]);
      Serial.print(" ");
  }
  Serial.println();
  
}

void loop(){
  char key = keypad.getKey();
  
  if (key){
    Serial.print(key);
    Serial.print(" ");
    Serial.println(datos[key-48]);
  }
}

Esta es la salida

Empezando H01 H02 H03 H04 H05 H06 H07 H08 H09 H10 H11 H12 1 H02 1 H02 2 H03 2 H03 3 H04 3 H04 4 H05

Exacto Surbyte ese es mi problema!!!!

La matriz botonera la voy a armar yo (son los 48 botones en un marco de madera que rodea una pantalla) eso es el menor problema, es solo respetar lineas, columnas y soldar cables

Haber si entiendo lo que me mandas: Ahí se asocia cada botón de la matriz a una posición del vector porque la variable char es de un solo carácter, ahora siguiendo ese pensamiento como pongo mas de 10 botones si tengo 0 a 9? Cuando tenga que poner el valor 10 en la matriz para la posición 10 del vector sigo en la misma situación..

Aca te copio lo que me ofreció un profesor como solución pero no pude comunicarme mas con el y solo me quedo esto (a lo mejor te aporto una opcion mas) a mi no se me prendio el foco en como conectar eso al codigo de una matriz:

const char* const array2D[] [2] PROGMEM ={
  {"abc" , "def"};
  {"jkl" , "mno"}
 };

void setup() {
Serial.begin(115200);

  Serial.println(array2D [0] [1];
  Serial.println(array2D [1] [0];
  
}

void loop() {
  // put your main code here, to run repeatedly:

}

El resultado de eso en el COM fue:

def jkl

Es exactamente lo mismo que yo te sugiero, solo que en el caso de tu profesor usa los datos en la FLASH pero para que si son solo 45.

perfecto surbite, ya vi y probe que funciona, la pregunta es:

¿Como hago cuando tengo mas de 10 teclas?

el char de aca me permite un caracter:

char keys[ROWS][COLS] = {
  { '0','1','2' },
  { '3','4','5' },
  { '6','7','8' },
  { '9','10','11' }

el 10 y el 11 saldran error

el for asigna un valor a la posicion del vector, osea tengo del 0 al 9 (son 10 posiciones) y después?

Respuesta simple: necesitas un teclado de mas filas y mas columnas.

Tu teclado debe albergar la cantidad de teclas que deseas representar directamente. Tu mismo lo has puesto asi. Quieres 45 cosas, entonces 45 teclas.

Usa la combinación que gustes, 9x5 por ejemplo. Arma un teclado con pulsadores y los dispones de froma matricial

me referia al codigo :

char keys[ROWS][COLS] = {
  { '0','1','2' },
  { '3','4','5' },
  { '6','7','8' },
  { '9','10','11' }

no puedo poner dos cifras en la matriz viejo, no funciona { ‘9’,‘10’,‘11’ } si pongo eso los botones correspondientes al 10 y 11 funcionan como el botón 0 y el botón 1 (y todo lo que ponga con dos cifras hace lo mismo, ósea solo lee la unidad del numero)

ese es el problema desde el inicio del post, en la matriz del código no se puede poner nada mayor a un carácter… osea esto ==> { ‘9’, ‘10’ , ‘11’ }

No se puede poner esto '10' ni nada en adelante. Eso no es un char sino 2 char y debería ponerse asi "10"

Ahora bien, todo eso plantea una reformulación del código y no se puede usar Keypad.h como esta planteado o tal vez si, porque yo probé de otro modo y al menos compiló.

Mas facil sería armar el scaneo filas, columnas con un código propio y entonces ahi si podes indicarle que corresponde a cada cruce X Y.

Acá tenes algo tomado de una matriz 6x6 o sea 36 botones identificados de este modo

filas de la 2 a la 7 en el UNO columnas d ela 8 a la 13 pero no hay limite con un MEGA por ejemplo.

En tu caso como te dije, 5x9 te da 45 teclas.

include 

#define BUTTON_COUNT 36
#define KEYPAD_OUTPUT_BEGIN 2
#define KEYPAD_OUTPUT_END 7
#define KEYPAD_INPUT_BEGIN 8
#define KEYPAD_INPUT_END 13


uint8_t keypad_button_pressed[BUTTON_COUNT];
volatile uint32_t ticks;
uint32_t lastTrigger;


ISR(TIMER0_COMPA_vect, ISR_BLOCK) {
    ticks++;
}

void init_systicks() {

    TCCR0B = _BV(CS02) | _BV(CS00);
    TCCR0A = _BV(WGM01);
    TIMSK0 = _BV(OCIE0A);

    // 8000000/1024/78 == 100HZ -> 10 ms
    OCR0A = 77; // !!! must me set last or it will not work!
}

uint32_t math_calc_diff(uint32_t value1, uint32_t value2) {
    if (value1 == value2) {
        return 0;
    }
    if (value1 > value2) {
        return (value1 - value2);
    }
    else {
        // check for overflow
        return (0xffffffff - value2 + value1);
    }
}

void keypad_reset_output() {
    // configure pull ups
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(5, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(7, HIGH);
}

void clear_buttons() {
    for(int i=0; i < BUTTON_COUNT; i++) {
        keypad_button_pressed[i] = 0;
    }
}

void keypad_setup() {
    // initialize the digital pin as an output:
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);

    keypad_reset_output();

    pinMode(8, INPUT);
    pinMode(9, INPUT);
    pinMode(10, INPUT);
    pinMode(11, INPUT);
    pinMode(12, INPUT);
    pinMode(13, INPUT);

    // configure pull ups
    digitalWrite(8, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(10, HIGH);
    digitalWrite(11, HIGH);
    digitalWrite(12, HIGH);
    digitalWrite(13, HIGH);
}



// the loop() method runs over and over again,
// as long as the Arduino has power

void keypad_read_buttons() {
    clear_buttons();
    uint8_t y=0;
    for(int i=KEYPAD_OUTPUT_BEGIN; i <= KEYPAD_OUTPUT_END; i++) {
        keypad_reset_output();
        digitalWrite(i, LOW);
        uint8_t x=0;
        for(int j=KEYPAD_INPUT_BEGIN; j <= KEYPAD_INPUT_END; j++) {
            if (digitalRead(j) == LOW) {
                uint8_t index = x+6*y;
                keypad_button_pressed[index] = 1;
            }
            x++;
        }
        y++;
    }
}

uint8_t keypad_button_is_pressed() {
    for (int i=0; i < BUTTON_COUNT; i++) {
        if (keypad_button_pressed[i]) {
            return 1;
        }
    }
    return 0; // no button pressed
}

// The setup() method runs once, when the sketch starts
void setup() {
    init_systicks();
    keypad_setup();

    Serial.begin(9600);
}

void loop() {

    keypad_read_buttons();

    // allow button processing only every 300ms (30 systicks)
    if (keypad_button_is_pressed() && (math_calc_diff(ticks, lastTrigger) > 30)) {
        lastTrigger = ticks;

        for(int i=0; i < BUTTON_COUNT; i++) {
            if (keypad_button_pressed[i]) {
                Serial.print(i);
                Serial.print(' ');
            }
        }
        Serial.println('-');
    }

    delay(1);
}

Este enfoque solo muestra que detectas XY teclas mas alla de lo que permite KEYPAD.h pero luego la idea de que cada tecla se corresponde con el vector es muy fácil.

MAESTRO Surbyte!!!! eso era...

Esto va a un Arduino MEGA, asi que pienso añadir una columna mas para los 42, y si necesito mas agrego mas..

probando antes de contestar encontre esto al añadir una columna:

uint8_t index = x+6*y; <== en esta linea tengo que cambiar el numero si vario las columnas yo puse 7 en mi caso.

Surbyte muchas gracias, por ahora, disculpas por no expresar de manera correcta mi problema en primera instancia, que nos habría salvado tantos intercambios de mensajes y tiempo.

Saludos

disculpas por no expresar de manera correcta mi problema en primera instancia, que nos habría salvado tantos intercambios de mensajes y tiempo.

Exactamente, luego de tanto tiempo en este foro me llama la atención porque a la gente le cuesta tanto ir de lleno al punto explicando que quieren hacer y como. Sin rodeos, porque supongo yo que algunos creen que lo que estan haciendo es TOP SECRET y también comprendo que otros no sepan explicarlo, de todos modos ya ves, cuando se comprende aparece la solución.

La librería esta pensada para algo mas chico y limitado. De todos modos yo hice una prueba y toleraba otro modo de ingreso que ahora no viene al caso... daba para jugar un poco o modificarla. Lo que te he sugerido sirve a tu necesidad asi que.

uint8_t index = x+6*y;

si claro esto te permite usar el ínidice para poder transformar la tecla en lo que quieres mostrar o sea ir al vector de String o el que te sugirió el profesor y presentar "HXX", donde XX es el índice