2

I have two arduinos (uno) and I would like to send the results of a key press on a 5X4 matrix pad to the other arduino. The matrix keypad works great. I can identify which key was pressed with a switch function.

switch (keypad())  
//switch used to specify which button
     {
      case 0:
        Serial.print("Key A Pressed");
        Serial.print(keypad());
        messageToSend = 0;
      break;  
        case 1:
        Serial.print("Key B Pressed");
        Serial.print(keypad());
        messageToSend = 1;
      break;
        case 2:
        Serial.print("Key C Pressed");
        Serial.print(keypad());
        messageToSend = 2;
      break;
       }

My RF units are both nrf24l01. I have tried working with the sample code and I think the issue is I don't understand how the unit works well enough.

  1. What is the nature of the data sent between units? I want to send integers, possibly even text. Is that possible? Do I need to convert to binary or something?

  2. My understanding of "ping" and "pong" is that ping sends a message then pong sends that same message back to ping... is this correct?

  3. Are RF units very different? Is this one particularly difficult?

  4. If I just want to send with one receive with the other shouldn't this simplify the code?

  5. What are pipes? How many can I open?

  6. If I have 3 or more of these what changes will I need to make to the code?

Thanks!

  • 1
    There are a lot of questions here. I suggest doing the best research you can on your own, and then bringing what your stuck with here as individual questions where you can get smaller, quicker answers. – BrettAM Aug 13 '15 at 0:28
  • I think the issue is ... - it would help to define what this "issue" is that you are having. You have posted a snippet of code. You haven't said what you expect it to do, nor what it actually does. I suggest you post the code that you are actually using, in its entirety (both sender and receiver if necessary). Then state what happens when you do something (eg. pressing a switch) compared to what you expect to happen. Include any debugging printout that you may have added to your code to help you debug it. – Nick Gammon Aug 13 '15 at 5:27
3

Many questions so broad answers, but hopefully informative for your research

  1. What is the nature of the data sent between units? I want to send integers, possibly even text. Is that possible? Do I need to convert to binary or something?

It depends broadly on what you use. If you use an ethernet peripheral then the communications will be entire ethernet packets with whatever protocol stack you have above it in payload. For simple RF communication modules it may be as simple as a serial stream delivered 8 bits at a time. The simplest rf (buzzer-style) would simply interrupt (or drive a pin high) when the transmitter is sending a signal.

In Your case the transmitter uses an addressed protocol with a payload packet of between 1 and 25 Bytes of data. This means that you will need code to read and store the necessary payload, maintain configuration data and keep track of addresses of the other systems to message. You also need to poll (or handle interrupts from) the rf module to make sure there aren't messages from the transmit node.

How you convert the data is up to you, a string can be represented by a sequence of bytes and can be send and read as a string on the receivers end. Your rf module will deliver you data in 1-25 byte chunks, what you send in that chunk and how to encode it is entirely up to you.

On the low level,the way this module is configured, the MCU sends data into the rf ic using a serial protocol, the module incorporates a buffer to allow the MCU (slow - 8 bit) to send the data and not have to keep up with the 1Mbps throughput of the rf. On a physical level the signals of the chip look thus:

enter image description here

  1. My understanding of "ping" and "pong" is that ping sends a message then pong sends that same message back to ping... is this correct?

Ping Pong is a game and not a well defined technical term. For precision you can define ping-pong as an echo where the transmitter effectively acknowledges the message by re-transmitting it back to you.

  1. Are RF units very different? Is this one particularly difficult?

RF units can be very different depending on what high level protocol they offer. This unit is somewhere half way between full blown wifi and simple and modulated RF communications. It gives you addressing and error correction as well as a robust communication scheme

This particular unit is made to be relatively "modern", it uses GFSK - a frequency modulation scheme -to transmit and receive data to uniquely addressable nodes on a number of channels. At 2.4 GHz it is high throughput, legal. It is not the simplest toy.

In terms of simplicity, this module has a lot of examples and documentation, given that it has an arduino library it has a high likelihood of working and succeeding, but you will need to use more advanced microcontroller features to fully utilize the device (e.g. interrupts, DMA).

For other RF options there are lots of things to consider. Going up to wifi requires you to maintain a much more complex stack, meaning more processing power and code, if you want to offer TCP/IP services (say webserver) it is even more code but can be done on an 8 bit arduino. Going down to simpler protocol may win you less power and simpler code but a headache to expand.

  1. If I just want to send with one receive with the other shouldn't this simplify the code?

You will still need to implement both a receiving and a transmitting application so the work is still all there, it will simplify the higher level logic into separate application which is easier.

  1. What are pipes? How many can I open?

I see nothing about pipes from a cursory glance at the docs, perhaps you can illuminate more on what you are confused about?

In general pipes are a "hole" where an application (in the broadest sense) can stream data and it will be consumed by whoever is on the other end, a black hole of a serial data stream. You can implement a pipe as a high level software construct that will buffer and consume data from peripherals and wait to send it out the RF transmitter, it may also be implemented on a hardware level with discrete buffers and additional logic around the rf transmitter etc. As a conceptual element you can probably use a "pipe" concept for communication between the different devices in your code (e.g. move byte to pipe 1 for device 1, move byte to pipe 2 for device 2, let the "driver" handle order), this is a design paradigm that makes software development easier.

  1. If I have 3 or more of these what changes will I need to make to the code?

The rf module is fully capable of addressing up to 65,536 unique hosts, so the device is fully ready to talk to 3 of your hosts, however the software logic needs to track the addresses and other comms data about each host as well as process the data for them (if its different) in enough time.

If you are expecting this in advance, good design decisions early on (e.g. small API or library) will make this much easier on yourself to add features in the future.

Final Thought

If you need a simple echo, this may be a bit overkill for your system, however it is relatively powerful and may make it easier for you to program since you can work with "real-world" data units and send multiple byte packets easily.

I would highly recommend you read and understand the datasheet for the RF chip, be thankful that the nice library takes care of the messy details for you, but understanding how it works will certainly help you understand how to use it best.

An 8 bit Atmega may not be powerful enough to process and transmit 3 separate streams together (if they are identical its less difficult) if you require a constant high rate transmission or if you do a significant amount of processing on the arduino before sending you will feel the limitations of the chip and a 32 bit board may be worth looking at.

  • The 8 bit Atmega was capable of running Toorum's Quest - a sideways scrolling arcade-style game with multiple sprites, sound effects, and reading a game controller, so I think it can transmit 3 streams of data from one to another (not at the absolute same moment, but in quick succession). – Nick Gammon Aug 13 '15 at 6:08
  • It entirely depends on the nature of the stream and the demands of its processing. 2 simultaneous 1 mbit streams would be hard to do in real time the total data volume is too large (supported by the IC with a single antenna). Additionally with larger payloads the 8 bit limitations really multiplies binary size of the application for data heavy tasks. For the simple use case of occasional asynchronous data I would wager its sufficient,however using this module to its full capacity would be beyond the uno's capability. – crasic Aug 13 '15 at 6:16
  • I totally agree. However the question was I have two arduinos (uno) and I would like to send the results of a key press on a 5X4 matrix pad to the other arduino. - so I believe it would be within the capabilities of a Uno to send a single keypress from a 5x4 keypad to another Uno. Another two Unos, even. – Nick Gammon Aug 13 '15 at 6:23
  • Completely agree, I addressed the numbered questions directly and broadened the scope so I missed that detail. You don't need much to send a few keypresses. – crasic Aug 13 '15 at 6:27
1

My RF units are both nrf24l01. I have tried working with the sample code and I think the issue is I don't understand how the unit works well enough.

Start here, this is the absolutely best resource I could find. I use MIRF libary and there are send and receive examples. They are really, really simple. Get them working first.

What is the nature of the data sent between units? I want to send integers, possibly even text. Is that possible? Do I need to convert to binary or something?

Technically, you send between 1 and 32 bytes of information. However, the libraries (see examples above) will take care of the technicality and allow you to send nums, chars or strings.

My understanding of "ping" and "pong" is that ping sends a message then pong sends that same message back to ping... is this correct?

Not necessarily. Since does all the signal checking for you, and you know that your TX device is the only one sending, you can just reply with "data received".

Anyways, why are even concerned with this? Pinging and ponging have nothing to do with your task at hand.

Are RF units very different? Is this one particularly difficult?

Yes, they are different in frequencies, protocols, power etc. No, this one isn't. It's an amazing, cheap and robust piece of Norwegian ingenuity.

If I just want to send with one receive with the other shouldn't this simplify the code?

Simplify compared to what exactly? It will simplify the code compared to a two-way communication, obviously.

What are pipes? How many can I open? As someone said before me, read the bloody manual, or a tutorial, or the data sheet, or something. The answer is 6.

Any unit can send on ONE pipe and receive on SIX pipes. Imagine having 6 phones on your table. You can simultaneously listen to all 6 phones but you can only TALK INTO ONE. You can choose which one to talk into to, at any point. Unless you have a lot of devices talking to each other (more than TWO), don't bother, forget the pipes.

If I have 3 or more of these what changes will I need to make to the code?

Get two Arduinos talking to each other first. No one has succeeded at making anything work by getting ahead of themselves.

Now here is a video of two Arduinos talking. There's only one button but you can easily change it to a 20-button setup.

The code for sending:

#include <SPI.h>
#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>
#include <nRF24L01.h>

const int buttonPin = 2;   
const int ledPin =  3;

// sends a string via the nRF24L01
void transmit(const char *string)
{
  byte c; 

  for( int i=0 ; string[i]!=0x00 ; i++ )
  { 
    c = string[i];
    Mirf.send(&c);
    while( Mirf.isSending() ) ;
  }
}

void setup() {
  //RADIO
  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.payload = 1;
  Mirf.channel = 90;
  Mirf.config();
  Mirf.configRegister(RF_SETUP,0x06);
  Mirf.setTADDR((byte *)"serv1");

  //BUTTON AND LED
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  Serial.println("Sending ... ");   
}

void loop() {
  int buttonState = digitalRead(buttonPin);
   if (buttonState == LOW) { //pressed
    digitalWrite(ledPin, HIGH);
    transmit("X");
  }
  else {
    digitalWrite(ledPin, LOW);
  }
}

The code for receiving:

#include <SPI.h>
#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>
#include <nRF24L01.h>

unsigned long lasttime;
unsigned long delaytime;
unsigned long time;
const int ledPin = 3;

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

  //RADIO  
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1"); 
  Mirf.payload = 1;
  Mirf.channel = 90;
  Mirf.config();
  Mirf.configRegister(RF_SETUP,0x06);

  //LED 
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);   
  Serial.println("Listening ... ");
}

void loop() {
  byte c;

  if( Mirf.dataReady() ) {
    Mirf.getData(&c);
    Serial.write(c);

    if (c == 'X') {
      digitalWrite(ledPin, HIGH);    
    }
  } else {
      digitalWrite(ledPin, LOW);
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.