Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Komponen dan Perlengkapan

Goldilocks Analogue
Masih prototipe saat ini, tetapi fungsionalitas dapat direkreasi dengan MCP4822 DAC, Mikrofon Penguat, dan Penguat Headphone, bersama dengan Arduino Uno.
×1
MAX9744
×1
MAX9814
×1
MCP4921 DAC
×1
Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio
Arduino UNO
×1
Arduino Wireless Shield (Xbee)
×1

Tentang Proyek Ini

Saya sedang membangun klon Arduino canggih berdasarkan MCU AVR ATmega1284p dengan beberapa fitur khusus termasuk DAC 12 bit MCP4822, penguat headphone, 2x Memori SPI (SRAM, EEPROM), dan Kartu SD. Ada banyak aplikasi dunia nyata untuk output analog, tetapi karena platform Arduino tidak memiliki kemampuan DAC terintegrasi, ada sangat sedikit aplikasi yang dipublikasikan untuk sinyal analog. Walkie Talkie adalah satu contoh penggunaan digital dan analog bersama untuk membuat proyek sederhana tetapi sangat berguna.

Goldilocks Analogue - Prototipe 3
Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Fungsi Walkie Talkie sebenarnya hanya beberapa baris kode, tetapi dibangun di atas fondasi input analog (sampling), output analog pada bus SPI ke DAC MCP4822, rutinitas timing sampel, dan platform radio digital XBee. Mari kita mulai dari atas dan kemudian gali ke bawah melalui lapisan-lapisannya.

XBee Radio

Saya menggunakan radio XBee Pro S2B, dikonfigurasi untuk berkomunikasi titik ke titik. Untuk XBee Pro, perlu ada satu radio dikonfigurasi sebagai Coordinator, dan yang lain sebagai Router. Ada panduan konfigurasi di Internet.

Saya telah mengonfigurasi radio untuk menunggu waktu inter-karakter maksimum sebelum mengirim paket, yang berarti paket akan dikirim hanya saat penuh (84 byte). Ini memaksimalkan throughput radio. Throughput mentah adalah 250 kbit/s, tetapi tingkat data pengguna yang sebenarnya terbatas sekitar 32 kbit/s. Ini memiliki dampak pada tingkat sampling dan kualitas ucapan yang dapat ditransmisikan.

Menggunakan sampel 8 bit, saya menemukan bahwa sampling sekitar 3 kHz menghasilkan sekitar banyak data yang dapat ditransmisikan tanpa kompresi. Saya meninggalkan kompresi untuk proyek lain.

Radio XBee dikonfigurasi dalam mode AT, yang bertindak sebagai pipa serial transparan antara dua titik akhir. Ini adalah cara termudah untuk menghubungkan dua perangkat melalui radio digital. Dan ini memungkinkan saya untuk melakukan pengujian sederhana, menggunakan kabel, sebelum khawatir apakah platform radio berfungsi atau tidak.

Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Melihat tracing dari logic analyser, kita dapat melihat paket data XBee tiba pada baris (ungu) Rx dari port serial. Data paket yang diterima disimpan ke dalam ring buffer, dan diputar pada tingkat konstan. Saya mengizinkan hingga 255 byte dalam ring buffer penerima, dan ini akan cukup karena ukuran paket XBee adalah 84 byte.

Sampel yang akan ditransmisikan ke perangkat lain ditransmisikan pada baris (biru) Tx, lebih atau kurang pada setiap periode sampel meskipun mereka di-buffer sebelum transmisi. Radio XBee menyimpan byte ini hingga 0xFF periode inter-simbol (konfigurasi), dan hanya mentransmisikan paket ke titik akhir lain ketika memiliki paket penuh.

Tingkat Sampling

Melihat anggaran bit untuk tautan transmisi, kita perlu menghitung berapa banyak data yang dapat ditransmisikan tanpa membebani platform radio XBee, dan menyebabkan kehilangan sampel. Karena kita tidak secara tegas mengompresi sampel suara, kita memiliki sampel 8 bit kali 3.000 Hz sampling atau 24 kbit/s untuk ditransmisikan. Ini terlihat bekerja cukup baik. Saya telah mencoba sampling 4 kHz, tetapi ini terlalu dekat dengan batas teoretis, dan tidak terlalu efektif.

Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Melihat logic analyser, kita dapat melihat kedatangan paket byte yang dimulai dengan 0x7E dan 0x7C pada baris Rx. Kedua penguat mikrofon dan output DAC berpusat sekitar 0x7F(FF), jadi kita dapat membaca bahwa tingkat sinyal yang ditangkap dan ditransmisikan di sini sangat rendah. Tingkat sampling yang ditunjukkan adalah 3.000 Hz.

Pengolahan Sampel

Saya menempatkan "ping" pada satu output untuk menangkap saat interupsi sampling sedang diproses (kuning). Kita dapat melihat bahwa waktu yang dihabiskan dalam pemrosesan interupsi sangat kecil untuk aplikasi ini, relatif terhadap total waktu yang tersedia. Mungkin jenis kompresi data dapat diimplementasikan.

Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Selama interupsi sampling, ada dua aktivitas utama, menghasilkan output audio, dengan menempatkan sampel ke DAC, dan kemudian membaca ADC untuk menangkap sampel audio dan mentransmisikannya ke buffer USART.

Ini dilakukan oleh fungsi audioCodec_dsp, yang dipanggil dari kode dalam interupsi timer.

Saya menggunakan Timer0 AVR 8 bit untuk menghasilkan interval sampling teratur, dengan memicu interupsi. Dengan menggunakan frekuensi FCPU MCU yang merupakan kelipatan biner dari frekuensi audio standar, kita dapat menghasilkan tingkat sampling reproduksi yang akurat dengan hanya menggunakan timer 8 bit dengan prescaler clock 64. Untuk menghasilkan frekuensi audio ganjil, seperti 44.100 Hz, Timer1 16 bit dapat digunakan untuk mendapatkan akurasi yang cukup tanpa memerlukan prescaler clock.

ADC ATmega1284p diatur ke mode free-run, dan diubah skala menjadi 192 kHz. Sementara ini dekat dengan kecepatan akuisisi maksimum yang didokumentasikan untuk ADC ATmega, ini masih dalam spesifikasi untuk sampel 8 bit.

Interupsi ini memakan waktu 14 us untuk diselesaikan, dan sangat pendek relatif terhadap 333 us yang kita miliki untuk setiap periode sampel. Ini memberi kita banyak waktu untuk melakukan pemrosesan lain, seperti menjalankan antarmuka pengguna atau pemrosesan audio lebih lanjut.

Transaksi SPI

Pada tingkat detail akhir, kita dapat melihat transaksi SPI sebenarnya untuk mengeluarkan sampel masuk ke DAC MCP4822.

Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Karena saya membangun aplikasi ini pada Goldilocks Analogue Prototype 2 yang menggunakan bus SPI standar, transaksi normal. Prototipe saya yang lebih baru menggunakan Mode SPI Master pada USART 1 dari ATmega1284p, yang sedikit mempercepat transaksi SPI melalui double buffering, dan membebaskan bus SPI normal untuk membaca atau menulis secara bersamaan ke Kartu SD atau Memori SPI, untuk streaming audio. Dalam aplikasi Walkie Talkie ini tidak perlu menangkap audio, jadi tidak ada sisi negatif dalam menggunakan prototipe yang lebih lama dan bus SPI normal.

Kesimpulan

Menggunakan beberapa alat yang sudah ada dan beberapa baris kode, mungkin untuk membangun walkie talkie digital yang terenkripsi dengan cepat, yang mampu berkomunikasi (dapat dipahami, tetapi tidak berkualitas tinggi) suara. Dan, tidak akan ada pengemudi truk CB yang akan mendengarkan percakapan keluarga Anda di masa depan.

Ini adalah tes menambahkan input mikrofon berdasarkan MAX9814 ke Goldilocks Analogue. Saya akan merevisi Prototipe 3 dan akan menambahkan rangkaian penguat mikrofon untuk mendukung aplikasi yang membutuhkan input audio, seperti contoh walkie talkie ini, atau voice changer, atau pengontrol musik vokal.

Dua prototipe Goldilocks Analogue dengan radio XBee, dan penguat mikrofon.
Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat Audio

Saya juga menjalankan perangkat ATmega1284p pada frekuensi yang ditingkatkan 24.576 MHz, melebihi lajur standar 20 MHz. Frekuensi tertentu ini memungkinkan reproduksi yang sangat tepat dari sampel audio dari 48 kHz hingga 4 kHz (atau bahkan hingga 1.500 Hz). Siklus clock MCU tambahan per periode sampel sangat dipersilakan ketika datang untuk menghasilkan musik sintetis.

Kode seperti biasa di Sourceforge AVR freeRTOS Juga, panggilan untuk Shuyang di SeeedStudio yang OPLnya hebat, dan adalah sumber banyak komponen dan PCB.


Kode

Kode
void audioCodec_dsp( uint16_t * ch_A, uint16_t * ch_B) { int16_t xn; uint8_t cn; /*----- Audio Rx -----*/ /* Get the next character from the ring buffer. */ if( ringBuffer_IsEmpty( (ringBuffer_t*) &(xSerialPort.xRxedChars) ) ) { cn = 0x80 ^ 0x55; // put A-Law nulled signal on the output. } else if (ringBuffer_GetCount( &(xSerialPort.xRxedChars) ) > (portSERIAL_BUFFER_RX>>1) ) // if the buffer is more than half full. { cn = ringBuffer_Pop( (ringBuffer_t*) &(xSerialPort.xRxedChars) ); // pop two samples to catch up, discard first one. cn = ringBuffer_Pop( (ringBuffer_t*) &(xSerialPort.xRxedChars) ); } else { cn = ringBuffer_Pop( (ringBuffer_t*) &(xSerialPort.xRxedChars) ); // pop a sample } alaw_expand1(&cn, &xn); // expand the A-Law compression *ch_A = *ch_B = (uint16_t)(xn + 0x7fff); // move the signal to positive values, put signal out on A & B channel. /*----- Audio Tx -----*/ AudioCodec_ADC( &mod7_value.u16 ); // sample is 10bits left justified. xn = mod7_value.u16 - 0x7fe0; // centre the sample to 0 by subtracting 1/2 10bit range. IIRFilter( &tx_filter, &xn); // filter transmitted sample train alaw_compress1(&xn, &cn); // compress using A-Law xSerialPutChar( &xSerialPort, cn); // transmit the sample } 
Kode
ISR(TIMER0_COMPA_vect) __attribute__ ((hot, flatten)); ISR(TIMER0_COMPA_vect) { #if defined(DEBUG_PING) // start mark - check for start of interrupt - for debugging only (yellow trace) PORTD |= _BV(PORTD7); // Ping IO line. #endif // MCP4822 data transfer routine // move data to the MCP4822 - done first for regularity (reduced jitter). DAC_out (ch_A_ptr, ch_B_ptr); // audio processing routine - do whatever processing on input is required - prepare output for next sample. // Fire the global audio handler which is a call-back function, if set. if (audioHandler!=NULL) audioHandler(ch_A_ptr, ch_B_ptr); #if defined(DEBUG_PING) // end mark - check for end of interrupt - for debugging only (yellow trace) PORTD &= ~_BV(PORTD7); #endif } 
Kode
void DAC_out(const uint16_t * ch_A, const uint16_t * ch_B) { DAC_command_t write; if (ch_A != NULL) { write.value.u16 = (*ch_A) >> 4; write.value.u8[1] |= CH_A_OUT; } else // ch_A is NULL so we turn off the DAC { write.value.u8[1] = CH_A_OFF; } SPI_PORT_SS_DAC &= ~SPI_BIT_SS_DAC; // Pull SS low to select the Goldilocks Analogue DAC. SPDR = write.value.u8[1]; // Begin transmission ch_A. while ( !(SPSR & _BV(SPIF)) ); SPDR = write.value.u8[0]; // Continue transmission ch_A. if (ch_B != NULL) // start processing ch_B while we're doing the ch_A transmission { write.value.u16 = (*ch_B) >> 4; write.value.u8[1] |= CH_B_OUT; } else // ch_B is NULL so we turn off the DAC { write.value.u8[1] = CH_B_OFF; } while ( !(SPSR & _BV(SPIF)) ); // check we've finished ch_A. SPI_PORT_SS_DAC |= SPI_BIT_SS_DAC; // Pull SS high to deselect the Goldilocks Analogue DAC, and latch value into DAC. SPI_PORT_SS_DAC &= ~SPI_BIT_SS_DAC; // Pull SS low to select the Goldilocks Analogue DAC. SPDR = write.value.u8[1]; // Begin transmission ch_B. while ( !(SPSR & _BV(SPIF)) ); SPDR = write.value.u8[0]; // Continue transmission ch_B. while ( !(SPSR & _BV(SPIF)) ); // check we've finished ch_B. SPI_PORT_SS_DAC |= SPI_BIT_SS_DAC; // Pull SS high to deselect the Goldilocks Analogue DAC, and latch value into DAC. } 
AVRfreeRTOS at Sourceforge
Repository of the AVR port of freeRTOS, including the DAC.h and Analogue testing files used in this project. Please DON'T use the linked github repository. Go to sourceforge for latest code. https://sourceforge.net/projects/avrfreertos/https://github.com/feilipu/avrfreertos

Skema Rangkaian

Itu tidak benar sepenuhnya, karena menggunakan MCP4725 DAC (I2C) dan bukan MCP4822 DAC (SPI), tetapi Fritzing tidak memiliki papan breakout Adafruit yang tepat.

Juga, itu digambar hanya satu arah... (kecuali Rx dan Tx yang saling terhubung).
Papan XBee cukup menggantikan dua kabel yang menghubungkan Rx dan Tx. Setiap radio yang dapat membawa cukup data akan bekerja.Walkie-Talkie Canggih XBee dengan Arduino, DAC, dan Penguat AudioSkema untuk output DAC dan penguat headphone.
Input mikrofon penguat akan ditambahkan pada prototipe 4.

Proses manufaktur

  1. Pertimbangan Utama untuk Swiss Machining Volume Tinggi
  2. Panduan Prototyping CNC: Presisi, Kecepatan, dan Produksi Hemat Biaya
  3. Manufaktur Shaft Pakar: Proses Presisi dan Solusi Kustom
  4. Passivation Stainless Steel: Meningkatkan Resistensi Korosi dan Performa
  5. Mengukur Sensor Analog pada Raspberry Pi dengan Satu Pin GPIO
  6. Menggunakan ADC MCP3008 untuk Membaca Sensor Analog dengan Raspberry Pi
  7. Pembentukan Gelombang Tinggi Presisi dengan PCB Kustom Berbasis DAC
  8. Pengontrol Irigasi Cerdas dengan Windows 10 IoT, Raspberry Pi, dan Sensor Kelembaban XBee
  9. Mengapa Pengukuran Analog Mendorong Performa Pabrik
  10. Kabel Terpindah Tingkat Lanjut untuk Sirkuit Sinyal: Teknik Koneksi Praktis (Bagian 2)