RFID-RC522 stopped working on Arduino mega - arduino

I tested my rfid module when I first got it, and it worked. Then, on my 2nd go-around, trying to actually use it for something, it just crapped out. I have used multiple test programs, and none of them produced any output. Rfid module: D1 light is on, but no idea what that means.
I tried this code:
/*
* --------------------------------------------------------------------------------------------------------------------
* Example sketch/program showing how to read data from a PICC to serial.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID
* Reader on the Arduino SPI interface.
*
* When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE
* then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When
* you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output
* will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages
* when removing the PICC from reading distance too early.
*
* If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading).
* So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all
* details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so
* keep the PICCs at reading distance until complete.
*
* #license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}
and this code:
//www.elegoo.com
//2016.12.09
/*
* --------------------------------------------------------------------------------------------------------------------
* Example to change UID of changeable MIFARE card.
* --------------------------------------------------------------------------------------------------------------------
* This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid
*
* This sample shows how to set the UID on a UID changeable MIFARE card.
* NOTE: for more informations read the README.rst
*
* #author Tom Clement
* #license Released into the public domain.
*
* Typical pin layout used:
* -----------------------------------------------------------------------------------------
* MFRC522 Arduino Arduino Arduino Arduino Arduino
* Reader/PCD Uno Mega Nano v3 Leonardo/Micro Pro Micro
* Signal Pin Pin Pin Pin Pin Pin
* -----------------------------------------------------------------------------------------
* RST/Reset RST 9 5 D9 RESET/ICSP-5 RST
* SPI SS SDA(SS) 10 53 D10 10 10
* SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16
* SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14
* SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15
*/
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 5 // Configurable, see typical pin layout above
#define SS_PIN 53 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
/* Set your new UID here! */
#define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF}
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
// Setting the UID can be as simple as this:
//void loop() {
// byte newUid[] = NEW_UID;
// if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
// Serial.println("Wrote new UID to card.");
// }
// delay(1000);
//}
// But of course this is a more proper approach
void loop() {
// Look for new cards, and select one if present
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
delay(50);
return;
}
// Now a card is selected. The UID and SAK is in mfrc522.uid.
// Dump UID
Serial.print(F("Card UID:"));
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
// Dump PICC type
// MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
// Serial.print(F("PICC type: "));
// Serial.print(mfrc522.PICC_GetTypeName(piccType));
// Serial.print(F(" (SAK "));
// Serial.print(mfrc522.uid.sak);
// Serial.print(")\r\n");
// if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI
// && piccType != MFRC522::PICC_TYPE_MIFARE_1K
// && piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
// Serial.println(F("This sample only works with MIFARE Classic cards."));
// return;
// }
// Set new UID
byte newUid[] = NEW_UID;
if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
Serial.println(F("Wrote new UID to card."));
}
// Halt PICC and re-select it so DumpToSerial doesn't get confused
mfrc522.PICC_HaltA();
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
return;
}
// Dump the new memory contents
Serial.println(F("New UID and contents:"));
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
delay(2000);
}
and neither of them worked. no progress.

Related

Arduino SPI clock phase synched with data for all 4 modes, what's wrong?

I'm trying to drive the LTC1664 DAC from an Arduino (Mega 2560). The SPI data and clock coming out of the Arduino is always synched (rise and falls) for all 4 modes when the DAC data sheet indicates phasing
I've tried all modes, the SS line on the chip is being brought low during the writes (as it should) and I've tried different speeds and shiftOut(), setClockDivider(), setDataMode(), beginTransaction() and endTransaction().
Is this a bug in Arduino SPI, something specific to the Mega 2560, should I try an Uno or Due? Help please! Code below o-scope traces.
BTW: The 16 bit word I'm trying to transmit is, 0x3600 (o-scope trace truncated).
/*
Test DAC Control
created 18 Mar 2020 (Covid-19, oppsies)
by Danny Holstein
*/
// inslude the SPI library:
#include <SPI.h>
void DAC(unsigned short value, unsigned char channel, int SS_Pin, int model);
enum models{LTC1664};
enum models model;
// set pin 10 as the slave select for the digital pot:
const int DAC_SS_Pin = 22;
void setup() {
// set the DAC_SS_Pin as an output:
// initialize SPI:
Serial.begin(115200);
SPI.begin();
Serial.println("SPI.begin");
pinMode(DAC_SS_Pin, OUTPUT);
}
void loop() {
// go through the six channels of the digital pot:
for (int channel = 1; channel < 6; channel++) {
delay(500);
DAC(128*channel, channel, DAC_SS_Pin, LTC1664);
}
delay(1000);
Serial.println("new loop");
}
/*
DAC Control
This function controls an LTC1664 Micropower Quad 10-Bit DAC.
The LTC1664 is SPI-controlled,and to command it, you send one 16 bit word,
A3 A2 A1 A0 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 X1 X0
| ADDR | INPUT CODE | DON'T CARE
The circuit:
* CS - to digital pin 22 (SS pin)
* SDI - to digital pin 51 (MOSI pin)
* SDO - to digital pin 50 (MISO pin, not used in this function)
* CLK - to digital pin 52 (SCK pin)
created 18 Mar 2020 (Covid-19, oppsies)
by Danny Holstein
*/
void DAC(unsigned short value, unsigned char channel, int SS_Pin, int model) {
// take the SS pin low to select the chip:
digitalWrite(SS_Pin, LOW); delay(100);
unsigned short buf, b16;
unsigned char *c, b; c = (unsigned char *) &buf;
switch (model)
{
case LTC1664:
if (channel > 4) channel = 0xF;
buf = (channel << 12) | ((value & 0x3FF) << 2);
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
b16 = SPI.transfer16(buf);
Serial.print("0x" + String(buf, HEX)); Serial.println("\t0x" + String(b16, HEX) + "\t");
SPI.endTransaction();
break;
default:
break;
}
delay(100);
// take the SS pin high to de-select the chip:
digitalWrite(SS_Pin, HIGH);
// printf("value = 0x%04x", buf);
}
Turns out it wasn't related to the Arduino SPI function or phasing issues, the LTC1664 has a CLR pin that I had attached to a GPIO but had failed to command HIGH, it had been floating and inhibiting the chip, command HIGH and everything is good now.

RFID <MFRC522.h> won't work with new ARDUINO UNO WiFi REV2

I followed a basic example for the RFID module on an ARDUINO UNO REV3 and it works great. But when I try to connect it to the new ARDUINO UNO WiFi REV2 it won't work. The code compiles, but when I scan the NFC badge, nothing is being printed to the console. The NFC module communicates via SPI protocol. Is the SPI connection different on the new Arduino Uno WiFi REV2?
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
/* Set your new UID here! */
#define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF}
MFRC522::MIFARE_Key key;
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Warning: this example overwrites the UID of your UID changeable card, use with care!"));
// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop() {
// Look for new cards, and select one if present
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
delay(50);
return;
}
// Now a card is selected. The UID and SAK is in mfrc522.uid.
// Dump UID
Serial.print(F("Card UID:"));
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
// Set new UID
byte newUid[] = NEW_UID;
if ( mfrc522.MIFARE_SetUid(newUid, (byte)4, true) ) {
Serial.println(F("Wrote new UID to card."));
}
// Halt PICC and re-select it so DumpToSerial doesn't get confused
mfrc522.PICC_HaltA();
if ( ! mfrc522.PICC_IsNewCardPresent() || ! mfrc522.PICC_ReadCardSerial() ) {
return;
}
// Dump the new memory contents
Serial.println(F("New UID and contents:"));
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
delay(2000);
}

ERROR SPI on ATmega328P of Arduino

I use SPI on ATmega328 with raw code, data is transferred correctly, but the value return just correct in the second time. I don't know why. I think the data buffer register doesn't update immediately, when I push the button (this is video left is yellow LED, right is red LED: https://drive.google.com/open?id=1bf2XlxRBGCaUo0j2ezB2XFxfSItUmChN and code below)
I use Arduino Uno is a master to send data and get response. Arduino Nano is a slave to receive data and response to master.
Arduino Uno (master) code:
#define DDR_SPI DDRB
#define PORT_SPI PORTB
#define MOSI 3
#define SCK 5
#define SS 2
#define red 2
#define cbi(port, bits) (port) &= ~(1 << (bits))
#define sbi(port, bits) (port) |= (1 << (bits))
volatile uint8_t Data1;
volatile uint8_t Data2;
void setup()
{
Serial.begin(9600); //debug by UART
SPCR = 0; // Reset SPCR = 0
DDR_SPI |= (1<<MOSI)|(1<<SCK)|(1<<SS);// MOSI,SCK,SS - OUTPUT , MISO - INPUT
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); // Enable spi , Set master , div/16
pinMode(red,OUTPUT); // led output at pin 2
pinMode(6,INPUT_PULLUP); // internal res input at pin6
pinMode(7,INPUT_PULLUP); // internal res input at pin7
sbi(PORT_SPI,SS); // disable slave
}
uint8_t SPI_MasterTransmit(uint8_t cData)
{
SPDR = cData; // Start transmission
delay(50);
while(bit_is_clear(SPSR,SPIF)); //Wait for transmission complete
return SPDR;
}
void loop()
{
if(bit_is_clear(PIND,6)) // if i push button at pin 6
{
while(bit_is_clear(PIND,6)); // if i still push button at pin 6
cbi(PORTB,SS); // enable slave
Data1 = SPI_MasterTransmit(1); // send value 1 to slave
Serial.print(Data1); // debug
delay(50);
if(Data1 == 2) //if slave response value = 2
digitalWrite(red,LOW); //turnOFF led at pin 2
sbi(PORT_SPI,SS); // disable slave
}
else if(bit_is_clear(PIND,7)) // if i push button at pin 7
{
while(bit_is_clear(PIND,7)); // if i still push button at pin 7
cbi(PORT_SPI,SS); // disable slave
Data2 = SPI_MasterTransmit(3); // send value 3 to slave
Serial.print(Data2); // debug
delay(50);
if(Data2==4) //if slave response value = 4
digitalWrite(red,HIGH); //turnON led at pin 2
sbi(PORT_SPI,SS); // disable slave
}
}
Arduino Nano (slave) code:
#define MISO 4
#define yellow 2
#define cbi(port, bits) (port) &= ~(1 << (bits))
#define sbi(port, bits) (port) |= (1 << (bits))
volatile uint8_t Data;
void setup()
{
SPCR = 0; // reset SPCR = 0
DDRB |= (1<<MISO); // MISO - OUTPUT , SCK,MOSI,SS - INPUT
SPCR |= (1<<SPE)|(1<<SPIE); // enable spi , spi_interrupt
pinMode(yellow ,OUTPUT); // Led output at pin2
}
void SPI_Response(uint8_t cData)
{
SPDR = cData; //Start transmission
while(bit_is_clear(SPSR,SPIF)); //Wait for transmission complete
}
void loop()
{
}
ISR(SPI_STC_vect) // Vector interrupt spi
{
Data = SPDR; // volatile Data = data receive
if(Data == 1)
{
digitalWrite(yellow ,HIGH); // i turnOn led if i receive data = 5
SPI_Response(2); // and response to master a value = 7
delay(10);
}
else if(Data == 3)
{
digitalWrite(yellow,LOW); // i turnOFF led if i receive data = 6
SPI_Response(4); //and response to master a value = 8
delay(10);
}
}
You know the four wire SPI is full duplex, right? The master and the slave are sending the data simultaneously.
The common way how to do what you want is sending control byte and then dummy byte (or bytes) to receive the data.

Arduino with two RC522

To pimp up my Carrera I'm going to build a round counter.
It contains an Arduino Nano, a lcd and 2 rc522 rfid-reader.
The readers share the pins for scd, miso, mosi and have own pins for sda and rst.
Actually I'm not able to get the two readers work together at the same time. Only if the one or the other reader is physically plugged (hardcore!) into the breadbord it works (without code changing). But not together.
It has to be an issue with my code, but where?
(The RFID-Communication ist inpired by the example from [addicore][1]http://www.addicore.com/v/vspfiles/downloadables/Product%20Downloadables/RFID_RC522/RFIDQuickStartGuide.pdf)
Is there anyone who has a hint for me?
#include <AddicoreRFID.h>
#include <SPI.h>
#include <LiquidCrystal.h>
#define uchar unsigned char
#define uint unsigned int
// create AddicoreRFID object to control the RFID module
/////////////////////////////////////////////////////////////////////
//set the pins
/////////////////////////////////////////////////////////////////////
//2 - SCK Digital 13
//3 - MOSI Digital 11
//4 - MISO Digital 12
const int SS1 = 8; //RFID1
const int RST1 = 9;
AddicoreRFID myRFID1 (SS1, RST1);
const int SS2 = 10; //RFID2
const int RST2 = A0;
AddicoreRFID myRFID2 (SS2, RST2);
//Maximum length of the array
#define MAX_LEN 16
//LCD init
// * LCD RS pin to digital pin 7
// * LCD Enable pin to digital pin 6
// * LCD D4 pin to digital pin 5
// * LCD D5 pin to digital pin 4
// * LCD D6 pin to digital pin 3
// * LCD D7 pin to digital pin 2
LiquidCrystal lcd1(7, 6, 5, 4, 3, 2);
//Counter
int a = 0;
int b = 0;
void setup() {
Serial.begin(9600);
//LCD init
init_lcd1();
myRFID1.AddicoreRFID_Init();
myRFID2.AddicoreRFID_Init();
}
void loop() {
uchar i, tmp, checksum1;
uchar status;
uchar str1[MAX_LEN];
uchar str2[MAX_LEN];
///////////// RFID1 ///////////////////
// 0x4400 = Mifare_UltraLight -Tag Type
str1[1] = 0x4400;
//Find tags, return tag type
// Manipuliert str1(!);
//AddicoreRFID::AddicoreRFID_Request(byte reqMode, byte *TagType)
status = myRFID1.AddicoreRFID_Request(PICC_REQIDL, str1);
if (status == MI_OK) {
serial_TagDetect(str1, 1);
}
//Anti-collision, return tag serial number 4 bytes
// Manipuliert str1(!);
status = myRFID1.AddicoreRFID_Anticoll(str1);
if (status == MI_OK) {
serial_TagData(str1);
lcd_counter(str1, lcd1);
//delay(500);
}
myRFID1.AddicoreRFID_Halt(); //Command tag into hibernation
///////////// RFID2 ///////////////////
str2[1] = 0x4400;
//Find tags, return tag type
status = myRFID2.AddicoreRFID_Request(PICC_REQIDL, str2);
if (status == MI_OK) {
serial_TagDetect(str2, 2);
}
//Anti-collision, return tag serial number 4 bytes
status = myRFID2.AddicoreRFID_Anticoll(str1);
if (status == MI_OK) {
serial_TagData(str2);
lcd_counter(str2, lcd1);
// liest sonst nonstop die Tags!
//delay(500);
}
myRFID2.AddicoreRFID_Halt(); //Command tag into hibernation
}
void init_lcd1() {
... inits the lcd ...
}
// Zählt das Auftreten der Tags
void lcd_counter (uchar *str, LiquidCrystal lcd ) {
... output to the lcd ....
}
// Meldet gefundenen Tag auf der Konsole
void serial_TagDetect(uchar *str, int reader) {
if (reader == 1) {
Serial.print("RFID1 tag detected: ");
} else {
Serial.print("RFID2 tag detected: ");
}
Serial.print(str[0], BIN);
Serial.print(" , ");
Serial.print(str[1], BIN); Serial.println(" ");
}
// gibt Tagdaten auf der Konsole aus
void serial_TagData(uchar *str) {
uchar checksum1 = str[0] ^ str[1] ^ str[2] ^ str[3];
Serial.print("The tag's number is: ");
//Serial.print(2);
Serial.print(str[0]);
Serial.print(" , ");
Serial.print(str[1], BIN);
Serial.print(" , ");
Serial.print(str[2], BIN);
Serial.print(" , ");
Serial.print(str[3], BIN);
Serial.print(" , ");
Serial.print(str[4], BIN);
Serial.print(" , ");
Serial.println(checksum1, BIN);
}
I wonder about that the same(!!) rfid tag has different values depending it gets read from RFID1 or RFID2:
RFID1 tag detected: 1000100 , 0
The tag's number is: 136 , 100 , 11100 , 1101011 , 11111011 , 11111011
RFID2 tag detected: 1000100 , 0
The tag's number is: 68 , 0 , 0 , 0 , 0 , 1000100
I use 10 RC522 together at the same time with Ardunio mega .
Try this example for 2 ncf reader, its work for me. I tested in Arduino Nano.
The readers share the pins for 3,3V, GND. SCD, MISO, MOSI, RST and have own pins for SDA. I don't use the IRQ pin.
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS1_PIN 10 // Configurable, see typical pin layout above
#define SS2_PIN 8 // Configurable, see typical pin layout above
MFRC522 mfrc522_1(SS1_PIN, RST_PIN); // Create MFRC522 instance
MFRC522 mfrc522_2(SS2_PIN, RST_PIN);
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522_1.PCD_Init(); // Init MFRC522
mfrc522_1.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
mfrc522_2.PCD_Init(); // Init MFRC522
mfrc522_2.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details
}
void loop() {
// Look for new cards
if ( mfrc522_1.PICC_IsNewCardPresent() || mfrc522_2.PICC_IsNewCardPresent()) {
Serial.println(F("New card..."));
} else {
return;
}
// Select one of the cards
if ( ! mfrc522_1.PICC_ReadCardSerial() && ! mfrc522_2.PICC_ReadCardSerial()) {
Serial.println(F("Read..."));
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called
mfrc522_1.PICC_DumpToSerial(&(mfrc522_1.uid));
mfrc522_2.PICC_DumpToSerial(&(mfrc522_2.uid));
}
//Anti-collision, return tag serial number 4 bytes
status = myRFID2.AddicoreRFID_Anticoll(str1); // <<<< needs to be strl2

Arduino - managing two SPI devices at once

I'm trying to control two SPI devices at once using identical MISO, MOSI, and CLOCK pins but different SS pins.
One is the Wifly shield from SparkFun that uses a SPI-to-UART chip, the other is a MAX31855.
They work independently, but not together..
The SPI-to-UART code that I'm using is listed below. The only changes I've made is in the header file; I set select() and deselect() to public.
#include "SpiUart.h"
// See section 8.10 of the datasheet for definitions
// of bits in the Enhanced Features Register (EFR)
#define EFR_ENABLE_CTS 1 << 7
#define EFR_ENABLE_RTS 1 << 6
#define EFR_ENABLE_ENHANCED_FUNCTIONS 1 << 4
// See section 8.4 of the datasheet for definitions
// of bits in the Line Control Register (LCR)
#define LCR_ENABLE_DIVISOR_LATCH 1 << 7
// The original crystal frequency used on the board (~12 MHz) didn't
// give a good range of baud rates so around July 2010 the crystal
// was replaced with a better frequency (~14 MHz).
#ifndef USE_14_MHZ_CRYSTAL
#define USE_14_MHZ_CRYSTAL true // true (14 MHz) , false (12 MHz)
#endif
#if USE_14_MHZ_CRYSTAL
#define XTAL_FREQUENCY 14745600UL // On-board crystal (New mid-2010 Version)
#else
#define XTAL_FREQUENCY 12288000UL // On-board crystal (Original Version)
#endif
// See datasheet section 7.8 for configuring the
// "Programmable baud rate generator"
#define PRESCALER 1 // Default prescaler after reset
#define BAUD_RATE_DIVISOR(baud) ((XTAL_FREQUENCY/PRESCALER)/(baud*16UL))
// TODO: Handle configuration better
// SC16IS750 register values
struct SPI_UART_cfg {
char DataFormat;
char Flow;
};
struct SPI_UART_cfg SPI_Uart_config = {
0x03,
// We need to enable flow control or we overflow buffers and
// lose data when used with the WiFly. Note that flow control
// needs to be enabled on the WiFly for this to work but it's
// possible to do that with flow control enabled here but not there.
// TODO: Make this able to be configured externally?
EFR_ENABLE_CTS | EFR_ENABLE_RTS | EFR_ENABLE_ENHANCED_FUNCTIONS
};
void SpiUartDevice::begin(unsigned long baudrate) {
/*
* Initialize SPI and UART communications
*
* Uses BAUD_RATE_DEFAULT as baudrate if none is given
*/
SPI.begin();
initUart(baudrate);
}
void SpiUartDevice::deselect() {
/*
* Deslects the SPI device
*/
digitalWrite(SS, HIGH);
}
void SpiUartDevice::select() {
/*
* Selects the SPI device
*/
digitalWrite(SS, LOW);
}
void SpiUartDevice::initUart(unsigned long baudrate) {
/*
* Initialise the UART.
*
* If initialisation fails this method does not return.
*/
// Initialise and test SC16IS750
configureUart(baudrate);
if(!uartConnected()){
while(1) {
// Lock up if we fail to initialise SPI UART bridge.
};
}
// The SPI UART bridge is now successfully initialised.
}
void SpiUartDevice::setBaudRate(unsigned long baudrate) {
unsigned long divisor = BAUD_RATE_DIVISOR(baudrate);
writeRegister(LCR, LCR_ENABLE_DIVISOR_LATCH); // "Program baudrate"
writeRegister(DLL, lowByte(divisor));
writeRegister(DLM, highByte(divisor));
}
void SpiUartDevice::configureUart(unsigned long baudrate) {
/*
* Configure the settings of the UART.
*/
// TODO: Improve with use of constants and calculations.
setBaudRate(baudrate);
writeRegister(LCR, 0xBF); // Access EFR register
writeRegister(EFR, SPI_Uart_config.Flow); // Enable enhanced registers
writeRegister(LCR, SPI_Uart_config.DataFormat); // 8 data bit, 1 stop bit, no parity
writeRegister(FCR, 0x06); // Reset TXFIFO, reset RXFIFO, non FIFO mode
writeRegister(FCR, 0x01); // Enable FIFO mode
}
boolean SpiUartDevice::uartConnected() {
/*
* Check that UART is connected and operational.
*/
// Perform read/write test to check if the UART is working
const char TEST_CHARACTER = 'H';
writeRegister(SPR, TEST_CHARACTER);
return (readRegister(SPR) == TEST_CHARACTER);
}
void SpiUartDevice::writeRegister(byte registerAddress, byte data) {
/*
* Write <data> byte to the SC16IS750 register <registerAddress>
*/
select();
SPI.transfer(registerAddress);
SPI.transfer(data);
deselect();
}
byte SpiUartDevice::readRegister(byte registerAddress) {
/*
* Read byte from SC16IS750 register at <registerAddress>.
*/
// Used in SPI read operations to flush slave's shift register
const byte SPI_DUMMY_BYTE = 0xFF;
char result;
select();
SPI.transfer(SPI_READ_MODE_FLAG | registerAddress);
result = SPI.transfer(SPI_DUMMY_BYTE);
deselect();
return result;
}
int SpiUartDevice::available() {
/*
* Get the number of bytes (characters) available for reading.
*
* This is data that's already arrived and stored in the receive
* buffer (which holds 64 bytes).
*/
// This alternative just checks if there's data but doesn't
// return how many characters are in the buffer:
// readRegister(LSR) & 0x01
return readRegister(RXLVL);
}
int SpiUartDevice::read() {
/*
* Read byte from UART.
*
* Returns byte read or or -1 if no data available.
*
* Acts in the same manner as 'Serial.read()'.
*/
if (!available()) {
return -1;
}
return readRegister(RHR);
}
size_t SpiUartDevice::write(byte value) {
/*
* Write byte to UART.
*/
while (readRegister(TXLVL) == 0) {
// Wait for space in TX buffer
};
writeRegister(THR, value);
}
size_t SpiUartDevice::write(const char *str, size_t size) {
/*
* Write string to UART.
*/
while (size--)
write(*str++);
while (readRegister(TXLVL) < 64) {
// Wait for empty TX buffer (slow).
// (But apparently still not slow enough to ensure delivery.)
};
}
void SpiUartDevice::flush() {
/*
* Flush characters from SC16IS750 receive buffer.
*/
// Note: This may not be the most appropriate flush approach.
// It might be better to just flush the UART's buffer
// rather than the buffer of the connected device
// which is essentially what this does.
while(available() > 0) {
read();
}
}
void SpiUartDevice::ioSetDirection(unsigned char bits) {
writeRegister(IODIR, bits);
}
void SpiUartDevice::ioSetState(unsigned char bits) {
writeRegister(IOSTATE, bits);
}
I attempted to use it like this:
SpiSerial.deselect(); //Deselect Wi-Fi
delay(100); //Wait, just for the heck of it.
currentTemp = thermocouple.readFarenheit(); //Read from max31855... readFarenheit selects and unselects its own SS pin.
SpiSerial.select(); //Reselect Wi-Fi
But it's still unable to function. What further things should I attempt in order to get this to function?
TWO issues:
You don't mention anything about the MAX31855 library or how it is used. It looks like you are using Adafruit_MAX31855. Did you set the second argument of the constructors instance to "SS" or the value of the pin for chip select tied to the MAX31855? Their respective chip selects can not share the same pin.
The Adafruit_MAX31855 bit bangs out an emulated SPI over GPIO. This is not the same as the Wi-Fi's true hard SPI. Once spi.begin(); from SpiUartDevice::begin() then the GPIO pins shared with the hard SPI are no longer available as GPIO. As a result, the Adafruit_MAX31855 bit bangs do nothing. There are several options for the latter problem.
Use a different MAX31855 library that does not bit bang it. But I don't quickly see one.
Fix the Adafruit_MAX31855 to hard SPI.
Use different pins for the MAX31855 other than the Hard SPI pins.
Use the SPI.end() function to shut down the SPI and return GPIO back to normal IO use, and then restart SPI.begin() after bit banging out the Adafruit_MAX31855 function calls.
Such as the following:
SpiSerial.deselect(); //Deselect Wi-Fi
SPI.end(); //Restore GPIO mode of pins
delay(100); //Wait, just for the heck of it
currentTemp = thermocouple.readFarenheit();
SPI.begin(); //Restore SPI mode of pins
SpiSerial.select(); //Reselect Wi-Fi

Resources