0

Dears, i'm working on a LiFi image transmission project using ESP32 microcontrollers. I then use 2 microcontrollers, one as transmitter through laser and another as receiver through an LDR. So far, the Arduino codes and Python script i've used for the transmission aren't working so far.

PYTHON CODE TO CONVERT IMAGE TO STRING:

import base64
def image_to_base64(image_path):
 with open(image_path, "rb") as img_file:
 # Read the image file in binary mode
     img_data = img_file.read()
 # Encode the binary data as base64
 base64_data = base64.b64encode(img_data)
 # Decode bytes to string
 base64_string = base64_data.decode("utf-8")
 return base64_string
# Example usage
image_path = "blue.png" # Replace with your image file path
base64_string = image_to_base64(image_path)
print(base64_string) 

ARDUINO CODE TO TRANSFER IMAGE:

#define LED_PIN 22
// #define BUTTON_PIN A0
//const int LED_PIN = 2;
#define PERIOD 15
char *string ="/9j/1/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAOABEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDzv4U6OPFd99mtWJu4iGaNI2YkbiCwD+nX0BZfbPonjz4OzeGdFjmnZbKWeWMwRTSCOWfqSFRnJYgZPC9AeleY/Bvxi/wq8ZDxRa2K3awxTSTWpfAkU5c4cg7W+RcNjjHIIyD+g3hr4AaP47tbP4t+Mtc1CbxH4n8GWuk3VtZOsGnWyytFcMYEKtID5igbnd+M8dAPwHNMBisuzb2lOXLGK5+nnePXTTe17Nddv1yXEcYYenGqtJKz031336Xv63sfBH/CCw/9BTVP+/En/wAVRXtP9hW/+x/37FFX/rtlP/Pyp9y/+RPX+pUv5fyP/9k=#";
int string_length;
void setup()
{
 pinMode(LED_PIN, OUTPUT);
  pinMode(3, INPUT);
  digitalWrite(3,LOW);
 string_length = strlen(string);
  delay(5000);
 if(digitalRead(3) == HIGH){
 for(int i = 0; i < string_length; i ++)
 {
 send_byte(string[i]);
 }
 delay(10);
 }
}
void loop()
{ 
}
void send_byte(char my_byte)
{
 digitalWrite(LED_PIN, LOW);
 delay(PERIOD);
 //transmission of bits
 for(int i = 0; i < 8; i++)
 {
 digitalWrite(LED_PIN, (my_byte&(0x01 << i))!=0 );
 delay(PERIOD);
 }
 digitalWrite(LED_PIN, HIGH);
 delay(PERIOD);
}

PYTHON CODE TO RECEIVE IMAGE:

import serial 
import base64 
from io import BytesIO 
from PIL import Image 
import time 
import binascii
from serial import Serial
long_string = "" 
fixed_base64_str = "" 
ser = serial.Serial('COM5', 9600, timeout=15) 
ser.reset_input_buffer()
#time.sleep(2) 
while True: 
     if ser.in_waiting > 0: 
         data = ser.read().decode('utf-8')  
         long_string += data 
         print(data, end="") 
         if " " in long_string: 
            break
ser.close() 
long_string = long_string[:-1] 
print(f"\n\n{long_string}\n\n")
# Decode the image from the fixed base64 string 
image_bytes = base64.b64decode(fixed_base64_str) 
image = Image.open(BytesIO(image_bytes)) 
image.show() 

Emission circuit

ARDUINO CODE TO RECEIVE:

#define LED_PIN 3 
#define LDR_PIN 34 
#define THRESHOLD 300
#define PERIOD 15 
bool previous_state,current_state; 
void setup() 
 {Serial.begin(9600); 
 pinMode(LED_PIN, OUTPUT);} 
void loop() 
 {current_state = get_ldr(); 
 if(!current_state && previous_state) 
 {print_byte(get_byte());} 
 previous_state = current_state;} 
bool get_ldr() 
 {int voltage = analogRead(LDR_PIN); 
 //Serial.println(voltage);
 return voltage > THRESHOLD ? true : false;} 
char get_byte() 
 {char ret = 0; 
 delay(PERIOD*1.5); 
 for(int i = 0; i < 8; i++){ 
 ret = ret | get_ldr() << i; 
 delay(PERIOD);} 
 return ret;} 
void print_byte(char my_byte) 
{char buff[2];
 sprintf(buff, "%c", my_byte);
 Serial.println(buff);}

RECEPTION CIRCUIT

When I run Python receiver code, I got this error:

Traceback (most recent call last):
  File "C:\Users\Yasmine\AppData\Local\Programs\Python\Python312\coderecep.py", line 15, in <module>
    data = ser.read().decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 0: unexpected end of data

I tried to adjust the synchronisation threshold between 210 and 800, but it did not work.

4
  • Your code has no synchronization or framing I can see - there's no way you can tell where a byte begins and where it ends. (Or, in the grander scheme of things, where your file ends.) That's likely why you're getting something that ends up being un-decodable-as-utf-8 into your Python program. Commented Dec 9, 2024 at 17:54
  • (To demonstrate, try changing your transmitter program to just send e. g. bytes from 0 to 255 over and over again. When you manage to successfully receive that sequence, try with more complex data. You'll also need to change the Python program to not try to decode those sequences as UTF-8.) Commented Dec 9, 2024 at 17:55
  • You are doing base64_string = base64_data.decode("utf-8") in image_to_base64 and in the Python code to receive the image you are doing data = ser.read().decode('utf-8') . It seems you are decoding an already decoded string. Commented Dec 9, 2024 at 18:20
  • @Lewis Trying to decode a str would be an AttributeError, not UnicodeDecodeError. (You're missing the part where the base64'd string is embedded in the esp32 program and sent over lasers - that'll have to be bytes at some point!) Commented Dec 9, 2024 at 19:06

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.