LiFi communication project

Hello everyone,

I hope that I’ve asked this correctly and I really appreciate any and all help with this. I’m working on a project to test lifi communication between two Arduino boards. One is the emitter and one is the collector.

I’ve built a LED driving circuit that is connected to PWM pin 6 of one Arduino so I can start off with OOK and then try PWM. Though I just can’t seem to get this working.

The receiver consists of 3 photodiodes reading into A3, A4, A5. I have a rolling vector collecting the signal input, I then make an average and two threshold limits to discern one’s and zero’s. Unfortunately, my experience drops short of making this work. ideally, the emitter will flash a recurring message and then the receiver will pick up this message and save it into a string.

I tried to also set the receiver to check of bits during an interrupt based on Timer1, though I don’t think I’ve gotten it quite right. I appreciate any and all help you guys can give me with this!

Emitter

#include <avr_stl.h>
#include <vector>

int LED_Driving_pin=6; //LED emitting PIN (Can Also be used for PWM)

byte char_byte = 0;
std::vector <byte> vect_string;

String string_input = "~Hello World~";//Hello World

void setup() {
  Serial.begin(9600);
  pinMode(LED_Driving_pin, OUTPUT);//LED's are set to output
  
    for(int i=0; i<string_input.length(); i++){
      vect_string.push_back(string_input[i]); //Transfers the string characters into the rolling vector
      }
  }

void Sentence_write(){ //This function takes the string and converts the letters into binary
    for(int i=0; i<string_input.length(); i++){
      char_byte = 64; // Setting the binary value to 10000000
      for(int j=0; j<8; j++){
        if((vect_string[i]&char_byte)>0){ //If the current bit is high, then swtich the LED on (This is a bit-wise-AND check)
          //Serial.println("1"); //Checking the output
          digitalWrite(LED_Driving_pin, HIGH);
          delay(6);
        }
        else{ //else the current bit is low and therefore switch the LED off
          //Serial.println("0"); //Checking the output
          digitalWrite(LED_Driving_pin, LOW);
          delay(6);
        }
       char_byte=char_byte>>1; //Allows for the binary count to be shifted up by one place
      }
      //delay(5);
     digitalWrite(LED_Driving_pin, LOW); //Switches the LED so that LED does not remain on for another cycle 
    }
  }

void loop() {
  Sentence_write(); //Calls the function every loop
}

Receiver

#include <TimerOne.h>
#include <avr_stl.h>
#include <vector>

double PinIn1=A3; //PD1
double PinIn2=A4; //PD2
double PinIn3=A5; //PD3

double val1=0;
double val2=0;
double val3=0;

double avg1=0;
double avg2=0;
double avg3=0;

double sum1=0;
double sum2=0;
double sum3=0;

double thresh1_upper=0;
double thresh2_upper=0;
double thresh3_upper=0;

double thresh1_lower=0;
double thresh2_lower=0;
double thresh3_lower=0;

double percentage_upper = 0.001;
double percentage_lower = 0.001;

int sample_size=100;

std::vector <int> vect1;
std::vector <int> vect2;
std::vector <int> vect3;

std::vector <bool> buff;

byte a=0;
char b=0;
bool check = false;
int count = 0;
String mem_string="";

bool timing_switch=false;
int t=0;

void setup(){
Serial.begin(9600);
Timer1.initialize(150000); // initialize timer1, and set a 1 second period (0.15)
Timer1.attachInterrupt(Timer); // attaches Blink() as a timer interrupt function
}

void Timer(void){
   if(analogRead(PinIn1)>=thresh1_upper){
      buff.push_back(true);
    }
    
    if(analogRead(PinIn1)<=thresh1_lower){
      buff.push_back(false);
    }
          timing_switch=!timing_switch;
    
}

void loop(){
  //Serial.println(buff[buff.size()-1]);
  
    vect1.push_back(analogRead(PinIn1));
    vect2.push_back(analogRead(PinIn2));
    vect3.push_back(analogRead(PinIn3));
    
    if(vect1.size()>sample_size){
      vect1.erase(vect1.begin());
      vect2.erase(vect2.begin());
      vect3.erase(vect3.begin());
    }

    for(int i=0; i<sample_size; i++){
      sum1+=vect1[i];
      sum2+=vect2[i];
      sum3+=vect3[i];
     }
      
    avg1=(sum1/sample_size);
    avg2=(sum2/sample_size);
    avg3=(sum3/sample_size);

    thresh1_upper=avg1+avg1*percentage_upper;
    thresh2_upper=avg2+avg2*percentage_upper;
    thresh3_upper=avg2+avg2*percentage_upper;

    thresh1_lower=avg1-avg1*percentage_lower;
    thresh2_lower=avg2-avg2*percentage_lower;
    thresh3_lower=avg3-avg3*percentage_lower;

  if(check){
    if(buff.size()>=8){
      for(int i=0; i<8; i++){
        if (buff[buff.begin()]){
          a=a<<1;
          a+=1;
        }
        else{
          a=a<<1;
        }
        buff.erase(buff.begin());
       }
      }
     }
     
   else{
    if(buff.size()>0){
        if (buff[buff.begin()]){
          a=a<<1;
          a+=1;
        }
        else{
          a=a<<1;
        }
        buff.erase(buff.begin());
        count++;
      }
     }
        
  if(a=='~'&&count==8){
    Serial.print("~");
    if(check){Serial.println(mem_string);;mem_string="";}
    check= !check;
    count=0;
    a=0;
  }

   else if(check&&count==8){
    b=a;
    mem_string+=b;
    Serial.println(a, BIN);
    /*Serial.print(" ");
    Serial.print(a, DEC);
    Serial.print(" ");
    Serial.println(b);
    Serial.println(a, BIN);*/
    }

  if(count==8&&check){count=0;}
  else if (count==8){count=7;}

  if(timing_switch==1){
    t=852;
  }
  else{
    t=846;
  }

 Serial.print(vect1[vect1.size()-1]);Serial.print(" ");Serial.print(thresh1_upper);Serial.print(" ");Serial.println(thresh1_lower);//Serial.println(t);//
    sum1=0;
    sum2=0;
    sum3=0;

    avg1=0;
    avg2=0;
    avg3=0;

    thresh1_upper=0;
    thresh2_upper=0;
    thresh3_upper=0;

    thresh1_lower=0;
    thresh2_lower=0;
    thresh3_lower=0;
delay(10);
}

Timer_interrupt_Receiver-working_attempt.ino (3.22 KB)

Emitter_code.ino (1.45 KB)

Unless the sketch is too large, it's better if you post your code inside code tags, rather than attach it. When it's attached, we have to download it, create a folder then open your code in our IDE. And afterwards, the folder remains unless we navigate to the "Temp" folder and manually remove it. It's much easier to just view the code in your post.

Please post your code using code tags. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpreted by the forum code as italics or funny emoticons. The "Code: [Select]" feature allows someone to select the entire sketch so it can be easily copied and pasted into the IDE for testing.

Please read "Read this before posting a programming question" at the top of the forum and post your sketch- all of it- using code tags.

Also, post a schematic in CAD or a picture of a hand drawn circuit in jpg or png- (NOT a pretty Fritzing drawing)

Have you tried using a really low data rate?

SteveMann: Please read "Read this before posting a programming question" at the top of the forum and post your sketch- all of it- using code tags.

Also, post a schematic in CAD or a picture of a hand drawn circuit in jpg or png- (NOT a pretty Fritzing drawing)

Have you tried using a really low data rate?

I haven't reallt tried a slower rate but I think that that may be my issue overall is a lack of bit/second undrestanding so I'm gonna go back to the drawing board and start somewhat from the beginning, thank you for your help!