Genius Things
Published © CC BY-NC-SA

Contact-less Entry and Contact Tracing

This project is about creating an IR air remote that has an ID for contact tracing and using gestures for contact-less entry.

IntermediateFull instructions providedOver 1 day1,592
Contact-less Entry and Contact Tracing

Things used in this project

Hardware components

Jumper wires (generic)
Jumper wires (generic)
×12
TFT Touchscreen, 320x240
TFT Touchscreen, 320x240
×1
Arduino Mega 2560
Arduino Mega 2560
×1
ProtoCentral VL53L0X Laser ToF Sensor breakout board
ProtoCentral Electronics ProtoCentral VL53L0X Laser ToF Sensor breakout board
×1
IR receiver (generic)
×1
LED (generic)
LED (generic)
×1
IR transmitter (generic)
×1
SparkFun Triple Axis Accelerometer and Gyro Breakout - MPU-6050
SparkFun Triple Axis Accelerometer and Gyro Breakout - MPU-6050
×1
Resistor 220 ohm
Resistor 220 ohm
×2
Arduino Pro Mini 328 - 3.3V/8MHz
SparkFun Arduino Pro Mini 328 - 3.3V/8MHz
×1
General Purpose Transistor NPN
General Purpose Transistor NPN
×1
Breadboard (generic)
Breadboard (generic)
It can be transferred onto a PCB prototype board.
×1
Battery, 3.7 V
Battery, 3.7 V
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

IR Air Remote

IR Air Remote

Elevator Controller

Code

IR Air Remote

Arduino
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <IRLib.h>

IRsend My_Sender;

int buttonPin = 6;
int ledPin = 5;

Adafruit_MPU6050 mpu;

unsigned long firstPressedTime;
unsigned long lastFlashingTime;
bool flashingOn = false;

bool sensing = false;

bool firstPressed = false;
bool firstReleased = false;
bool secondPressed = false;
bool secondReleased = false;

int timeToWaitFor2 = 800;

unsigned long timeout = 60000;

unsigned long myID = 0xC9123456;
unsigned long finalFlag = 0xC9FFFFFF;

void sendCode(unsigned long code){
  My_Sender.send(NEC, code, 32);
  delay(15);  
  My_Sender.send(NEC, code, 32);
}

void resetStates(){
  firstPressed = false;
  secondPressed = false;
  
  firstReleased = false;
  secondReleased = false;

  flashingOn = false;
  sensing = false;
  digitalWrite(ledPin, HIGH);
}

void setup(void) {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);

  digitalWrite(ledPin, HIGH);

  while (!Serial) {
    delay(10); // will pause Zero, Leonardo, etc until serial console opens
  }

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }

  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);
  mpu.setGyroRange(MPU6050_RANGE_250_DEG);
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.println("");
  delay(100);
}

void loop() {
  if (sensing){
    unsigned long current = millis();
    
    if (firstPressedTime + timeout < current){
      Serial.println("Sensing timed out!");

      resetStates();
      return;
    }

    if (lastFlashingTime + 600 < current){
      if (flashingOn){
        //Serial.println("Flashing off");

        digitalWrite(ledPin, HIGH);
        flashingOn = false;
      }
      else{
        //Serial.println("Flashing on");
        
        digitalWrite(ledPin, LOW);
        flashingOn = true;
      }

      lastFlashingTime = millis();
      
    }

    if (digitalRead(buttonPin) == LOW){
      Serial.println("Stop sensing");
  
      sensing = false;
      firstPressed = false;
  
      sendCode(finalFlag);
      digitalWrite(ledPin, HIGH);
    }
  }

  if (!sensing & digitalRead(buttonPin) == HIGH & firstPressed & !firstReleased){
    firstReleased = true;
    
    Serial.println("Button released first time.");

  }

  if (!sensing & digitalRead(buttonPin) == HIGH & secondPressed & !secondReleased){
    Serial.println("Button released second time.");
  
    secondReleased = true;
  }
  
  if (!sensing & digitalRead(buttonPin) == HIGH & firstPressed & firstReleased & (firstPressedTime + timeToWaitFor2 < millis())){
    if (secondReleased) {
    //Signal double-click
      sendCode(0xC9E10000 + (unsigned long) 0xFF*256 + (unsigned long) 0xFF);
      Serial.println("Start sensing");
      digitalWrite(ledPin, LOW);
      flashingOn = false;
      lastFlashingTime = millis();
      delay(500);
      sendCode(myID);
      resetStates();
      sensing = true;
    }
    else {
      sendCode(myID);
      resetStates();
    }
  }

  //handling first time button pressed
  if (digitalRead(buttonPin) == LOW & !firstPressed){
    firstPressed = true;
    firstPressedTime = millis();
    digitalWrite(ledPin, LOW);
    Serial.println("Button pressed first time.");
    //sendCode(myID);
    
    
  }
  else if (digitalRead(buttonPin) == LOW & firstReleased & !sensing){
    Serial.println("Button pressed second time.");
    secondPressed = true; 
  }
  
  
  if (sensing){
    /* Get new sensor events with the readings */
  
  
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);
  
    float x = a.acceleration.x + 10;
  
    if (x < 0) {
      x = 0;
    }
  
    if (x > 20) {
      x = 20;
    }
  
    x = x * 255.0/20;
    
    float y = a.acceleration.y + 10;
  
    if (y < 0) {
      y = 0;
    }
  
    if (y > 20) {
      y = 20;
    }
  
    y = y * 255.0/20;
  
    float z = a.acceleration.z + 10;
  
    if (z < 0) {
      z = 0;
    }
  
    if (z > 20) {
      z = 20;
    }
  
    z = z*255.0/20;
  
    
    
    sendCode(0xC9E10000 + (unsigned long) x*256 + (unsigned long) y);
    Serial.print(a.acceleration.x);
    Serial.print(",");
    Serial.print(a.acceleration.y);
    Serial.print(",");
    Serial.print(a.acceleration.z);
    Serial.print(", ");
    Serial.print(x);
    Serial.print(",");
    Serial.print(y);
    Serial.print(",");
    Serial.print(z);
    Serial.println("");
  }
  delay(50);
}

Elevator Controller

Arduino
#include <stdint.h>
#include <TFTv2.h>
#include <SPI.h>
#include <SD.h>
#include <IRremote.h>
#include <ThreeWire.h>  
#include <RtcDS1302.h>

#include "Adafruit_VL53L0X.h"

ThreeWire myWire(32,30,34); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

Adafruit_VL53L0X lox = Adafruit_VL53L0X();

int RECV_PIN = 19;

char buff1[32];

char buff2[32];

char prevLabel1[3];

char label1[3];

char label2[3];

char label3[3];

char buff[32];


int DELAY_INTERVAL = 200;

IRrecv irrecv(RECV_PIN);
decode_results results;

unsigned long oldID = 0;

unsigned long prevID = 0;

unsigned long prevIDTime = 0;

unsigned long oldDistance = 0;

unsigned long prevLevelChangeTime = 0;

unsigned long lastIRDetected = 0;

unsigned long idleTime = 1600;

unsigned long currentID = 0;

unsigned long finalFlag = 0xc9ffffff;

unsigned long doubleFlag = 0xc9e1ffff;

unsigned long doubleFlagTime = 0;

char IDStr[11];

const int maximum = 100;

const int minimum = 5;

int prevMark = 0;

uint16_t measures[20];

int b_h = 1;
int b_t = 0;

int textx = 0, texts = 3;

//File myFile;

int unit_size = 3;

int oldLevel = (int)(maximum - minimum)/unit_size + 2;

int savedLevel = -1;

int sensitivity = 0.2 * 29 * 2;
const int pingPin = 16; // Trigger Pin of Ultrasonic Sensor
const int echoPin = 15; // Echo Pin of Ultrasonic Sensor

const int PIN_SD_CS = 4;  

bool drawingButton = false;

bool prompting = false;

unsigned long promptingTime = 0;

unsigned long promptingTimeout = 4000;

unsigned long lastTimeIRDetected = 0;

bool displayingSelection = false;

char buttonLetter[][12] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#"};

int highlightedButton = -1;

int digit1 = -1;

int digit2 = -1;

int digit3 = -1;


int prevDigit1 = -1;

int prevDigit2 = -1;

int prevDigit3 = -1;

unsigned long buttonHighlightedTime = 0;

bool hasHighlightedButton =  false;

void drawButton(int bn, unsigned int bc, unsigned int fc){
  drawButton(20 + (bn%3) * 80, 80 + ((int)bn/3) * 65, buttonLetter[bn], bc, fc);
}

void drawButton(int x, int y, char *s, unsigned int bc, unsigned int fc){
  Tft.fillRectangle(x, y, 40, 40, bc);
  Tft.drawString(s, x+7, y+5, 4, fc);
}

void drawButtons(){
  Tft.drawString(buff2, textx, 100, texts, BLACK);
  for (int i = 0; i < 12; i++){
     drawButton(i, WHITE, BLUE);
  }
}

void clearButtons(){
  for (int i = 0; i < 12; i++){
     drawButton(i, BLACK, BLACK);
  }
}
void inputSelected(){
  int level = 0;
    //this is going to level selected
    if (digit1 != 10){
      //the first digit is not zero
      level = level + (digit1 + 1) * 100;
    } 

    if (digit2 != 10){
      //the first digit is not zero
      level = level + (digit2 + 1) * 10;
    }
      if (digit3 != 10){
      //the first digit is not zero
      level = level + (digit3 + 1);
    }

  if (level == 0){
    return;
  }
        
    clearButtons();
    levelSelected(level);
    
    digit1 = -1;
    digit2 = -1;
    digit3 = -1;
          
}

void levelSelected(int level){
  char t[32];

  if (level == 0){
    return;
  }
  
  String s = String("Going to level ") + String(level);
  s.toCharArray(t, s.length() + 1);
   
  //Tft.fillScreen(MIN_X, MAX_X, MIN_Y, MAX_Y, GREEN);
  //clearButtons();
  Tft.drawString(t,5,155,2, WHITE);
  delay(2000);
  //Tft.fillScreen();
  Tft.drawString(t,5,155,2, BLACK);
  //drawButtons();      
  saveLevelForID(IDStr, level);
  strcpy(IDStr, "Default");
  prevLevelChangeTime = millis(); 
}

void clearScreen(){
   clearButtons();
   digit1 = -1;
   digit2 = -1;
   digit3 = -1;
   updateInputBuffer();
   
   Tft.drawString(buff2, textx, 100, texts, BLACK);
   Tft.drawString(label1, 10, MAX_Y-30, 2, BLACK);
   Tft.drawString(label2, MAX_X/2, MAX_Y-30, 2, BLACK);
   Tft.drawString(label3, MAX_X-20, MAX_Y-30, 2, BLACK);
   Tft.drawVerticalLine(prevMark, MAX_Y - 15, 15, BLACK);
   
   for(int i = 0; i < 20; i++){
     Tft.drawHorizontalLine(MAX_X - 15, measures[i], 15, BLACK);
  }
  

          
}

int cmToLevel(int cm){
  int level = (int)(cm - minimum)/unit_size + 1;
  return level;
}

#define countof(a) (sizeof(a) / sizeof(a[0]))

void saveIDForTracing(char* ID){
  RtcDateTime  dt = Rtc.GetDateTime();

  char dateString[20];

    snprintf_P(dateString, 
            countof(dateString),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    
  if (strlen(ID) != 8){
    return;
  }

  char* fn = "tracing.csv";

  

  File tracing = SD.open(fn, FILE_WRITE);
  if (tracing) {
    Serial.println("Writing to file: ");
    Serial.println(fn);
    tracing.print(dateString);
    tracing.print(",");
    tracing.println(ID);
    Serial.print(dateString);
    Serial.print(",");
    Serial.println(ID);

    // close the file:
    tracing.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.print("error opening tracing file: ");
    Serial.println(fn);
  }
}

void displayTracingData(){
  File tracing = SD.open("tracing.csv");
  if (tracing) {
    Serial.println("tracing.csv");
    
    // read from the file until there's nothing else in it:
    while (tracing.available()) {
      Serial.write(tracing.read());
    }
    // close the file:
    tracing.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening tracing.csv");
  }
}


void saveLevelForID(char* ID, int level){
  if (strlen(ID) != 8){
     Serial.println("Error: ID size is wrong.");
     Serial.println(ID);


    return;
  }

  char fn[13];

  strcpy(fn, ID);
  strcat(fn, ".txt");

  if (SD.exists(fn)){
    SD.remove(fn);
  }

  File saveLevel = SD.open(fn, FILE_WRITE);
  if (saveLevel) {
    Serial.print("Writing to file: ");
    Serial.print(fn);
    saveLevel.println(level);
  // close the file:
    saveLevel.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.print("error opening file: ");
    Serial.println(fn);

  }
  
}

int getSavedLevel(char* ID){
  char fn[13];
  String level = "";
  
  strcpy(fn, ID);
  strcat(fn, ".txt");
   
  File myFile = SD.open(fn);
  if (myFile) {
    Serial.print("reading from file: ");
    Serial.println(fn);
    
    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      char c = myFile.read();

      if( c == '\n'){
        break;
      }

      level = level + c;
    }
    // close the file:
    myFile.close();

    
    
    return level.toInt();
  } else {
    // if the file didn't open, print an error:
    Serial.print("error opening file: ");
    Serial.println(fn);
    return -1;
  }
}

void updateInputBuffer(){
  if (digit1 == -1){
        if (prevDigit1 == -1){
          //do nothing
        }
        else {
          //to erase the old one
          //Tft.drawString(buttonLetter[prevDigit1], 80, 5, 4, BLACK);
          drawButton(80, 5, buttonLetter[prevDigit1], BLACK, BLACK);
          prevDigit1 = -1;

        }
    }
   else {
    if (prevDigit1 != -1 & prevDigit1 != digit1){
          //erase the old one
          //Tft.drawString(buttonLetter[prevDigit1], 80, 5, 4, BLACK);
          drawButton(80, 5, buttonLetter[prevDigit1], BLACK, BLACK);

          //draw the new one
          //Tft.drawString(buttonLetter[digit1], 80, 5, 4, BLUE);
          drawButton(80, 5, buttonLetter[digit1], WHITE, BLUE);

          //remember the new one.
          prevDigit1 = digit1;
        }
        else if (prevDigit1 != digit1){
          //draw the new one 
          
          drawButton(80, 5, buttonLetter[digit1], WHITE, BLUE);
          //remember the new one.
          prevDigit1 = digit1;
    }
   }
   
   if (digit2 == -1){
        if (prevDigit2 == -1){
          //do nothing
        }
        else {
          //to erase the old one
          //Tft.drawString(buttonLetter[prevDigit2], 110, 5, 4, BLACK);
          drawButton(110, 5, buttonLetter[prevDigit2], BLACK, BLACK);

          prevDigit2 = -1;

        }
    }
   else {
    if (prevDigit2 != -1 & prevDigit2 != digit2){
          //erase the old one
          //Tft.drawString(buttonLetter[prevDigit2], 110, 5, 4, BLACK);
          drawButton(110, 5, buttonLetter[prevDigit2], BLACK, BLACK);

          //draw the new one
          //Tft.drawString(buttonLetter[digit2], 110, 5, 4, BLUE);
          drawButton(110, 5, buttonLetter[digit2], WHITE, BLUE);
          //remember the new one.
          prevDigit2 = digit2;
        }
        else if (prevDigit2 != digit2) {
          //draw the new one
          //Tft.drawString(buttonLetter[digit2], 110, 5, 4, BLUE);
          drawButton(110, 5, buttonLetter[digit2], WHITE, BLUE);
          //remember the new one.
          prevDigit2 = digit2;
    }
   }

   if (digit3 == -1){
        if (prevDigit3 == -1){
          //do nothing
        }
        else {
          //to erase the old one
          //Tft.drawString(buttonLetter[prevDigit3], 140, 5, 4, BLACK);
          drawButton(140, 5, buttonLetter[prevDigit3], BLACK, BLACK);
          prevDigit3 = -1;

        }
    }
   else {
    if (prevDigit3 != -1 & prevDigit3 != digit3){
          //erase the old one
          //Tft.drawString(buttonLetter[prevDigit3], 140, 5, 4, BLACK);
          drawButton(140, 5, buttonLetter[prevDigit3], BLACK, BLACK);
          //draw the new one
          //Tft.drawString(buttonLetter[digit3], 140, 5, 4, BLUE);
          drawButton(140, 5, buttonLetter[digit3], WHITE, BLUE);
          //remember the new one.
          prevDigit3 = digit3;
        }
        else if (prevDigit3 != digit3){
          //draw the new one
          //Tft.drawString(buttonLetter[digit3], 140, 5, 4, BLUE);
          drawButton(140, 5, buttonLetter[digit3], WHITE, BLUE);
          //remember the new one.
          prevDigit3 = digit3;
    }
   }
}

void clearPrompting(){
  Tft.drawString(buff1, textx, 100, texts, BLACK);
          
  Tft.drawString(buff2, textx, 150, texts, BLACK);

}
void setup(){
  buff[0] = 0;
  
  strcpy(IDStr, "Default");
  
  Serial.begin(9600);
  pinMode(pingPin, OUTPUT);
  pinMode(echoPin, INPUT);
  strcpy(label1, "");
  strcpy(label2, "");
  strcpy(label3, "");
  irrecv.enableIRIn(); // Start the receiver

  for(int i = 0; i < 20; i++){
    measures[i] = 0;
  }
  
  Serial.println("Adafruit VL53L0X test");
  if (!lox.begin()) {
    Serial.println(F("Failed to boot VL53L0X"));
    while(1);
  }

    pinMode(PIN_SD_CS,OUTPUT);
    digitalWrite(PIN_SD_CS,HIGH);

    TFT_BL_ON;      // turn on the background light
    
    Tft.TFTinit();
    
    Sd2Card card;
    card.init(SPI_FULL_SPEED, PIN_SD_CS); 
    
    if(!SD.begin(PIN_SD_CS))              
    { 
        Serial.println("failed!");
        while(1);                               // init fail, die here
    }
    
  Serial.println("SD OK!");

  Rtc.Begin();

  //RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);

  if (!Rtc.IsDateTimeValid()) 
    {
        // Common Causes:
        //    1) first time you ran and the device wasn't running yet
        //    2) the battery on the device is low or even missing

        Serial.println("RTC lost confidence in the DateTime!");
    //    Rtc.SetDateTime(compiled);
    }

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }

}

void loop()

{

  long duration, inches, cm, mark;
   int level;

   int kx, ky;
   bool hasIRValue = false;

    
   unsigned long current = millis();

    if (prompting & promptingTime + promptingTimeout < current){
      Tft.drawString(buff1, textx, 100, texts, BLACK);
          
      Tft.drawString(buff2, textx, 150, texts, BLACK);

      prompting = false;
    }

   //Hover over a button has timed out for selection.
   if (highlightedButton != -1 & buttonHighlightedTime + idleTime < current){
      buttonHighlightedTime = current;
      drawButton(highlightedButton, WHITE, BLUE);
      //delay(1000);
             
      //button is selected
      if (highlightedButton == 9){
        //Erase input buffer
        digit1 = -1;
        digit2 = -1;
        digit3 = -1;
      }
      else if (highlightedButton == 11){
          inputSelected();
          buttonHighlightedTime = millis();
          highlightedButton = -1;
          //drawButtons();
      }
      else {
          digit1 = digit2;
          digit2 = digit3;
          digit3 = highlightedButton;
      }

      highlightedButton = -1;
      
   }

   //Update input buffer display
   updateInputBuffer();
   
  
   // Check IR input
   if (irrecv.decode(&results)) {
    if (results.value >= 0xC9000000 & results.value <= 0xC9FFFFFF ){
      lastTimeIRDetected = millis();
    
      Serial.print(results.value, HEX);
      Serial.print("  ");
      Serial.println(results.value, BIN);
    
      String o = String(results.value, HEX);

      //this is final flag
      if (results.value == finalFlag){
        Serial.println("Handling Final Flag.");
        inputSelected();
        buttonHighlightedTime = millis();
        highlightedButton = -1;
        delay(100);
        
        irrecv.resume(); // Receive the next value}
        return; 
      }

      if (results.value == doubleFlag){
        Serial.println("Handling double Flag.");

        doubleFlagTime = millis();

        if (prompting){
          clearPrompting();
        }
        
        prevID = 0;
        irrecv.resume(); // Receive the next value}
        return; 
      }
      if ((results.value > 0xc9000000 & results.value < 0xc9FFFFFF) & !(results.value > 0xc9e10000 & results.value < 0xc9e1FFFF)){
        //this is an ID code
        

        if (results.value == prevID & prevIDTime + 5000 > millis()){
          RtcDateTime  dt = Rtc.GetDateTime();

          char dateString[20];

          snprintf_P(dateString, 
            countof(dateString),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
  
          Serial.print("Recieved second ID at ");
          Serial.println(dateString);

          
          Tft.drawString(buff1, textx, 100, texts, BLACK);
          
          Tft.drawString(buff2, textx, 150, texts, BLACK);

          levelSelected(savedLevel);

          prompting = false;

          prevID = 0;
            
        }
        else {
          RtcDateTime  dt = Rtc.GetDateTime();

          char dateString[20];

          snprintf_P(dateString, 
            countof(dateString),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
  
          Serial.print("Recieved ID at ");
          Serial.println(dateString);
          
          currentID = results.value;
          String s = String(results.value, HEX);
          s.toCharArray(IDStr, 11);  
          saveIDForTracing(IDStr);

          if (doubleFlagTime + 3000 < millis()){
            savedLevel = getSavedLevel(IDStr);
          }
          else {
            savedLevel = -1;
          }

          Serial.print("Current ID: ");
          Serial.println(IDStr);

          if (savedLevel != -1){
            //promptUser(savedLevel);
            clearScreen();
            strcpy(buff1,"Press Button");
            
            strcpy(buff2, "To Go To Level:");
            char temp[11];
            String s = String(savedLevel);
            s.toCharArray(temp, 11);
            strcat(buff2, temp);
            textx = 5;
            texts = 2;
            prompting = true;
            promptingTime = millis();
            clearButtons();
            
            Tft.drawString(buff1, textx, 100, texts, WHITE);
          
            Tft.drawString(buff2, textx, 150, texts, WHITE);
          }
        }
        
        prevIDTime = millis();
        prevID = results.value;
      }
      
      if (results.value > 0xc9e10000 & results.value < 0xc9e1FFFF){
        if (prompting){
          clearScreen();
          prompting = false;
          drawButtons();
        }
    
      if (!drawingButton){
        drawButtons();
        drawingButton = true;
      }
      
        lastIRDetected = millis();
        unsigned long encoded = results.value - 0xc9e10000;
        unsigned long y = (unsigned long) encoded / 256;
        unsigned long x = encoded % 256;
        /*
        Serial.print("x = ");
        Serial.print(x);
        Serial.print(", y = ");
        Serial.print(y);
        Serial.println();
        */
        
        cm = map(x, 0, 255, 0, 80);

        duration = map(x, 0, 255, 0, 80 * 29 * 2);
        hasIRValue = true; 

        
        if (x < 115){
          x = 115;
        }
        else if (x > 175){
          x = 175;
        }

        x = 175 - x;

      if (y < 95){
          y = 95;
        }
        else if (y > 155){
          y = 155;
        }

        y = y - 95;


        

        ky = map(x, 0, 60, 0, 3);
        kx = map(y, 0, 60, 0, 2);

        int bi = ky*3 + kx;

         Serial.print("kx = ");
         Serial.print(kx);
         Serial.print(" kY = ");
         Serial.print(ky);
         Serial.print(" bi = ");
         Serial.println(bi);

         //
         if (highlightedButton != -1 & highlightedButton != bi){
          buttonHighlightedTime = millis();
           drawButton(highlightedButton, WHITE, BLUE);
           drawButton(bi, GREEN, YELLOW);
            highlightedButton = bi;
         }
         else if (highlightedButton == -1) {
          drawButton(bi, GREEN, YELLOW);
          buttonHighlightedTime = millis();
          highlightedButton = bi;
         }
           
           delay(10);
   
        irrecv.resume(); // Receive the next value} 
      }
      /*
      else {
          if (!drawingButton){
              o.toCharArray(buff, o.length() + 1);
              buff[o.length()+1] = 0;
              Tft.drawString(buff,60,220,3, WHITE);    
          }
          
          delay(200);
          
          irrecv.resume(); // Receive the next value} 
      
      }
      */
    }
    irrecv.resume(); // Receive the next value} 
          
      
    
   }

    if (!prompting & drawingButton & lastTimeIRDetected + idleTime < millis()){
      drawingButton = false;
      clearScreen();
    }

    if (!(drawingButton | prompting)) {      
         VL53L0X_RangingMeasurementData_t measure;
          
      //  Serial.print("Reading a measurement... ");
        lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!
      
        
        if (measure.RangeStatus != 4) {  // phase failures have incorrect data
          //Serial.print("Distance (mm): "); Serial.println(measure.RangeMilliMeter);
        } else {
         // Serial.println(" out of range ");
        }
      
  //      irrecv.resume(); // Receive the next value}
        
        measures[b_t] = map(measure.RangeMilliMeter, 0, 400, MIN_Y, MAX_Y);
        
        Tft.drawHorizontalLine(MAX_X - 15, measures[b_t], 15, RED);
        
        Tft.drawHorizontalLine(MAX_X - 15, measures[b_h], 15, BLACK);
         
        b_t++;
        b_h++;
      
        if (b_t == 15){
          b_t = 0;
        }
      
        if (b_h == 15){
          b_h = 0;
        }
        
        cm = measure.RangeMilliMeter/10;
      
        duration = measure.RangeMilliMeter * 29 * 2 / 10;

    }
    
   
   if (drawingButton | prompting){
    return;
   }
   
   if (cm <= maximum & cm >= minimum){
     level = cmToLevel(cm);
     String d = String(level);
         if (oldLevel == level){
          unsigned long currentTime = millis();
          if (prevLevelChangeTime + idleTime < currentTime & level < 48){
            Tft.drawString(buff2, textx, 100, texts, BLACK);
            prevLevelChangeTime = currentTime;
            levelSelected(level);
          }
   //       Tft.drawString(buff2, textx, 100, texts, WHITE);
      
          mark = map(duration, ((level-1)*unit_size + minimum)*2*29, ((level-1)*unit_size + minimum + unit_size)*2*29, MIN_X, MAX_X);
          //
          
          if (abs(mark - prevMark) > sensitivity){
              Tft.drawVerticalLine(prevMark, MAX_Y - 15, 15, BLACK);
             //   
              Tft.drawVerticalLine(mark, MAX_Y - 15, 15, GREEN);
             //
              prevMark = mark;
              delay(10);   
                
          }
          return; 
         }
         else {
          prevLevelChangeTime = millis(); 
          oldDistance = cm;
          oldLevel = level;
         }
         
     Tft.drawString(buff2, textx, 100, texts, BLACK);
     Tft.drawString(label1, 10, MAX_Y-30, 2, BLACK);
     Tft.drawString(label2, MAX_X/2, MAX_Y-30, 2, BLACK);
     Tft.drawString(label3, MAX_X-20, MAX_Y-30, 2, BLACK);

    
     d.toCharArray(buff2, d.length() + 1);
     strcpy(label2, buff2);
     Tft.drawString(label2, MAX_X/2, MAX_Y-30, 2, WHITE);

     d = String(level+1);
     d.toCharArray(label3, d.length() + 1);
     Tft.drawString(label3, MAX_X-20, MAX_Y-30, 2, WHITE);

     d = String(level-1);
     d.toCharArray(label1, d.length() + 1);
     
     Tft.drawString(label1, 10, MAX_Y-30, 2, WHITE);
     
     
     textx = MAX_X/2 - 60;
     texts = 18;

     if (strlen(buff2) == 2){
      textx = textx - 50;
     }

   }
   else if (lastIRDetected + idleTime < millis() & strcmp(buff2, "Not Detected") != 0){
    Tft.drawString(buff2, textx, 100, texts, BLACK);
    Tft.drawString(label1, 10, MAX_Y-30, 2, BLACK);
    Tft.drawString(label2, MAX_X/2, MAX_Y-30, 2, BLACK);
    Tft.drawString(label3, MAX_X-20, MAX_Y-30, 2, BLACK);

    strcpy(buff2, "Not Detected");
    textx = 5;
    cm = 101;
    level = 48;
    texts = 3;
   }
   
   
   mark = map(duration, ((level-1)*unit_size + minimum)*2*29, ((level-1)*unit_size + minimum + unit_size)*2*29, MIN_X, MAX_X);

   Tft.drawVerticalLine(prevMark, MAX_Y - 15, 15, BLACK);
      
   Tft.drawVerticalLine(mark, MAX_Y - 15, 15, GREEN);
   
   prevMark = mark;
    
   oldID = results.value;
   Tft.drawString(buff, 60, 220, 3, WHITE);

   if (!drawingButton){
       Tft.drawString(buff2, textx, 100, texts, WHITE);    
   }

   Tft.drawHorizontalLine(MIN_X, MAX_Y, MAX_X, RED);
   Tft.drawString(buff2, textx, 100, texts, WHITE);

   delay(100);
}

Credits

Genius Things

Genius Things

1 project • 0 followers

Comments