Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * ----------------------------------------------------------------------------
  3.  * Arduino Uno distance NFC reader with OLED display
  4.  *
  5.  * ----------------------------------------------------------------------------
  6.  * The following sketch is intended to be used to mesaure the ditance between the
  7.  * NFC board and NFC tag. Once a tag is detected an interrupt is fired and the
  8.  * meassured distance displayed.
  9.  *
  10.  * Typical pin layout used:
  11.  * ------------------------------------------------
  12.  *
  13.  * Arduino     MFRC5522  Ultrasound  OLED Display
  14.  *   Uno          Pin        Pin           Pin
  15.  * ------------------------------------------------
  16.  *   2          IRQ       -           -
  17.  *   3          -         ECHO        -
  18.  *   4          -         TRIGGER     -
  19.  *   SCL        -         -           SCL
  20.  *   SDA        -         -           SDA
  21.  *   9          RST       -           -
  22.  *   10         SDA       -           -
  23.  *   11         MOSI      -           -
  24.  *   12         MISO      -           -
  25.  *   13         SCK       -           -
  26.  *
  27.  */
  28.  
  29. #include <SPI.h>
  30. #include <MFRC522.h>
  31. #include <Wire.h>
  32. #include <Adafruit_GFX.h>
  33. #include "U8x8lib.h"     //Using u8g2 library
  34.  
  35. // Pin setup
  36. constexpr uint8_t RST_PIN = 9;      // NFC Reset
  37. constexpr uint8_t SS_PIN  = 10;     // Select
  38. constexpr uint8_t IRQ_PIN = 2;      // Interrupt
  39.  
  40. constexpr int  TRIGGER_PIN = 4;     // US trigger
  41. constexpr int  ECHO_PIN    = 3;     // US echo
  42.  
  43. constexpr int  LED    = 7;     // US echo
  44.  
  45. constexpr uint8_t BUZZ_PIN = 8;      // Buzzer
  46.  
  47. // Variables
  48. volatile long duration;
  49. volatile int distance;
  50. volatile bool bNewInt = false;
  51. byte regVal = 0x7F;
  52. int offset=20;
  53. String distStr;
  54.  
  55. // Config variables
  56. const float USONIC_DIV          = 58.0;
  57. const int MEASURE_SAMPLE_DELAY  = 3;
  58. const int MEASURE_SAMPLES       = 20;
  59. const int MEASURE_DELAY         = 50;
  60.  
  61. // NFC Operation init.
  62. MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
  63. MFRC522::MIFARE_Key key;
  64.  
  65. void activateRec(MFRC522 mfrc522);
  66. void clearInt(MFRC522 mfrc522);
  67.  
  68. U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(  /* clock=*/ A5,   /* data=*/ A4, /* reset=*/ U8X8_PIN_NONE);   // OLEDs without Reset of the Display
  69.  
  70.  
  71. /**
  72.  * Initialize.
  73.  */
  74.  
  75. void setup() {
  76.   Serial.begin(115200); // Initialize serial communications with the PC
  77.   SPI.begin();          // Init SPI bus
  78.  
  79.   pinMode(TRIGGER_PIN, OUTPUT);    // Trigger Output
  80.   pinMode(ECHO_PIN, INPUT);        // Echo Input
  81.  
  82.   pinMode(BUZZ_PIN, OUTPUT);    // Buzzer Output
  83.   pinMode(LED, OUTPUT);    // LED Output
  84.  
  85.   mfrc522.PCD_Init(); // Init MFRC522 card
  86.  
  87.   /* setup the IRQ pin*/
  88.   pinMode(IRQ_PIN, INPUT_PULLUP);
  89.   Serial.println("1");
  90.  
  91.   /*
  92.    * Allow the ... irq to be propagated to the IRQ pin
  93.    * For test purposes propagate the IdleIrq and loAlert
  94.    */
  95.   regVal = 0xA0; //rx irq
  96.   mfrc522.PCD_WriteRegister(mfrc522.ComIEnReg, regVal);
  97.  
  98.   bNewInt = false; //interrupt flag
  99.  
  100.   /*Activate the interrupt*/
  101.   attachInterrupt(digitalPinToInterrupt(IRQ_PIN), readCard, FALLING);
  102.  
  103.   /* Clear distance sensor */
  104.   digitalWrite(TRIGGER_PIN, LOW);
  105.   delayMicroseconds(500);
  106. }
  107.  
  108. /**
  109.  * Main loop.
  110.  */
  111. void loop() {
  112.   delay(MEASURE_DELAY);
  113.   long distance = measure();
  114.  
  115.   digitalWrite(BUZZ_PIN, HIGH);
  116.  
  117.   //new read interrupt
  118.   if (bNewInt)
  119.   {
  120.       distStr = String(distance);
  121.    
  122.       u8x8.begin();
  123.       u8x8.setPowerSave(0);
  124.      
  125.       u8x8.setFont(u8x8_font_amstrad_cpc_extended_r);
  126.       u8x8.setCursor(0, 3);
  127.       u8x8.print(distance);
  128.       u8x8.print("mm");
  129.  
  130.       digitalWrite(LED, HIGH);
  131.  
  132.       dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  133.       Serial.println();
  134.       digitalWrite(BUZZ_PIN, LOW);
  135.       delay(100);
  136.       digitalWrite(BUZZ_PIN, HIGH);
  137.       delay(3000);
  138.  
  139.       digitalWrite(LED, LOW);
  140.  
  141.       clearInt(mfrc522);
  142.       mfrc522.PICC_HaltA();
  143.       bNewInt = false;
  144.  
  145.       u8x8.clearDisplay();
  146.   }
  147.  
  148.   // The receiving block needs regular retriggering (tell the tag it should transmit??)
  149.   // (mfrc522.PCD_WriteRegister(mfrc522.FIFODataReg,mfrc522.PICC_CMD_REQA);)
  150.   activateRec(mfrc522);
  151.   delay(100);
  152. }
  153.  
  154. /**
  155.  * Returns mean value of samples
  156.  */
  157. long measure(){
  158.  
  159.   long value = 0;
  160.  
  161.   long measureSum = 0;
  162.   for (int i = 0; i < MEASURE_SAMPLES; i++)
  163.   {
  164.     delay(MEASURE_SAMPLE_DELAY);
  165.     measureSum += singleMeasurement();
  166.   }
  167.  
  168.   value = (measureSum / MEASURE_SAMPLES)-offset;
  169.  
  170.  
  171.   if(value < 0){
  172.     return 0;
  173.   }
  174.   else{
  175.     return value;
  176.   }
  177. }
  178.  
  179. /**
  180.  *  Does a single measuremet
  181.  */
  182. long singleMeasurement()
  183. {
  184.   long duration = 0;
  185.   // Measure: Put up Trigger...
  186.   digitalWrite(TRIGGER_PIN, HIGH);
  187.   // ... wait for 11 µs ...
  188.   delayMicroseconds(11);
  189.   // ... put the trigger down ...
  190.   digitalWrite(TRIGGER_PIN, LOW);
  191.   // ... and wait for the echo ...
  192.   duration = pulseIn(ECHO_PIN, HIGH);
  193.   return (long) (((float) duration / USONIC_DIV) * 10.0);
  194. }
  195.  
  196. /**
  197.  * Helper routine to dump a byte array as hex values to Serial.
  198.  */
  199. void dump_byte_array(byte *buffer, byte bufferSize) {
  200.   for (byte i = 0; i < bufferSize; i++) {
  201.     Serial.print(buffer[i] < 0x10 ? " 0" : " ");
  202.     Serial.print(buffer[i], HEX);
  203.   }
  204. }
  205. /**
  206.  * MFRC522 interrupt serving routine
  207.  */
  208. void readCard() {
  209.   bNewInt = true;
  210. }
  211.  
  212. /*
  213.  * The function sending to the MFRC522 the needed commands to activate the reception
  214.  */
  215. void activateRec(MFRC522 mfrc522) {
  216.   mfrc522.PCD_WriteRegister(mfrc522.FIFODataReg, mfrc522.PICC_CMD_REQA);
  217.   mfrc522.PCD_WriteRegister(mfrc522.CommandReg, mfrc522.PCD_Transceive);
  218.   mfrc522.PCD_WriteRegister(mfrc522.BitFramingReg, 0x87);
  219. }
  220.  
  221. /*
  222.  * The function to clear the pending interrupt bits after interrupt serving routine
  223.  */
  224. void clearInt(MFRC522 mfrc522) {
  225.   mfrc522.PCD_WriteRegister(mfrc522.ComIrqReg, 0x7F);
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement