0

I am implementing an FIR filter using Arduino. I am using an input signal as an audio signal. The audio signal has a duration of 3 seconds with total samples, 66150. What I am doing is reading this file in python and storing the data in an array. Using Serial, I want to send this sampled data to Arduino serial and process it, then send it back to serial and receive in Python.

Python Code

import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.io import wavfile # get the api
import serial, time
samplerate, data = wavfile.read("sample.wav")
samples = len(data)
plt.plot(data[:20000])
arduino = serial.Serial('COM4', 9600, timeout=.1)
time.sleep(1) #give the connection a second to settle
for i in range(0,samples):
 arduino.write(data[i])
 time.sleep(1)
 print(arduino.readline())

Arduino Code

 void setup() {
 Serial.begin(9600);
 }
 int i = 0;
 int newdata[10];
 void loop() {
 if(Serial.available() > 0) {
 int data = Serial.read();
 newdata[i] = data;
 Serial.print(newdata[i]);
 i = i+1;
 }
 }

The problem I am facing is that I am stuck at very first step. As a check, I sent 10 samples values at start from Python to arduino using a loop and tried to recover them back to read on Python console. These values were not correct. When I entered a string inside the arduino.write(), it was receiving but when I input a variable inside the arduino.write(), it doesn't print that value after transferring back to python. I just tried many things like changing to string but I didn't get the desired result. The output for this code is attached. Tomorrow is my submission and I am stuck in this thing. Help will be highly appreciated.Python cmd window output

asked Jan 5, 2020 at 3:58
5
  • I want just to check whether the value I am writing to arduino from python is correct or not. Firstly I sent string from Python to arduino it was fine. But when i tried variable data, it doesn't catch that value. The very first step is going wrong so I can not proceed further (for processing stage). Commented Jan 5, 2020 at 5:47
  • int values or float values which are stored in data array are not being transferred to arduino. So if I can't get proper value of x[n] at a point it will not be useful for implementation of an FIR filter. Commented Jan 5, 2020 at 5:49
  • I just edited the question with more explanation. Kindly look over it. Commented Jan 5, 2020 at 5:54
  • 1
    first problem. you don't reset i Commented Jan 5, 2020 at 10:13
  • 1
    second problem. you read a byte/character and then print it as int. but print(int) will output the number as text. use Serial.write(data); Commented Jan 5, 2020 at 10:14

2 Answers 2

1

I have found a way to tackle this. Here is my arduino code:

char buf[100];
const double coefficients[28] = {
-0.006416610121367, -0.01179616274682, -0.01212859343535,-0.001491136183145,
 0.0175211951058, 0.03193599126761, 0.0259553014052,-0.004580133449276,
-0.04206485416456, -0.05260424218688,-0.007566809377484, 0.09242896920118,
 0.2100842841173, 0.2894365184419, 0.2894365184419, 0.2100842841173,
 0.09242896920118,-0.007566809377484, -0.05260424218688, -0.04206485416456,
-0.004580133449276, 0.0259553014052, 0.03193599126761, 0.0175211951058,
-0.001491136183145, -0.01212859343535, -0.01179616274682,-0.006416610121367
};
int order_of_filter = 27;
int sample_array[28] = {};
double output_sample = 0;
void setup()
{
 Serial.begin(9600);
 Serial.setTimeout(50000);
}
void loop()
{
 int sample_in;
 int num_read = Serial.readBytesUntil('\n', buf, 100);
 buf[num_read] = '0円';
 sscanf(buf, "%d", &sample_in);
 for (int i = order_of_filter; i > 0; i--)
 {
 sample_array[i] = sample_array[i-1];
 }
 sample_array[0] = sample_in;
 for(int i = 0; i<=order_of_filter; i++)
 {
 output_sample = output_sample + sample_array[i]*coefficients[i];
 }
 Serial.println(output_sample);
 output_sample = 0;
}

And here is my Python Code:

 import matplotlib.pyplot as plt
 from scipy.fftpack import fft
 from scipy.io import wavfile # get the api
 import serial, time
 import numpy as np
 import sounddevice as sd
 arduino = serial.Serial('COM4', 9600, timeout=1) #COM port depends on the USB port
 time.sleep(3) #time to get connection ready
 # %%
 fs, data = wavfile.read('hfsound.wav')
 samples = len(data)
 #Plot the signal
 plt.plot(data[:samples])
 plt.ylabel("Amplitude")
 plt.xlabel("Time") 
 plt.title("Time Domain Response of the Input Signal")
 plt.grid()
 plt.show()
 #Plotting fft
 fft_input = fft(data)
 half_length = int(len(fft_input)/2)
 omega_axis = np.linspace(0, fs/2, half_length)
 fft_n = fft_input[:half_length]
 plt.plot(omega_axis,abs(fft_n))
 plt.xlabel('frequency')
 plt.ylabel('Amplitude')
 plt.title("Frequency Domain Response of the Input Signal")
 plt.grid()
 plt.show()
 # %%
 #Declare an Array of zeros
 outputArray = np.zeros(64000)
 #Sending data to aurdino
 for i in range(samples):
 number = data[i]
 string = str(number).encode(encoding='utf-8') + b'\n'
 arduino.write(string)
 byt = arduino.read_until();
 print(byt.strip())
 outputArray[i] = byt.strip()
 arduino.close()
 # %%
 #Plotting Output waveform
 #Plot the time-domain output signal
 plt.plot(outputArray[:len(outputArray)])
 plt.ylabel("Amplitude")
 plt.xlabel("Time") 
 plt.title("Time Domain Response of the Output Signal")
 plt.grid()
 plt.show()
 #Plotting fft of output
 fft_out = fft(outputArray)
 half_length = int(len(fft_out)/2)
 omega_axis = np.linspace(0, fs/2, half_length)
 fft_n = fft_out[:half_length]
 plt.plot(omega_axis,abs(fft_n))
 plt.xlabel('frequency')
 plt.ylabel('Amplitude')
 plt.title("Frequency Domain Response of the Output Signal")
 plt.grid()
 plt.show()
 # %%
 #Playback code
 sd.play(outputArray, fs)
 # %%
answered Jan 25, 2020 at 16:12
0
 arduino.write(data[i].tobytes())
 time.sleep(.1)
 print(int.from_bytes(arduino.readline(),byteorder='little') )

Is this what you whant?

answered Jan 7, 2020 at 12:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.