SPI/I2C clash?

I have a part of a project that uses a RFID reader and Oled, (both on SPI) and a RTC on I2C.

The RFID and OLED code work well together and if I run the OLED and RTC together in another sketch they work Ok together, but when I combine all three and call the RTC subroutine, the display just goes blank.

I cant see why calling the RTC makes it crash.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <PN532_SPI.h>
#include "PN532.h"
#include "RTClib.h"
PN532_SPI pn532spi(SPI, 10);
PN532 nfc(pn532spi);
RTC_DS3231 rtc;

#define dc   A2 
#define cs   53
#define rst  4

#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF

Adafruit_SSD1351 tft = Adafruit_SSD1351(cs, dc, rst);
boolean success;
String cardNum;
//unsigned long RFID;
int powerPin = 13;
int powerpinRead;
int prevpowerpinRead = LOW;
int powerpinState = LOW;
long time = 0;         
long debounce = 200;   
float p = 3.1415926;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
uint8_t secs = 0;

void setup(void) {
 Serial.begin(9600);
 
  tft.begin();
  tft.fillRect(0, 0, 128, 128, BLACK);
  tft.setCursor(30, 5);
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.println("Suzuki");
  tft.setTextSize(4);
  tft.println(" 112");
  delay (2000);
 //  tft.fillRect(0, 0, 128, 128, BLACK);
 
 nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
  Serial.print("Didn't find PN53x board");
  while (1); // halt
  }
  nfc.setPassiveActivationRetries(0x01);
  nfc.SAMConfig();
   
  pinMode(powerPin, OUTPUT); 

 uint16_t time = millis();
 // tft.fillRect(0, 0, 128, 128, BLACK);
  time = millis() - time;

 }

void loop() 
{
 readRfid();
 powerpinRead = (success);
 
 RTCNow(); 
 
}

void readRfid()
{
  
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  if (success) {
    //Serial.println(success);
    Serial.println("Found a card!");
    for (uint8_t i=0; i < uidLength; i++) 
    {
     // Serial.print(" 0x");Serial.print(uid[i], HEX); 
    }
    }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Timed out waiting for a card");
  }
  delay(1000);
if (powerpinRead == HIGH && prevpowerpinRead == LOW && millis() - time > debounce) 
  {
    if (powerpinState == HIGH)
    powerpinState = LOW;
        else
        powerpinState = HIGH;
        time = millis();    
  }
    digitalWrite(powerPin, powerpinState);
    
    prevpowerpinRead = powerpinRead;
  
  if (powerpinState == HIGH|| powerpinState == 0x11)
  
  {
  
  RTCNow(); 
  }

  Serial.println (powerpinState);
  
}

void RTCNow()

{
 DateTime now = rtc.now();
  if (secs == now.second())//do more for hrs etc to save time
  {
    return;
  }
  secs = now.second();
   
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.setCursor(12,7);
  tft.print("  Clock ");
  tft.setTextSize(2);
  tft.setTextColor(MAGENTA, BLACK);
  tft.setCursor(15, 25);
  if ( now.hour()<10 ) tft.print(" ");
  tft.print(now.hour(), DEC);
  tft.print(":");
  if ( now.minute()<10 ) tft.print("0");
  tft.print(now.minute(), DEC);
  tft.print(":");

  if ( secs <10 ) tft.print("0");//previously uses second.now()but this should speed it up?
  tft.print(secs, DEC);
 

  tft.setTextSize(1);
  tft.setCursor(30, 45);
  tft.print(now.day(), DEC);
  tft.print("-");
  tft.print(now.month(), DEC);
  tft.print("-");
  tft.print(now.year(), DEC);
  tft.setCursor(17, 55);
  tft.setTextSize(2);
  tft.setTextColor(GREEN, BLACK);
  tft.print(daysOfTheWeek[now.dayOfTheWeek()]);
  tft.print("   "); // erase any previous date string that was longer
}

I've put a check in the RTC code now to serial.print seconds so I can see the RTCNow() sub is being run from the loop and that the RTC is running. That all works fine but it just wont display.

The RTC is on I2c on pins 20/21 and the OLED and NFC/RFID are on SPI.

I just cant see why running the RTCNow sub crashes the display.

If I leave the SPI defines in;

#define sclk 52//was out
//#define mosi 51//was out

Then the display wont even run in startup whereas it normally does until the RTCNow sub runs.......I clearly don't understand SPI enough.....

Full code is now;

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <PN532_SPI.h>
#include "PN532.h"
#include "RTClib.h"
PN532_SPI pn532spi(SPI, 10);
PN532 nfc(pn532spi);
RTC_DS3231 rtc;
//#define sclk 52//was out
//#define mosi 51//was out
#define dc   A2 
#define cs   53
#define rst  4

#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF

Adafruit_SSD1351 tft = Adafruit_SSD1351(cs, dc, rst );//mosi,slk were out as with define
boolean success;
String cardNum;
//unsigned long RFID;
int powerPin = 13;//was 3
int powerpinRead;
int prevpowerpinRead = LOW;
int powerpinState = LOW;
long time = 0;         
long debounce = 200;   
float p = 3.1415926;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
uint8_t secs = 0;

void setup(void) {
 Serial.begin(9600);
 
  tft.begin();
  tft.fillRect(0, 0, 128, 128, BLACK);
  tft.setCursor(30, 5);
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.println("Suzuki");
  tft.setTextSize(4);
  tft.println(" 113");
  delay (2000);
 //  tft.fillRect(0, 0, 128, 128, BLACK);

tft.fillScreen(BLACK);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  rtc.adjust(DateTime(__DATE__, __TIME__));
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.setCursor(0, 5);
  tft.print("  Clock ");
  delay(3000);
 // tft.fillScreen(BLACK);
 
 nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
  Serial.print("Didn't find PN53x board");
  while (1); // halt
  }
  nfc.setPassiveActivationRetries(0x01);
  nfc.SAMConfig();
   
  pinMode(powerPin, OUTPUT); 

 uint16_t time = millis();
 // tft.fillRect(0, 0, 128, 128, BLACK);
  time = millis() - time;


 
 
 }
void loop() 
{
 Serial.println ("loop running");
 RTCNow(); 
 readRfid();
 powerpinRead = (success);
 

 
}

void readRfid()
{
  
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  if (success) {
    //Serial.println(success);
    Serial.println("Found a card!");
    for (uint8_t i=0; i < uidLength; i++) 
    {
     // Serial.print(" 0x");Serial.print(uid[i], HEX); 
    }
    }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Timed out waiting for a card");
  }
  delay(1000);
if (powerpinRead == HIGH && prevpowerpinRead == LOW && millis() - time > debounce) 
  {
    if (powerpinState == HIGH)
    powerpinState = LOW;
        else
        powerpinState = HIGH;
        time = millis();    
  }
    digitalWrite(powerPin, powerpinState);
    
    prevpowerpinRead = powerpinRead;
  
  if (powerpinState == HIGH|| powerpinState == 0x11)
  
  {
  
  //RTCNow(); 
  }
  Serial.println (powerpinState);
  
}

void RTCNow()
{
 DateTime now = rtc.now();
  
  tft.setTextSize(2);
  tft.setTextColor(MAGENTA, BLACK);
  tft.setCursor(0, 0);
  if ( now.hour()<10 ) tft.print(" ");
  tft.print(now.hour(), DEC);
  tft.print(":");
  if ( now.minute()<10 ) tft.print("0");
  tft.print(now.minute(), DEC);
  tft.print(":");
 if (secs == now.second())//do more of these IF's to save time on days and hours etc. not printing
  {
    return;
   
  }
   secs = now.second();
  if ( now.second()<10 ) tft.print("0");
  tft.print(now.second(), DEC);

  tft.setTextSize(1);
  tft.setCursor(0, 18);
  tft.print(now.day(), DEC);
  tft.print("-");
  tft.print(now.month(), DEC);
  tft.print("-");
  tft.print(now.year(), DEC);
  tft.setCursor(0, 30);
  tft.print(daysOfTheWeek[now.dayOfTheWeek()]);
  tft.print("   "); // erase any previous date string that was longer
  Serial.println (secs);//test
}

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

Tom

Image attached. I have put dotted squares around the RFID, RTC and OLED modules and shown the whole Mega and the pins linking to the 3 modules.

Hope this helps.

Thanks for all the help.

Kev

Hi,
The resolution of your diagram is very low and just not enough to read any text.

Rather than a screen capture, your CAD should be able to EXPORT as a jpg image.

Thanks.. Tom... :slight_smile:

You can buy RTC with SPI interface, which would allow you to make your design "cleaner" (but would only save 1 pin).
rtc spi.jpg

rtc spi.jpg

It was generated in a PCB program. Hopefully this export to Word is better. Thanks.....

CCT.doc (196 KB)

Don't you need SPI.begin(); in setup?

I don't see

digitalWrite (cs, LOW);
SPI.transfer = whatever;
digitalWrite (cs, HIGH);

kind of statements. How is SPI being used?
You're sending data out, yes? If I read the schematic correctly (still hard to follow even zoomed in), it doesn't look like MOSI is connected.

OLed wiring is;

MOSI 51
Sclk 52
CS 53
DC A2
RST 4

RFID wiring is;

ICSP pins - Miso, Mosi, SCk

CS 10

RTC is SDA/SLC - 20 and 21

As I posted the OLED works fine in startup, the RFID works, the RTC is running (i have a serial.print test) but the RTC info wont display once RTCNow() runs.

I have provision for a SD card on 50/51/52 as well but that isnt connected yet.

Thanks

Kev

Hi,
Sorry .doc file is just as bad.
EXPORT from Eagle, it should be in the File TAB, as jpg and it will be full readable resolution.

Tom... :slight_smile:

Tom

I am running Kicad and dont have that option.

If I open it in Word and zoom it it seems very readable and I am old and blind!!

Sorry this is a hassle. I will try again but if you can just zoom in it may be OK?

Thanks again

Kev

I tried zooming, the fuzzy blobs get bigger but no less fuzzy.

Can you export as PDF and attach that to your post?

Maybe you need to add this code in setup()?

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

If you zoom in word and wait a few seconds it is very clear.

I just tried pdf and it is much worse.

Thanks for the suggestion, I did have that RTF test in setup and it didnt halt and again I placed a RTC read seconds test at the end the RTCNow sub and I can see seconds with serial.print to it is running the RTC, it just isnt displaying it.

Attached as a .PNG now. My Word version still seems clearer but maybe this is better for others.

Appreciate the help.

Kev

Most of us read the forum on phones & tablets much of the time. Maybe that's why, when we zoom, your schematic doesn't get any clearer. This is what I see for example, and waiting doesn't change anything.

kpg:
I did have that RTF test in setup and it didnt halt and again I placed a RTC read seconds test at the end the RTCNow sub and I can see seconds with serial.print to it is running the RTC, it just isnt displaying it.

It's not just a test, the call to rtc.begin() is necessary for normal operation.

Looks like that on a 15" laptop too. Needs to be printed with more resolution.

Hi,
I think we need a schematic with just the SPI and IC bus wiring.

Tom.. :slight_smile:

Resolution seems to be a KiCad issue. Export prints the whole page to the Clipboard for pasting into something else. Can't zoom in and export the zoomed in window. No resolution settings.