Author Topic: Help using Keypad with Moteino  (Read 5234 times)

aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Help using Keypad with Moteino
« on: February 08, 2018, 08:06:17 AM »
Hi Guys,
I am using the standard Moteino to read a custom 17key keypad I made and then transmit the Key pressed to a receiver.  Once the receiver receives the code it will drive a relay output.  Sounds simple  :)
I have written the code for the Keypad and it works great, all buttons are Identified when pressed.
I am using the keypad.h library for this.

As a test to make sure it would transmit and be received before I went any further I used this simple code on a 1 second delay.  It worked great and the receiver board received the commands every second.  So I know all my other settings are correct.

Code: [Select]
   if (radio.sendWithRetry(RECEIVER, "H", 1)) //target node Id, message as string or byte array, message length
        {
          Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks
          Serial.println("Marker C Sent Ack"); Serial.println("Command Transmitted");
        }

Here is my Loop function that is not working.  When I press the 'H' button it does not transmit.
Is there some rule to say I can not do this within the Switch Case?
If I remove the sendwithretry and put a simple Serial.println("Marker H Pressed"); then it works every time so the Switch condition is working.

But as soon as I put the sendwithretry back in it will not transmit.  I am sure I am missing something simple here.
Do I need to call a function from the Switch Condition?  I tried that but couldn't get the button pressed to transfer into the function I made correctly.
I also tried a seperate if condition at the end of the Switch Case looking for the Key pressed and then calling the sendwithretry but no luck.
I may not have written this properly as I am still learning.

Can someone please have a look and let me know what I am doing wrong.  I am sure it is something simple I have missed.


Code: [Select]
void loop()  {

  char key = kpd.getKey();
  if (key) // Check for a valid key.
  {
    switch (key)
    {
      case 'H':
        if (radio.sendWithRetry(RECEIVER, "H", 1)) //target node Id, message as string or byte array, message length
        {
          Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks
          Serial.println("Marker C Sent Ack"); Serial.println("Command Transmitted");
        }
        break;

      case 'C':
        if (radio.sendWithRetry(RECEIVER, "C", 1)) //target node Id, message as string or byte array, message length
        {
          Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks
          Serial.println("Marker C Sent Ack"); Serial.println("Command Transmitted");
        }
        break;

      default:
        Serial.println(key); Serial.println("   Transmitted");
    }

  }
 }
UPTDATED: TomWS: enclosed in code blocks
« Last Edit: February 08, 2018, 09:09:17 AM by TomWS »

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Help using Keypad with Moteino
« Reply #1 on: February 08, 2018, 09:15:01 AM »
First, I modified your post so that the code portion is in code blocks (use the button with the '#') so they're easier to read.

Secondly, the only thing I don't see is a delay between calls to sendWithRetry().  If the key is pressed for any length of time, does the getkey() method return immediately?  If so, you should add a delay at the bottom of the if (key)... block.

Tom

aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #2 on: February 08, 2018, 04:44:06 PM »
Thank you Tom,
I am new to this so didn't realise you could do that.  It makes it much easier.

Yes as soon as a button is pressed it shows instantly in the Serial monitor screen. 

With the switch Case commands if 'H' is pressed it will display the 'H' button then there is a break command that puts it back into the loop waiting for another button to be pressed.  It doesn't keep displaying 'H' continuously until another is pressed.
Although just to check I might clear the key pressed to make sure.
I will also add a delay at the bottom to give it a chance to transmit the first keypress.

The serial monitor shows everything as if it should work, maybe there is a key bounce that the serial monitor is not picking up causing an instant retransmit.
I know it works otherwise as if I make it really simple and don't put any getkey calls in just a loop with a 1 second delay it transmits without fail.
Code: [Select]
 if (radio.sendWithRetry(RECEIVER, "H", 1)) //target node Id, message as string or byte array, message length
        {
          Blink(LED, 40, 3); //blink LED 3 times, 40ms between blinks
          Serial.println("Marker C Sent Ack"); Serial.println("Command Transmitted");
delay(1000);
        }


Is there anything else I may have done wrong?

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Help using Keypad with Moteino
« Reply #3 on: February 08, 2018, 05:30:36 PM »
I think you need to begin at the beginning by:
1. Posting your sketch for both the transmitter and for the receiving nodes. (Use 'attachments')
2. You need to be more precise in your language.  When you say "Yes as soon as a button is pressed it shows instantly in the Serial monitor screen." (emphasis mine) According to the code you posted, the 'H' should never appear in the transmitter's Serial monitor so 'it' may mean something other than the 'H' returned by the getkey() method or 'Serial monitor screen' refers to a serial monitor attached to the receiver. 

Make it easy for people to help you by being crisp and clear on everything you're referencing.

Tom


aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #4 on: February 09, 2018, 05:17:42 AM »
Thanks Tom,
Really appreciate your replies.

Your are correct my Serialprint line was not printing 'H' but a 'C'  This wasn't the case in the code.  It was a typo when I cut and pasted it into this forum.
These things happen when you are half asleep scratching your head about what you have done wrong at 1.30am in the morning.  :)

I have attached the transmit and receive codes.
The Receive code is basically Felix's TxRxBlinky.ino file.  The only thing I have done to the receiver code is to Change it to look for 1 byte transmitted as a 'H'.
Please let me know what you think.

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Help using Keypad with Moteino
« Reply #5 on: February 09, 2018, 08:41:40 AM »
...
These things happen when you are half asleep scratching your head about what you have done wrong at 1.30am in the morning.  :)
....
I know of many bugs that were found and fixed at 1:30AM (and beyond).  However, I know exponentially more that were created at that time of day!

I'll try to take a look later today.
Tom

aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #6 on: February 09, 2018, 05:35:26 PM »
Yes I have as well many times.   :) This time it didn't help.

Thanks for having a look for me.  It really has me stumped and I am sure it is something very easy. 

I am looking forward to see what you find.  I am also working on it as well but have the feeling you will work it out first  ;) 8)

TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Help using Keypad with Moteino
« Reply #7 on: February 09, 2018, 05:44:12 PM »
Ignoring your redundant and duplicate (but harmless) .ino.ino naming convention, I suspect that your problem is related to this:
Code: [Select]
byte rowPins[ROWS] = {11, 10, 9, 8, 7, 6, 5};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = {2, 3, 4};

Note that the Moteino radio uses pins: 2, 10, 11, 12, & 13.
Note that the Moteino flash memory uses pins: 8, 11, 12, 13
Note that the Moteino LED uses pin 9.

You can send H's all day long as long as you don't press a key...

Tom


aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #8 on: February 09, 2018, 07:26:12 PM »
 8)
Thanks Tom I was wondering along those lines but hadn't invested that far yet.  I wasn't confident enough in my programming skills to be sure it was hardware or my programming that was the problem.  Was ruling out the programming first.   :)

That will explain it then  ;D

I need 10 pins to make the keypad work... so the standard Moteino is not going to have enough pins is it.
 
I did buy a Moteino Mega for the remote originally but wired up the standard one and started using it to test code while waiting for it to arrive.

I will get the Mega out and wire it up.

Is there any pins to look out for on the Mega that I shouldn't use?


TomWS

  • Hero Member
  • *****
  • Posts: 1930
Re: Help using Keypad with Moteino
« Reply #9 on: February 09, 2018, 08:41:22 PM »
...
I need 10 pins to make the keypad work... so the standard Moteino is not going to have enough pins is it.
...
I counted 7 pins: 4 rows, 3 cols needed for the keypad.  Looking at Moteino, I see, as spare, digital pins: 3,4,5,6,7,14,15,16,17, 18, & 19.  By my count, that's 10, leaving you 3 pins as 'extras'.
And, if you don't have a flash memory chip installed, pin 8 is also available.

So, what's the problem?
Tom

aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #10 on: February 09, 2018, 11:28:37 PM »
Thanks Tom,
I have 7 Rows and 3 Columns so need 10 pins the way I have wired it.

I had a good look at the pinouts after my last post and you are correct, there are enough spare pins to do what I want.

I don't have a Flash memory but To play it safe I thought I will use D3 - D7, D14 - D18.

Just out of interested you mentioned the Flash was only used on pin 8?  The pinouts from the website say D8, D11-D13 for the flash? 
It doesn't matter for this project but just interested which pins it actually uses for future reference.


aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #11 on: February 10, 2018, 04:03:02 AM »
Thanks again for your help Tom.
I have changed the Pins around and it works perfect.

I Appreciate you giving me your time to help. 
Have a great weekend.

Uncle Buzz

  • Full Member
  • ***
  • Posts: 146
  • Country: fr
Re: Help using Keypad with Moteino
« Reply #12 on: February 10, 2018, 04:28:49 AM »
Just out of interested you mentioned the Flash was only used on pin 8?  The pinouts from the website say D8, D11-D13 for the flash? 

D11-D13 pins are used for SPI communication, D8 is the dedicated Chip Select for the flash IC on moteino. Removing flash IC will free D8, but if you use radio module, you still need SPI communication, D11-D13 are still in use.

aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #13 on: February 10, 2018, 08:22:20 AM »
Thanks Uncle Buzz,
I avoided those pins.

aburfitt

  • NewMember
  • *
  • Posts: 24
  • Country: au
Re: Help using Keypad with Moteino
« Reply #14 on: February 10, 2018, 08:40:41 AM »
Hi Everyone,
I have a problem now with the receiver.  Not sure if I need a new thread or I can use this one. 

There are 17 receivers boards that drive there own single outputs in total for my project, one for each button on the remote.
I have written the code so that after the 'if (radio.receiveDone())' statement I then do a check to see if this receiver board has an active output already and if it does turn it off.
So what I am trying to do is...  Only one receiver can be active at a time so when any button is pressed the remote the active one will turn off and the receiver specific to the button pressed will turn on.  Make sense?

I have the receiver code working some of the time.  Most of the time it thinks the board is active when it is not.  I have played around with different code options and are not getting very far.

There must be a better way to do this.  Has anyone got any ideas?  I have attached the transmit and receiver files.
Is there a better way to do this?

Code: [Select]
#include <RFM69.h>
#include <SPI.h>
#include <LowPower.h>

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     100  //the same on all nodes that talk to each other
#define RECEIVER      1    //unique ID of the gateway/receiver
#define SENDER        2
#define NODEID        RECEIVER  //change to "SENDER" if this is the sender node (the one with the button)

#define FREQUENCY     RF69_915MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Remove/comment if you have RFM69W!
//*********************************************************************************************
#define SERIAL_BAUD   115200
#define LED           9 // Moteinos have LEDs on D9
#define BUTTON_INT    1 //user button on interrupt 1 (D3)
#define BUTTON_PIN    3 //user button on interrupt 1 (D3)


RFM69 radio;

int Announce = 8;           //Pin used for Relay Output

void setup() {
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  Serial.flush();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(LED, OUTPUT);

  // initialize digital pin 4 as an Output to drive the relay to control Turn the Flood Lights on/off
  pinMode(8, OUTPUT);
  digitalWrite(Announce, LOW);
}

byte LEDSTATE = LOW; //LOW=0
byte Delay = LOW;

void loop() {

  //Receive Signal
  //check if something was received (could be an interrupt from the radio)


  if (radio.receiveDone())    //if radio has received a signal check what it is
  {
    delay(200);
    //print message received to serial
    Serial.print('['); Serial.print(radio.SENDERID); Serial.print("] ");
    Serial.print((char*)radio.DATA);
    Serial.print("   [RX_RSSI:"); Serial.print(radio.RSSI); Serial.print("]");
    Serial.println();

    if (radio.DATALEN == 1 && radio.DATA[0] =='Q' && LEDSTATE == HIGH);   // If any button is pressed on the remote and this marker is already calling than stop it calling and turn outputsoff
    {
      Serial.println("Receiver Output is Activated so Turning off Outputs");
      LEDSTATE = LOW;
      digitalWrite(LED, LEDSTATE);
      Serial.print("LED State =    ");Serial.print(LEDSTATE);
      Serial.println();
      digitalWrite(Announce, LEDSTATE);           // Set Output Low
      radio.DATA[0] = 'U';                                 //Set the DATA to a random letter like U to make sure of no false triggers
      Delay = LOW;
    }
  }
  //Exit out of if routine
  else
  {

  }

  //This section to looks for the Marker Letter for this Marker.
  //check if received message is 2 bytes long, and check if the message is specifically "H"

  if (radio.DATALEN == 1 && radio.DATA[0] == 'S' && LEDSTATE == LOW)
  {
    Serial.println("Receiver output is not Activated yet so turning on Outputs");
    LEDSTATE = HIGH;
    Delay = HIGH;                                                 //Activate Delay sequence until a button is pressed
    digitalWrite(Announce, HIGH);
    digitalWrite(LED, LEDSTATE);
    Serial.print("LEDSTATE Value:"); Serial.print(LEDSTATE);
    Serial.println();
    radio.DATALEN = 0;
    radio.DATA == 'Q';
 
  }

  //check if sender wanted an ACK
  if (radio.ACKRequested())
  {
    radio.sendACK();
    Serial.println(" - ACK sent");

  }


  radio.receiveDone(); //put radio in RX mode
  Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU


/*  if (Delay == HIGH)
  {
    Serial.println(" entering Delay of 0.1 seconds");
    digitalWrite(Announce, LOW);
    delay(250);
    digitalWrite(Announce, HIGH);
  }
*/
}