I am trying to control both RFID sensor RC522 and lcd st7920 (128x64) via a single SPI bus on the NodeMCU esp8266. I am using Arduino core for my esp8266. Now in this portion of the code, I only want to display the UID of the card on the lcd each time a card is scanned on the RC522. The code is as follows:
#include <SPI.h>
#include <MFRC522.h>
#include <U8g2lib.h>
#define SPI_SCK_pin 14 // Clock pin of SPI
#define SPI_MOSI_pin 13 // MOSI pin of SPI
#define SPI_RST_pin 0 // RST-PIN for RC522 - RFID - SPI - Modul GPIO5
#define SPI_rfid_SS_pin 15 // SDA-PIN for RC522 - RFID - SPI - Modul GPIO4
MFRC522 mfrc522(SPI_rfid_SS_pin, SPI_RST_pin); // Create MFRC522 instance
#define SPI_lcd_SS_pin 5 // Slave Select pin of SPI for lcd<->RS
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R2, SPI_SCK_pin, SPI_MOSI_pin, SPI_lcd_SS_pin, U8X8_PIN_NONE);
void setup() {
SPI.begin(); // Init SPI bus
Serial.begin(115200); // Initialize serial communications
u8g2.setFont(u8g2_font_amstrad_cpc_extended_8f);
}
void loop() {
mfrc522.PCD_Init(); // Init MFRC522
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
delay(50);
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
delay(50);
return;
}
Serial.print(F("Card UID:"));
String uid = dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
digitalWrite(SPI_rfid_SS_pin, HIGH); //return rfid slave pin back to normal
u8g2.begin();
u8g2.clearBuffer();
u8g2.setCursor(3,10);
u8g2.print (uid);
u8g2.sendBuffer();
digitalWrite(SPI_lcd_SS_pin, HIGH); //return lcd slave pin back to normal
// delay (10);
}
// Helper routine to dump a byte array as hex values to Serial
String dump_byte_array(byte *buffer, byte bufferSize) {
String userid;
for (byte i = 0; i < bufferSize; i++) {
userid += String(buffer[i]);
}
Serial.print(userid);
return userid;
}
I am new to using the esp8266 and this is my first time using multiple slaves on a single SPI bus so I may not know the correct way to using multiple slaves. I tried connecting only the rfid rc522 with esp8266 via SPI and it worked flawlessly with the schematic. Similarly the lcd also works flawlessly individually on the SPI bus with the same schematic.
The issue only exists if I try to connect both via SPI. The problem is that only the first time a card is scanned, is it displayed on the lcd. After that no more cards are scanned and the only the first card scanned is displayed on the lcd.
What I am trying to do is that every time a card is scanned, its UID be displayed on the lcd. I've posted the schematic and my actual setup which you can check.
Are you sure that the Init calls in loop() do not do anything unwanted?
In case of trouble you miss to reset the select lines! Check all return; statements.
You have both SPI devices using the same output pin.
SCK on the RF522 is more accurately labeled SS in the SPI context; it must have a separate signal (output pin) so each device interacts only when it is selected.
The three other SPI are shared.
In you code, you must carefully select which device you mean to control by asserting its SS (E on the LCD). And un-asserting, so to speak, the other.
Get the polarity of the two distinct select outputs correct and make sure only one device is selected at a time.
HTH
a7
alto777:
You have both SPI devices using the same output pin.
I am using this setup where the SCLK, MISO and MOSI pins are shared but each slave has its own SS pin.
Get the polarity of the two distinct select outputs correct and make sure only one device is selected at a time.
Can you please explain how to do that? Since I'm using libraries for both slave devices, I do not know how to switch between them.
DrDiettrich:
Are you sure that the Init calls in loop() do not do anything unwanted?
In case of trouble you miss to reset the select lines! Check all return; statements.
Thanks for replying. Can you explain me how to reset the select slave lines when a slave device finishes its task?
UPDATE:
The issue resolves if I just put SPI.begin() in start of void loop() instead of void setup(). Now every time I scan a card, then its corresponding UID will be displayed on the lcd.
I know this is not a solution but a workaround. Normally you only initialize SPI once in setup and never reinitialize it every loop. I am checking if I can fix that. If anyone has any idea, please do guide me.
Then your schematic is incorrect.
I don’t know but you should:
is SS active high or active low?
If, e.g., active low, de-select one device:
digitalWrite(ssRF522, HIGH);
and select the other:
digitalWrite(ssLCD, LOW);
When you are done with either, de-select itlike above. If the active-low or active-high nature of the SS pin is different, make the appropriate change, swamping HUGH and LOW.
The two select signals may be differ3nt, just write the appropriate value to select or de-select.
Select only one at a time, deselect both when all is quite.
a7
alto777:
You have both SPI devices using the same output pin.
Do you mean output pin as in master out slave in? If you do that is wrong.
The SS pin is set up when you instantiate the module, so :-
#define SPI_rfid_SS_pin 15 // SDA-PIN for RC522 - RFID - SPI - Modul GPIO4
MFRC522 mfrc522(SPI_rfid_SS_pin, SPI_RST_pin); // Create MFRC522 instance
// and
#define SPI_lcd_SS_pin 5 // Slave Select pin of SPI for lcd<->RS
U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R2, SPI_SCK_pin, SPI_MOSI_pin, SPI_lcd_SS_pin, U8X8_PIN_NONE);
Both set up the SPI to work with a different slave device select pin, that is pin 15 and pin 5.
So the libraries will ensure that correct select pin will be driven low at the right time.
The problem appears to be that according to your diagram these pins are not connected to your devices.
Can you explain me how to reset the select slave lines when a slave device finishes its task?
You don't have to do anything the libraries handle this for you.
is SS active high or active low?
SS is ALWAYS active low.
SS is ALWAYS active low.
ALWAYS is NEVER a good word to use when talking about “standards” like SPI.
Best to check and be sure, even if or maybe especially because yours might be more like 99.44 percent of the time a correct assertion.
a7
ALWAYS is NEVER a good word to use when talking about "standards" like SPI.
I pick my words with care, show me a device that has an active high select pin and I will send you a free copy of my book.
As unused inputs in TTL logic floats high no one ever designed a chip that would be accidental active under fault conditions or broken wires.
Grumpy_Mike:
The problem appears to be that according to your diagram these pins are not connected to your devices.
I checked and the SS pins for both devices are connected correctly according to the schematic and the code.
SS for LCD RS pin ---> pin 5 on esp8266 (GPIO 5 pin)
SS for RC522 SDA pin ---> pin 15 on esp8266 (GPIO 15 pin)
Have you also measured the signal levels after boot and when the malfunction occurs?
DrDiettrich:
Have you also measured the signal levels after boot and when the malfunction occurs?
No. I'm sorry but I do not know how to do that. Can you guide me?
Do you have a DMM at hand?