Взаимодействие Arduino с Python Serial
Я реализую КИХ-фильтр с помощью Arduino. Я использую входной сигнал в качестве аудиосигнала. Звуковой сигнал имеет продолжительность 3 секунды с общим количеством выборок, 66150. Что я делаю, так это читаю этот файл в python и сохраняю данные в массиве. Используя Serial, я хочу отправить эти выборочные данные в последовательный порт Arduino и обработать их, а затем отправить обратно в последовательный порт и получить в Python.
Код Python
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
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;
}
}
Проблема, с которой я столкнулся, заключается в том, что я застрял на самом первом шаге. В качестве проверки я отправил 10 образцов значений при запуске из Python в arduino с помощью цикла и попытался восстановить их обратно для чтения в консоли Python. Эти значения неверны. Когда я ввел строку внутри arduino.write(), она была получена, но когда я ввожу переменную внутри arduino.write(), она не печатает это значение после передачи обратно в python. Я просто пробовал много вещей, таких как переход на строку, но не получил желаемого результата. Вывод для этого кода прилагается. Завтра мое представление, и я застрял в этом деле. Мы будем очень признательны за помощь.
@Asad Sultan, 👍0
Обсуждение2 ответа
Лучший ответ:
Я нашел способ решить эту проблему. Вот мой код Arduino:
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;
}
А вот мой код Python:
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)
# %%
arduino.write(data[i].tobytes())
time.sleep(.1)
print(int.from_bytes(arduino.readline(),byteorder='little') )
Это то, что вам нужно?
- Построение графика на Python с использованием Tkinter Canvas
- Что является более быстрой альтернативой parseInt()?
- SerialUSB на Arduino Due
- Использование экрана SD-карты на Arduino Due
- Связь между Python и Arduino ненадежна
- Serial.availableForWrite против Serial.flush
- Проблемы с I2C и Wire.Available()
- Протокол связи Arduino с python — помимо примера pyserial и Arduino
Я хочу просто проверить, правильно ли значение, которое я пишу в arduino из python, или нет. Сначала я отправил строку из Python в Arduino, все было в порядке. Но когда я пробовал переменные данные, он не улавливал это значение. Самый первый шаг идет не так, поэтому я не могу двигаться дальше (для стадии обработки)., @Asad Sultan
значения int или значения с плавающей запятой, которые хранятся в массиве данных, не передаются в arduino. Поэтому, если я не могу получить правильное значение x[n] в какой-то момент, это не будет полезно для реализации КИХ-фильтра., @Asad Sultan
Я только что отредактировал вопрос с дополнительным объяснением. Пожалуйста, просмотрите его., @Asad Sultan
первая проблема. ты не перезагрузишь меня, @Juraj
вторая проблема. вы читаете байт/символ, а затем печатаете его как int. но print(int) выведет число как текст. используйте
Serial.write(данные);
, @Juraj