RF24 sending <keypad> button matrix Due Tx --> DigiX Rx

hi - i would really appreciate any help,

have been trying for almost two days to remotely control 16 LEDs on a digiX reciever from 16 buttons on a Due transmitter from a 4x4 matrix (on YL-4) using library over the NRF24 (using RF24 lib).

I started with the 4 direct switches in the code below (added using #) and this worked a dream, with matching array lengths in the payload of the FIFOs, first all LEDs are On, then when there is any activity this triggers the send (radio.write(const void *buf uint8_t length))to the (radio.read(const void *buf uint8_t length) ) the single change in activity resends the whole array so that the appropriate LED toggles (see sketch below).

But - when i tried using the keypad through which the row and column pins are mapped - i have a number of issues. The fact that i can send a stay low (0) (IDLE), low to high (1) (PRESSING), stay high (2) (HOLD) and high to low(3) (RELEASE) command would be very useful for me )(i guess i would need matching switching statements for Tx and Rx)- but right now i’m just trying to put the information into an array for the payload buffer that i can put into the radio.write function above. I cant get it to transmit the right data and the recieve sketch only has zeros in the buffer. Good news is that the LEDs do light up at the start, so something is getting through. I can also get an array containing the 0, 1, 2, 3 (and even get just 0 and 1 for now, while i try to get something working) to print on the serial monitor BUT i cant seem to get the keypad data into the TX_FIFO infact i cant get them into an array of values (when there is no activity) so that when there is activity the appropriate array element changes, to trigger a send and to send in such a way that the correct LED toggles.

I am thinking that i should go back to dealing with the actual pins, with digitalRead and digitalWrite (as this worked with the direct switches sketch below) rather than the mapped values via the keypad and use colPin && colRow for the matrix values so that i can combine the matrix and direct switches

  • i have been trying ALL DAY and most of yesterday with this - so ANY help would be VERY VERY MUCH appreciated - having used the mirf library before i hadnt expected this to be so tricky and i have an imminent deadline.

The attached file is the one with that i cant get to work TX_MAtrix_test2forum and the one below with the switches works fine

/*
 hacked from:
 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
*/

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <Keypad.h>

//KEYPAD MATRIX CONFIGURATION

const byte ROWS = 4; //4 rows
const byte COLS = 4; //4 columns

char keys[ROWS][COLS] =  {
          {'0', '1','2','3'},
          {'4', '5','6','7'},
          {'8', '9','A','B'},
          {'C', 'D','E','F'}
      };

byte rowPins[ROWS] = {50, 48, 46, 44}; //connect to the row pinouts of the keypad R1, R2, R3, R4
byte colPins[COLS] = {30, 28, 26, 24}; //connect to the column pinouts of the keypad

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

boolean blink = false;
boolean ledWrnPin_state;

// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10

RF24 radio(9, 10); //DUE CS0 10 CS1 4 CS2 52 DIGIX  RF24 radio(53,52);

// sets the role of this unit in hardware.  Connect to GND to be the 'led' board receiver
// Leave open to be the 'remote' transmitter
const int role_pin = A4;

// Pins on the remote for buttons uint8_t = UNSIGNED 8-BIT INT
const uint8_t button_pins[] = { 45, 41, 39, 37 }; //42, 43, 44 4pin push 46 = 2pin 
const uint8_t num_button_pins = sizeof(button_pins);

// Pins on the LED board for LED's
const uint8_t led_pins[] = { 94, 95, 96, 97 };
const uint8_t num_led_pins = sizeof(led_pins);

//
// Topology
//

// Single radio pipe address for the 2 nodes to communicate.
const uint64_t pipe = 0xE8E8F0F0E1LL;

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes in this
// system.  Doing so greatly simplifies testing.  The hardware itself specifies
// which node it is.
//
// This is done through the role_pin
// The various roles supported by this sketch
typedef enum {  role_remote = 1, role_led } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Remote", "LED Board"};

// The role of the current running sketch
role_e role;

// Payload

uint8_t button_states[num_button_pins];
uint8_t led_states[num_led_pins];


void setup()
{
  
    pinMode(ledWrnPin, OUTPUT);              // Sets the digital pin as output.
    digitalWrite(ledWrnPin, HIGH);           // Turn the LED on.

    ledWrnPin_state = digitalRead(ledWrnPin);   // Store initial LED state. HIGH when LED is on.
    keypad.addEventListener(keypadEvent); // Add an event listener for this keypad
  //
  // Role
  // set up the role pin
    pinMode(role_pin, INPUT);
    digitalWrite(role_pin,HIGH);
    delay(20); // Just to get a solid reading on the role pin

  // read the address pin, establish our role
  if ( digitalRead(role_pin) )
    role = role_remote;
 else
   role = role_led;

  // Print preamble

  Serial.begin(57600);
  
  p("\n\rRF24/examples/led_remote/\n\r");
  p("ROLE: %s\n\r",role_friendly_name[role]);

  //
  // Setup and configure rf radio
  //

  radio.begin();

  //
  // Open pipes to other nodes for communication
  //

  // This simple sketch opens a single pipes for these two nodes to communicate
  // back and forth.  One listens on it, the other talks to it.

 if ( role == role_remote )
 {
    radio.openWritingPipe(pipe);
 }
 else
 {
   radio.openReadingPipe(1,pipe);
  }

  //
  // Start listening
  //

 if ( role == role_led )
   radio.startListening();
 
  // Dump the configuration of the rf unit for debugging

  radio.printDetails();
 
  // Set up buttons / LED's

  // Set pull-up resistors for all buttons
 if ( role == role_remote )
  {
    int i = num_button_pins;
    while(i--)
    {
      pinMode(button_pins[i],INPUT);
      digitalWrite(button_pins[i],HIGH);
    }
 }

  // Turn LED's ON until we start getting keys
  if ( role == role_led )
  {
   int i = num_led_pins;
   while(i--)
   {
       pinMode(led_pins[i],OUTPUT);
      led_states[i] = HIGH;
      digitalWrite(led_pins[i],led_states[i]);
    }
   }

}

//
// Loop
//

void loop(void)
{
  //
  // Remote role.  If the state of any button has changed, send the whole state of
  // all buttons.
  //
 char key = keypad.getKey();

  

  if (key)
  {    Serial.println(key);   //PRINTS THE KEYPAD KEY CHARACTERS TO THE SERIAL MONITOR (NO ATTEMPT TO SEND OVER RF24
  }
  if (blink) 
  { digitalWrite(ledWrnPin, !digitalRead(ledWrnPin)); // Change the ledWrnPin from Hi2Lo or Lo2Hi.
  }
  
 if ( role == role_remote )
  {
    // Get the current state of buttons, and
    // Test if the current state is different from the last state we sent
    int i = num_button_pins;
    bool different = false;
    while(i--)
    {
      uint8_t state = ! digitalRead(button_pins[i]);
      if ( state != button_states[i] )
      {
        different = true;
        button_states[i] = state;
      }
  }

    // Send the state of the buttons to the LED board
    if ( different )
    {
      p("Now sending...");
      radio.stopListening();
      bool ok = radio.write( button_states, num_button_pins );
      radio.startListening();
      if (ok)
        p("ok\n\r");
      else
        p("failed\n\r");
    }

    // Try again in a short while
    delay(20);
  }

  //
  // LED role.  Receive the state of all buttons, and reflect that in the LEDs
  //

  if ( role == role_led )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      bool done = false;
      while (!done)
   {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( button_states, num_button_pins );

        // Spew it
        p("Got buttons\n\r");

        // For each button, if the button now on, then toggle the LED
        int i = num_led_pins;
        while(i--)
      {
          if ( button_states[i] )
          {
            led_states[i] ^= HIGH;
            digitalWrite(led_pins[i],led_states[i]);
         }
        }
    }
    }
 }

}
// vim:ai:cin:sts=2 sw=2 ft=cpp

//TAKING CARE OF SOME SPECIAL EVENTS
void keypadEvent(KeypadEvent key)
{
  switch (keypad.getState()) 
  {
    case PRESSED:
    if (key == 'A')
    {
     digitalWrite(ledWrnPin, !digitalRead(ledWrnPin));
     ledWrnPin_state = digitalRead(ledWrnPin);    // Remember LED state, lit or unlit.
    }
    break;
    case RELEASED:
           if (key == 'F') 
           {

            digitalWrite(ledWrnPin,ledWrnPin_state);    // Restore LED state from before it started blinking.
            blink = false;
           }
     break;
    case HOLD:
        if (key == 'F') 
        {
            blink = true;    // Blink the LED when holding the * key.
        }
        break;
    }

}

TX_MAtrix_test2forum.ino (10.4 KB)