Good Day, I am trying to send packetized binary data from an mp3 file which is located on my Raspberry Pi to my Arduino using serial UART connection. I have 3 cables connected from the pi to arduino (Tx, Rx and GND). Everything is going well except the pi is not able to send the packets to my arduino. I have tried simple code to send hex data and it works well so its not the connection. Please do have a look and any help is appreciated!
Pi Code:
import serial
import time
from pydub import AudioSegment
import os
# Constants
PACKET_SIZE = 128
SERIAL_PORT = '/dev/ttyAMA0'
BAUD_RATE = 9600
PACKET_DELAY = 0.5
# Read the MP3 file
def read_mp3_file(filename):
audio = AudioSegment.from_mp3(filename)
return audio.raw_data, audio.frame_rate
# Packetize the audio data
def packetize_data(audio_data):
packetized_data = []
num_packets = (len(audio_data) + PACKET_SIZE - 1) // PACKET_SIZE
for i in range(num_packets):
packet_payload = audio_data[i * PACKET_SIZE: (i + 1) * PACKET_SIZE]
packet = packet_payload
packetized_data.append(packet)
print(f"Packet {i}: Payload={packet_payload}") # Display the generated packet
return packetized_data
# Calculate the checksum of a packet
def calculate_checksum(packet):
checksum = 0
for byte in packet:
checksum ^= byte
return checksum
# Transmit packets to Arduino
def transmit_packets(packets):
try:
ser = serial.Serial(SERIAL_PORT, BAUD_RATE)
print("Transmitting packets...")
for i, packet in enumerate(packets):
sequence_number = i.to_bytes(1, byteorder='big') # Convert the sequence number to bytes
header = b'\x00' # Placeholder for the header
payload = packet
checksum = calculate_checksum(sequence_number + header + payload) # Calculate the checksum
serialized_packet = sequence_number + header + payload + bytes([checksum])
ser.write(serialized_packet)
time.sleep(PACKET_DELAY)
# Wait for acknowledgement
while True:
if ser.readable() and ser.in_waiting >= 1:
received_sequence_number = ord(ser.read())
if received_sequence_number == sequence_number[0]:
print(f"Acknowledged packet: Sequence={received_sequence_number}")
break # Acknowledgement received, move to the next packet
else:
print(f"Incorrect acknowledgement received: Sequence={received_sequence_number}")
else:
print(f"No acknowledgement received for packet: Sequence={i}")
# Retry sending the packet
ser.write(serialized_packet)
time.sleep(PACKET_DELAY)
ser.close()
print("Transmission complete")
except serial.SerialException as e:
print(f"Serial communication error: {str(e)}")
except Exception as e:
print(f"An error occurred during transmission: {str(e)}")
# Example usage
if __name__ == '__main__':
# Read the MP3 file
filename = '/home/sit57/test.mp3'
if not os.path.exists(filename):
print(f"File '{filename}' does not exist")
exit(1)
data, sample_rate = read_mp3_file(filename)
# Packetize the audio data
packets = packetize_data(data)
# Print the number of packets
print("Number of packets to transmit:", len(packets))
# Transmit packets serially to Arduino
transmit_packets(packets)
Arduino Code:
#include <Arduino.h>
#define PACKET_SIZE 128
void setup() {
Serial.begin(9600);
while (!Serial) {
; // Wait for Serial port to be ready
}
}
void loop() {
byte expected_sequence_number = 0;
// Wait for packet from Raspberry Pi
while (Serial.available() < PACKET_SIZE) {
// Wait until enough bytes are available
}
byte received_sequence_number = Serial.read();
byte header = Serial.read();
byte payload[PACKET_SIZE - 2];
for (int i = 0; i < PACKET_SIZE - 2; i++) {
payload[i] = Serial.read();
}
byte checksum = Serial.read();
// Verify the checksum
byte calculated_checksum = calculate_checksum(received_sequence_number, header, payload, checksum);
if (calculated_checksum == checksum) {
// Print the received packet
Serial.print("Received packet: Sequence=");
Serial.print(received_sequence_number);
Serial.print(", Header=");
Serial.print(header);
Serial.print(", Payload=");
for (int i = 0; i < PACKET_SIZE - 2; i++) {
Serial.print(payload[i]);
}
Serial.println();
// Send acknowledgement
Serial.write(received_sequence_number);
expected_sequence_number++; // Move to the next expected sequence number
} else {
// Resend acknowledgement for the previous packet
Serial.write(expected_sequence_number - 1);
}
}
// Calculate the checksum of a packet
byte calculate_checksum(byte sequence_number, byte header, byte* payload, byte received_checksum) {
byte checksum = 0;
checksum ^= sequence_number;
checksum ^= header;
for (int i = 0; i < PACKET_SIZE - 2; i++) {
checksum ^= payload[i];
}
checksum ^= received_checksum; // Include the received checksum in the calculation
return checksum;
}