Mega 2560, enc28j60, rf24 radio - can't work 2 SPI devices at the same time ?

OK. I have the parts mentioned in the subject, but am really struggling to get them to all work together.

After a day of running in circles, I started back at the beginning.

Using IDE 1.5.6r2

Here's my results / progress so far :

After reading about the 3.3V problems on the Mega, I used an LM317T and pot. to create a seperate 3.3V supply. Common ground to the Arduino supply, and capacitors over the ic.

I stripped everything off the board, and connected only the enc28j60 ethernet module ( cheap $1 unit ) as follows :
Gnd > common system ground.
Vcc > 3.3V
CS > pin 53
SCK > pin 52
SI > pin 51
SO pin 50

Added the UIPEthernet library.
On my local PC, using XAMPP, created a php script to receive data from the Mega, and write to a file.
Code in the script sends data to the PC's php page.

This is now all working very reliably.

Next I stripped the board down again, and tried the NRF24L01 module.
Using the same pins as I had for the ethernet module, and no results whatsoever.

Next changed CS pin to pin 7, and added code :

#include <SPI.h>
#include <RF24.h>
#include "printf.h"
#define RF_CE 9
#define RF_CSN 7
RF24 radio(RF_CE, RF_CSN);
void setup() {
Serial.begin(9600);
printf_begin();
radio.begin();
radio.printDetails();
}
void loop() {
}

The printDetails gave a load of values, but all were zero / blank. Nothing like what I had seen on other web searches.

Before trying to rip the Arduino Uno out of another project, I tried 1 last thing : I connected the MISO, SCK, and MOSI to pins 1, 3, and 4 of the Mega's ICSP headers ( next to the reset button ).
All of a sudden, the above sketch ran and the values were populated with an array of data, much like I have seen on other sites.

Now I can't explain why the rf24 library would not see the ethernet module on pins 50 - 53, but does on the ICSP pins. Could it be the library ? or the board definition / layout file used in the IDE ? I don't know, and since it wasted 2 days of tearing my hair out, I was just glad to have found something that works.

But here's the next problem :

I am wanting the Mega to communicate with another Mega using the RF module, and then upload data to the php on the PC over the ethernet. But I can't get them to all work together.

The ethernet works, but as soon as I add code for the RF, it stops working. Code includes :

#include "RF24.h"
#include "printf.h"
#define RF_CE 9
#define RF_CSN 7
RF24 radio(RF_CE, RF_CSN);
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };  // Radio pipe addresses for the 2 nodes to communicate.

// in setup
printf_begin();
radio.begin();
radio.setRetries(15,15);
radio.setPayloadSize(8);
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);
radio.startListening();
radio.printDetails();

Ideally, I would like to use the ethernet to not only push data to the php page, but also to act as a server to serve a http page to the PC, so the PC user can click on links to activate options on the Mega. I know how to do all this, but I can't get the ethernet and RF to work at the same time.

Is this a case of multiple SPI devices, although can exist on the system at the same time, each being controlled / activated with its CS pin, but therefore can not have the ethernet server running at the same time that the RF is listening ?
I have even tried removing the ethernet Server code, and only using the ethernet Client code, and would re-code so that the Client reads a txt file on the PC every few minutes to get commands issued to it. But after removing the Server code, it still does not work.

I have also tried using radio.stoplistening and .startlistening before and after ethernet client code, but has no effect.

Any suggestions or advice ?

The newer ethernet shields do not have anything connected to D11-D13. All SPI lines are on the ICSP connector. I am not sure about the enc28j60. Maybe a link to the hardware would help.

The nrf24 may use a different SPI mode. That causes communication problems, but can be overcome if you can figure out the mode difference between the two devices.

Yeah it's a classic and your hell time is a made by mainly two problems.

One of your library require the spi to roll 2x faster then the other, use another library for your nrf24. Use MIRF instead and all will be fine.

Also it is a know bug that mega256 does not supply the requied power for the nrf24 module on the 3.3v out. You might recieve the data, and be unable to send. So prepare your self to find an external 3.3v supply.

Thanks for the replies.

OK. So if a solution can be found for the mode & speed issue, is it possible for these 2 devices to work at the same time - can ethernet server listen for incoming data / html page requests, at the same time as radio is listening for signal ?

I do already have a separate 3.3V supply, and the ethernet is a module ( not a shield ).

I also wonder if the reason the RF24 would not see the rf module on the pins 50-53, could be that the rf24 library does not turn on the SPI ? whereas the UIPethernet does, so the ethernet module works fine on those pins.
I assume that the ICSP pins are SPI 'active' all the time, and that's why the RF module worked when connected there.

My very limited understanding is making me think that SPI, which has a separate CS pin for each device, would logically need to have only 1 device active at a time. So like --
Device A - CS pin LOW - interact with module A
Device A - CS pin HIGH - stop interaction with module A
Device B - CS pin LOW - interact with module B
Device B - CS pin HIGH - stop interaction with module B

If this is he case, then it is not going to work to have the 2 devices listing at the same time.

Having slept on this, I am starting to see an alternate solution. The last Mega ( currently with ethernet and radio ) is next to my PC. I am using Serial Monitor to debug while I am coding and testing. So why not scrap the ethernet, and write a small VisualBasic application to read the data coming in on the USB port, and add code to the Mega sketch to listen for incoming serial data over the usb.
That way, the radio can listen / talk without interruption, and the sketch can send data to the PC, and also receive commands from the pc.

Well you are working on 8bits controller so no, it's not multitasking, how ever, it is going incredibly fast so it's just alike. What you are doing right now, I have done before with the exact same modules, so keep going you can make it happen.

Change the nrf library to MIRF, and your thing will work.

Ah another important thing, the 2 CS pin have to have 2 different pin port on your Arduino for sure.

http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01

Also, both your device have FIFO buffer, so even if Arduino does not take care of the data at the exact moment it come in, you will still be able to gfetch it when the sketch get to that point

Frédéric_Plante:
Change the nrf library to MIRF, and your thing will work.

Thanks for the advice.

So with your experience, is my thinking here possibly correct :

I also wonder if the reason the RF24 would not see the rf module on the pins 50-53, could be that the rf24 library does not turn on the SPI ? whereas the UIPethernet does, so the ethernet module works fine on those pins.
I assume that the ICSP pins are SPI 'active' all the time, and that's why the RF module worked when connected there.

At the end of the day, I would love to see this working as I originally wanted, but it is a free ( no charge, no profit ) setup I am doing for a kids swim team, so have to consider if it is worth trying to solve the SPI problem, or just hack the USB Serial Monitor.

First option would be first prize, but second option looks more do-able as a way to get the project working and completed.

... so have to consider if it is worth trying to solve the SPI problem, or just hack the USB Serial Monitor.

First option would be first prize, but second option looks more do-able as a way to get the project working and completed.

Well if you settle this at once, you will know how to do it for good, and you will have a sketch base for the next time you must do that kind of project.

If you don't you will have to resort on the serial port every time you will need an output, until you settle it once and for all.

So it's a mater to know if you want to learn, or not, AND, Are you a quitter, or not. :wink:

It's when it's hard that the victory are really worth it.

Finally, i could just grab the DVD containing my backup of 2 years ago and send you the sketch, but would that not be loser? :wink:

Do the PING client/server example, and cut out the crap you don't need until you are able to send and "Hello world" back and forward.

Thanks Frédéric_Plante

Really appreciate the pointers.

I am going to spend a bit more time on the project as you suggested and try to get the 2 modules working together.

I am certainly not a quitter, but sometimes I do have to weigh-up the amount of time and effort I can afford to spend on a preferred method, compared to an alternate method that still gets the same end result.

Question : how do you know that the one library ( which one ? ) requires 2x speed on the SPI ? Is it in the documentation or code somewhere, or did you just learn the hard way over time ? Am asking in case it is possible to change the 'faster' library back to the same speed as the other.

Well I have learned the hard and frustrating way which consiste of browsing the library line by line to see what could be the problem emmiting hypothesis trying and bitching. Lol

At first, I was thinking that an harmonic value(1 x, 2x, 4x, 8x), would of been good, but just like on the UART, every one as to speak at the same speed, period.

I would really suggest that you spend the required time to get those two to work together, cause it will be valuable for your futur projects, these are very good base to start with before getting any bluetooth or wifi. Plus UIP, is very important to master. Get your self to start a TCP client or a server on the ENC device and get the stuff repeted to the NRF device. Then connect your computer using Telnet on your ENC device, your gain will be great for your futur projects.

Thanks Frédéric_Plante

I now have the mirf server loaded on 1 Mega, and the mirf client loaded on another.

I added the code :

Mirf.configRegister(RF_SETUP, 0x26);  //switch to 250kbit/s

to slow down the connection, but am getting lots of "Timeout on response from server" messages. Distance between Mega's is currently about 3 meters, but am wanting to eventually move to about 30 meters ( 100 feet ).

If I can find the solution to get the rf working reliably and consistantly, then I can add the UIPEthernet code and see if they all run together.

Any suggestions for the RF code ?

At the moment, I have :

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

long SentTime = 0;
int PingTimeOut = 0;
int FailCount = 0;

void setup(){
  Serial.begin(9600);
  Mirf.cePin = 9;
  Mirf.csnPin = 7;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"clie1");
  Mirf.payload = sizeof(unsigned long);
  Mirf.configRegister(RF_SETUP, 0x26);  //switch to 250kbit/s (0x26) (2Mbit => 0x0f)
  Mirf.config();

// Read and print RF_SETUP
byte rf_setup = 0;
Mirf.readRegister( RF_SETUP, &rf_setup, sizeof(rf_setup) );
Serial.print( "rf_setup = " );
Serial.println( rf_setup, BIN );
Serial.println( "Wireless initialized!" );

  Serial.println("Beginning ... "); 
  delay(500);
  
}

void loop(){
  unsigned long NowTime = millis();
  unsigned long timeBack = 0;
  
  Mirf.setTADDR((byte *)"serv1");
  
  // echo the data being sent to the rf server
  Serial.print("Long Data : ");
  Serial.println(NowTime);
  
  Mirf.send((byte *)&NowTime);
  
  while(Mirf.isSending()){
  }
  Serial.println("Sent");
  delay(10);
  SentTime = millis();

  PingTimeOut = 0;
  while(!Mirf.dataReady()){
    if ( ( millis() - SentTime ) > 1000 ) {
      FailCount++;
      Serial.print("Timeout on response from server : ");
      Serial.println(FailCount);
      PingTimeOut = 1;
      delay(500);
    }
  }
  
if(PingTimeOut == 0){
    Mirf.getData((byte *) &timeBack);
    Serial.print("Ping Data : ");
    Serial.println(timeBack);
    Serial.print("Ping msec : ");
    Serial.println((millis() - timeBack));
}
  PingTimeOut = 0;
  delay(3000);
}

Ok now if you have an UNO, use it as test bench by loading the ping server on it, why the UNO? cause I know it supply enogh current to the NRF MODULE. So what will happen is, your UNO will send the ping no problem, your Mega will receive the ping, but wont be able to answer.

If that happen, you will know that the power supply on the mega side does not deliver the power that the nrf device need.

Any ways, do not worry about the latency at 2x or at 4x. It will go very fast any way, and the distance wont be really mater since the signal travel at light speed. :wink:

In any case, at the end you will only need to use MIRF on the side that run ENC + NRF, you will be able to use the RF24 LIBRARY on the other side if you wish, since the communication protocole is internal in the NRF module and as nothing to do with the library you use.

If you are trying to test the nRF24, and the enc28j60 ethernet shield is still attached to the Arduino, you must disable the enc28j60 SPI by setting D10 as OUTPUT and HIGH. If the shield has a SD slot and you have a SD card in that slot, you must also disable the SD SPI.

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

  // disable SD SPI
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // disable enc28j60 SPI
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);

  Mirf.cePin = 9;
  Mirf.csnPin = 7;

  // rest of your setup

S.Tim is right.

How ever, i would suggest to remove every thing, but the NRF device for as long as theNRF device does not work like you wish.

We will do the same for the ENC device when it will be the time to work with the ENC device.

After that we will make them work together.

If the OP hasn't tested those devices separately, then I also recommend that. But I am past that part. The nRF24 and enc28j60 seem to be SPI compatible except for the SPI bus speed. The MIRF library sets the speed to SPI_CLOCK_DIV16, which is much slower than the standard SPI bus speed used by the enc28j60 or the SD card.

Uipethernet library and mirf both set the spi speed to 2x check your librarys again. :wink:

You tell me the difference between these two defines:

#define SPI_CLOCK_DIV16 0x01
#define SPI_2XCLOCK_MASK 0x01  // SPI2X = bit 0 on SPSR

Then look at the begin() call:

void MirfHardwareSpiDriver::begin(){
	SPI.begin();
	SPI.setDataMode(SPI_MODE0);
	SPI.setClockDivider(SPI_2XCLOCK_MASK);
}

Yeah but you compare that to nothing, show more.

In any case, the 2 librarys work together