Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SoftSPI #24

Closed
henrikekblad opened this issue Oct 2, 2014 · 50 comments
Closed

SoftSPI #24

henrikekblad opened this issue Oct 2, 2014 · 50 comments

Comments

@henrikekblad
Copy link

I'm having serious problems combining RF24 with w5100 ethernet module (which hogs SPI interface) and a touch screen I've been working on. Would it be possible to add support for soft SPI in your fork?

Found this PR to maniacbug..
https://github.com/maniacbug/RF24/pull/34/files

A little explaination:
http://shanes.net/how-to-use-an-nrf24l01-rf24-with-an-arduino-ethernet-shield/

@TMRh20
Copy link
Member

TMRh20 commented Oct 2, 2014

Definitely possible. If you have an ethernet module and an RF24 chip, do you have any use for the UART? On 328s etc, the UART can operate in master SPI mode, giving you a second SPI BUS and I'm sure there is another way to do the same with hardware driven SPI on arm devices. Any of that feasable, or would you require the software solution?

@henrikekblad
Copy link
Author

UART=Serial?
Only necessary for doing debug prints I guess. I'm totally lost when it comes to SPI interface/UART configuration. :)
Are you saying it is possible to use UART as secondary SPI with the current library? Could you provide me with an example?

@TMRh20
Copy link
Member

TMRh20 commented Oct 2, 2014

It is a built-in feature of the UART, the only limitation being that it cannot operate in slave mode. I just pushed a library I made to run RF24 chips this way. I haven't used it in a while, and can't remember much for details atm, but assume it would still work. Pin 4 (XCK) is the sck pin, and cs/ce are optional. On MEGA, the xck pin requires soldering onto or connecting to an unused pin on the chip if I remember, but it can be done the same way, or driven manually.

@henrikekblad
Copy link
Author

Great! Funny that you just happened to have this around ;)
So how would I combine this with the RF24 to let it communicate over the secondary SPI?

@TMRh20
Copy link
Member

TMRh20 commented Oct 2, 2014

I think you just need to replace the reference to Spi.h with this lib name in the config file and the sketch. It should be miso (master IN) would be rx and mosi (master out) would be tx.

Think that's it. If you think it might work with these pins being used etc. it should be easy to include in a branch for testing.

@henrikekblad
Copy link
Author

it should be easy to include in a branch for testing.

👍

FYI: This is the first usecase: http://forum.mysensors.org/topic/446/scene-controller-preview/2

@TMRh20
Copy link
Member

TMRh20 commented Oct 2, 2014

In your sketch:
#include <SPI_UART.h>

Pin Differences:

NRF Arduino Uno Pin
MOSI TX(0)
MISO RX(1)
SCK XCK(4)

Download RF24/w SPI_UART from Updates Branch

I just put it in as a user define - edit RF24_config.h and comment #define SPI_UART to revert to normal SPI. note Any calls to serial.print etc. will interfere with the SPI functionality.

*Edit to add: Side note - I did some testing/play with UART vs SPI, and the UART actually performed smoother at very high rates when compared to the SPI hardware.

TMRh20 added a commit that referenced this issue Oct 2, 2014
@TMRh20
Copy link
Member

TMRh20 commented Oct 2, 2014

Forgot to sync the commit... should be good now.

@henrikekblad
Copy link
Author

Hope I can try later tonight.

@henrikekblad
Copy link
Author

Are you suggesting to solder something here:
arduinomega2650front_21

Puh.. that might be a too big challenge for me.

@TMRh20
Copy link
Member

TMRh20 commented Oct 2, 2014

Well, if you are comfortable with that, but in the case of the mega, I would probably suggest modifying the library to manually drive the SCK on another pin. I wasn't aware you were using a Mega for this.

If interested, I used this xck pin with UART1 on my 2560, just left of the arduino symbol:

pict0186

TMRh20 added a commit that referenced this issue Oct 3, 2014
- Added softSPI support for https://github.com/greiman/DigitalIO library
- Updated SPI_UART code to allow use at the same time as the SPI library
@TMRh20
Copy link
Member

TMRh20 commented Oct 3, 2014

FYI, since the UART idea may not work, I added support for the softspi lib from https://github.com/greiman/DigitalIO. I also updated the SPI_UART library to allow its use along with the SPI library, since I realized it would not work at the same time as the ethernet SPI, so it would need to be re-installed to work with these changes. I haven't had a chance to fully test it all.

@henrikekblad
Copy link
Author

DigitalIO would be great and add full flexibility without modifying the hardware. So if you would consider it I'd be very grateful.. Was banging my head last night with all this. I still cannot understand why the Display/touch/SD shield won't work together with the NRF-module. It should if everyone followed the specification I guess.
They both work great by themselves.

@TMRh20
Copy link
Member

TMRh20 commented Oct 3, 2014

I don't understand that myself, since the SPI spec is pretty simple. Unless the Arduino is being used as a slave device for the touchscreen, but I don't think that is likely. The changes are included for digitalIO, just reinstall and edit the #define SPI_UART or #define SOFTSPI as desired in RF24_config.h.

Out of curiosity, what library does it use, and what kind of screen is it?

@henrikekblad
Copy link
Author

Great! Travelling this weekend so I cannot hack anything :(

I'm using this screen:
http://www.ebay.com/itm/300894857599?_trksid=p2059210.m2749.l2649&var=600107267291&ssPageName=STRK%3AMEBIDX%3AIT

With the UTFT/Touch libraries:
http://www.henningkarlsen.com/electronics/library.php?id=51

@TMRh20
Copy link
Member

TMRh20 commented Oct 3, 2014

Well, from the looks of the shield, the only thing connected to SPI is the SD card, which is using the standard SPI pins on the Mega. The TFT library has no SD functionality, so I assume you are using either the standard SD lib or SDFat? Both of these libraries do work well with the RF24 lib last I checked, so should work in theory if you have it all hooked up correct. (using different cs/ce pins, but the same miso,mosi, sck pins) If not, I would assume a hardware issue. I can't really see it being software related, but anything is possible. Not sure what you are using for a power supply, but would assume the SD + Screen uses quite a bit, so it could be the standard nrf24l01 power issues, which could be ruled out using a 3.3v battery to power it etc.

@henrikekblad
Copy link
Author

Tried moving CS/CE yesterday. RF24 works fine using the new pins until I add the shield. Are there any pins on ATMega I should avoid. Used 9/10.

I'm not currently using the SD card reader and nothing getting initialized in the sketch. Could it help to add SD library and initialize it?

Isn't the touch-function using SPI?

@TMRh20
Copy link
Member

TMRh20 commented Oct 3, 2014

I can't remember off-hand if you need the SD card initialized, but it seems like a good possibility. I don't find any reference to SPI or SD functions anywhere in the touch or tft libs, and there is a schematic here that shows the connections of the shield. Its totally driven by digital I/O as far as I can tell.

TMRh20 added a commit that referenced this issue Oct 4, 2014
- Revert SPI to default lib by default. Configure via RF24_config.h #24
- Corrected CRC status reporting per https://github.com/evorios by
checking AA register
TMRh20 added a commit that referenced this issue Oct 5, 2014
Fix compile errors when trying to use any of the three libraries
together - should allow softspi and uartspi to play nicely with the std
SPI library now
@TMRh20
Copy link
Member

TMRh20 commented Oct 5, 2014

Ok, so I've had a chance to look more at these issues, n here's what I got:
SoftSPI
I fixed some issues with the library that should actually allow the software spi lib or the spi_uart to work in conjunction with the SPI lib, so two can run at once. I don't have a w5100 to test with, but I've confirmed RF24 works with softSPI after initializing the regular SPI.

To test it out:

  1. Install the digitalIO library
  2. Reinstall the RF24 library from Updates
  3. Open RF24_config.h in a text editor. Uncomment the line #define SOFTSPI
  4. In your sketch, add #include DigitalIO.h

Note: Pins are listed as follows and can be modified in the RF24_config.h file
const uint8_t SOFT_SPI_MISO_PIN = 16;
const uint8_t SOFT_SPI_MOSI_PIN = 15;
const uint8_t SOFT_SPI_SCK_PIN = 14;

w5100 ethernet module

  1. It turns out that the wiznet chips basically have a CE pin similar to RF24, and it needs to be toggled for other devices to get control of the SPI BUS. It seems the newer boards have some circuitry to manage this automatically.
  2. Some older boards may have a jumper or pad labelled 'prog' of which one side is connected to this 'ce' pin. Advanced users could solder a wire to this, connect it to a digital pin, and toggle it before accessing other SPI devices. IMHO this is kind of a hack, but essentially a true fix that would allow hardware SPI.

@henrikekblad
Copy link
Author

Great, Will try this when I'm back home. Thanks for helping out with this issue!

@henrikekblad
Copy link
Author

Yiha! The display/rf24 works together with SoftSPI! Thanks!

@TMRh20
Copy link
Member

TMRh20 commented Oct 6, 2014

Hahaha, after all that... softspi. I think the issues have been otherwise addressed as far as they can be, so closing the issue. Feel free to re-open or add comments if you have further info or issues. The changes have been merged into the master branch.

@chriskelman
Copy link

Not sure if this is still open...
I have been impressed with the nRF42 capabilities and support from TMRh20
I did think that the above would sort out my long-standing problem of trying to run a catalex SD card with just about any other SPI device. However I have had no luck running the RF42 + SD card. Compile errors include "new declaration 'void badPinNumber()'"
Has there been any further progress on this problem or am I doing something wrong with the SoftSPI approach?

@TMRh20
Copy link
Member

TMRh20 commented Mar 11, 2016

@chriskelman It sounds like something is wrong. See here for current info on using softspi.

@chriskelman
Copy link

Much appreciated.

I will have one last attempt to make this work!

I Have spent a week so far trying to get anything to run on SPI - if I have an SD (+- ethernet) card installed.

@Avamander
Copy link
Member

@chriskelman Have you tried running all the devices on the same bus and just using CS/SS to toggle the slave you're talking to, just as SPI was intended to work. SoftSPI in my opinion should only be used if one of the SPI slaves tends to lock or mess up the bus.

@chriskelman
Copy link

Yes, that is what I was expecting/hoping to be able to do.

I have managed to run an ethernet card (W5100) + its inbuilt SD card on the SPI bus.

However, if I install the ether shield or just the micro SD card module, I can get nothing else to operate on this bus.

My application requires multiple Arduino sensor modules (with local 'mission critical' data storage on an SD card) plus an RF mesh link to a Pi web server, so the nRF24 seems an obvious choice. So far, everything is working well - until I include the SD card...

Any suggestions on how to use the hardware SPI bus for SD + nRF24 would be gratefully accepted, but it seems from my experience (and reading what others have said) that the SD card device hogs the SPI bus. So that is why I started investigating the S-SPI software - so far no success but I will try installing the updated files suggested by TMRh20.

I have been using a generic SD module similar to

http://www.ebay.com/itm/Micro-SD-Storage-Board-Mciro-SD-TF-Card-Memory-Shield-Module-SPI-For-Arduino-New/131132034753?_trksid=p2047675.c100005.m1851&_trkparms=aid%3D222007%26algo%3DSIC.MBE%26ao%3D1%26asc%3D35696%26meid%3Df2e6b6cc7f86489b92786253b6eab6cb%26pid%3D100005%26rk%3D3%26rkt%3D6%26sd%3D140717254516

Thanks for your interest!


From: Avamander [email protected]
Sent: 14 March 2016 05:43
To: TMRh20/RF24
Cc: chriskelman
Subject: Re: [RF24] SoftSPI (#24)

@chriskelmanhttps://github.com/chriskelman Have you tried running all the devices on the same bus and just using CS/SS to toggle the slave you're talking to, just as SPI was intended to work. SoftSPI in my opinion should only be used if one of the SPI slaves tends to lock or mess up the bus.

Reply to this email directly or view it on GitHubhttps://github.com//issues/24#issuecomment-196018188.

@deloarts
Copy link

@chriskelman:
Hey, I had the same problem as you, but with another device. I wanted to use the catalex card reader and a RFID-module together. Both should work on the SPI-Bus, but they don't.

I figured out, this is due to the SN74LVC125A level shifter, which is used on the catalex-boards. It is capable of allowing multiple devices on one bus, but the manufacturer decided to solder the neccessary pins direct to ground. And now it blocks the bus.

I see 2 ways to work around:
Get another module (maybe another catalex [besides v1.0] could work, but therefor you must see the datasheet).
Or use softSPI.

I tried the second method, but until now (and I tried a long time) it doesn't work. I really don't know why ... but if you're able to get it running, please post here how you've done it.

Kind regards!

@chriskelman
Copy link

OK, thanks for the encouragement.
I have now at least managed to drive the nRF24 module from S-SPI - using mesh topology!
I was very pleased with this progress, but when I installed the SD card (on the standard Mega SPI pins 50-53) and added SD.h to the header files, I ran into further problems, (despite installing the latest versions).

It seems there is a conflict with other header files as I now get errors for re-defining variables such as:
from Sd2Card.h -> error: new declaration 'uint8_t badPinNumber()'
error: void value not ignored as it ought to be, return badPinNumber();
from DigitalIO.h -> error: ambiguates old declaration 'void badPinNumber()'
from Sd2PinMap.h -> error: new declaration 'uint8_t fastDigitalRead(uint8_t)'

Any suggestions?

@TMRh20
Copy link
Member

TMRh20 commented Mar 16, 2016

The errors indicate conflict between the digitalIO/softspi library and the
stock ad lib.

This one seems kind of ugly. Some pf the w5100 and some other devices hog
the spi bus so an alternate may be required.

Unfortunately the obvious softspi conflicts with SD lib.

The sdfat lib at github.com/greiman supports its own softspi, and may work
but is a bit different than the stock spi lib.

Rf24 also supports using the serial port as separate spi bus per the docs.,
but of course you lose the serial debugging etc.

All in all it seems like a bunch of ugly conflicts, but there are
potentially some ugly solutions to match if you have the patience time etc.

Sent from my iPod

On 2016-03-15, at 7:25 PM, chriskelman [email protected] wrote:

OK, thanks for the encouragement.
I have now at least managed to drive the nRF24 module from S-SPI - using
mesh topology!
I was very pleased with this progress, but when I installed the SD card (on
the standard Mega SPI pins 50-53) and added SD.h to the header files, I ran
into further problems, (despite installing the latest versions).

It seems there is a conflict with other header files as I now get errors
for re-defining variables such as:
from Sd2Card.h -> error: new declaration 'uint8_t badPinNumber()'
error: void value not ignored as it ought to be, return badPinNumber();
from DigitalIO.h -> error: ambiguates old declaration 'void badPinNumber()'
from Sd2PinMap.h -> error: new declaration 'uint8_t
fastDigitalRead(uint8_t)'

Any suggestions?


You are receiving this because you modified the open/close state.
Reply to this email directly or view it on GitHub
#24 (comment)

@chriskelman
Copy link

I trialled SdFat.h - it does provide an alternative SPI pin-set for the SD card which seems to work well, however - it has conflicts with the RF24 libraries.
I may have to look for alternative SD hardware that has better bus behaviour...

@Avamander
Copy link
Member

You can always just modify the SD library's conflicting function's name.

@chriskelman
Copy link

You mean - in effect just exclude it from the 'include' list?
I will try this again, but it seemed that some of the functions were needed

@TMRh20
Copy link
Member

TMRh20 commented Mar 16, 2016

Rf24 should be compatible with sdfat. Im sure ive tested it with rf audio
streaming. Make sure to re-comment/disable softspi for rf24 if using sdfat
w/softspi

Sent from my iPod

On 2016-03-16, at 3:23 AM, chriskelman [email protected] wrote:

You mean - in effect just exclude it from the 'include' list?
I will try this again, but it seemed that some of the functions were needed


You are receiving this because you modified the open/close state.
Reply to this email directly or view it on GitHub
#24 (comment)

@Avamander
Copy link
Member

@chriskelman No, I meant you modify the SD card or whatever library created the redeclaration errors and make sure they use unique names.

@chriskelman
Copy link

You were correct TMRH20 - I had forgotten to re-comment soft SPI in RF24... thus creating obvious conflicts.
So I now have it all working with a Catalex SD card on S_SPI and nRF24 on standard SPI pins
For the record, the changes I had to make were

  1. Use SdFat instead of SD library
  2. in SdFatConfig.h #define SD_SPI_CONFIGURATION 3 (or 2 perhaps)
  3. disable SSPI in RF24_config.h (when using SdFat-SSPI as the alternative)
    Thanks for your help all - this has been a one year project to get this sorted out!

@deloarts
Copy link

Hey chriskelman!
Thanks a lot for sharing this!

Correct me if I'm wrong. You're using the catalex sd module on soft spi and the rf24 on the standard spi?

If so, would you please send me your pinout (which pin of the catalex goes to which pin on the arduino).

Best regards!

@chriskelman
Copy link

I am working with a Mega so pins for standard SPI are as normal. The S_SPI pins are user-configurable as I understand - but I set them to:
Catalex SD card pins:
const uint8_t SOFT_MISO_PIN = 12;
const uint8_t SOFT_MOSI_PIN = 11;
const uint8_t SOFT_SCK_PIN = 13;
const uint8_t SD_CHIP_SELECT_PIN = 10;
const int8_t DISABLE_CHIP_SELECT = -1;

nRF24 module pins:
CE - pin 7
CS - pin 8
MISO - pin 50
MOSI - pin 51
SCK - pin 52

Best of luck!

@deloarts
Copy link

Thanks a lot, this helps so much !

@linargonne
Copy link

hey I am working on a project with rf24 sharing SPI pins with touch screen shield (Adafruit 1947). Since Adafruit use all the SPI pins on UNO (9-13 are all used). I tried to use SOFT-SPI for RF24. All I did is follow above-mentioned instruction by TMRh20:

  1. Install the digitalIO library
  2. Reinstall the RF24 library from Updates (page do not exist)
  3. Open RF24_config.h in a text editor. Uncomment the line #define SOFTSPI
  4. In your sketch, add #include DigitalIO.h

Note: Pins are listed as follows and can be modified in the RF24_config.h file
const uint8_t SOFT_SPI_MISO_PIN = 16; (I changed it to 13)
const uint8_t SOFT_SPI_MOSI_PIN = 15; (I changed it to 12)
const uint8_t SOFT_SPI_SCK_PIN = 14; (I changed it to 11).
I connected RF24 with CE_>2, CSN->3, SCK->5, MOSI->6, MISO->7 on UNO.
It does not work. What did I do wrong?

@TMRh20
Copy link
Member

TMRh20 commented Nov 15, 2016

Change the softspi pins to match the rf24 5,6,7 instead of 13,12,11

@linargonne
Copy link

oh my god! It works finally. I have been struggling with this for 5 or 6 months. I cannot believe this will work with both devices on one UNO. Thank you so so very much!

@raillersing
Copy link

It works!I use it on UNO and NANO an it works fine with SPI_UART and SOFT_SPI. But if we use the RF24 library with MEGA 2560, it doesn't work properly (with normal SPI). There are many error and SOFT_SPI and SPI_UART dosn't work. Thank you for your help tmrh20.
But can you help me on the MEGA?

@demascr
Copy link

demascr commented Apr 27, 2017

How if I use nRF24 to be a network with RF24Network.h library? Are they works?

@raillersing
Copy link

raillersing commented May 5, 2017 via email

@scallas
Copy link

scallas commented Jun 5, 2017

Hi there
Just want to know if its possible to configure the Soft SPi from within arduino sketch(IDE)?

Will be using three rf modules but only one with soft spi configured. Do I have to make seperate libraries with soft spi enabled?
Cheers
S

@raillersing
Copy link

raillersing commented Jun 7, 2017 via email

@scallas
Copy link

scallas commented Jun 7, 2017

Its possible. At the moment I must either have two different libraries or change the rf25_config.h to use softspi or not.
Was just wondering if it is possible to change this behaviour from within Arduino IDE.

@Tailwindz
Copy link

Hello, I have been trying to get my UNO to work with the USB Host Shield by Circuitsathome to read in information from a USB joystick and send the data wirelessly with the nrf24l01+ to another UNO with another nrf24l01+ and display the info via the serial monitor. I can use the nrf24l01+ modules and the USB host shield successfully as separate projects, but if I try to put them on the same SPI bus (with different CS pins), they do not work. I have tried the Soft SPI method described above but the transmitter does not transmit. I have seen this guy do it successfully with an xbox controller but he did not explain how: https://www.youtube.com/watch?v=tjH-t8bMipI

Any help would be greatly appreciated.

Below is the code I used (I am just trying to get the modules to work by sending Hello World with the USB host shield attached). On the transmitter (on top of the USB host shield and using soft SPI) the pins are set to SCK: 6, MOSI: 4, MISO: 5, CSN: 3, CE: 2. On the receiver (using regular SPI) the pins are SCK: 13, MISO: 12, MOSI: 11, CSN: 3, CE: 2.

Transmitter:

`#include <DigitalIO.h>
#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <SPI.h>
#include "le3dp_rptparser.h"
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);

const byte address[6] = "00001";

int joyX = 512; // min: 0 | max: 1023 | center: 512
int joyY = 512; // min: 0 | max: 1023 | center: 512
int joyHat = 8; // up: 0 | right-up: 1 | right: 2 | right-down: 3 | down: 4 | left-down: 5 | left: 6 | left-up: 7 | center: 8
int joyTwist = 128; // min: 0 | max: 255 | center: 128
int joySlider = 0; // min: 0 | max: 255
int joyButtonsA = 0;
int joyButtonsB = 0;

RF24 radio(2, 3);

void setup()
{
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
SPI.beginTransaction(SPISettings(1200000, MSBFIRST, SPI_MODE0));
if (Usb.Init() == -1)
delay( 200 );

if (!Hid.SetReportParser(0, &Joy))
    ErrorMessage<uint8_t>(PSTR("SetReportParser"), 1  );
SPI.endTransaction();
digitalWrite(10, LOW);

radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();

}

void loop()
{
digitalWrite(10, HIGH);
SPI.beginTransaction(SPISettings(1200000, MSBFIRST, SPI_MODE0));
Usb.Task();
SPI.endTransaction();
digitalWrite(10, LOW);

const char text[] = "Hello World";
radio.write(&text, sizeof(text));

}

void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
//Put the values from the joystick in another variable:
joyX = evt->x;
joyY = evt->y;
joyHat = evt->hat;
joyTwist = evt->twist;
joySlider = evt->slider;
joyButtonsA = evt->buttons_a;
joyButtonsB = evt->buttons_b;
}

`
Receiver:

`#include <SPI.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

RF24 radio(2,3);

const byte address[6] = "00001";

void setup(){
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}

void loop(){
if(radio.available()){
char text[32] = "";
radio.read(&text, sizeof(text));
Serial.println(text);
}
}`

@xandcapcom
Copy link

I'm looking for the same video code, to make a similar project, but I can not make the two work. USB shield and NRF24 :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests