Keypad - Unique Pressed

Hi all,
I'm using this code for send out a data using key pad, when i press one the first should send one and then when i press one again i received back 0. But what I see that each time that press a button on keypad I not have only one pressed but alternatly one a zero ...like a train of pulse ... is there something for adjust this ?

below reported the code for the trasmitter and the receiver:

#include <VirtualWire.h> // include la libreria per la comunicazione
#include <Keypad.h>

// definizione del Keypad
byte buttonState = LOW;
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] = {8, 7, 6, 5}; //Righe collegate ai PIN 8,7,6,5
byte colPins[COLS] = {4, 3, 2}; //Colonne collegate ai PIN 4,3,2
// byte buttonState = LOW;

// Inizializzazione del Keypad
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup() 
{

Serial.begin(9600);  

vw_setup(1200); // setta la velocità di trasmissione a 1200 Bits per sec
vw_rx_start();       // Start the receiver PLL running


}

void loop()  // loop del micro controllore
{
     // Leggo il Keypad
   char customKey = customKeypad.getKey();
   delay(10);
   if (customKey != NO_KEY)
     { 
      char msg[1];  
      msg[0] = customKey;
      digitalWrite(13, true); // Flash a light to show transmitting
      vw_send((uint8_t *)msg, strlen(msg));  // invia la lettera a
      digitalWrite(13, false); // spegni il led quando ha finito di trasmettere    
      }
    else
      {
      uint8_t buf[VW_MAX_MESSAGE_LEN];
      uint8_t buflen = VW_MAX_MESSAGE_LEN;
      if (vw_get_message(buf, &buflen)) // Non-blocking
         {
          int i;
          
          for (i = 0; i < buflen; i++)
             {
              
                if (buf[i] == '1')    // controllo se il carattere è uguale ad "a"
                      {
                      buttonState = !buttonState;  // se si inverti il valore se è ACCESO spegni il led se è SPENTO accendilo
                 
                 
                      if (buttonState == 0)
                           {
                              
                             Serial.println("Led 1 Spento");
                   
                            }
                     else
                        {
                         
                          if (buttonState == 1)
                                {
                                       
                                      
                                   Serial.println("Led 1 Acceso");
                   
                                   }
                        
                      }
                 
 }
                 }
         
          }
        }
   
}

receiver

  #include <VirtualWire.h>  // includi la libreria per la comunicazione

const int ledPin4 =  4; 
const int ledPin =  13;   // definisci come led il builtin sul piedino 13
byte buttonState = LOW;  // definisci il lo stato del pulsante se premuto o meno
// const int ledPin8 = 8;  // Piedino8 collegato al relè

void setup()
{
  Serial.begin(9600);     // setto la velocità della seriale usb che mi serve per vedere sul mio monitor cosa fa il micro
  Serial.println(" Ricevo i Dati dal Master "); 
   // vw_set_ptt_inverted(true); // Required for DR3100 
   vw_setup(1200);         // setto la velocità di ricezione a 1200 Bits per sec
         // Start the receiver PLL running
  
   vw_rx_start(); 
   
   pinMode(ledPin, OUTPUT);
   pinMode(ledPin4, OUTPUT);
}
void loop()
{
  
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
    if (vw_get_message(buf, &buflen)) // Non-blocking
        {
          int i;
          
      for (i = 0; i < buflen; i++)
           {
              
        if (buf[i] == '1')    // controllo se il carattere è uguale ad "a"
            {
                 buttonState = !buttonState;  // se si inverti il valore se è ACCESO spegni il led se è SPENTO accendilo
                 digitalWrite(ledPin, buttonState); // passo lo stato del led che si accederà e spegnera in base al valore della variabile
                 digitalWrite(ledPin4, buttonState);
                 Serial.println(buttonState);
                    if (buttonState == 0)
                        {
                               char msg[1];
                               msg[0] = buttonState;
                               uint8_t buf[VW_MAX_MESSAGE_LEN];
                               uint8_t buflen = VW_MAX_MESSAGE_LEN;
                               // digitalWrite(13, true); // Flash a light to show transmitting
                               vw_send((uint8_t *)msg, strlen(msg));
                               vw_wait_tx(); // Wait until the whole message is gone
                               Serial.println("Inviato Stato Spento");
                   
                        }
                     else
                        {
                         
                          if (buttonState == 1)
                                    {
                                       
                                      char msg[1];
                                       msg[0] = buttonState;
                                      // const char *msg = "acceso";
                                       uint8_t buf[VW_MAX_MESSAGE_LEN];
                                       uint8_t buflen = VW_MAX_MESSAGE_LEN;
                                     //  digitalWrite(13, true); // Flash a light to show transmitting
                                       vw_send((uint8_t *)msg, strlen(msg));
                                       vw_wait_tx(); // Wait until the whole message is gone
                                       Serial.println("Inviato Stato Acceso");
                   
                                      }

                        
                        
                      }
                 

                 }
         
          }
        }
      //  delay(0.96);
}

Thanks Andrea

                                   }
                        
                      }
                 
 }
                 }
         
          }
        }
   
}

What a beautiful pattern of close braces. Sure makes it easy to see which one matches which open brace. Not!

                               char msg[1];
                               msg[0] = buttonState;
                               uint8_t buf[VW_MAX_MESSAGE_LEN];
                               uint8_t buflen = VW_MAX_MESSAGE_LEN;
                               // digitalWrite(13, true); // Flash a light to show transmitting
                               vw_send((uint8_t *)msg, strlen(msg));
                               vw_wait_tx(); // Wait until the whole message is gone
                               Serial.println("Inviato Stato Spento");

What are buf and buflen declared here for?

What are your Serial.print() statements telling you?

There are events generated in the keypad class when a key is pressed, when a key is released, etc. Perhaps you need to actually look at those events.

have you reason ...

so due the fact i want do this:

press keypad for example the number one :

when press the number one send out 1 using virtual wire, to the client. When the client has received 1, if 1 is for the client at the first press turn on a led, at the second time that the client received 1 turn off a led. Plus this the client when has turn on or turn off a led, should be send back the button status. The Master should received this status has should print on serial "Ok Im on" if the button status is one, "Ok Im off" if the status is 0. What I received back when I press one time the button 1 on the keypad are a multiple status and not only status ... So, my expectation is received back at the first press "Ok Im on" and the second time "Ok Im off" and then when i press the button "Ok Im On" etc etc ... this is the nature of my question, what I've think is that due the fact the keypad is a button and then should be something that send out only one pulse and not a train of pulse ... in this way I can know the status led ... maybe there is another way how to manage that but I didn't know this ...

I've traslated for you the serial results below reported:

![](http://arduino.cc/Users/gnusso/Desktop/Schermata 2012-04-07 a 12.39.13.png)

I don't know if the image will be avaiable then I will report the results below also:
Led 1 on
Led 1 off
Led 1 on
Led 1 off
Led 1 on
Led 1 off
Led 1 on
Led 1 off
Led 1 on
Led 1 off
Led 1 on
Led 1 off
Led 1 on
Led 1 off
Led 1 on

So, I hope to clarify my issues ...

I've seen that here talk about the events that you have talk

http://www.arduino.cc/playground/Code/Keypad

so for example my scope is have only one value when the button is pressed could I use that ? KeyState getState()
if yes how I can use this ?

Thanks for the help,
Andrea

Ciao, I've tried to do some test using the code like your suggestion but I receive the same result ... not only one result but a lot of result ...below reported the code ...

void loop()  // loop del micro controllore
{
     // Leggo il Keypad
   char customKey = customKeypad.getKey();
  
//if(sw.uniquePress())
 //{ 
 
if (customKeypad.getState() == PRESSED)
{
//if (customKey != NO_KEY)
   // { 
      char msg[1];  
      msg[0] = customKey;
      digitalWrite(13, true); // Flash a light to show transmitting
      vw_send((uint8_t *)msg, strlen(msg));  // invia la lettera a
      digitalWrite(13, false); // spegni il led quando ha finito di trasmettere    
  //   }
 }    
//}    
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_wait_rx_max(200))  
  {
  if (vw_get_message(buf, &buflen)) // Non-blocking
     {
      int i;
      for (i = 0; i < buflen; i++)
         {
          if (buf[i] == '1')    // controllo se il carattere è uguale ad "a"
            {
             buttonState = !buttonState;  // se si inverti il valore se è ACCESO spegni il led se è SPENTO accendilo
             if (buttonState == 0)
               {   
                Serial.println("Led 1 Spento");
               }
             if (buttonState == 1)
               {
                 Serial.println("Led 1 Acceso");
               }
             }
        } // end for
     
      
      }  // end if get message
} // end wait rx      
}  // end loop

could you help me ? have nice day, Andrea

There is an EventKeypad example that does what you want...

But what I see that each time that press a button on keypad I not have only one pressed but alternatly one a zero ...like a train of pulse

I assume that you want to have single values passed when you click the button on the keypad once, that calls for adjusting for button debounce handling.

Yes it's correct, the strange thinks is that if I do a simple example with key print what you press, the system recognize only one pressed ... I think that there is something to adjust syncronization between trasmission and reception ... correct ?

Thanks
Andrea

    char msg[1];  
    msg[0] = customKey;
    digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));  // invia la lettera a

This is confusing, and wrong.

First you have an array of 1 byte. Why bother?
Second, you are taking its length with strlen. That almost certainly will return an invalid result. strlen works by find a trailing 0x00 byte. But you can't have a trailing 0x00 byte in a 1-byte field. Maybe this:

    vw_send((uint8_t *)msg, sizeof msg);  // invia la lettera a

And please start using the "auto format" facility in the IDE. Braces all over the place are confusing to me, and they must be confusing to you as well.

ok, I've used srtlen because was used inside the example, so I'm not an expert like you for this reason I'm asking help and piece by piece I will learng things and will commit less errors ...

so looking this and the virtualwire library

vw_send((uint8_t *)msg, sizeof msg);  // invia la lettera a

i assume that vwsend call the function that send the message, (uint8_t *) define data type ?, msg is the message and then sizeof(msg) is the message lenght ?

so, right now I'm little bit demotivated becase I banging my head agaist this issues a lot's of time ...

Thanks
Andrea

ok, I've used srtlen because was used inside the example, so I'm not an expert like you

Yes, well they used a null-delimited string.

    const char *msg = "hello";
...
    vw_send((uint8_t *)msg, strlen(msg));

so, right now I'm little bit demotivated becase I banging my head agaist this issues a lot's of time ...

It's like trying to fly an aircraft without having any idea of what the controls do. It would be demotivating.

I suggest you work your way through some C tutorials. Learn the difference between arrays and "null terminated" strings. Then things will work and you will be more motivated.

(uint8_t *) define data type ?

vw_send expects a pointer to uint8_t (byte) type, so in the example they "cast" from a char to a byte.