산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

XBee 워키토키

구성품 및 소모품

Goldilocks 아날로그
현재 프로토타입이지만 MCP4822 DAC, 마이크 증폭기 및 헤드폰 증폭기를 사용하여 기능을 다시 만들 수 있습니다. 아두이노 우노와 함께합니다.
× 1
MAX9744
× 1
MAX9814
× 1
MCP4921 DAC
× 1
Arduino UNO
× 1
Arduino Wireless Shield(Xbee)
× 1

이 프로젝트 정보

저는 12비트 DAC MCP4822, 헤드폰 증폭기, 2x SPI 메모리(SRAM, EEPROM) 및 SD 카드를 포함한 몇 가지 특수 기능이 있는 AVR ATmega1284p MCU를 기반으로 하는 고급 Arduino 클론을 구축 중입니다. 아날로그 출력을 위한 많은 실제 응용 프로그램이 있지만 Arduino 플랫폼에는 통합 DAC 기능이 없기 때문에 아날로그 신호용으로 게시된 응용 프로그램은 거의 없습니다. 워키토키는 디지털과 아날로그를 함께 사용하여 간단하지만 매우 유용한 프로젝트를 만든 한 가지 예입니다.

Goldilocks 아날로그 - 프로토타입 3

실제 워키토키 기능은 실제로 몇 줄의 코드에 불과하지만 아날로그 입력(샘플링), MCP4822 DAC에 대한 SPI 버스의 아날로그 출력, 샘플 타이밍 루틴 및 XBee 디지털 라디오 플랫폼을 기반으로 구축되었습니다. 위에서부터 시작하여 레이어를 자세히 살펴보겠습니다.

XBee 라디오

지점간 통신을 위해 구성된 XBee Pro S2B 라디오를 사용하고 있습니다. XBee Pro의 경우 하나의 라디오는 코디네이터로, 다른 하나는 라우터로 구성되어야 합니다. 인터넷에 구성 가이드가 있습니다.

패킷을 보내기 전에 최대 문자 간 시간을 기다리도록 라디오를 구성했습니다. 이는 패킷이 가득 찼을 때(84바이트)만 설정된다는 것을 의미합니다. 이것은 무선 처리량을 최대화합니다. 원시 처리량은 250kbit/s이지만 실제 사용자 데이터 속도는 약 32kbit/s로 제한됩니다. 이는 샘플링 속도에 영향을 미치므로 전송할 수 있는 음성 품질에 영향을 미칩니다.

8비트 샘플을 사용하여 약 3kHz 샘플링이 압축 없이 전송할 수 있는 만큼의 데이터를 생성한다는 것을 발견했습니다. 다른 프로젝트를 위해 압축을 남겨두고 있습니다.

XBee 라디오는 두 끝점 사이의 투명한 직렬 파이프 역할을 하는 AT 모드로 구성됩니다. 이것은 디지털 라디오를 통해 두 장치를 연결하는 가장 간단한 방법입니다. 그리고 무선 플랫폼이 작동하는지 여부를 걱정하기 전에 유선을 사용하여 간단한 테스트를 수행할 수 있었습니다.

로직 분석기의 추적을 보면 직렬 포트의 (보라색) Rx 라인에 도착하는 XBee 데이터 패킷을 볼 수 있습니다. 수신된 패킷 데이터는 링 버퍼에 저장되고 일정한 속도로 재생됩니다. 수신 링 버퍼에 최대 255바이트를 허용했으며 XBee 패킷 크기가 84바이트이기 때문에 충분할 것입니다.

다른 장치로 전송될 샘플은 (파란색) Tx 라인을 통해 전송되며, 전송 전에 버퍼링되더라도 각 샘플 주기마다 다소 차이가 있습니다. XBee 라디오는 최대 0xFF 심볼 간 기간(구성) 동안 이러한 바이트를 버퍼링하고 전체 패킷이 있을 때만 다른 엔드포인트로 패킷을 전송합니다.

샘플링 속도

전송 링크의 비트 버짓을 살펴보면 XBee 무선 플랫폼에 과부하가 걸리고 샘플 손실이 발생하지 않고 전송할 수 있는 데이터의 양을 계산해야 합니다. 우리는 음성 샘플을 과도하게 압축하지 않기 때문에 8비트 샘플에 3,000Hz 샘플링 또는 24kbit/s를 전송해야 합니다. 이것은 꽤 잘 작동하는 것 같습니다. 4kHz 샘플링을 시도했지만 이론상 최대값에 너무 가깝고 너무 효율적으로 작동하지 않습니다.

로직 분석기를 보면 Rx 라인에서 0x7E 및 0x7C로 시작하는 바이트 패킷이 도착하는 것을 볼 수 있습니다. 마이크 증폭기와 DAC 출력은 모두 0x7F(FF)를 중심으로 바이어스되므로 여기에서 캡처 및 전송되는 신호 레벨이 매우 낮다는 것을 읽을 수 있습니다. 표시된 샘플 속도는 3,000Hz입니다.

샘플 처리

샘플링 인터럽트가 처리될 때(노란색) 캡처하기 위해 하나의 출력에 "핑"을 넣었습니다. 인터럽트 처리에 소요된 시간의 양은 사용 가능한 총 시간에 비해 이 애플리케이션의 경우 매우 적습니다. 일종의 데이터 압축이 구현될 수 있습니다.

샘플링 인터럽트 동안 DAC에 샘플을 배치하고 ADC를 읽어 오디오 샘플을 캡처하고 USART 버퍼로 전송하여 오디오 출력을 생성하는 두 가지 주요 활동이 있습니다.

이것은 타이머 인터럽트의 코드에서 호출되는 audioCodec_dsp 함수에 의해 수행됩니다.

저는 AVR 8비트 Timer0을 사용하여 인터럽트를 트리거하여 일반 샘플 간격을 생성하고 있습니다. 표준 오디오 주파수의 이진 배수인 MCU FCPU 주파수를 사용하면 클럭 프리스케일러가 64인 8비트 타이머만 사용하여 정확한 재생 샘플링 속도를 생성할 수 있습니다. 44,100Hz와 같은 홀수 오디오 주파수를 생성하려면 16 비트 Timer1을 사용하면 클록 프리스케일러 없이도 충분한 정확도를 얻을 수 있습니다.

ATmega1284p ADC는 자유 실행 모드로 설정되고 192kHz로 축소됩니다. 이것은 ATmega ADC에 대해 문서화된 최대 획득 속도에 가깝지만 여전히 8비트 샘플에 대한 사양 내에 있습니다.

이 인터럽트는 완료하는 데 14 us가 소요되며 각 샘플 기간에 대해 333 us에 비해 매우 짧습니다. 이를 통해 사용자 인터페이스 실행 또는 추가 오디오 처리와 같은 다른 처리를 수행할 수 있는 충분한 시간을 확보할 수 있습니다.

SPI 거래

최종 세부 수준에서 들어오는 샘플을 MCP4822 DAC로 출력하는 실제 SPI 트랜잭션을 볼 수 있습니다.

표준 SPI 버스를 사용하는 Goldilocks Analogue Prototype 2에 이 애플리케이션을 구축했기 때문에 트랜잭션은 정상입니다. 내 이후 프로토타입은 ATmega1284p의 USART 1에서 마스터 SPI 모드를 사용하고 있습니다. 이 모드는 이중 버퍼링을 통해 SPI 트랜잭션을 약간 가속화하고 오디오 스트리밍을 위해 SD 카드 또는 SPI 메모리에 동시 읽기 또는 쓰기를 위해 일반 SPI 버스를 해제합니다. 워키토키 애플리케이션에서는 오디오를 캡처할 필요가 없으므로 구형 프로토타입과 일반 SPI 버스를 사용하는 데 단점이 없습니다.

마무리

몇 가지 기존 도구와 몇 줄의 코드를 사용하여 (이해할 수 있지만 고품질은 아님) 음성 통신이 가능한 디지털 암호화 워키토키를 빠르게 구축할 수 있습니다. 그리고 앞으로의 가족 대화에 귀를 기울일 CB 트럭 운전사는 없습니다.

Goldilocks Analogue에 MAX9814 기반 마이크 입력을 추가하는 테스트였습니다. Prototype 3를 수정하고 마이크 증폭 회로를 추가하여 이 워키토키 예, 음성 체인저 또는 음성 제어 음악 신디사이저와 같이 오디오 입력이 필요한 응용 프로그램을 지원합니다.

XBee 라디오와 마이크 증폭기가 있는 두 개의 Goldilocks 아날로그 프로토타입.

나는 또한 20MHz의 표준 속도보다 24.576MHz의 증가된 주파수에서 ATmega1284p 장치를 실행하고 있습니다. 이 특정 주파수를 사용하면 48kHz에서 4kHz(또는 1,500Hz까지)까지 오디오 샘플을 매우 정확하게 재생할 수 있습니다. 샘플 기간당 추가 MCU 클록 사이클은 합성 음악 생성에 있어 매우 환영합니다.

Sourceforge AVR freeRTOS에서 평소와 같이 코드를 작성하세요. 또한 SeeedStudio에서 OPL을 맡은 Shuyang에게 전화를 걸면 매우 훌륭하고 많은 구성 요소와 PCB의 소스입니다.


<섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

코드

<울>
  • 코드
  • 코드
  • 코드
  • 코드C/C++
    <사전> 무효 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 nulled 신호를 넣습니다. } else if (ringBuffer_GetCount( &(xSerialPort.xRxedChars) )> (portSERIAL_BUFFER_RX>>1) ) // 버퍼가 절반 이상 차면. { cn =ringBuffer_Pop((ringBuffer_t*) &(xSerialPort.xRxedChars) ); // 따라잡기 위해 두 개의 샘플을 팝하고 첫 번째 샘플은 버립니다. cn =ringBuffer_Pop((ringBuffer_t*) &(xSerialPort.xRxedChars) ); } else { 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; // 1/2 10비트 범위를 빼서 샘플을 0으로 중앙에 놓습니다. IIRFilter( &tx_filter, &xn); // 전송된 샘플 트레인 필터링 alaw_compress1(&xn, &cn); // A-Law를 사용하여 압축 xSerialPutChar( &xSerialPort, cn); // 샘플 전송}
    코드C/C++
    ISR(TIMER0_COMPA_vect) __attribute__ ((hot, flatten));ISR(TIMER0_COMPA_vect){#if defined(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);#if defined(DEBUG_PING) // 종료 표시 - 인터럽트 종료 확인 - 디버깅 전용(노란색 추적) PORTD &=~_BV(PORTD7);#endif} 
    코드C/C++
    무효 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는 NULL이므로 DAC를 끕니다. { write.value.u8[1] =CH_A_OFF; } SPI_PORT_SS_DAC &=~SPI_BIT_SS_DAC; // SS를 로우로 당겨 Goldilocks 아날로그 DAC를 선택합니다. SPDR =쓰기.값.u8[1]; // ch_A 전송을 시작합니다. 동안 ( !(SPSR &_BV(SPIF)) ); SPDR =쓰기.값.u8[0]; // ch_A 전송을 계속합니다. if (ch_B !=NULL) // ch_A 전송을 수행하는 동안 ch_B 처리 시작 { write.value.u16 =(*ch_B)>> 4; write.value.u8[1] |=CH_B_OUT; } else // ch_B는 NULL이므로 DAC를 끕니다. { write.value.u8[1] =CH_B_OFF; } 동안 ( !(SPSR &_BV(SPIF)) ); // ch_A가 완료되었는지 확인합니다. SPI_PORT_SS_DAC |=SPI_BIT_SS_DAC; // SS를 하이로 당겨 Goldilocks Analogue DAC를 선택 해제하고 값을 DAC에 래치합니다. SPI_PORT_SS_DAC &=~SPI_BIT_SS_DAC; // SS를 로우로 당겨 Goldilocks 아날로그 DAC를 선택합니다. SPDR =쓰기.값.u8[1]; // ch_B 전송 시작. 동안 ( !(SPSR &_BV(SPIF)) ); SPDR =쓰기.값.u8[0]; // ch_B 전송을 계속합니다. 동안 ( !(SPSR &_BV(SPIF)) ); // ch_B가 완료되었는지 확인합니다. SPI_PORT_SS_DAC |=SPI_BIT_SS_DAC; // SS를 하이로 당겨 Goldilocks Analogue DAC를 선택 해제하고 값을 DAC에 래치합니다.}
    Sourceforge의 AVRfreeRTOS
    이 프로젝트에 사용된 DAC.h 및 아날로그 테스트 파일을 포함한 freeRTOS의 AVR 포트 저장소입니다. 연결된 github 저장소를 사용하지 마십시오. 최신 코드를 보려면 sourceforge로 이동하십시오.https://sourceforge.net/projects/avrfreertos /https://github.com/feilipu/avrfreertos

    회로도

    MCP4822 DAC(SPI)가 아닌 MCP4725 DAC(I2C)를 사용하고 있다는 점에서 절대적으로 정확하지는 않지만 Fritzing에는 올바른 Adafruit 브레이크아웃 보드가 없었습니다.

    또한 한 방향으로만 그려집니다...(Rx와 Tx가 상호 연결되는 경우 제외).
    XBee 보드는 Rx와 Tx를 연결하는 두 개의 와이어를 교체하기만 하면 됩니다. 충분한 데이터를 전달할 수 있는 모든 라디오 세트가 작동합니다. DAC 출력 및 헤드폰 증폭기 회로도.
    마이크 입력 증폭기는 프로토타입 4에 추가됩니다.

    제조공정

    1. 대량 생산 스위스 가공에 대한 고려 사항
    2. CNC 프로토타이핑 가이드
    3. 샤프트 제조 공정 이해
    4. 스테인레스 스틸 패시베이션이란 무엇입니까?
    5. 하나의 GPIO 핀으로 아날로그 센서 읽기
    6. MCP3008을 사용하는 Raspberry Pi의 아날로그 센서
    7. DAC와 맞춤형 PCB를 사용하여 고정밀 파형을 생성하는 방법
    8. 수분 센서가 있는 Win10 IOT 관개 컨트롤러
    9. 아날로그 측정의 가치
    10. 신호 회로용 차폐 케이블(2부)