Current and voltage acquisition 6.25 kHz

// Data acquisition software for Non Intrusive Load Monitoring
// S. Houidi, F. Auger, D. Fourer, IREENA, 2018-2019
// improvements are welcome : send an email to francois.auger@univ-nantes.fr
//
//------------------------------------------------------------------------------
// Parse the DATE predefined macro to generate date defaults:
// Date Format: MMM DD YYYY (First D may be a space if <10)
//
#define BUILD_MONTH_JAN ((DATE[0] == 'J') && (DATE[1] == 'a')) ? 1 : 0
#define BUILD_MONTH_FEB (DATE[0] == 'F') ? 2 : 0
#define BUILD_MONTH_MAR ((DATE[0] == 'M') && (DATE[1] == 'a') && (DATE[2] == 'r')) ? 3 : 0
#define BUILD_MONTH_APR ((DATE[0] == 'A') && (DATE[1] == 'p')) ? 4 : 0
#define BUILD_MONTH_MAY ((DATE[0] == 'M') && (DATE[1] == 'a') && (DATE[2] == 'y')) ? 5 : 0
#define BUILD_MONTH_JUN ((DATE[0] == 'J') && (DATE[1] == 'u') && (DATE[2] == 'n')) ? 6 : 0
#define BUILD_MONTH_JUL ((DATE[0] == 'J') && (DATE[1] == 'u') && (DATE[2] == 'l')) ? 7 : 0
#define BUILD_MONTH_AUG ((DATE[0] == 'A') && (DATE[1] == 'u')) ? 8 : 0
#define BUILD_MONTH_SEP (DATE[0] == 'S') ? 9 : 0
#define BUILD_MONTH_OCT (DATE[0] == 'O') ? 10 : 0
#define BUILD_MONTH_NOV (DATE[0] == 'N') ? 11 : 0
#define BUILD_MONTH_DEC (DATE[0] == 'D') ? 12 : 0
#define BUILD_MONTH BUILD_MONTH_JAN | BUILD_MONTH_FEB | BUILD_MONTH_MAR |
BUILD_MONTH_APR | BUILD_MONTH_MAY | BUILD_MONTH_JUN |
BUILD_MONTH_JUL | BUILD_MONTH_AUG | BUILD_MONTH_SEP |
BUILD_MONTH_OCT | BUILD_MONTH_NOV | BUILD_MONTH_DEC
//
#define BUILD_DAY_0 ((DATE[4] == ' ') ? 0 : (DATE[4] - 0x30))
#define BUILD_DAY_1 (DATE[5] - 0x30)
#define BUILD_DAY ((BUILD_DAY_0 * 10) + BUILD_DAY_1)
//
#define BUILD_YEAR_SINCE_2000 (((DATE[9] - 0x30) * 10) + (DATE[10] - 0x30))

//------------------------------------------------------------------------------
// Parse the TIME predefined macro to generate time defaults:
// TIME Format: HH:MM:SS (First number of each is padded by 0 if <10)
//
#define BUILD_HOUR_0 ((TIME[0] == ' ') ? 0 : (TIME[0] - 0x30))
#define BUILD_HOUR_1 (TIME[1] - 0x30)
#define BUILD_HOUR ((BUILD_HOUR_0 * 10) + BUILD_HOUR_1)
//
#define BUILD_MINUTE_0 ((TIME[3] == ' ') ? 0 : (TIME[3] - 0x30))
#define BUILD_MINUTE_1 (TIME[4] - 0x30)
#define BUILD_MINUTE ((BUILD_MINUTE_0 * 10) + BUILD_MINUTE_1)
//
#define BUILD_SECOND_0 ((TIME[6] == ' ') ? 0 : (TIME[6] - 0x30))
#define BUILD_SECOND_1 (TIME[7] - 0x30)
#define BUILD_SECOND ((BUILD_SECOND_0 * 10) + BUILD_SECOND_1)
//------------------------------------------------------------------------------

#include <SPI.h>
#include <SD.h>
#include <Arduino.h>
#include <RTCZero.h>

#include <Bounce2.h>
// Include the Bounce2 library found here :
// GitHub - thomasfredericks/Bounce2: Debouncing library for Arduino and Wiring

#include "avdweb_SAMDtimer.h"
// SAMD21 Timer library for the SAM15x15 and Arduino Zero
// SAMD21 Timer
// SAMD21 Timer library for the Arduino Zero - Libraries - Arduino Forum

#include "Albert.h"
// Fast ADC library
// http://www.avdweb.nl/arduino/libraries/fast-10-bit-adc.html

Sd2Card card;

#define TRANSMISSIONSPEED 115200

#define BUTTON1_PIN 4
#define BUTTON2_PIN 5

#define AnalogPinU A1 // Analog Channel for voltage acquisition
#define AnalogPinI A2 // Analog Channel for current acquisition
#define BUFFSIZE 510 // 512/5=102, 102*2=204 acquisitions of current and voltage per block in the SD card
#define Te 160 // Aquisition period in ┬Ás : Fe= 6250 Hz

#define InformationBlockNumber 1

//#define MyDebug

#define NbrLines 20 // Number of Acquisition Table lines

//------------------------------------------------------------------------------
void ISR_acquisition(struct tc_module *const module_inst); // This is just a prototype
//------------------------------------------------------------------------------

boolean start_acq, success, WriteFlag[NbrLines], ErrorFlag, STOP, verbose, LedState = HIGH;

byte dataUI, dateByte1, dateByte2, dateByte3, dateByte4;
uint8_t NumAcquisition, Data[NbrLines][510], DataSD[510], InformationBlock[512];

int dataU, dataI, dataDebug = 0, dataU0_int, dataI0_int, dataU1_int, dataI1_int, LineIndex, SD_LineIndex, ColIndex, IndexInformationBlock, i;
int DigitU01_32, DigitU00_32, DigitI01_32, DigitI00_32, DigitU11_32, DigitU10_32, DigitI11_32, DigitI10_32;
int DigitU01_B, DigitU00_B, DigitI01_B, DigitI00_B, DigitU11_B, DigitU10_B, DigitI11_B, DigitI10_B;
int Year, Month, Day, Hours, Minutes, Seconds;

long NumberOfBlocks, BlockNumberR, BlockNumberW, LastBlockNumber, FirstBlockNumber;

char serInString[100]; // array that will hold the different bytes 100=100characters;
int serInIndex = 0, SizeOfSerInString; // index of serInString in which to insert the next incoming byte

unsigned long int Now, LastTime, HalfPeriod = 300 ;

char var = 'X';

Bounce debouncer1 = Bounce(); // Instantiate two Bounce objects
Bounce debouncer2 = Bounce();

RTCZero rtc;
SAMDtimer timer = SAMDtimer(3, ISR_acquisition, Te, 0); // ISR ISR_timer4, 1Hz (0.5s on, 0.5s off), timer is disabled

//------------------------------------------------------------------------------

void ISR_acquisition(struct tc_module *const module_inst) {
dataU = analogReadFast(AnalogPinU); dataI = analogReadFast(AnalogPinI);
//dataU = dataDebug; dataI = dataDebug + 1; dataDebug = (dataDebug + 2) % 1024;

if (ColIndex % 5 == 0) {
dataUI = dataU & 0B11;
dataUI = (dataUI << 2) | (dataI & 0B11);
Data[LineIndex][ColIndex] = dataU >> 2; ColIndex = ColIndex + 1;
Data[LineIndex][ColIndex] = dataI >> 2; ColIndex = ColIndex + 1;
} else if (ColIndex % 5 == 2) {
dataUI = (dataUI << 2) | (dataU & 0B11);
dataUI = (dataUI << 2) | (dataI & 0B11);
Data[LineIndex][ColIndex] = dataU >> 2; ColIndex = ColIndex + 1;
Data[LineIndex][ColIndex] = dataI >> 2; ColIndex = ColIndex + 1;
Data[LineIndex][ColIndex] = dataUI; ColIndex = ColIndex + 1;
}

if (ColIndex == BUFFSIZE) {
WriteFlag[LineIndex] = true;
ColIndex = 0;
if (LineIndex < (NbrLines - 1)) {
LineIndex = LineIndex + 1;
} else {
LineIndex = 0;
}
if (WriteFlag[LineIndex]) {
timer.enableInterrupt(0); Serial.println(F("ERROR ! next block not stored ")); Serial.println(LineIndex);
ErrorFlag = true;
//Serial.println(t2-t1);
}
}
}

//------------------------------------------------------------------------------

void setRtcFromCompilationTimeDate() {
// Set the time
rtc.setHours(BUILD_HOUR); rtc.setMinutes(BUILD_MINUTE); rtc.setSeconds(BUILD_SECOND);

// Set the date
rtc.setDay(BUILD_DAY); rtc.setMonth(BUILD_MONTH); rtc.setYear(BUILD_YEAR_SINCE_2000);
}

//------------------------------------------------------------------------------

void CodeDate()
{
int i, Day = rtc.getDay(), Month = rtc.getMonth(), Year = rtc.getYear(),
Hours = rtc.getHours(), Minutes = rtc.getMinutes(), Seconds = rtc.getSeconds();

dateByte1 = (Year << 2) | ((Month & 0b1100) >> 2);
dateByte2 = ((Month & 0b11) << 6) | ((Day & 0b11111) << 1) | ((Hours & 0b10000) >> 4);
dateByte3 = ((Hours & 0b1111) << 4) | ((Minutes & 0b111100) >> 2);
dateByte4 = ((Minutes & 0b11) << 6) | (Seconds & 0b111111);
#ifdef MyDebug
Serial.print("time stamp: ");
for (i = 7; i > 1; i = i - 1) {
Serial.print(bitRead(dateByte1, i));
}
Serial.print(" ");
Serial.print(bitRead(dateByte1, 1)); Serial.print(bitRead(dateByte1, 0));
Serial.print(bitRead(dateByte2, 7)); Serial.print(bitRead(dateByte2, 6)); Serial.print(" ");
for (i = 5; i > 0; i = i - 1) {
Serial.print(bitRead(dateByte2, i));
}
Serial.print(" ");
Serial.print(bitRead(dateByte2, 0));
for (i = 7; i > 3; i = i - 1) {
Serial.print(bitRead(dateByte3, i));
}
Serial.print(" ");
for (i = 3; i > 0; i = i - 1) {
Serial.print(bitRead(dateByte3, i));
}
Serial.print(bitRead(dateByte4, 7)); Serial.print(bitRead(dateByte4, 6)); Serial.print(" ");
for (i = 5; i > 0; i = i - 1) {
Serial.print(bitRead(dateByte4, i));
}
Serial.println();
#endif
}

//------------------------------------------------------------------------------

void DecodeDateAndLastBlock(int NumAcquisition) { /* Decode Date and Lastblock address */

IndexInformationBlock = (NumAcquisition - 1) * 8 + 1;
Year = InformationBlock[IndexInformationBlock ] >> 2;
Month = ((InformationBlock[IndexInformationBlock ] & 0B00000011) << 2) | ((InformationBlock[IndexInformationBlock + 1] & 0B11000000) >> 6);
Day = ((InformationBlock[IndexInformationBlock + 1] & 0B00111110) >> 1);
Hours = ((InformationBlock[IndexInformationBlock + 1] & 0B00000001) << 4) | ((InformationBlock[IndexInformationBlock + 2] & 0B11110000) >> 4);
Minutes = ((InformationBlock[IndexInformationBlock + 2] & 0B00001111) << 2) | ((InformationBlock[IndexInformationBlock + 3] & 0B11000000) >> 6);
Seconds = InformationBlock[IndexInformationBlock + 3] & 0B00111111;

LastBlockNumber = InformationBlock[IndexInformationBlock + 4];
LastBlockNumber = LastBlockNumber << 8 | InformationBlock[IndexInformationBlock + 5];
LastBlockNumber = LastBlockNumber << 8 | InformationBlock[IndexInformationBlock + 6];
LastBlockNumber = LastBlockNumber << 8 | InformationBlock[IndexInformationBlock + 7];

if (NumAcquisition == 1) {
FirstBlockNumber = 2;
} else {
FirstBlockNumber = InformationBlock[(NumAcquisition - 2) * 8 + 1 + 4];
FirstBlockNumber = FirstBlockNumber << 8 | InformationBlock[(NumAcquisition - 2) * 8 + 1 + 5];
FirstBlockNumber = FirstBlockNumber << 8 | InformationBlock[(NumAcquisition - 2) * 8 + 1 + 6];
FirstBlockNumber = FirstBlockNumber << 8 | InformationBlock[(NumAcquisition - 2) * 8 + 1 + 7];
FirstBlockNumber = FirstBlockNumber + 1;
}
}
//------------------------------------------------------------------------------

void SerialPrint32BasedDigit(int Digit) {
if (Digit < 10)
Serial.write(Digit + 48);
else
Serial.write(Digit + 55);
}
//------------------------------------------------------------------------------

void setup() {
Serial.begin(TRANSMISSIONSPEED);
//delay(7000);
pinMode(SDCARD_SS_PIN, OUTPUT);

#ifdef MyDebug
Serial.println(F("Application started"));
Serial.print("SDCARD_SS_PIN="); Serial.println(SDCARD_SS_PIN);
#endif
pinMode(LED_BUILTIN, OUTPUT);
card.init(SPI_FULL_SPEED, SDCARD_SS_PIN);

// pinMode(BUTTON1_PIN, INPUT_PULLUP);
// digitalWrite(BUTTON1_PIN, HIGH);
debouncer1.attach(BUTTON1_PIN, INPUT_PULLUP);
debouncer1.interval(5);

// pinMode(BUTTON2_PIN, INPUT_PULLUP);
// digitalWrite(BUTTON2_PIN, HIGH);
debouncer2.attach(BUTTON2_PIN, INPUT_PULLUP);
debouncer2.interval(5);
#ifdef MyDebug
Serial.println(F("Buttons initialized"));
#endif

rtc.begin();
setRtcFromCompilationTimeDate();
#ifdef MyDebug
Serial.println("RTC initialized");
#endif

success = card.readBlock(InformationBlockNumber, InformationBlock); //try to read block
#ifdef MyDebug
if (!success) {
Serial.println("Unable to read InformationBlock");
}
#endif

if (InformationBlock[0] == 0) {
BlockNumberW = 2;
} else {
IndexInformationBlock = (InformationBlock[0] - 1) * 8 + 5;
BlockNumberW = InformationBlock[IndexInformationBlock ];
BlockNumberW = BlockNumberW << 8 | InformationBlock[IndexInformationBlock + 1];
BlockNumberW = BlockNumberW << 8 | InformationBlock[IndexInformationBlock + 2];
BlockNumberW = BlockNumberW << 8 | InformationBlock[IndexInformationBlock + 3];
BlockNumberW = BlockNumberW + 1;
}

start_acq = false;

NumberOfBlocks = card.cardSize();
#ifdef MyDebug
Serial.print(InformationBlock[0]); Serial.println(" acquisition(s) already stored in the SD card");
Serial.print("First block number available = "); Serial.println(BlockNumberW);
Serial.print("Total number of blocks="); Serial.println(NumberOfBlocks);
Serial.println("System ready");
Serial.println("Press button 1 to start the acquisition and button 2 to display the acquired data");
#endif
}

//------------------------------------------------------------------------------

void loop() {
if (start_acq && WriteFlag[SD_LineIndex]) {
uint8_t (&temp)[BUFFSIZE] = Data[SD_LineIndex];
success = card.writeBlock(BlockNumberW, temp);
#ifdef MyDebug
if (!success) {
Serial.println("unable to write a data block");
}
#endif
WriteFlag[SD_LineIndex] = false ;
if (SD_LineIndex < (NbrLines - 1)) {
SD_LineIndex = SD_LineIndex + 1;
} else {
SD_LineIndex = 0 ;
}

if (BlockNumberW < NumberOfBlocks - 1) { // is SD card full ?
  BlockNumberW = BlockNumberW + 1;   // Serial.println(BlockNumberW);
} else {

#ifdef MyDebug
Serial.println("end of SD card reached, stopping acquisition ");
#endif
timer.enableInterrupt(0); // disable ISR_acquisition
LastBlockNumber = BlockNumberW;
InformationBlock[0] = InformationBlock[0] + 1;

  IndexInformationBlock = (InformationBlock[0] - 1) * 8 + 1;
  InformationBlock[IndexInformationBlock    ] = dateByte1;
  InformationBlock[IndexInformationBlock + 1] = dateByte2;
  InformationBlock[IndexInformationBlock + 2] = dateByte3;
  InformationBlock[IndexInformationBlock + 3] = dateByte4;

  InformationBlock[IndexInformationBlock + 4] = (LastBlockNumber >> 24) & 0xFF;
  InformationBlock[IndexInformationBlock + 5] = (LastBlockNumber >> 16) & 0xFF;
  InformationBlock[IndexInformationBlock + 6] = (LastBlockNumber >> 8)  & 0xFF;
  InformationBlock[IndexInformationBlock + 7] =  LastBlockNumber        & 0xFF;

  success = card.writeBlock(InformationBlockNumber, InformationBlock);

#ifdef MyDebug
if (!success) {
Serial.println("unable to update InformationBlock");
} else {
Serial.println("InformationBlock updated");
Serial.print("LastBlockNumber= "); Serial.println(LastBlockNumber);
}
#endif
} // End of case of full SD
if (ErrorFlag) {
timer.enableInterrupt(1); Serial.println("Reprise des acquisitions "); Serial.println(LineIndex);
ErrorFlag = !ErrorFlag;
}

} else if (debouncer1.update() && debouncer1.fell()) {
start_acq = !start_acq;
if (start_acq) { // start acquisition
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
#ifdef MyDebug
Serial.println("button 1 pressed, starting acquisition ");
#endif
CodeDate();
LineIndex = 0;
SD_LineIndex = 0;
ColIndex = 0;

  for (i = 0; i < NbrLines; i++) {
    WriteFlag[i] = false; // Initialize WriteFlag Table
  }

  timer.enableInterrupt(1); // enable ISR_acquisition
}
else
{ digitalWrite(LED_BUILTIN, LOW); // turn the LED off                             // stop acquisition
  timer.enableInterrupt(0); // disable ISR_acquisition

#ifdef MyDebug
Serial.println("button 1 pressed, stopping acquisition ");
#endif
LastBlockNumber = BlockNumberW - 1;
InformationBlock[0] = InformationBlock[0] + 1;

  IndexInformationBlock = (InformationBlock[0] - 1) * 8 + 1;
  InformationBlock[IndexInformationBlock    ] = dateByte1;
  InformationBlock[IndexInformationBlock + 1] = dateByte2;
  InformationBlock[IndexInformationBlock + 2] = dateByte3;
  InformationBlock[IndexInformationBlock + 3] = dateByte4;

  InformationBlock[IndexInformationBlock + 4] = (LastBlockNumber >> 24) & 0xFF;
  InformationBlock[IndexInformationBlock + 5] = (LastBlockNumber >> 16) & 0xFF;
  InformationBlock[IndexInformationBlock + 6] = (LastBlockNumber >> 8)  & 0xFF;
  InformationBlock[IndexInformationBlock + 7] =  LastBlockNumber        & 0xFF;

  success = card.writeBlock(InformationBlockNumber, InformationBlock);

#ifdef MyDebug
if (!success) {
Serial.println("unable to update InformationBlock");
} else {
Serial.println("InformationBlock updated");
Serial.print("LastBlockNumber= "); Serial.println(LastBlockNumber);
}
#endif
}
} else if ( debouncer2.update() && debouncer2.fell()) {
Serial.println(F("Button pressed : dialog started"));
Serial.println(F("Press H for Help"));
STOP = false; verbose = true; LastTime = millis(); digitalWrite(LED_BUILTIN, LedState); var = 'D';
do {
Now = millis(); if (Now - LastTime > HalfPeriod) {
LedState = !LedState;
digitalWrite(LED_BUILTIN, LedState);
LastTime = Now;
}
if (Serial.available()) {
serInIndex = 0;
while (Serial.available()) {
serInString[serInIndex] = toupper(Serial.read());
serInIndex++;
}
SizeOfSerInString = serInIndex;
if (serInString[0] == 'H') {
Serial.println(F("Dialog session"));
Serial.println(F("Please enter: "));
Serial.println(F("I to get information on acquisitions"));
Serial.println(F("F followed by the block number you wish to read"));
Serial.println(F("F followed by the first block number and L followed by the last block number to read the blocks"));
Serial.println(F("T to select transmission mode. +'B' Binary, +'D' Decimal, +'X' Base 32"));
Serial.println(F("R to remove the SD card content"));
Serial.println(F("E to leave the Dialog session"));
} else if (serInString[0] == 'I') {
if (verbose) {
Serial.print(F("Total Number of Acquisitions "));
}
Serial.println(InformationBlock[0]);
for (NumAcquisition = 1; NumAcquisition <= InformationBlock[0]; NumAcquisition++) {
DecodeDateAndLastBlock(NumAcquisition);
if (verbose) {
Serial.print("NumAcquisition = ");
Serial.print(NumAcquisition);
Serial.print(" ");
Serial.print("Date: "); Serial.print(Day); Serial.print("/"); Serial.print(Month); Serial.print("/"); Serial.print(Year); Serial.print(" ");
Serial.print("Time: "); Serial.print(Hours); Serial.print(":"); Serial.print(Minutes); Serial.print(":"); Serial.print(Seconds);
Serial.print(" First Block = ");
}
Serial.print(FirstBlockNumber);
if (verbose) {
Serial.print(" Last Block = ");
}
else
{
Serial.println();
}
Serial.println(LastBlockNumber);
}
if (verbose) {
Serial.print(100.0 * LastBlockNumber / NumberOfBlocks);
Serial.println(" % of the SD card used");
}
} else if (serInString[0] == 'E') {
digitalWrite(LED_BUILTIN, LOW);
Serial.println(F("End of Dialog Session")); STOP = true;
Serial.println(F("Press the button again to open a new Dialog session"));

    } else if (serInString[0] == 'T') {
      if (serInString[1] == 'D')
      {
        var = 'D';
      }
      else
      {
        if (serInString[1] == 'B')
        {
          var = 'B';
        }
        else if (serInString[1] == 'X')
        {
          var = 'X';
        }
      }
    }
    else if (serInString[0] == 'F') {
      FirstBlockNumber = 0;
      serInIndex = 1;
      while ((serInIndex < SizeOfSerInString) && (serInString[serInIndex] != 'L'))
      {
        FirstBlockNumber = FirstBlockNumber * 10 + (serInString[serInIndex] - 48);
        serInIndex += 1;
      }
      if ((serInIndex < SizeOfSerInString) && (serInString[serInIndex] == 'L')) {
        serInIndex += 1;
        LastBlockNumber = 0;
        while (serInIndex < SizeOfSerInString) {
          LastBlockNumber = LastBlockNumber * 10 + (serInString[serInIndex] - 48); serInIndex += 1;
        }
      } else {
        LastBlockNumber = FirstBlockNumber;
      }
      Serial.print("Type of transmission chosen: "); Serial.print(var); Serial.println(" ");
      Serial.print("F="); Serial.print(FirstBlockNumber); Serial.print(", L="); Serial.println(LastBlockNumber);

      for (BlockNumberR = FirstBlockNumber; BlockNumberR <= LastBlockNumber; BlockNumberR += 1) {
        if (!card.readBlock(BlockNumberR, DataSD)) { //try to read block
          Serial.println(F("Unable to read a data block"));
        } else {
          for (ColIndex = 0; ColIndex < BUFFSIZE; ) {
            byte dataU0 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
            byte dataI0 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
            byte dataU1 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
            byte dataI1 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
            byte dataIU = DataSD[ColIndex]; ColIndex = ColIndex + 1;
            dataU0_int  = (dataU0 << 2)  | ((dataIU & 0B11000000) >> 6) ;
            dataI0_int  = (dataI0 << 2 ) | ((dataIU & 0B00110000) >> 4);
            dataU1_int  = (dataU1 << 2)  | ((dataIU & 0B00001100) >> 2) ;
            dataI1_int  = (dataI1 << 2 ) | ((dataIU & 0B00000011));

            if (var == 'B') {
              //Serial.write(dataU0_int, 2); Serial.write(dataI0_int, 2);
              //Serial.write(dataU1_int, 2); Serial.write(dataI1_int, 2);
              //Serial.write((byte*)&dataU0_int, 2); Serial.write((byte*)&dataI0_int, 2);
              //Serial.write((byte*)&dataU1_int, 2); Serial.write((byte*)&dataI1_int, 2);
              
              Serial.write(dataU0);
              Serial.write(dataI0);
              Serial.write(dataU1);
              Serial.write(dataI1);
              Serial.write(dataIU);
            }
            else if (var == 'X') {

              DigitU01_32 = dataU0_int / 32;
              if (DigitU01_32 > 0)
                SerialPrint32BasedDigit(DigitU01_32);
              DigitU00_32 = dataU0_int % 32; SerialPrint32BasedDigit(DigitU00_32); Serial.print(" ");

              DigitI01_32 = dataI0_int / 32;
              if (DigitI01_32 > 0)
                SerialPrint32BasedDigit(DigitI01_32);
              DigitI00_32 = dataI0_int % 32; SerialPrint32BasedDigit(DigitI00_32); Serial.print(" ");

              DigitU11_32 = dataU1_int / 32;
              if (DigitU11_32 > 0)
                SerialPrint32BasedDigit(DigitU11_32);
              DigitU10_32 = dataU1_int % 32; SerialPrint32BasedDigit(DigitU10_32); Serial.print(" ");

              DigitI11_32 = dataI1_int / 32;
              if (DigitI11_32 > 0)
                SerialPrint32BasedDigit(DigitI11_32);
              DigitI10_32 = dataI1_int % 32; SerialPrint32BasedDigit(DigitI10_32); Serial.print(" ");
            }
            else if (var == 'D') {
              Serial.print(dataU0_int); Serial.print(" "); Serial.print(dataI0_int); Serial.print(" ");
              Serial.print(dataU1_int); Serial.print(" "); Serial.print(dataI1_int); Serial.print(" ");
            }
          }
          Serial.println();

        }
        if (debouncer2.update() && debouncer2.fell()) {
          BlockNumberR = LastBlockNumber + 1;
        } else {
          Now = millis(); if (Now - LastTime > HalfPeriod) {
            LedState = !LedState;
            digitalWrite(LED_BUILTIN, LedState);
            LastTime = Now;
          }
        }
      }
    } else if (serInString[0] == 'V') {
      verbose = !verbose;
    } else if (serInString[0] == 'R') {
      for (IndexInformationBlock = 0; IndexInformationBlock < 256; IndexInformationBlock++) {
        InformationBlock[IndexInformationBlock] = 0;
      }
      if (!card.writeBlock(InformationBlockNumber, InformationBlock)) {
        Serial.println("unable to initialize InformationBlock");
      } else {
        Serial.println("InformationBlock initialized");
      }
    }
  }
  if ( debouncer2.update() && debouncer2.fell()) {
    Serial.println(F("End of Dialog Session")); STOP = true;
    Serial.println(F("Press the button again to open a new Dialog session"));
  }
} while (!STOP);

}
}

What about it?

That is a lot of code but it is useless at this point. What is it? What does it do? You might explain your project a bit and what is or is not working. Posting a schematic helps explain the hardware. It is not worth my time to try and figure this out without a reasonable amount of information.