S Christian Chavez
Published © MIT

Secure Data Transmission Through Light - LiFi

We know that computers at the most basic level computers only understand ones and zeros. These ones and zeroes can be sent with light.

IntermediateShowcase (no instructions)Over 3 days67
Secure Data Transmission Through Light - LiFi

Things used in this project

Hardware components

Argon
Particle Argon
×1
Photo resistor
Photo resistor
×1
Laser Diode, 655 nm
Laser Diode, 655 nm
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×2

Software apps and online services

VS Code
Microsoft VS Code
Fusion 360
Autodesk Fusion 360

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Schematics

Laser Emitter Diagram

Code

LiFi Data Receiver

C/C++
Received data from laser diode and converts to readable information.
/*
 * Project Receive OLED
 * Description: LiFi Reciever with OLED
 * Author: Christian Chavez
 * Date: December, 2020
 */

SYSTEM_MODE(SEMI_AUTOMATIC);

#include <Adafruit_SSD1306.h>

#define OLED_RESET D4

Adafruit_SSD1306 display(OLED_RESET);

const int anodePin = A5;

int anodeRead;
int triggerValue = 100;
unsigned int zeroTime = 20;
unsigned int zeroMin = 10;
unsigned int zeroMax = 30;
unsigned int oneTime = 40;
unsigned int oneMin = 35;
unsigned int oneMax = 50;
unsigned int startTime;
unsigned int endTime;
unsigned int duration;
bool timerState;
int bitZero;
int bitOne;
int bitTwo;
int bitThree;
int bitFour;
int bitFive;
int bitSix;
int bitSeven;

String temp;
char temp_array[6];
byte send_array[8];
int i;
int n;
byte value[8];

void setup() {

  Serial.begin(9600);
  pinMode(anodePin, INPUT);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();

  display.clearDisplay();
  // display.setRotation(1);
  display.setTextSize(2);
  display.setTextColor(WHITE);

  delay(1000); //system set up time
  display.printf("SYSTEM\nREADY...\n");
  display.display();
  Serial.printf("System Ready...\n");
  delay(3000);
  display.clearDisplay();

}

void loop() {


  anodeRead = analogRead(anodePin);
  //Serial.printf("Anode Read: %i\n", anodeRead); //for testing trigger values only
  
    if (!timerState && anodeRead > triggerValue){ //if timer is off and anode is triggered then continue
      startTime = millis();
      timerState = true;
    }
  
    if (timerState && anodeRead < triggerValue){ //if timer is on and anode is not triggered then continue 
      endTime = millis();
      timerState = false;
      duration = endTime - startTime;
      if(duration > zeroMin && duration < zeroMax){
        readZero();
      }
      else if(duration > oneMin && duration < oneMax){
        readOne();
      }
    }
}

void readZero() {
  send_array[i] = 0;
   //Serial.printf("send_array[i]: %i i: %i\n", send_array[i], i);
  i++;
  if(i > 7){
    decodeData(send_array);
    i = 0;
  }
}

void readOne() {
  send_array[i] = 1;
   //Serial.printf("send_array[i]: %i i: %i\n", send_array[i], i);
  i++;
  if(i > 7){
    decodeData(send_array);
    i = 0;
  }
}

void decodeData(byte data[8]){ 
  byte bitData = 0x00;
  for(i = 7; i >= 0; i--){
    bitData = bitData << 1 | data[i];
  }
  bitZero = send_array[0];
  bitOne = send_array[1];
  bitTwo = send_array[2];
  bitThree = send_array[3];
  bitFour = send_array[4];
  bitFive = send_array[5];
  bitSix  = send_array[6];
  bitSeven = send_array[7];

  if(bitZero == 0 && bitOne == 0 && bitTwo == 0 && bitThree == 0 && bitFour == 1 && bitFive == 1 && bitSix == 0 && bitSeven ==1){
    Serial.printf("° Celsius\n");
    display.clearDisplay();
    display.setCursor(0,0);
    display.printf("TEMP\nIN %cC:\n", char(247));
    display.display();
  }
  else{
  Serial.printf("%c", bitData);
  display.printf("%c", bitData);
  display.display();
  //Serial.printf("bitData: %x, %c, %s\n", bitData, bitData, bitData);
  }
}

Laser Emitter

C/C++
Reads data from BME280 sensor, converts to binary, and sends to laser.
/*
 * Project Laser Emitter
 * Description: LiFi Emitter
 * Author: Christian Chavez
 * Date: 11-23-2020
 */


SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

#include <OneButton.h>
#include <Adafruit_BME280.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET D4

Adafruit_SSD1306 display(OLED_RESET);


const int laserPin = A5;
const int buttonPin = D5;
const int extraButtonPin = D6;

OneButton button1(buttonPin, false, false);
OneButton button2(extraButtonPin, false, false);
Adafruit_BME280 bme;


// unsigned int zeroTime = 15;
// unsigned int oneTime = 40;
// unsigned int offDelay = 10;
unsigned int zeroTime = 20; //below for OLED
unsigned int oneTime = 40;
unsigned int offDelay = 150;
unsigned int zeroCurrentTime;
unsigned int zeroLastTime;
unsigned int oneCurrentTime;
unsigned int oneLastTime;

bool buttonState;
bool extraButtonState;

String temp;
char temp_array[6];
byte data[8];
int i;
int n;


void setup() {

  Serial.begin(9600);

  bme.begin(0x76);

  pinMode(laserPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLDOWN);
  pinMode(extraButtonPin, INPUT_PULLDOWN);
  pinMode(A1, OUTPUT); //used for testing 
  pinMode(D7, OUTPUT); //used for testing
  
  button1.attachClick(click1);
  button1.attachLongPressStart(longPressStart1);
  button1.attachLongPressStop(longPressStop1);
  button1.setClickTicks(250);

  button2.attachClick(click2);
  button2.setClickTicks(250);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();

  display.clearDisplay();
  // display.setRotation(1);
  display.setTextSize(2);
  display.setTextColor(WHITE);

  delay(1000);
  display.printf("SYSTEM\nREADY...\n");
  display.display();
  Serial.printf("System Ready...\n");
  delay(3000);


}

void loop() {
  temp = String(bme.readTemperature());
  float realTemp = bme.readTemperature();
  display.clearDisplay();
  display.setCursor(0,0);
  display.display();
  display.printf("SENDING\nDATA:\n%.2f%cC",realTemp, char(247));
  display.display();
  temp.toCharArray(temp_array, 7);
  Serial.printf("Temperature: %.2f\n", realTemp);
  for(n = 0; n < 5; n++){
    for(i = 0; i < 8; i++){
      data[i] = temp_array[n] >> i & 0x01;
      Serial.printf("temp_array: %x data: %i i: %i n: %i\n", temp_array[n], data[i], i, n);
      delay(10);
    }
    sendAscii(data);
  }
  sendReturn();
}
void sendAscii(byte send_array[8]){
  for(i = 0; i < 8; i++){ 

      if(send_array[i] == 0){ //laser 
      beamZero(); 
      //Serial.printf("Zero ");
      Serial.printf("0");
      }
      else if(send_array[i] == 1){
      beamOne();
      //Serial.printf("One ");
      Serial.printf("1");
      }
  }
}

void sendReturn(){
  //00001101 \n
  beamZero();
  beamZero();
  beamZero();
  beamZero();
  beamOne();
  beamOne();
  beamZero();
  beamOne();

}



void click1(){

  buttonState = !buttonState;

}

void click2(){

  extraButtonState = !extraButtonState;

}

void beamZero() {

  // Serial.printf("Array value is ZERO\n");
  digitalWrite(laserPin, HIGH);
  //Serial.printf("ZERO\n");
  delay(zeroTime);
  digitalWrite(laserPin, LOW);
  delay(offDelay);

}

void beamOne() {

  //Serial.printf("Array value is ONE\n");
  digitalWrite(laserPin, HIGH);
  //Serial.printf("ONE\n");
  delay(oneTime);
  digitalWrite(laserPin, LOW);
  delay(offDelay);

}

Lifi "Key"

C/C++
Used as a key to open a lock connected to a LiFi receiver.
/*
 * Project: Laser Key
 * Description: LiFi Key
 * Author: Christian Chavez
 * Date: December, 2020
 */

SYSTEM_MODE(SEMI_AUTOMATIC);

#include <Adafruit_SSD1306.h>

#define OLED_RESET D4

Adafruit_SSD1306 display(OLED_RESET);

#include <OneButton.h>

const int laserPin = A5;
const int buttonPin = A2;
const int extraButtonPin = A3;

 OneButton button1(buttonPin, false, false);
 OneButton button2(extraButtonPin, false, false);

 int array[] = {1, 1, 0, 1, 0, 1, 1, 0, 1, 0};
 int extraArray[] = {0, 0, 1, 0, 1, 0, 0, 1, 0, 1};
 // int array[] = {134, 2342, 5125, 72456, 235654};
 int i;

unsigned int zeroTime = 10;//works with ReceiverKeyOLED.ino
unsigned int oneTime = 20; 
unsigned int offDelay = 50;
// unsigned int zeroTime = 1000;//works with ReceiverKeyOLED.ino
// unsigned int oneTime = 2000; 
// unsigned int offDelay = 500;
// unsigned int zeroTime = 100;//works with ReceiverKey.ino
// unsigned int oneTime = 200; 
// unsigned int offDelay = 50;
unsigned int zeroCurrentTime;
unsigned int zeroLastTime;
 unsigned int oneCurrentTime;
 unsigned int oneLastTime;

 bool buttonState;
 bool extraButtonState;



 void setup() {

   Serial.begin(9600);

   pinMode(laserPin, OUTPUT);
   pinMode(A1, OUTPUT);
   pinMode(buttonPin, INPUT_PULLDOWN);
   pinMode(extraButtonPin, INPUT_PULLDOWN);
   pinMode(A1, OUTPUT); //used for testing 

   button1.attachClick(click1);
   button1.setClickTicks(250);
   button2.attachClick(click2);
   button2.setClickTicks(250);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
  display.clearDisplay();
  display.setCursor(0,0);
  // display.setRotation(1);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  delay(1000);


  Serial.printf("System Ready...");
  display.printf("LASER\nSYSTEM\nREADY...\n");
  display.display();

 }

 void loop() {

   button1.tick();
   button2.tick();
   digitalWrite(A1, HIGH);
   //Serial.printf("Button State: %i\n", buttonState);


   if(buttonState){
     display.clearDisplay();
     display.setCursor(0,0);
     display.printf("SENDING\nCONFIRMED\nDATA...");
     display.display();

   for(i = 0; i <= 9; i++){


    if(array[i] == 0){
       
       beamZero();

    }
    else if(array[i] == 1){

       beamOne();

     }

       if(i < 9){

        buttonState = false;
       }
       if(i == 9){
        display.clearDisplay();
        display.setCursor(0,0);
        display.printf("DATA\nSENT");
        display.display();
       }
     }
   }

   if(extraButtonState){
     display.clearDisplay();
     display.setCursor(0,0);
     display.printf("SENDING\nINVALID\nDATA...");
     display.display();

     for(i = 0; i <= 9; i++){

       if(extraArray[i] == 0){

         beamZero();

       }
       else if(extraArray[i] == 1){

         beamOne();

       }

       if(i < 9){

         extraButtonState = false;

       }
       if(i == 9){
        display.clearDisplay();
        display.setCursor(0,0);
        display.printf("DATA\nSENT");
        display.display();
       }       
     }
   }
   
 }

void beamZero() {

  // Serial.printf("Array value is ZERO\n");
  digitalWrite(laserPin, HIGH);
  //Serial.printf("ZERO\n");
  delay(zeroTime);
  digitalWrite(laserPin, LOW);
  delay(offDelay);

}

void beamOne() {

  //Serial.printf("Array value is ONE\n");
  digitalWrite(laserPin, HIGH);
  //Serial.printf("ONE\n");
  delay(oneTime);
  digitalWrite(laserPin, LOW);
  delay(offDelay);

}

 void click1(){

   buttonState = !buttonState;

 }

 void click2(){

   extraButtonState = !extraButtonState;

 } 

Credits

S Christian Chavez

S Christian Chavez

3 projects • 4 followers
Internet of Things Coding and Hardware Design Student

Comments

Add projectSign up / Login