SPI clash?

Today I got a scope on the modules. Both modules connected to hardware SPI as in the previous program/drawings

So running the OLED program only the oled pins are;

OCS - 4v to data when screen page writes
Reset - floats high (approx. 4v)
DC - 4v to data when screen writes
Sclk - 4v to data when screen writes
MOSI - data when screen writes and switching between high (4v) or low (0v)

and running the RFID program alone ;

SDA - data all time at 4v max
MISO - data all time at 2v max
Reset - floats high at 4v
SCLK - Data all time at 3v max
MOSI - data all time at 3v

When I run the combined 'main' program calling both modules I notice that when the serial monitor outputs the status of the RFID some of the data lines are tied to that 'pulse', so on the OLED I get;

OCS - High then data every couple of seconds but not tied to serial pulse
reset - 4v
DC - High then data every couple of seconds but not tied to serial pulse
SCLK - 0-2v data tied to serial 'pulse'
MOSI - data between 2 and 4v tied to serial 'pulse'

and on the RFID I get;

SDA - data 2-4v tied to serial pulse
MOSI - data between 2 and 4v tied to serial 'pulse'
Reset - floats high at 4v
SCLK - Data 0-2v tied to serial pulse
MISO - data 0-2v tied to serial pulse

Any bright ideas?

The problem must be with the SPI and RFID libraries because as soon as I run either of;

//SPI.begin(); 
  // RC522.init();

It crashes and the OLED won't load.

The RFID code is the one that needs the SPI library. The OLED runs fine without it but as initialising the SPI or the RFID makes it crash, It may need a modification to both?

I don't have any experience with library modifications and it would be really nice to get two SPI modules running as everyone seems to have problems with this..........

You obviously don't believe it, but

Whandall:
I also had to isolate a RC522 with a level shifter/buffer with inhibit/enable to make it work alongside a NRF24L01+.

I found that out in

Whandall:
I could resolve the bus contention with my setup.

I'm using an yf08e based 8-bit bidirectional level shifter to bring the voltages from the Nano to
a level that's inside the MFR522 specs, that has an output enable pin.

Too bad it has the wrong polarity to drive it by CS, so I just used a free pin to control it.

My code which works (much debug output and no real action)

#include <SPI.h>

#include <MFRC522.h>
#include <printf.h>
#include <RF24.h>

#define RST_PIN        7
#define SS_PIN          8

MFRC522 mfrc522(SS_PIN, RST_PIN);

RF24 radio(9, 10);

const byte addresses[] = "10000" "20000" "30000" "40000" "50000" "60000";

struct Pack {
  byte number;
  unsigned long tStamp;
} Data;

byte currentTarget;

void setup() {
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
  printf_begin();
  Serial.begin(250000);
  SPI.begin();
  radio.begin();
  radio.enableDynamicPayloads();
  radio.setDataRate(RF24_2MBPS);
  radio.printDetails();
  digitalWrite(6, HIGH);
  mfrc522.PCD_Init();
  mfrc522.PCD_DumpVersionToSerial();
  digitalWrite(6, LOW);
  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
  radio.printDetails();
}

void loop() {
  digitalWrite(6, HIGH);
  if (mfrc522.PICC_IsNewCardPresent()) {
    if (mfrc522.PICC_ReadCardSerial()) {
      mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
    }
  }
  digitalWrite(6, LOW);
  static unsigned long lastSend;
  unsigned long topLoop = millis();
  if (topLoop - lastSend >= 2000) {
    lastSend = topLoop;
    Data.number++;
    Data.tStamp = topLoop;
    radio.openWritingPipe(addresses + 5 * currentTarget);
    if (!radio.write(&Data, sizeof(Data))) {
      Serial.print(F("Failed for #"));
      Serial.print(currentTarget);
      Serial.print(F(" ""));
      for (byte idx = 0; idx < 5; idx++) {
        Serial.write(addresses[5 * currentTarget + idx]);
      }
      Serial.write('"');
      Serial.println();
    }
    if (++currentTarget > 5) {
      currentTarget = 0;
    }
  }
}





STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x3030303034 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x3030303034
RX_PW_P0-6 = 0x20 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x08
CONFIG = 0x0e
DYNPD/FEATURE = 0x3f 0x04
Data Rate = 2MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MIN
Firmware Version: 0x11 = (unknown)
Scan PICC to see UID, SAK, type, and data blocks...
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x3030303034 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x3030303034
RX_PW_P0-6 = 0x20 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x08
CONFIG = 0x0e
DYNPD/FEATURE = 0x3f 0x04
Data Rate = 2MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MIN
Failed for #0 "10000"
Failed for #1 "20000"
Failed for #2 "30000"
Failed for #3 "40000"
Failed for #4 "50000"
Card UID: 9E 07 41 C5
Card SAK: 08
PICC type: MIFARE 1KB
Sector Block  0  1  2  3  4  5  6  7  8  9 10 11  12 13 14 15  AccessBits
  15    63  00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
        62  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
        61  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
        60  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
  14    59  00 00 00 00  00 00 FF 07  80 69 FF FF  FF FF FF FF  [ 0 0 1 ]
        58  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
        57  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
        56  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  [ 0 0 0 ]
** rest of dump removed, 9000 char limit **

Failed for #5 "60000"



The failed sends are caused by the missing receiver.

With an inverter CS could be used directly and that would not require the manual disabling of the buffer.

I had a quick glance at the datasheet of the MFR, it should behave differently.

I do appreciate the help....thank you.

My only questioning of the level shifter thought is both that modules run independently with their own programs so the shifting issue isn't between the MEGA and the modules?

When I scope the lines when the individual programs are running they are similar in level, its just when they are joined in the one program they conflict.

This is what's confusing me.

I've also tried to add some code in the loop to test the CS control by digitalWriting it LOW or HIGH but it doesn't seem to have an affect. The OLED code (on its own) still runs.

I was wondering if software SPI would work on the RFID module alongside the hardware SPI on the OLED as a last resort.

This is all part of a much larger MEGA project that pretty much uses all the I/O but its the entry point so I really to get this going......

The RC522 is a 3.3V device IMHO, which seems to 'work' in an 5V environment even without level shifters,
but I think that is running the chip outside the guaranteed limits.

Using a level shifter is one the standard ways to integrate 3.3V devices to 5V Arduinos,
the chip I used additionaly allows to isolate the device,
which was the only way I found to make it work with a NRF24L01.

Don't get me wrong, the level shifting alone did not make the system work IIRC,
but it stopped mistreating the 3.3V inputs of the RC522,
which is probably a good thing in regard of long term stability.

If you add some inverting hardware* you can tie the CS to the now inverted enable of the level shifter
and there is no need for any software changes in your code or the library.

* could be a pullup resistor, a transistor and a base resistor

P.S. I don't own a SPI OLED, mine are all I2C, so I can not reproduce your setup here.

kpg:
I was wondering if software SPI would work on the RFID module alongside the hardware SPI on the OLED as a last resort.

That would probably work, but need even more pins (3) than running the OLED (2) via software SPI.
Both would need more pins than the direct drive of the enable via pin (1) or the hardware inversion (0).