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

  • 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). – Asad Sultan Jan 5 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. – Asad Sultan Jan 5 at 5:49
  • I just edited the question with more explanation. Kindly look over it. – Asad Sultan Jan 5 at 5:54
  • 1
    first problem. you don't reset i – Juraj Jan 5 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); – Juraj Jan 5 at 10:14
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)
 # %%
| improve this answer | |
0
    arduino.write(data[i].tobytes())
    time.sleep(.1)
    print(int.from_bytes(arduino.readline(),byteorder='little') )

Is this what you whant?

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.