Smart DoorBell

Author: Adriana-Iuliana Boncu

Master: AAC2

1. Project Objective

The objective of this paper is to create an intelligent doorbell system. This system can be divided into two subsystems, one that takes care of capturing images and classifying them according to known faces, and the second, upon receiving the command from the first system to activate a motor to open the door and also to have the possibility to ring the bell by pressing a button.

2. Hardware used

Door Opening System

  • 28BYJ-48 5V Stepper Motor
  • Driver ULN2003
  • Buzzer
  • Button
  • 10K resistor
  • ESP-WROOM-32

Video Capturing System:

  • Raspberry Pi 4 Model B/2GB
  • USB Camera

3. Systems hardware schematics

1. Door Opening System

For the automatic door opener I chose to use an ESP-WROOM-32. This is a module with which a wide variety of applications can be realized, from low-power sensors to the most demanding tasks, such as voice encoding, music streaming and P3 decoding. The basis of this module is the ESP32-D0EDQ6 chip. This chip is designed to be scalable and adaptive. It contains two CPUs that can be controlled individually, and the clock frequency can be adjusted in the range (80 MHz;240 MHz). The user can turn off the CPU and use the coprocessor to monitor the occurrence of changes, consuming fewer resources.

Due to the fact that it integrates Bluetooth, Bluetooth LE and Wi-Fi ensures the possibility of many applications. With the help of the WI-FI module, whose specifications are specified in Table 1, which can provide a direct connection to the Internet, the ESP32 will be able to communicate with the Raspberry Pi board to receive commands for the automatic opening and closing of the door.

The ESP32 also takes care of driving the stepper motor that allows the door to be opened and the operation of a doorbell at the push of a button. The wiring diagram with all components included can be found in fallowing Figure.

 Door Bell 
System

As can be seen in figure, the stepper motor driver is connected to pins D13,D12,D14,D27 (IN1,IN2,IN3,IN4-stepper driver pins in order), the button is connected to the pin D34, and the buzzer is connected to pin D32.

2. Video Capturing System

For this system I used a web camera and the Raspberry Pi 4 platform, as can be seen in the figure below.

 Video 
Capturing System

Since the two systems communicate through the two UDP & TCP protocols, I connected the platform to the Internet via an ethernet cable. Also, to have a preview of the camera, I connected a display through one of the two micro HDMI ports.

Implementation of the solution

Secure Connection

In order to have a secure connection, we followed the example discussed in this paper that combines two communication protocols TCP and UDP, creating 5 layers of security for sending the command. These layers are: Encryption, Compression, Key generation, Browsing data and Combination of UDP and TCP

1. Encryption & Decryption

For data encryption, I chose to use the Diffie-Hellman algorithm with which a secret key can be established that is unknown only to the one who sends the command and the one who receives it.

 Diffie
Hellman

As can be seen in figure, this algorithm is carried out in several steps. To begin with, each device knows two shared keys. Each of these devices randomly generates an integer with which it performs the mathematical calculation presented in point 3, obtaining a result. This result is sent using the TCP communication protocol between the devices. With the help of the information available up to this moment, the operation from point 4 is carried out, which will result in the common key of those devices.

With the help of this key, the “open” command is encrypted with the help of the Caesar cipher. Caesar's cipher is also called displacement cipher because with the help of an integer and the alphabet each character is replaced by another. In the girl's case, with the help of the previously obtained key, all characters will be replaced by the 9th letter of the alphabet from the position of the letter in question.

2. Compression & Decompression

In this level, several calculations are made. First, the string is written in ascii, obtaining values from which the value 97 is subtracted, calculating two vectors that represent the mean and the difference. The values from these two vectors are written in binary and will be passed through the next security layer.

3. Key generation

On the side of the device that sends the command, the key is generated that will be sent using the UDP protocol. The key is generated from the mean and difference vectors calculated upon compression.

4. Browsing data

The next level refers to how the data is traversed. For example, if we have a string of numbers from 1 to 10, it can be read as in the example in the figure.  Browsing
Data

5. Combination of UDP and TCP

Implementation

1. Door Opening System

All the security levels together with the functionalities for the motor, button and buzzer were implemented and written in the following code that was uploaded to the ESP32 using the Arduino IDE. It should be mentioned that the reverse of the security actions are carried out at the level of the ESP because the information is encrypted at the level of the Raspberry Pi.

#include <WiFi.h>
#include<stdio.h>
#include<math.h>
#include <string>
#include <cstring>
#include <WiFiUdp.h>
 
// this will assign the name PushButton to pin numer 15
const int PushButton = 34;
// Pin connected to buzzer
int speakerPin = 32;
// caracteristicile tonului folosit la sonerie
const int length = 32; // numarul de note piesa
const char * note = "ggagsed deggsgg ggagsed deggsgg ";
const int beats[]= {2,2,1,1,1,1,4,2,2,2,2,2,2,4,2,2,2,2,1,1,1,1,4,2,2,2,2,2,2,4,2,2,3,1,1,1,1};
const int tempo =150;
 
// definire pini pentru motorul de deschidere
#define IN1 13
#define IN2 12
#define IN3 14
#define IN4 27
#define FULL_ROTATION 1270
// faze ale motorului 
const int phases1[] = {0, 0, 0, 0, 0, 1, 1, 1};
const int phases2[] = {0, 0, 0, 1, 1, 1, 0, 0};
const int phases3[] = {0, 1, 1, 1, 0, 0, 0, 0};
const int phases4[] = {1, 1, 0, 0, 0, 0, 0, 1};
 
int Phase = 0;
int Speed = 100; //MUST BE 1 – 100
 
const char* ssid = "330";
const char* password = "pandapanda";
char packetBuffer[255]; //buffer pentru a tine datele ce sunt primite
 
 
// portul pentru trimitere data UDP
const int udpPort = 1234;
 
//instantiere UDP
WiFiUDP Udp;
WiFiServer server(80);
 
time_t start_criptare, end_criptare, start_decompresie, end_decompresie, start_parcurgere, end_parcurgere, start_generare_cheie, end_generare_cheie, start_TCP, end_TCP, start_UDP, end_UDP;
 
void playTone(int tone, int duration)
{
 for (long i = 0; i < duration * 1000L; i += tone * 2)
 {
 digitalWrite(speakerPin, HIGH);
 delayMicroseconds(tone);
 digitalWrite(speakerPin, LOW);
 delayMicroseconds(tone);
 }
}
void playNote(char note, int duration)
{
 const char names[] = { 'c', 'd', 'e', 'f', 's', 'g', 'a', 'v', 'b', 'C', 'D', 'E' }; // note
 const int tones[] = { 1915, 1700, 1519, 1432, 1352, 1275, 1136, 1073, 1014, 956, 852, 758 };
// frecvente
 for (int i = 0; i < 12; i++)
 {
 if (names[i] == note) playTone(tones[i], duration);
 } 
}
 
void descriptare_ceaser(char message[], int key){
  char ch;
  for(int i = 0; message[i] != '\0'; ++i){
    ch = message[i];
    if(ch >= 'a' && ch <= 'z'){
    ch = ch - key;
    if(ch < 'a'){
    ch = ch + 'z' - 'a' + 1;
    }
    message[i] = ch;
    }
    else if(ch >= 'A' && ch <= 'Z'){
    ch = ch - key;
      if(ch < 'A'){
      ch = ch + 'Z' - 'A' + 1;
      }
    message[i] = ch;
    }
  } 
}
 
int binaryToDecimal(int n)
{
    int num = n;
    int dec_value = 0;
    int base = 1;
    int temp = num;
    while (temp) {
        int last_digit = temp % 10;
        temp = temp / 10;
        dec_value += last_digit * base;
        base = base * 2;
    }
    return dec_value;
}
 
int * rezolvare_sisteme(int a[],int dif[]){
 
    int determinant = 2;
    static int solutii[8];
    for(int k=0, i=0 ;k<8;k=k+2,i=i+1)
    {
      solutii[k] = (dif[i]+a[i])/determinant;
      solutii[k+1] = (a[i]-dif[i])/determinant;
    }
 
  return solutii;
}
int * restaurare_cheie_proba(int s[2][17]){
 
  static int key[34];
  int k=0;    
  for(k=0;k<34-1;k=k+2){
    key[k]=s[0][k/2];
    key[k+1]=s[1][k/2];
  }
 
  return key;
}
int * restaurare_cheie(int s[]){
 
  static int * key;
  static int sir1[2][17];
  int k=0,j=0;    
  for(k=0,j=0;k<17;k++,j++){
    sir1[0][k] = s[k];
    sir1[1][k] = s[k+17];
  }
  key = restaurare_cheie_proba(sir1);
  return key;
}
 
int decriptare_dif(int diff_b_com){
  int dec_diff_b_com;
  if(diff_b_com > 100000){
  dec_diff_b_com=binaryToDecimal(diff_b_com-100000);
  dec_diff_b_com=-dec_diff_b_com;
  } 
  else {
    dec_diff_b_com=binaryToDecimal(diff_b_com);
  }
  return dec_diff_b_com;
}
 
char * determinare_comanda (int key[], int med[]){
  int ka=0,kb=0;
  int diff_b_com0=0,diff_b_com1=0,diff_b_com2=0,diff_b_com3=0;
  int medie0=0,medie1=0,medie2=0,medie3=0;
      start_generare_cheie=micros();
  for(int g=0;g<24;g++){
 
        if(g < 6)
      medie0=medie0*10 + med[g];
        if(g >= 6 & g < 12)
      medie1=medie1*10 + med[g];
        if(g >= 12 && g < 18)
      medie2=medie2*10 + med[g];
        if(g >= 18 && g < 24)
      medie3=medie3*10 + med[g];
    }
 
  for(int k=0;k<34;k++){
    if(k < 6)
      diff_b_com0=diff_b_com0*10 + key[k];
      if((k>=6 && k<10) || (k >=16 && k < 17 ))
        ka=ka*10+key[k];
      if(k>=10 && k<16)
        diff_b_com1 =diff_b_com1*10+ key[k];
      if((k>=17 && k<20) || (k>=26 && k<28 ))
        kb=kb*10+key[k];
      if(k>=20 && k<26)
        diff_b_com2 = diff_b_com2*10+key[k];
    if(k>=28 && k<34)
        diff_b_com3 = diff_b_com3*10 + key[k];  
  } 
    end_generare_cheie=micros();
    start_decompresie=micros();
   //decriptare
  int ka_dec = binaryToDecimal(ka);
  int kb_dec = binaryToDecimal(kb);
 
 
  if (ka_dec != 1 || kb_dec != 7){
    Serial.print("Chei nepotrivite! Utilizator neidentificat!");
    return "Null";
    }
  int dec_diff_b_com0 = decriptare_dif(diff_b_com0);
  int dec_diff_b_com1 = decriptare_dif(diff_b_com1);
  int dec_diff_b_com2 = decriptare_dif(diff_b_com2);
  int dec_diff_b_com3 = decriptare_dif(diff_b_com3);
 
 
  int m0 = binaryToDecimal(medie0);
  int m1 = binaryToDecimal(medie1);
  int m2 = binaryToDecimal(medie2);
  int m3 = binaryToDecimal(medie3);
 
  int medie[4]={2*m0,2*m1,2*m2,2*m3};
  int diferente[4]={dec_diff_b_com0,dec_diff_b_com1,dec_diff_b_com2,dec_diff_b_com3};
 
  static char comanda_finala[9];
  int * comanda = rezolvare_sisteme(medie,diferente);
 
  for(int j=0; j<8; j++){
    char c=(char)(comanda[j]+97); //revenire la alfabet conform cod ascii
    comanda_finala[j] = c ;
  }   
  comanda_finala[8]='\0';
  end_decompresie=micros();
  return comanda_finala;
}
 
//functie pentru returnarea valori a ^ b mod P
int power(int a,int b,int P)
{
    if (b == 1)
        return a;
 
    else
        return (((int)pow(a, b)) % P);
}
 
void IncrementPhase(int rotationDirection){
Phase += 8;
Phase += rotationDirection;
Phase %= 8;
}
 
 
void stepper(int count){
int rotationDirection = count < 1 ? -1 : 1;
count *= rotationDirection;
 
  for (int x = 0; x < count; x++)
  {
 
  digitalWrite(IN1, phases1[Phase]);
  digitalWrite(IN2, phases2[Phase]);
  digitalWrite(IN3, phases3[Phase]);
  digitalWrite(IN4, phases4[Phase]);
 
  IncrementPhase(rotationDirection);
  delay(100/Speed);
  }  
}
    int C_cunoscut = 23;
    int S_cunoscut = 9;
 
    int S_secret = rand() % 10 + 1; //valoarea secreta din server
 
void setup()
{
    Serial.begin(115200);
    delay(1000);
 
    // We start by connecting to a WiFi network
 
    Serial.println();
    Serial.println();
    Serial.print("Se conecteaza la ");
    Serial.println(ssid);
 
    WiFi.begin(ssid, password);
 
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
 
    Serial.println("");
    Serial.println("WiFi conectat.");
    Serial.println("Adresa IP : ");
    Serial.println(WiFi.localIP());
 
    server.begin();
 
    Serial.println("Valoarea aleasa de client cunoscuta este: ");
    Serial.println(C_cunoscut);
    Serial.println("Valoarea aleasa de server cunoscuta este: ");
    Serial.println(S_cunoscut);
 
    // Initializeaza udp-ul 
    Udp.begin(udpPort);
 
 
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
 
    // This statement will declare pin 15 as digital input 
    pinMode(PushButton, INPUT);
 
    // Defines the Buzzer pin as output 
    pinMode(speakerPin,OUTPUT);  
}
char * returnare_comanda_comunicatieUDP(int packetSize){
    int  key_neformata[58];
    int * key;
    int medie[24];
    static char * comanda;
    Serial.print("Pachet primit de dimensiunea ");
    Serial.println(packetSize);
    Serial.print("De la ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());
 
    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.println("Continut primit:");
    Serial.println(packetBuffer);
 
    String s = (String) packetBuffer; 
    for(int i=0;i<34;i++){
     key_neformata[i] = (int)(s[i]-48);
    }
    for(int i=34;i<58;i++){
     medie[i-34] = (int)(s[i]-48);
    }
    start_parcurgere=micros();
    key = restaurare_cheie(key_neformata);
    end_parcurgere=micros();
 
    Serial.println("Comanda:" );
      comanda = determinare_comanda(key,medie);
 
  return comanda;
}
 
void afisare_timpi(){
      double time_taken_criptare = double(end_criptare - start_criptare);
      double time_taken_decompresie = double(end_decompresie - start_decompresie);
      double time_taken_parcurgere = double(end_parcurgere - start_parcurgere);
      double time_taken_gen_cheie = double(end_generare_cheie - start_generare_cheie);
      double time_taken_TCP = double(end_TCP - start_TCP);
      double time_taken_UDP = double(end_UDP - start_UDP);
 
      Serial.print("----- Timp decriptare: " );
      Serial.println(time_taken_criptare);
      Serial.print("----- Timp decompresie: " );
      Serial.println(time_taken_decompresie);
      Serial.print("----- Timp parcurgere: " );
      Serial.println(time_taken_parcurgere);
      Serial.print("----- Timp generare cheie: " );
      Serial.println(time_taken_gen_cheie);
      Serial.print("----- Timp TCP: " );
      Serial.println(time_taken_TCP);
      Serial.print("----- Timp UDP: " );
      Serial.println(time_taken_UDP);
}
int k_secreta_server;
void loop(){
  char * comanda;
  int ka_kb;
  // Daca este valabil se citeste un pachet
  int packetSize = Udp.parsePacket();
 
  if (packetSize) {
      start_UDP=micros();
      comanda = (char *)returnare_comanda_comunicatieUDP(packetSize);
      end_UDP=micros();
 
      start_criptare=micros();
      descriptare_ceaser(comanda, k_secreta_server);
      end_criptare=micros();
 
     Serial.print("Comanda");
     for(int j=0; j<8; j++){
      Serial.print(comanda[j]);
  }
    Serial.println();
      char corect[] = {'d','e','s','c','h','i','d','e','\0'}; 
 
      if( strcmp(comanda, corect) == 0)
    {
        Serial.println("equal");
        stepper(FULL_ROTATION);
          delay(3000);
        stepper(-FULL_ROTATION);
    }
    else  Serial.println("not equal");
    afisare_timpi();
  }
 
 //realizare conexiune TCP pentru calcularea unei chei cu algoritmul DH
 WiFiClient client = server.available();   // verifica daca apar clienti
      start_TCP=micros();
  if (client) {                             // daca este detectat un client
    Serial.println("Client nou.");           // print a message out the serial port
 
    while (client.connected()) {            // cat timp clientul este conectat
      if (client.available()) {             // daca clientul transmite date
        int x_client = (client.read());             // se citesc datele
        Serial.println("Valoarea clientului secreta (int): ");
        Serial.println(x_client);                   
        int x_server = power(S_cunoscut,S_secret,C_cunoscut);
        client.write(x_server); 
        k_secreta_server = power(x_client, S_secret, C_cunoscut);
        Serial.println("Cheia secreta este: ");
        Serial.println(k_secreta_server);
        ka_kb=k_secreta_server;
      }
        // inchide conexiunea
        client.stop();
    }
      Serial.println("Clientul s-a deconectat.");
  }
      end_TCP=micros();
 
  int Push_button_state = digitalRead(PushButton);  // in cazul apasarii butonului pentru sonerie va incepe soneria
   if (Push_button_state == HIGH){
    Serial.println(" ---- Buton apasat ---- ");
 
     for(int n = 0 ; n < 73; n++){
        playNote(note[n], beats[n] * tempo);  
         delay(tempo / 2);
         }
 
   }
 
  //Asteapta o secunda
  delay(1000);
}

2. Video Capturing System

First of all, after we have a functional Linux Raspberry Pi image, we must make sure that we have the necessary environment, for this we install the following with the help of a terminal:

$ sudo apt install python3.8
$ sudo apt-get -y install python3-pip
$ pip3 install opencv
$ pip3 install face_recognition

The software implementation on the Raspberry Pi was made in python and consists of two scripts.

1. Face recognition

In this script, the following is done: camera preview, face detection and calling the function to send the opening command to the ESP32.

#!/usr/bin/python3
import face_recognition
import cv2
import numpy as np
import os
import glob
from transmisie import *
 
 
# Get a reference to webcam #0 (the default one)
video_capture = cv2.VideoCapture(0)
 
#make array of sample pictures with encodings
known_face_encodings = []
known_face_names = []
dirname = os.path.dirname(__file__)
path = os.path.join(dirname, 'known_people/')
 
#make an array of all the saved jpg files' paths
list_of_files = [f for f in glob.glob(path+'*.jpg')]
#find number of known faces
number_files = len(list_of_files)
 
names = list_of_files.copy()
 
for i in range(number_files):
    globals()['image_{}'.format(i)] = face_recognition.load_image_file(list_of_files[i])
    globals()['image_encoding_{}'.format(i)] = face_recognition.face_encodings(globals()['image_{}'.format(i)])[0]
    known_face_encodings.append(globals()['image_encoding_{}'.format(i)])
 
    # Create array of known names
    names[i] = names[i].replace("known_people/", "")  
    known_face_names.append(names[i])
 
# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
 
while True:
    # Grab a single frame of video
    ret, frame = video_capture.read()
 
    # Resize frame of video to 1/4 size for faster face recognition processing
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
 
    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    rgb_small_frame = small_frame[:, :, ::-1]
 
    # Only process every other frame of video to save time
    if process_this_frame:
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
 
        face_names = []
        for face_encoding in face_encodings:
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            name = "Unknown"
 
            # # If a match was found in known_face_encodings, just use the first one.
            # if True in matches:
            #     first_match_index = matches.index(True)
            #     name = known_face_names[first_match_index]
 
            # Or instead, use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]
 
            face_names.append(name)
 
    process_this_frame = not process_this_frame
 
 
    # Display the results
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        # Scale back up face locations since the frame we detected in was scaled to 1/4 size
        top *= 4
        right *= 4
        bottom *= 4
        left *= 4
 
        # Draw a box around the face
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
 
        # Draw a label with a name below the face
        cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
        if name != "Unknown":
            print("Known face detected!")
            trimite_comanda()
 
    # Display the resulting image
    cv2.imshow('Video', frame)
 
    # Hit 'q' on the keyboard to quit!
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
 
# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()

2. The opening command

When the door opening function is called in the facial recognition script, the 5 layers of security are applied and the command is sent to the ESP32.

import socket
import random 
import numpy as np
import math
import time
 
# criptare cu cifrul Caesar
def encrypt(text,s):
    result = ""
    for i in range(len(text)):
        char = text[i]
        if (char.isupper()):
            result+=chr((ord(char) + s-65) % 26 + 65)
        else:
            result+=chr((ord(char) + s - 97) % 26 + 97)
    return result
 
def obtine_cheie_TCP():
 
    HOST = '192.168.43.5'  # Adresa IP server
    PORT = 80               # Port server
 
    C_cunoscut = 23
    S_cunoscut = 9
 
    print('Valoarea aleasa de client cunoscuta este :%d'%(C_cunoscut))
    print('Valoarea aleasa de server cunoscuta este :%d'%(S_cunoscut))
 
    C_secret = random.randint(3, 15)
 
    # gets the generated key
    x_client = int(pow(S_cunoscut,C_secret,C_cunoscut)) 
    x_client_byte=bytes([x_client])
 
    print(x_client_byte)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        s.sendall(x_client_byte)
        data = s.recv(1024)       
    # print('S-a primit', data)
    x_server=int.from_bytes(data, "big")
    k_secreta_client = int(pow(x_server,C_secret,C_cunoscut))
    print('Cheia secreta pentru client este: %d'%(k_secreta_client))
 
    return k_secreta_client
 
def generare_medie(x):
    medie = []
    medie_com = []
    for i in x:
        if i < 0:
            medie.append(str(bin(i)[3:]))
            aux = str(medie[len(medie) - 1])
 
            for k in range(1,7-len(medie[len(medie) - 1])):
                if k==7-len(medie[len(medie) - 1])-1:
                    aux = str(1) + aux
                else:
                    aux = str(0) + aux
 
            medie_com.append(aux)
        else:
            medie.append((str(bin(i))[2:]))
            aux = str(medie[len(medie) - 1])
 
            for k in range(1,7-len(medie[len(medie) - 1])):
                aux = str(0) + aux
            medie_com.append(aux)
   # print(medie)
   # print(medie_com)
    string_medie=str(medie_com[0])+str(medie_com[1])+str(medie_com[2])+str(medie_com[3])
    return string_medie	
 
def generare_cheie(k_secreta_client):   
    comanda='deschide'
    start_time_enc = time.time()
    string=encrypt(comanda,k_secreta_client)
    print("--- Timp criptare: %.4f seconds ---" % (time.time() - start_time_enc))
 
    start_time_compresie = time.time()
    i=0
    # "deschide" este scris in cod ascii
    valori_ascii=[]
    for fiecare in string:
        valori_ascii.append(ord(fiecare)-97)
        i=i+1
 
   # print(f"valori_ascii = {valori_ascii}")
 
    x = [] # stochez media 
    diff = [] # stochez diferenta
    even_nos = [num for num in range(len(valori_ascii)) if num % 2 == 0]
 
    for l in even_nos:
        x.append(math.ceil(0.5*(valori_ascii[l]+valori_ascii[l+1])))
        diff.append(valori_ascii[l]-valori_ascii[l+1])
 
   # print(f"medie = {x}")
   # print(f"diff = {diff}")
 
    diff_b = []
    aux = str()
    diff_b_com = []
 
    # adug totul la forma dorita
    for i in diff: 
        if i < 0:
            diff_b.append(str(bin(i)[3:]))
            aux = str(diff_b[len(diff_b) - 1])
 
            for k in range(1,7-len(diff_b[len(diff_b) - 1])):
                if k==7-len(diff_b[len(diff_b) - 1])-1:
                    aux = str(1) + aux
                else:
                    aux = str(0) + aux
 
            diff_b_com.append(aux)
        else:
            diff_b.append((str(bin(i))[2:]))
            aux = str(diff_b[len(diff_b) - 1])
 
            for k in range(1,7-len(diff_b[len(diff_b) - 1])):
                aux = str(0) + aux
            diff_b_com.append(aux)
 
 
   # print(diff_b)
   # print(diff_b_com)
 
    string_medie = generare_medie(x) # generez media corespunzator
    print("--- Timp compresie: %.4f seconds ---" % (time.time() - start_time_compresie))
 
    start_time_gen_cheie = time.time()
    # declar chei pentru integrare in cheia mare si le procesez
    ak = (bin(1))[2:]
    bk = (bin(7))[2:]
 
    for i in range(1,6-len(ak)):
        ak = str(0)+ak
 
    for i in range(1,6-len(bk)):
        bk = str(0)+bk 
 
    key = ak+bk
    seg1 = key[:4]
    seg2 = key[4:8]
    seg3 = key[8:]
    key = str(diff_b_com[0])+seg1+str(diff_b_com[1])+seg2+str(diff_b_com[2])+seg3+str(diff_b_com[3])
    print("--- Timp generare cheie: %.4f seconds ---" % (time.time() - start_time_gen_cheie))
    return key, string_medie # returnez key si media
 
# Converitre lista in string
def listToString(s):     
    # initializez string gol
    str1 = ""     
    # parcurg stringul
    for ele in s: 
        str1 += ele     
    # returnez string  
    return str1 
 
# realizez parcurgerea orizontala
def vertical(key,string_medie):
    array = []
    row1=[]
    row2=[]
    for i in range(len(key)):
        if i%2 == 0:
            row1.append(key[i])
        else:
            row2.append(key[i])
    array.append(row1)
    array.append(row2)
    row_1 = listToString(row1)
    row_2 = listToString(row2)
    string = str(str(row_1)+str(row_2)+str(string_medie))
    return string
 
def UDP_trimite_cheie(string):
    UDP_IP = '192.168.43.5'
    UDP_PORT = 1234
    MESSAGE = string
 
   # print("UDP  IP: %s" % UDP_IP)
   # print("UDP  port: %s" % UDP_PORT)
   # print("Mesaj: %s" % MESSAGE)
 
    sock = socket.socket(socket.AF_INET, # Internet
                         socket.SOCK_DGRAM) # UDP
    sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT))
 
def trimite_comanda():
    start_time_TCP = time.time()
    k_secreta_client = obtine_cheie_TCP()
    print("--- Timp TCP: %.4f seconds ---" % (time.time() - start_time_TCP))
    key, string_medie = generare_cheie(k_secreta_client)
    start_time_parcurgere = time.time()
    string = vertical(key, string_medie)
    print("--- Timp parcurgere: %.4f seconds ---" % (time.time() - start_time_parcurgere))
    start_time_UDP = time.time()
    UDP_trimite_cheie(string)
    print("--- Timp UDP: %.4f seconds ---" % (time.time() - start_time_UDP))
 
if __name__ == '__main__':
    print("Main")

Results obtained

1. Door Opening System

 ESP32
Results System

2. Video Capturing System

 RPI
Results System

Demo Video

iothings/proiecte/2022/dor_bell.txt · Last modified: 2023/01/20 11:31 by adriana.boncu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0