Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

XBee Walkie Talkie

Komponenten und Verbrauchsmaterialien

Goldlöckchen-Analog
Derzeit noch als Prototyp, aber die Funktionalität kann mit MCP4822 DAC, Mikrofonverstärker und Kopfhörerverstärker nachgebildet werden. zusammen mit Arduino Uno.
× 1
MAX9744
× 1
MAX9814
× 1
MCP4921 DAC
× 1
Arduino UNO
× 1
Arduino Wireless Shield (Xbee)
× 1

Über dieses Projekt

Ich baue einen fortschrittlichen Arduino-Klon basierend auf der AVR ATmega1284p MCU mit einigen Besonderheiten, darunter einen 12-Bit-DAC MCP4822, einen Kopfhörerverstärker, 2x SPI-Speicher (SRAM, EEPROM) und eine SD-Karte. Es gibt viele reale Anwendungen für analoge Ausgänge, aber da die Arduino-Plattform keine integrierte DAC-Funktion hat, gibt es nur sehr wenige veröffentlichte Anwendungen für analoge Signale. Ein Walkie Talkie ist ein Beispiel für die gemeinsame Verwendung von Digital und Analog, um ein einfaches, aber sehr nützliches Projekt zu erstellen.

Goldlöckchen Analog - Prototyp 3

Die eigentliche Walkie-Talkie-Funktionalität besteht eigentlich nur aus wenigen Codezeilen, aber sie basiert auf einer analogen Eingabe (Sampling), einer analogen Ausgabe auf dem SPI-Bus zum MCP4822 DAC, Sample-Timing-Routinen und der XBee-Digitalradioplattform. Beginnen wir von oben und graben wir uns dann durch die Schichten.

XBee-Radio

Ich verwende XBee Pro S2B-Funkgeräte, die für die Punkt-zu-Punkt-Kommunikation konfiguriert sind. Für den XBee Pro muss ein Funkgerät als Koordinator und das andere als Router konfiguriert sein. Im Internet gibt es Konfigurationsanleitungen.

Ich habe die Funkgeräte so konfiguriert, dass sie die maximale Zeit zwischen den Zeichen warten, bevor ein Paket gesendet wird, was bedeutet, dass die Pakete nur gesetzt werden, wenn sie voll sind (84 Byte). Dies maximiert den Funkdurchsatz. Der Rohdurchsatz beträgt 250 kbit/s, die tatsächliche Nutzdatenrate ist jedoch auf etwa 32 kbit/s begrenzt. Dies hat Auswirkungen auf die Abtastrate und damit auf die Sprachqualität, die übertragen werden kann.

Bei Verwendung von 8-Bit-Samples habe ich festgestellt, dass bei einer Abtastung von 3 kHz ungefähr so ​​viele Daten generiert werden, wie ohne Komprimierung übertragen werden können. Ich verlasse die Komprimierung für ein anderes Projekt.

Die XBee-Funkgeräte sind im AT-Modus konfiguriert, der als transparente serielle Pipe zwischen den beiden Endpunkten fungiert. Dies ist die einfachste Möglichkeit, zwei Geräte über Digitalfunk zu verbinden. Und es ermöglichte mir, einfache Tests mit Kabel durchzuführen, bevor ich mir Sorgen machte, ob die Funkplattform funktioniert oder nicht.

Betrachtet man das Tracing eines Logikanalysators, sieht man die XBee-Datenpakete, die auf der (lila) Rx-Leitung des seriellen Ports ankommen. Die empfangenen Paketdaten werden in einem Ringpuffer gespeichert und mit konstanter Rate abgespielt. Ich habe bis zu 255 Byte im Empfangsringpuffer zugelassen, und dies wird ausreichen, da die XBee-Paketgröße 84 Byte beträgt.

Die an das andere Gerät zu übertragenden Abtastwerte werden auf der (blauen) Tx-Leitung übertragen, mehr oder weniger in jeder Abtastperiode, obwohl sie vor der Übertragung zwischengespeichert werden. Das XBee-Funkgerät puffert diese Bytes für bis zu 0xFF-Intersymbolperioden (Konfiguration) und überträgt ein Paket nur dann an den anderen Endpunkt, wenn es ein volles Paket hat.

Abtastrate

Mit Blick auf das Bitbudget für die Übertragungsstrecke müssen wir berechnen, wie viele Daten übertragen werden können, ohne die XBee-Funkplattform zu überlasten und Sample-Verluste zu verursachen. Da wir die Sprachsamples nicht offen komprimieren, müssen wir 8-Bit-Samples mal 3.000 Hz-Sampling oder 24 kbit/s übertragen. Dies scheint ziemlich gut zu funktionieren. Ich habe 4 kHz Sampling ausprobiert, aber das ist zu nah am theoretischen Maximum und funktioniert nicht allzu effektiv.

Wenn wir uns den Logikanalysator ansehen, können wir die Ankunft eines Pakets von Bytes sehen, das mit 0x7E und 0x7C auf der Rx-Leitung beginnt. Sowohl der Mikrofonverstärker als auch der DAC-Ausgang haben eine Vorspannung von 0 x 7 F(FF), sodass wir ablesen können, dass die hier erfassten und übertragenen Signalpegel sehr niedrig sind. Die angezeigte Abtastrate beträgt 3.000 Hz.

Probenverarbeitung

Ich habe einen "Ping" an einen Ausgang gelegt, um zu erfassen, wann der Sampling-Interrupt verarbeitet wird (gelb). Wir sehen, dass der Zeitaufwand für die Interrupt-Verarbeitung für diese Anwendung im Verhältnis zur verfügbaren Gesamtzeit sehr gering ist. Möglicherweise könnte eine Art Datenkomprimierung implementiert werden.

Während des Sampling-Interrupts gibt es zwei Hauptaktivitäten:Generieren einer Audioausgabe durch Platzieren eines Samples auf dem DAC und anschließendes Lesen des ADC, um ein Audio-Sample zu erfassen und an den USART-Puffer zu übertragen.

Dies geschieht durch die Funktion audioCodec_dsp, die aus dem Code in einem Timer-Interrupt aufgerufen wird.

Ich verwende den AVR 8-Bit-Timer0, um die regelmäßigen Abtastintervalle durch Auslösen eines Interrupts zu generieren. Durch die Verwendung einer MCU-FCPU-Frequenz, die ein binäres Vielfaches der Standard-Audiofrequenzen ist, können wir genaue Wiedergabe-Abtastraten erzeugen, indem wir nur den 8-Bit-Timer mit einem Taktvorskalierer von 64 verwenden. Um ungerade Audiofrequenzen wie 44.100 Hz zu erzeugen, ist der 16 bit Timer1 kann verwendet werden, um eine ausreichende Genauigkeit zu erreichen, ohne dass ein Taktvorskalierer erforderlich ist.

Der ATmega1284p ADC ist auf den Free-Run-Modus eingestellt und auf 192 kHz herunterskaliert. Dies ist zwar nahe der maximalen Erfassungsgeschwindigkeit, die für den ATmega-ADC dokumentiert ist, liegt aber immer noch innerhalb der Spezifikation für 8-Bit-Samples.

Dieser Interrupt dauert 14 us und ist im Vergleich zu den 333 us, die wir für jede Abtastperiode haben, sehr kurz. Dadurch haben wir viel Zeit für andere Bearbeitungen, wie zum Beispiel das Ausführen einer Benutzeroberfläche oder die weitere Audiobearbeitung.

SPI-Transaktion

Auf der letzten Detailebene können wir die eigentliche SPI-Transaktion sehen, um das eingehende Sample an den MCP4822 DAC auszugeben.

Da ich diese Anwendung auf dem Goldilocks Analogue Prototype 2 erstellt habe, der den Standard-SPI-Bus verwendet, ist die Transaktion normal. Meine späteren Prototypen verwenden den Master-SPI-Modus auf USART 1 des ATmega1284p, der die SPI-Transaktion durch doppelte Pufferung leicht beschleunigt und den normalen SPI-Bus zum gleichzeitigen Lesen oder Schreiben auf die SD-Karte oder den SPI-Speicher für Audiostreaming freigibt. In der Walkie-Talkie-Anwendung ist es nicht erforderlich, das Audio aufzunehmen, daher gibt es keine Nachteile bei der Verwendung der älteren Prototypen und des normalen SPI-Busses.

Abschluss

Unter Verwendung einiger bereits vorhandener Tools und einiger Codezeilen ist es möglich, schnell ein digital verschlüsseltes Walkie-Talkie zu erstellen, das in der Lage ist, (verständliche, aber nicht hochwertige) Stimme zu übertragen. Und es wird keine CB-Trucker mehr geben, die den Familiengesprächen zuhören werden.

Dies war ein Test zum Hinzufügen eines Mikrofoneingangs basierend auf dem MAX9814 zum Goldlöckchen-Analog. Ich werde den Prototype 3 überarbeiten und eine Mikrofonverstärkungsschaltung hinzufügen, um Anwendungen zu unterstützen, die eine Audioeingabe benötigen, wie dieses Walkie-Talkie-Beispiel oder Sprachwechsler oder stimmgesteuerte Musiksynthesizer.

Zwei Goldlöckchen-Analog-Prototypen mit XBee-Funkgeräten und Mikrofonverstärkern.

Ich betreibe auch die ATmega1284p-Geräte mit der erhöhten Frequenz von 24,576 MHz über der Standardrate von 20 MHz. Diese spezielle Frequenz ermöglicht eine sehr präzise Wiedergabe von Audio-Samples von 48 kHz bis hinunter zu 4 kHz (oder sogar bis hinunter zu 1.500 Hz). Die zusätzlichen MCU-Taktzyklen pro Abtastperiode sind sehr willkommen, wenn es darum geht, synthetisierte Musik zu erzeugen.

Code wie gewohnt auf Sourceforge AVR freeRTOS Außerdem ist ein Anruf bei Shuyang von SeeedStudio, dessen OPL großartig ist und die Quelle vieler Komponenten und PCBs ist, großartig.


Code

  • Code
  • Code
  • Code
CodeC/C++
void audioCodec_dsp( uint16_t * ch_A, uint16_t * ch_B){ int16_t xn; uint8_tcn; /*----- Audio Rx -----*/ /* Hole das nächste Zeichen aus dem Ringpuffer. */ if(ringBuffer_IsEmpty((ringBuffer_t*) &(xSerialPort.xRxedChars))) {cn =0x80 ^ 0x55; // A-Law-nulliertes Signal auf den Ausgang setzen. } else if (ringBuffer_GetCount( &(xSerialPort.xRxedChars) )> (portSERIAL_BUFFER_RX>>1) ) // wenn der Puffer mehr als halb voll ist. { cn =ringBuffer_Pop( (ringBuffer_t*) &(xSerialPort.xRxedChars)); // Zwei Samples aufholen, um aufzuholen, das erste verwerfen. cn =ringBuffer_Pop( (ringBuffer_t*) &(xSerialPort.xRxedChars) ); aufrechtzuerhalten. Sonst { cn =ringBuffer_Pop( (ringBuffer_t*) &(xSerialPort.xRxedChars)); // eine Probe einfügen } alaw_expand1(&cn, &xn); // Erweiterung der A-Law-Komprimierung *ch_A =*ch_B =(uint16_t)(xn + 0x7fff); // Verschieben Sie das Signal auf positive Werte, geben Sie das Signal auf dem A- und B-Kanal aus. /*----- Audio Tx -----*/ AudioCodec_ADC( &mod7_value.u16 ); // Sample ist 10 Bit linksbündig. xn =mod7_value.u16 - 0x7fe0; // zentrieren Sie das Sample auf 0, indem Sie 1/2 10-Bit-Bereich subtrahieren. IIRFilter( &tx_filter, &xn); // übertragenen Sample-Train filtern alaw_compress1(&xn, &cn); // komprimieren mit A-Law xSerialPutChar( &xSerialPort, cn); // Probe übertragen}
CodeC/C++
ISR(TIMER0_COMPA_vect) __attribute__ ((hot, flatten));ISR(TIMER0_COMPA_vect){#if define(DEBUG_PING) // Startmarkierung - Check auf Interruptstart - nur für Debugging (gelber Trace) PORTD |=_BV( PORTD7); // Ping IO line.#endif // MCP4822 Datenübertragungsroutine // Verschieben Sie die Daten auf den MCP4822 - erfolgt zuerst aus Gründen der Regelmäßigkeit (reduzierter Jitter). DAC_out (ch_A_ptr, ch_B_ptr); // Audio-Processing-Routine - tun Sie, was auch immer an der Eingabe erforderlich ist - bereiten Sie die Ausgabe für das nächste Sample vor. // Den globalen Audio-Handler auslösen, der eine Rückruffunktion ist, falls gesetzt. if (audioHandler!=NULL) audioHandler(ch_A_ptr, ch_B_ptr);#if define(DEBUG_PING) // Endmarkierung - Check auf Interrupt-Ende - nur für Debugging (gelbe Spur) PORTD &=~_BV(PORTD7);#endif} 
CodeC/C++
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 ist NULL, also schalten wir den DAC aus { write.value.u8[1] =CH_A_OFF; } SPI_PORT_SS_DAC &=~SPI_BIT_SS_DAC; // Ziehen Sie SS niedrig, um den analogen Goldlöckchen-DAC auszuwählen. SPDR =write.value.u8[1]; // Beginn der Übertragung ch_A. while ( !(SPSR &_BV(SPIF)) ); SPDR =write.value.u8[0]; // Übertragung fortsetzen ch_A. if (ch_B !=NULL) // Verarbeitung von ch_B starten, während wir die ch_A-Übertragung durchführen { write.value.u16 =(*ch_B)>> 4; write.value.u8[1] |=CH_B_OUT; } else // ch_B ist NULL, also schalten wir den DAC aus { write.value.u8[1] =CH_B_OFF; } while ( !(SPSR &_BV(SPIF)) ); // prüfe, ob wir ch_A fertig haben. SPI_PORT_SS_DAC |=SPI_BIT_SS_DAC; // Ziehen Sie SS hoch, um den analogen Goldlöckchen-DAC abzuwählen und den Wert in den DAC zu verriegeln. SPI_PORT_SS_DAC &=~SPI_BIT_SS_DAC; // Ziehen Sie SS niedrig, um den analogen Goldlöckchen-DAC auszuwählen. SPDR =write.value.u8[1]; // Beginn der Übertragung ch_B. while ( !(SPSR &_BV(SPIF)) ); SPDR =write.value.u8[0]; // Übertragung fortsetzen ch_B. while ( !(SPSR &_BV(SPIF)) ); // prüfe, ob wir ch_B fertig haben. SPI_PORT_SS_DAC |=SPI_BIT_SS_DAC; // Ziehen Sie SS hoch, um den Goldilocks-Analog-DAC abzuwählen und den Wert in den DAC zu verriegeln.}
AVRfreeRTOS bei Sourceforge
Repository des AVR-Ports von freeRTOS, einschließlich der in diesem Projekt verwendeten DAC.h- und Analogue-Testdateien.Bitte verwenden Sie NICHT das verlinkte Github-Repository.Gehen Sie zu Sourceforge für den neuesten Code.https://sourceforge.net/projects/avrfreertos /https://github.com/feilipu/avrfreertos

Schaltpläne

Es ist nicht absolut korrekt, da es einen MCP4725 DAC (I2C) und keinen MCP4822 DAC (SPI) verwendet, aber Fritzing hatte nicht das richtige Adafruit Breakout Board.

Außerdem wird es nur in eine Richtung gezeichnet... (mit der Ausnahme, dass Rx und Tx miteinander verbunden sind).
Die XBee-Boards ersetzen einfach die beiden Drähte, die Rx und Tx verbinden. Jedes Funkgerät, das genügend Daten übertragen kann, würde funktionieren. Schema für den DAC-Ausgang und den Kopfhörerverstärker.
Bei Prototyp 4 wird ein Mikrofoneingangsverstärker hinzugefügt.

Herstellungsprozess

  1. Überlegungen zur Schweizer Hochproduktionsbearbeitung
  2. Leitfaden zum CNC-Prototyping
  3. Den Wellenherstellungsprozess verstehen
  4. Was ist eine Edelstahlpassivierung?
  5. Lesen analoger Sensoren mit einem GPIO-Pin
  6. Analoge Sensoren auf dem Raspberry Pi mit einem MCP3008
  7. Generieren einer hochpräzisen Wellenform mit einem DAC und einer benutzerdefinierten Leiterplatte
  8. Win10 IOT-Bewässerungssteuerung mit Feuchtigkeitssensoren
  9. Der Wert der analogen Messung
  10. Abgeschirmte Kabel für Signalschaltkreise (Teil 2)