Różnice między wybraną wersją a wersją aktualną.
Nowa wersja | Poprzednia wersja | ||
projekty:arduinoadcshack [2025/05/07 12:37] – created administrator | projekty:arduinoadcshack [2025/05/16 17:30] (aktualna) – administrator | ||
---|---|---|---|
Linia 7: | Linia 7: | ||
{{ : | {{ : | ||
+ | ====== Arduino: ArdunioADCs-Hack ====== | ||
+ | |||
+ | Proste rozwiązanie do przekształcania wygenerowanych przez Pythona fal do wartości PWM dla Arduino oraz konwertowania wartości wejścia analogowego Arduino na pliki WAV. | ||
+ | |||
+ | {{./ | ||
+ | Arduino | ||
+ | |||
+ | |||
+ | ===== Spis treści: ===== | ||
+ | |||
+ | - W jakich projektach możesz użyć tego narzędzia? | ||
+ | - Jakie są części tego narzędzia? | ||
+ | - Wyjaśnienie części narzędzi | ||
+ | - Jak korzystać z tego narzędzia? | ||
+ | - Lista rzeczy do zrobienia | ||
+ | - Wnioski | ||
+ | |||
+ | ==== Gdzie możesz użyć tego narzędzia? ==== | ||
+ | |||
+ | Stworzyłem ten zestaw narzędzi, ponieważ pomyślałem, | ||
+ | |||
+ | ==== Części tego narzędzia. ==== | ||
+ | |||
+ | To narzędzie składa się z kilku części: | ||
+ | |||
+ | * values.txt - w tym pliku wklejasz wartości do wave_file_writer.py, | ||
+ | * input.txt - w tym pliku wklejasz lub zapisujesz wartości odczytane przez ADC Arduino, powinny być w zakresie od 0 do 1024 | ||
+ | * pwm.txt - to plik, w którym umieszczasz wartości do translate_to_pwm.py, | ||
+ | * pwm.txt - to plik, w którym umieszczasz wartości do translate_to_pwm.py, | ||
+ | * wave_file_writer.py - ten skrypt służy, jak sama nazwa wskazuje, do zapisywania danych z values.txt do pliku .wav | ||
+ | * translate_to_pwm.py - ten skrypt konwertuje wartości z zakresu -1, 1 do zakresu 0, 255, które są wartościami dla wyjścia PWM Arduino | ||
+ | * trans_ard_wav.py - ten plik bierze wartości wejścia analogowego Arduino w zakresie od 0 do 1024 i konwertuje je na wartości 16-bitowego pliku .wav | ||
+ | |||
+ | ==== Wyjaśnienie części ==== | ||
+ | |||
+ | === wave_file_writer.py === | ||
+ | |||
+ | cały kod skryptu | ||
+ | |||
+ | <code python> | ||
+ | import wave, struct, math, random, numpy | ||
+ | |||
+ | text = open(" | ||
+ | string = text.read() | ||
+ | text.close() | ||
+ | |||
+ | sampleRate = 44100.0 | ||
+ | duration = 100.0 | ||
+ | frequency = 440.0 | ||
+ | obj = wave.open(' | ||
+ | obj.setnchannels(1) # mono | ||
+ | obj.setsampwidth(2) | ||
+ | obj.setframerate(sampleRate) | ||
+ | audio=[] | ||
+ | audio = string.splitlines() | ||
+ | audio2 = [] | ||
+ | for i in audio: | ||
+ | audio2.append(int(i)) | ||
+ | print(audio2) | ||
+ | for c in audio2: | ||
+ | data = struct.pack('< | ||
+ | obj.writeframesraw( data ) | ||
+ | obj.close() | ||
+ | </ | ||
+ | |||
+ | <code python> | ||
+ | text = open(" | ||
+ | string = text.read() | ||
+ | text.close() | ||
+ | </ | ||
+ | |||
+ | - Skrypt otwiera plik w bieżącym katalogu o nazwie values.txt | ||
+ | - Odczytuje zawartość pliku i przypisuje ją do zmiennej o nazwie //string// | ||
+ | - Zamyka plik o nazwie text | ||
+ | |||
+ | <code python> | ||
+ | sampleRate = 44100.0 | ||
+ | duration = 100.0 | ||
+ | frequency = 440.0 | ||
+ | </ | ||
+ | |||
+ | Tutaj przypisuję parametry pliku WAV | ||
+ | |||
+ | <code python> | ||
+ | obj = wave.open(' | ||
+ | obj.setnchannels(1) # mono | ||
+ | obj.setsampwidth(2) | ||
+ | obj.setframerate(sampleRate) | ||
+ | </ | ||
+ | |||
+ | - Skrypt otwiera plik o nazwie sound_writer.wav z uprawnieniami do zapisu w nim i przypisuje go do zmiennej //obj// | ||
+ | - Określona jest liczba kanałów w pliku | ||
+ | - Określona jest długość pojedynczego próbki | ||
+ | - „Częstotliwość próbkowania” pliku audio jest określona i przypisana do zmiennej // | ||
+ | |||
+ | <code python> | ||
+ | audio=[] | ||
+ | audio = string.splitlines() | ||
+ | audio2 = [] | ||
+ | </ | ||
+ | |||
+ | - Tworzymy listę //audio// | ||
+ | - Wywołujemy metodę splitlines() na zmiennej //string//, która dzieli ją na linie i przypisuje do zmiennej //audio// | ||
+ | - Tworzymy listę //audio2// | ||
+ | |||
+ | <code python> | ||
+ | for i in audio: | ||
+ | audio2.append(int(i)) | ||
+ | print(audio2) | ||
+ | </ | ||
+ | |||
+ | - Pętla for jest wywoływana na zmiennej //audio// | ||
+ | - Każdy element //i// jest konwertowany na liczbę całkowitą | ||
+ | - Następnie drukujemy zmienną //audio// | ||
+ | |||
+ | <code python> | ||
+ | for c in audio2: | ||
+ | data = struct.pack('< | ||
+ | obj.writeframesraw( data ) | ||
+ | obj.close() | ||
+ | </ | ||
+ | |||
+ | - Używamy pętli for do iterowania przez listę //audio2// | ||
+ | - Używamy funkcji struct.pack() do przypisania wartości do zmiennej //data//, która przygotowuje miejsce na zapis danych WAV | ||
+ | - Następnie zapisujemy ramki danych do naszego pustego obiektu o nazwie //data// | ||
+ | - Zamyka plik .wav | ||
+ | |||
+ | = To cały mechanizm działania tego narzędzia. Może być używane do zapisywania czegokolwiek do pliku audio, o ile jest to w pliku values.txt i mieści się w zakresie +/- 32768 = | ||
+ | |||
+ | === translate_to_pwm.py === | ||
+ | |||
+ | cały kod skryptu | ||
+ | |||
+ | <code python> | ||
+ | import numpy as np | ||
+ | |||
+ | text = open(" | ||
+ | string = text.read() | ||
+ | text.close() | ||
+ | lines = string.splitlines() | ||
+ | values = [] | ||
+ | result = [] | ||
+ | counter = 0 | ||
+ | for i in lines: | ||
+ | values.append(float(i)) | ||
+ | for i in values: | ||
+ | counter += 1 | ||
+ | result.append(int(round(np.interp | ||
+ | (i, | ||
+ | print(result) | ||
+ | </ | ||
+ | |||
+ | <code python> | ||
+ | text = open(" | ||
+ | string = text.read() | ||
+ | text.close() | ||
+ | lines = string.splitlines() | ||
+ | values = [] | ||
+ | result = [] | ||
+ | counter = 0 | ||
+ | </ | ||
+ | |||
+ | - Skrypt otwiera plik pwm.txt i zapisuje go w zmiennej //text// | ||
+ | - Plik przypisany do zmiennej //text// jest odczytywany i wynik zapisany w zmiennej //string// | ||
+ | - Następnie plik //text// jest zamykany | ||
+ | - Rozdzielamy zmienną //string// na linie | ||
+ | - Tworzymy listę //values// | ||
+ | - Tworzymy listę //result// | ||
+ | - Tworzymy zmienną //counter// | ||
+ | |||
+ | <code python> | ||
+ | for i in lines: | ||
+ | values.append(float(i)) | ||
+ | </ | ||
+ | |||
+ | W tej pętli przechodzimy przez wartości w liście //lines// i dodajemy je do listy //values//, po konwersji na typ float | ||
+ | |||
+ | <code python> | ||
+ | for i in values: | ||
+ | counter += 1 | ||
+ | result.append(int(round(np.interp | ||
+ | (i, | ||
+ | print(result) | ||
+ | </ | ||
+ | |||
+ | W tej pętli przechodzimy przez dane w liście //values//, dodajemy 1 do zmiennej //counter// (która nie jest używana), dodajemy wartość zmiennej //i// po jej zaokrągleniu (bez miejsc po przecinku) oraz interpolujemy ją z zakresu -1, 1 do zakresu 0, 255, a następnie drukujemy wynik ###### to wszystko, co powinieneś wiedzieć o tym narzędziu, może być używane do konwersji dowolnej wartości na wartość cyklu PWM. Poniżej znajduje się mały przykład, jak obliczyć wartości sinusoidalne do pliku pwm.txt, aby przekonwertować je na PWM | ||
+ | |||
+ | <code python> | ||
+ | Python 3.6.9 (default, Nov 7 2019, 10: | ||
+ | [GCC 8.3.0] na linuxie | ||
+ | Typ " | ||
+ | >>> | ||
+ | >>> | ||
+ | >>> | ||
+ | >>> | ||
+ | >>> | ||
+ | ... | ||
+ | ... | ||
+ | >>> | ||
+ | [0.0, 0.009999833334166664, | ||
+ | </ | ||
+ | |||
+ | = Spróbuj eksperymentować z różnymi wartościami kroków (ostatnia wartość w funkcji np.arange()), | ||
+ | |||
+ | === trans_ard_wav.py === | ||
+ | |||
+ | <code python> | ||
+ | import numpy as np | ||
+ | |||
+ | |||
+ | text = open(" | ||
+ | string = text.read() | ||
+ | text.close() | ||
+ | lines = string.splitlines() | ||
+ | values = [] | ||
+ | result = [] | ||
+ | counter = 0; | ||
+ | for i in lines: | ||
+ | values.append(int(i)) | ||
+ | for i in values: | ||
+ | counter += 1 | ||
+ | result.append(int(round(np.interp | ||
+ | (i, | ||
+ | for i in result: | ||
+ | print(i) | ||
+ | </ | ||
+ | |||
+ | <code python> | ||
+ | text = open(" | ||
+ | string = text.read() | ||
+ | text.close() | ||
+ | lines = string.splitlines() | ||
+ | values = [] | ||
+ | result = [] | ||
+ | counter = 0; | ||
+ | </ | ||
+ | |||
+ | Dobrze, teraz sprawdźmy, co robi ten fragment kodu. Pierwsza linia otwiera plik, potem standardowo odczytujemy jego zawartość i zamykamy plik. Następnie pod zmienną „lines” przypisujemy tekst z pliku, ale jest on podzielony na oddzielne linie. Tworzymy kilka zmiennych, które będą przydatne później. | ||
+ | |||
+ | <code python> | ||
+ | for i in lines: | ||
+ | values.append(int(i)) | ||
+ | for i in values: | ||
+ | counter += 1 | ||
+ | result.append(int(round(np.interp | ||
+ | (i, | ||
+ | for i in result: | ||
+ | print(i) | ||
+ | </ | ||
+ | |||
+ | Pierwsza pętla for odczytuje każdą wartość i konwertuje ją z typu str na int, następnie w kolejnej pętli dodajemy 1 do zmiennej „counter” (która nie jest używana), zaokrąglamy wartości (bez miejsc po przecinku) i interpolujemy je z zakresu 0,1024 na zakres 16-bitowego pliku audio. Ostatnia pętla for drukuje wynik każdej wartości w nowej linii, a po tym możemy przekierować wynik do innego pliku. | ||
+ | |||
+ | === Lista rzeczy do zrobienia === | ||
+ | |||
+ | * ☒ przetłumaczenie z Pythona na cykl PWM | ||
+ | * ☒ przetłumaczenie z wejścia analogowego Arduino na plik WAV | ||
+ | * ☐ generowanie prostych fal w plikach .wav | ||
+ | * ☐ przetłumaczenie z wejścia analogowego Arduino na wykres matplotlib | ||
+ | * ☐ stworzenie GUI dla całego projektu | ||
+ | * ☐ stworzenie prostego generatora tonów .wav w oparciu o GUI/tekst | ||
+ | * ☐ konwerter ASCII na sygnał cyfrowy w formacie .wav i dla Arduino | ||
+ | |||
+ | Jeśli masz pomysły na ciekawe ulepszenia tego projektu, skontaktuj się ze mną lub po prostu wyślij swoją zmianę. | ||
+ | |||
+ | ==== Wnioski ==== | ||
+ | |||
+ | Moim zdaniem to był interesujący projekt. Może nauczyć trochę o cyfrowym przetwarzaniu sygnałów .wav i trochę o Arduino. Jeśli masz trochę więcej wolnego czasu i chcesz obejrzeć filmy wyjaśniające podobne projekty do tego, odwiedź moją [[http:// | ||