Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

XBee Walkie Talkie

Компоненты и расходные материалы

Аналог Златовласки
В настоящее время все еще в качестве прототипа, но функциональность может быть воссоздана с помощью ЦАП MCP4822, усилителя микрофона и усилителя для наушников, вместе с Arduino Uno.
× 1
MAX9744
× 1
MAX9814
× 1
MCP4921 DAC
× 1
Arduino UNO
× 1
Arduino Wireless Shield (Xbee)
× 1

Об этом проекте

Я создаю продвинутый клон Arduino на основе микроконтроллера AVR ATmega1284p с некоторыми специальными функциями, включая 12-битный ЦАП MCP4822, усилитель для наушников, 2x SPI-память (SRAM, EEPROM) и SD-карту. Существует множество реальных приложений для аналоговых выходов, но поскольку платформа Arduino не имеет встроенных возможностей ЦАП, опубликованных приложений для аналоговых сигналов очень мало. Уоки-токи - это один из примеров совместного использования цифрового и аналогового сигналов для создания простого, но очень полезного проекта.

Аналог Златовласки - Прототип 3

Фактическая функциональность рации - это всего лишь несколько строк кода, но она построена на основе аналогового входа (выборки), аналогового выхода на шине SPI на ЦАП MCP4822, процедур выборки синхронизации и цифровой радиоплатформы XBee. Давайте начнем сверху, а затем углубимся в слои.

XBee Radio

Я использую радиостанции XBee Pro S2B, настроенные для связи точка-точка. Для XBee Pro необходимо, чтобы один радиомодуль был настроен как координатор, а другой как маршрутизатор. В Интернете есть руководства по настройке.

Я настроил радиомодули на ожидание максимального межсимвольного времени перед отправкой пакета, что означает, что пакеты будут установлены только при заполнении (84 байта). Это максимизирует пропускную способность радио. Необработанная пропускная способность составляет 250 кбит / с, но фактическая скорость передачи данных пользователя ограничена примерно 32 кбит / с. Это влияет на частоту дискретизации и, следовательно, на качество передаваемой речи.

Используя 8-битные выборки, я обнаружил, что выборка около 3 кГц генерирует примерно столько данных, сколько может быть передано без сжатия. Я оставляю сжатие для другого проекта.

Радиомодули XBee настроены в режиме AT, который действует как прозрачный последовательный канал между двумя конечными точками. Это самый простой способ соединить два устройства через цифровое радио. И это позволило мне провести простое тестирование с помощью проводов, прежде чем беспокоиться о том, работает ли радиоплатформа или нет.

Глядя на трассировку логического анализатора, мы можем видеть пакеты данных XBee, поступающие на (фиолетовую) линию Rx последовательного порта. Полученные пакетные данные сохраняются в кольцевом буфере и воспроизводятся с постоянной скоростью. Я разрешил до 255 байтов в кольцевом буфере приема, и этого будет достаточно, потому что размер пакета XBee составляет 84 байта.

Выборки, которые должны быть переданы на другое устройство, передаются по (синей) линии Tx, более или менее в каждом периоде выборки, даже если они буферизуются перед передачей. Радиобуфер XBee буферизует эти байты до 0xFF межсимвольных периодов (конфигурация) и передает пакет другой конечной точке только тогда, когда у нее есть полный пакет.

Частота дискретизации

Рассматривая битовый бюджет для канала передачи, нам необходимо рассчитать, сколько данных может быть передано без перегрузки радиоплатформы XBee и потери выборки. Поскольку мы явно не сжимаем голосовые образцы, у нас есть 8-битные выборки, умноженные на 3000 Гц, или 24 кбит / с для передачи. Кажется, это работает очень хорошо. Я пробовал дискретизировать 4 кГц, но это слишком близко к теоретическому максимуму и не работает слишком эффективно.

Посмотрев на логический анализатор, мы можем увидеть прибытие пакета байтов, начинающегося с 0x7E и 0x7C на линии Rx. И микрофонный усилитель, и выход ЦАП смещены около 0x7F (FF), поэтому мы можем видеть, что уровни захваченного и переданного здесь сигнала очень низкие. Показанная частота дискретизации составляет 3000 Гц.

Образец обработки

Я поставил «пинг» на один выход, чтобы зафиксировать, когда обрабатывается прерывание выборки (желтый). Мы видим, что время, затрачиваемое на обработку прерывания, очень мало для этого приложения по сравнению с общим доступным временем. Возможно, может быть реализовано какое-то сжатие данных.

Во время прерывания дискретизации выполняются два основных действия:генерация аудиовыхода путем помещения отсчета в ЦАП и последующее чтение АЦП для захвата аудиосэмпла и передачи его в буфер USART.

Это выполняется функцией audioCodec_dsp, которая вызывается из кода при прерывании таймера.

Я использую 8-битный Timer0 AVR для генерации регулярных интервалов выборки путем запуска прерывания. Используя частоту микроконтроллера FCPU, которая является двоичным кратным стандартным звуковым частотам, мы можем сгенерировать точные частоты дискретизации воспроизведения, используя только 8-битный таймер с предварительным делителем частоты 64. Для генерации нечетных звуковых частот, например 44100 Гц, 16 бит Timer1 можно использовать для получения достаточной точности без предварительного делителя частоты.

АЦП ATmega1284p установлен в автономный режим и уменьшен до 192 кГц. Хотя это близко к максимальной скорости сбора данных, задокументированной для АЦП ATmega, она все еще находится в пределах спецификации для 8-битных выборок.

Для выполнения этого прерывания требуется 14 мкс, что очень мало по сравнению с 333 мкс, которые мы имеем для каждого периода выборки. Это дает нам достаточно времени для другой обработки, такой как запуск пользовательского интерфейса или дальнейшая обработка звука.

Транзакция SPI

На последнем уровне детализации мы можем увидеть фактическую транзакцию SPI для вывода входящей выборки на ЦАП MCP4822.

Поскольку я создал это приложение на прототипе Goldilocks Analogue Prototype 2, который использует стандартную шину SPI, транзакция проходит нормально. Мои более поздние прототипы используют режим Master SPI на USART 1 ATmega1284p, который немного ускоряет транзакцию SPI за счет двойной буферизации и освобождает обычную шину SPI для одновременного чтения или записи на SD-карту или память SPI для потоковой передачи звука. В приложении Walkie Talkie нет необходимости захватывать звук, поэтому нет недостатка в использовании старых прототипов и обычной шины SPI.

Заключение

Используя несколько уже существующих инструментов и несколько строк кода, можно быстро создать рацию с цифровым шифрованием, способную передавать (понятный, но невысокого качества) голос. И никто из дальнобойщиков CB не будет подслушивать семейные разговоры в будущем.

Это был тест добавления микрофонного входа на базе MAX9814 к аналогу Goldilocks. Я буду пересматривать Prototype 3 и добавлю схему усиления микрофона для поддержки приложений, требующих аудиовхода, таких как этот пример рации, или устройств смены голоса, или музыкальных синтезаторов с голосовым управлением.

Два аналоговых прототипа Златовласки с радиоприемниками XBee и микрофонными усилителями.

Я также использую устройства ATmega1284p на увеличенной частоте 24,576 МГц по сравнению со стандартной частотой 20 МГц. Эта конкретная частота позволяет очень точно воспроизводить аудиосэмплы от 48 кГц до 4 кГц (или даже до 1500 Гц). Дополнительные такты MCU на период выборки очень приветствуются, когда дело доходит до создания синтезированной музыки.

Кодируйте как обычно на Sourceforge AVR freeRTOS Также обращаюсь к Шуянгу из SeeedStudio, у которого потрясающий OPL, который является источником многих компонентов и печатных плат.


Код

  • Код
  • Код
  • Код
Код C / C ++
 void audioCodec_dsp (uint16_t * ch_A, uint16_t * ch_B) {int16_t xn; uint8_t cn; / * ----- Audio Rx ----- * / / * Получить следующий символ из кольцевого буфера. * / if (ringBuffer_IsEmpty ((ringBuffer_t *) &(xSerialPort.xRxedChars))) {cn =0x80 ^ 0x55; // помещаем обнуленный сигнал A-Law на выход. } else if (ringBuffer_GetCount (&(xSerialPort.xRxedChars))> (portSERIAL_BUFFER_RX>> 1)) // если буфер заполнен более чем наполовину. {cn =ringBuffer_Pop ((ringBuffer_t *) &(xSerialPort.xRxedChars)); // извлекаем два образца, чтобы догнать, отбрасываем первый. cn =ringBuffer_Pop ((ringBuffer_t *) &(xSerialPort.xRxedChars)); } еще {cn =ringBuffer_Pop ((ringBuffer_t *) &(xSerialPort.xRxedChars)); // извлекаем образец} alaw_expand1 (&cn, &xn); // расширяем сжатие A-Law * ch_A =* ch_B =(uint16_t) (xn + 0x7fff); // перемещаем сигнал в положительные значения, выводим сигнал на канал A и B. / * ----- Передача звука ----- * / AudioCodec_ADC (&mod7_value.u16); // выборка выровнена по левому краю на 10 бит. xn =mod7_value.u16 - 0x7fe0; // центрируем выборку до 0, вычитая 1/2 10-битного диапазона. IIRFilter (&tx_filter, &xn); // фильтруем переданную последовательность выборок alaw_compress1 (&xn, &cn); // сжатие с использованием A-закона xSerialPutChar (&xSerialPort, cn); // передаем образец} 
Код C / C ++
 ISR (TIMER0_COMPA_vect) __attribute__ ((hot, flatten)); ISR (TIMER0_COMPA_vect) {# если определено (DEBUG_PING) // начальная метка - проверка начала прерывания - только для отладки (желтый след) PORTD | =_BV ( PORTD7); // Ping IO line. # Endif // Процедура передачи данных MCP4822 // перемещаем данные в MCP4822 - выполняется в первую очередь для регулярности (уменьшение джиттера). DAC_out (ch_A_ptr, ch_B_ptr); // процедура обработки звука - выполнить любую обработку на входе - подготовить вывод для следующего сэмпла. // Запуск глобального обработчика звука, который является функцией обратного вызова, если установлен. if (audioHandler! =NULL) audioHandler (ch_A_ptr, ch_B_ptr); # если определено (DEBUG_PING) // конечная метка - проверка на конец прерывания - только для отладки (желтый след) PORTD &=~ _BV (PORTD7); # endif} 
Код C / C ++
 void DAC_out (const uint16_t * ch_A, const uint16_t * ch_B) {DAC_command_t write; если (ch_A! =NULL) {write.value.u16 =(* ch_A)>> 4; write.value.u8 [1] | =CH_A_OUT; } else // ch_A имеет значение NULL, поэтому мы выключаем ЦАП {write.value.u8 [1] =CH_A_OFF; } SPI_PORT_SS_DAC &=~ SPI_BIT_SS_DAC; // Потяните SS на низком уровне, чтобы выбрать аналоговый ЦАП Goldilocks. SPDR =write.value.u8 [1]; // Начинаем передачу ch_A. пока (! (SPSR &_BV (SPIF))); SPDR =write.value.u8 [0]; // Продолжаем передачу ch_A. if (ch_B! =NULL) // начинаем обработку ch_B, пока мы выполняем передачу ch_A {write.value.u16 =(* ch_B)>> 4; write.value.u8 [1] | =CH_B_OUT; } else // ch_B имеет значение NULL, поэтому мы выключаем ЦАП {write.value.u8 [1] =CH_B_OFF; } пока (! (SPSR &_BV (SPIF))); // проверяем, что мы закончили ch_A. SPI_PORT_SS_DAC | =SPI_BIT_SS_DAC; // Вытяните SS на высокий уровень, чтобы отменить выбор аналогового ЦАП Златовласки, и зафиксируйте значение в ЦАП. SPI_PORT_SS_DAC &=~ SPI_BIT_SS_DAC; // Потяните SS на низком уровне, чтобы выбрать аналоговый ЦАП Goldilocks. SPDR =write.value.u8 [1]; // Начинаем передачу ch_B. пока (! (SPSR &_BV (SPIF))); SPDR =write.value.u8 [0]; // Продолжаем передачу ch_B. пока (! (SPSR &_BV (SPIF))); // проверяем, что мы закончили ch_B. SPI_PORT_SS_DAC | =SPI_BIT_SS_DAC; // Вытяните SS на высокий уровень, чтобы отменить выбор аналогового ЦАП Златовласки, и зафиксируйте значение в ЦАП.} 
AVRfreeRTOS на Sourceforge
Репозиторий порта AVR для freeRTOS, включая файлы тестирования DAC.h и Analogue, используемые в этом проекте. НЕ используйте связанный репозиторий github. Для получения последней версии кода перейдите в sourceforge. Https://sourceforge.net/projects/avrfreertos /https://github.com/feilipu/avrfreertos

Схема

Это не совсем правильно, поскольку он использует ЦАП MCP4725 (I2C), а не ЦАП MCP4822 (SPI), но у Fritzing не было подходящей коммутационной платы Adafruit.

Кроме того, он нарисован только в одном направлении ... (за исключением того, что Rx и Tx соединены между собой).
Платы XBee просто заменяют два провода, соединяющие Rx и Tx. Подойдет любой радиоприемник, который может передавать достаточно данных. Схема выхода ЦАП и усилителя для наушников.
На прототипе 4 будет добавлен усилитель микрофонного входа.

Производственный процесс

  1. Рекомендации по высокопроизводительной швейцарской обработке
  2. Руководство по созданию прототипов с ЧПУ
  3. Понимание процесса изготовления вала
  4. Что такое пассивация нержавеющей стали?
  5. Считывание аналоговых датчиков с одним контактом GPIO
  6. Аналоговые датчики на Raspberry Pi с использованием MCP3008
  7. Как сгенерировать высокоточный сигнал с помощью ЦАП и специальной печатной платы
  8. Контроллер полива Win10 IOT с датчиками влажности
  9. Значение аналогового измерения
  10. Экранированные кабели для сигнальных цепей (часть 2)