Interrups with Wemos D1R1, RFID-RC522 and a flow sensor. (and upload errors)

I'm working on a project to combine Wifi with an RFID reader, to read an RFID card, send the UID to a webservice and then activate a flow sensor.

The project is using a Wemos D1 R1 (RETIRED) and a Sunfounder RFID-RC522 and a DIGITEN flow sensor FL-S402B.

I have a few questions:

  1. Is it possible to hook up the RC522 to the Wemos D1 AND have another available interrupt for the flow sensor?
  2. Does the Wemos D1R2 or D1 R2 Mini (or other variants using the esp8266) have different capability for the interrupts?
  3. How do I reset the board after a persistent skets upload error:
    Uploading 226352 bytes from C:\Users\XXXX\AppData\Local\Temp\buildd69075b1d789db7f28178c535b46a7a7.tmp/Blink.ino.bin to flash at 0x00000000
    warning: espcomm_send_command: didn't receive command response
    warning: espcomm_send_command(FLASH_DOWNLOAD_BEGIN) failed
    error: espcomm_upload_mem failed
  4. The pin mapping for the Wemos D1R1 shows multiple D pins mapped to the same GPIO pins. IE D5 & D13 both map to GPIO14. Does this mean that both D pins really point to the same exact location and thus are effectively one in the same?

Any assistance is greatly appreciated. Apologies for the overly long post.
---- Detail below.

It took a little bit of work to figure out the pin configuration, but through some trial and Error I was able to get the WIFI + RFID working with the following:

#include <ESP8266WiFi.h>
//WIFI stuff
WiFiClient client;
const char* ssid     = "myRouter";
const char* password = "myPwd";

const char* host = "192.168.0.103";


const unsigned long HTTP_TIMEOUT = 10000;  // max respone time from server
const size_t MAX_CONTENT_SIZE = 512;       // max size of the HTTP response

byte mac[6];                     // the MAC address of your Wifi shield
char macAddr[18];

//RFID stuff
#include <SPI.h>
#include <MFRC522.h>

constexpr uint8_t RST_PIN = 2;     // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 4;     // Configurable, see typical pin layout above
 
MFRC522 rfid(SS_PIN, RST_PIN); // Instance of the class

MFRC522::MIFARE_Key key; 

// Init array that will store new NUID 
byte nuidPICC[4];



void setup() {
  Serial.begin(115200);
  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  WiFi.macAddress(mac);

  sprintf(macAddr, "%2X:%2X:%2X:%2X:%2X:%2X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.println(macAddr);

  //and connect to the RFID card
  SPI.begin(); // Init SPI bus
  Serial.println("test setup");
  rfid.PCD_Init(); // Init MFRC522 

  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }

  Serial.println(F("This code scan the MIFARE Classsic NUID."));
  Serial.print(F("Using the following key:"));
  printHex(key.keyByte, MFRC522::MF_KEY_SIZE);

}



void loop() {
  delay(10);
  ++value;

    // Look for new cards
    if ( ! rfid.PICC_IsNewCardPresent()){
       // Serial.println(F("No New card"));
         delay(50);
      return;
    }
    else{
       delay(50);
       // Serial.println(F("New card"));
     }
    // Verify if the NUID has been readed
    if ( ! rfid.PICC_ReadCardSerial())
      return;
  
    Serial.print(F("PICC type: "));
    MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
    Serial.println(rfid.PICC_GetTypeName(piccType));
  
  
    // Check is the PICC of Classic MIFARE type
    if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&  
      piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
      piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
      Serial.println(F("Your tag is not of type MIFARE Classic."));
      return;
    }
  
    if (rfid.uid.uidByte[0] != nuidPICC[0] || 
      rfid.uid.uidByte[1] != nuidPICC[1] || 
      rfid.uid.uidByte[2] != nuidPICC[2] || 
      rfid.uid.uidByte[3] != nuidPICC[3] ) {
     // Serial.println(F("A new card has been detected."));
  
      // Store NUID into nuidPICC array
      for (byte i = 0; i < 4; i++) {
        nuidPICC[i] = rfid.uid.uidByte[i];
      }
  
        unsigned long UID_unsigned;
        UID_unsigned =  rfid.uid.uidByte[0] << 24;
        UID_unsigned += rfid.uid.uidByte[1] << 16;
        UID_unsigned += rfid.uid.uidByte[2] <<  8;
        UID_unsigned += rfid.uid.uidByte[3];
        String UID_string =  (String)UID_unsigned;
        
      Serial.print(F("RFID scanned: "));
      Serial.println(UID_string);    
      if(makeAuthorizationCall(UID_string) ==0){

         for (byte i = 0; i < 4; i++) {
          nuidPICC[i] = 0;
        }
        delay(2000);
      }
    }
    
  }
}
int makeAuthorizationCall(String UID_string ){

  const int httpPort = 80;
  Serial.print("connecting to ");
  Serial.print(host);
  Serial.print(":");
  Serial.println(httpPort);
  
  // Use WiFiClient class to create TCP connections

  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return -1;
  }
  
  // We now create a URI for the request and pass the RFID UID
  String url = "/url/somemapping/"+UID_string+"/";
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return -1;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
    Serial.println("ready to read result..");
    while(client.available()){
      //Serial.println("read line");
      String line  = client.readStringUntil('\r');


      Serial.print(line);
    }
 //  now do something with the result.
  Serial.println("closing connection");

  return 0;
}

The pin configuration between wemos and rc522
[WemosD1] >(COLOR) RC522
[D14/SDA/D4] >(Y)-NSS
[D13/SCK/D5] >(O)-SCK
[D1/MOSI/D7] >(R)-MOSI
[D12/MISO/D6] >(B)-MISO
[GND] >GND
[D2] >(P)-RST
[3.3] >(W)-VCC

After I got this working, I attempted to hook up a simple flow(hall) sensor to an interrupt and quickly discovered I couldn't find an avaliable pin for the interrupt.

I have had some difficulty finding which pin to use, since most discussin is around the D1R2, but ultimately found that it might be D4.
Since D4 is used as RC522 SCK, I tried unsuccessfully to configure it to every other pin on the board. None worked. Either it would cause an error with the WIFI connection, or with the RFID.

Again, having difficulty finding any documentation on D1R1 interrupts, I built a simple sketch to test each pin individually.

{
 const byte interruptPin = 4;//4 works with the wemosD1R1

 void setup() {
  Serial.begin(115200);
  
  pinMode(interruptPin, INPUT_PULLUP);
  delay(1000);
  Serial.println("attaching..");
  
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);

  Serial.print("connectedToPin:");
  Serial.print(interruptPin);
  Serial.print(" Interrupt:");
  Serial.println(digitalPinToInterrupt(interruptPin));
 }

 void loop() {
  Serial.println("delay");
  delay(5000);
 }

 void blink() {
  Serial.println("+");
 }
}

I discovered the following results:
//1-3 - no function
//4 yes
//5 - no function
//6 makes the wifi board crash
Cant attempt further tests due to flash issue.

At this point, the IDE stopped uploading the sketches to the board. Subsequently, any upload (even basic blink) fail.
Uploading 226352 bytes from C:\Users\XXXX\AppData\Local\Temp\buildd69075b1d789db7f28178c535b46a7a7.tmp/Blink.ino.bin to flash at 0x00000000
warning: espcomm_send_command: didn't receive command response
warning: espcomm_send_command(FLASH_DOWNLOAD_BEGIN) failed
error: espcomm_upload_mem failed

I searched around and found reference to resetting it with a pulldown to ground from D0, D3, D8, none of which has resolved the issue.

Pin Mapping: Arduino/pins_arduino.h at master · esp8266/Arduino · GitHub

I was able to get past the reset by connecting D8/DPIO0 > GND, then powering it up and sending the sketch.. I swear I tried this before, but it worked when I tried again. I did try it in a different GND pin, so perhaps something is wrong with a GND pin.

After getting the sketch upload working again, I was able to resume testing each pin for interrupt capabilities. I found that D12 works on its own as an interrupt, however, it conflicts with the RFID communications when running concurrently.

According to the following pin layout, D12 = GPIO12 and D6 =GPIO12, so attaching an interrupt to D12 catches the activity on D6. Which results in a conflict between the interrupt on D12 and the RFID reader connected to D6

D15 SCL GPIO5
D14 SDA GPIO4

GND
D13 SCK GPIO14
D12 MISO GPIO12
D11 MOSI GPIO13
D10 SS GPIO15
D9 TX1 GPIO2
D8 GPIO0
D7 MOSI GPIO13
D6 MISO GPIO12
D5 SCK GPIO14
D4 SDA GPIO4
D3 SLC GPIO5
D2 GPIO16
D1 TX GPIO1
D0 RX GPIO3

I'm definitely still stuck.

Use this for reference:

  • https://wiki.wemos.cc/products:d1:d1

  • All the pins are interrupt pins.

  • Your code makes no sense. You have code in it for a wifi shield?? The Wemos (ESP8266) uses no wifi shield, it is the wifi chip. Start using a standard example for connecting to wifi provided with the ESP8266 library.

  • You also are not using a standard example provided with the MFRC522 library. Do not use those long delays in your sketches, they are not provided in the examples and for good reason.

The MFRC522 uses SPI for communication, thus it will use 4 pins on your board. That leaves you with 4 other pins to use for interrupt.

Also when coding for the Wemos (and for every ESP8266 out there) ONLY use the GPIO pins in your code.

For example: if you want to use D5, you will need to use GPIO14. >>

digitalWrite(5, HIGH); This does not work. Now you are selecting D3. D3 = GPIO5.

The correct coding would be:

digitalWrite(14, HIGH); Now you set D5 high.

Thanks for taking the time to provide some feedback Lenny. It's much appreciated.

I definitely hadn't figured out that the digitalWrite is going to the GPIO, not to the D#. That's a pretty big miss and explains a lot.

I'm away from my Arduino IDE right now, but I believe the WiFi code I'm using is based directly from the Wemos D1 (retired) example sketch code for WiFiWebClient. The RFID code was from MFC522 / ReadNUID sketch. I tested them individually, then merged them into the first sketch that I posted above. The delays in that first sketch were mainly for observation while monitoring the Serial communication for testing. They'll definitely be stripped out.

Thanks again for your feedback and for the link to the wiki.wemos.cc

skydogs:
Thanks for taking the time to provide some feedback Lenny. It's much appreciated.

I definitely hadn't figured out that the digitalWrite is going to the GPIO, not to the D#. That's a pretty big miss and explains a lot.

I'm away from my Arduino IDE right now, but I believe the WiFi code I'm using is based directly from the Wemos D1 (retired) example sketch code for WiFiWebClient. The RFID code was from MFC522 / ReadNUID sketch. I tested them individually, then merged them into the first sketch that I posted above. The delays in that first sketch were mainly for observation while monitoring the Serial communication for testing. They'll definitely be stripped out.

Thanks again for your feedback and for the link to the wiki.wemos.cc

It also took me a while before I figured it out that I had to use the GPIO and not the D# labeling. It's because different boards can have different labeling but they all have the same GPIO. Good luck with your project and it would be nice if you keep us posted about your progress. Have a good day.