Obsah:
Video: DTMF detektor: 4 kroky
2024 Autor: John Day | [email protected]. Naposledy zmenené: 2024-01-30 11:59
Prehľad
K zostrojeniu tohto zariadenia ma inšpirovala domáca úloha v online kurze spracovania digitálneho signálu. Toto je dekodér DTMF implementovaný s Arduino UNO, ktorý detekuje číslicu stlačenú na klávesnici telefónu v tónovom režime podľa zvuku, ktorý vydáva.
Krok 1: Pochopenie algoritmu
V DTMF je každý symbol kódovaný dvoma frekvenciami podľa tabuľky na obrázku.
Zariadenie zachytáva vstup z mikrofónu a vypočítava amplitúdy ôsmich frekvencií. Dve frekvencie s maximálnymi amplitúdami poskytujú riadok a stĺpec kódovaného symbolu.
Zber dát
Na vykonanie spektrálnej analýzy by sa vzorky mali zachytávať na určitej predvídateľnej frekvencii. Aby som to dosiahol, použil som voľne spustiteľný režim ADC s maximálnou presnosťou (prescaler 128), ktorý dáva vzorkovaciu frekvenciu 9615 Hz. Nasledujúci kód ukazuje, ako nakonfigurovať ADC Arduina.
zrušiť initADC () {
// inicializácia ADC; f = (16 MHz/predzvárač)/13 cyklov/prevod ADMUX = 0; // Channel sel, right-adj, use AREF pin ADCSRA = _BV (ADEN) | // ADC povoliť _BV (ADSC) | // Spustenie ADC _BV (ADATE) | // Automatické spustenie _BV (ADIE) | // Povolenie prerušenia _BV (ADPS2) | _BV (ADPS1) | _BV (ADPS0); // 128: 1 /13 = 9615 Hz ADCSRB = 0; // Režim voľného chodu DIDR0 = _BV (0); // Vypnutie digitálneho vstupu pre pin ADC TIMSK0 = 0; // Časovač 0 vypnutý} A obsluha prerušenia vyzerá takto ISR (ADC_vect) {uint16_t sample = ADC; sample [samplePos ++] = sample - 400; if (samplePos> = N) {ADCSRA & = ~ _BV (ADIE); // Vyrovnávacia pamäť je plná, prerušenie je vypnuté}}
Analýza spektra
Po zozbieraní vzoriek vypočítam amplitúdy kódujúcich symbolov 8 frekvencií. Na to nepotrebujem spustiť celý FFT, takže som použil Goertzelov algoritmus.
neplatný goertzel (uint8_t *vzorky, float *spektrum) {
float v_0, v_1, v_2; float re, im, amp; pre (uint8_t k = 0; k <IX_LEN; k ++) {float c = pgm_read_float (& (cos_t [k])); float s = pgm_read_float (& (sin_t [k])); plavák a = 2. * c; v_0 = v_1 = v_2 = 0; pre (uint16_t i = 0; i <N; i ++) {v_0 = v_1; v_1 = v_2; v_2 = (float) (vzorky ) + a * v_1 - v_0; } re = c * v_2 - v_1; im = s * v_2; amp = sqrt (re * re + im * im); spektrum [k] = amp; }}
Krok 2: Kód
Obrázok vyššie ukazuje príklad kódovania číslice 3, kde maximálna amplitúda zodpovedá frekvenciám 697 Hz a 1477 Hz.
Kompletný náčrt vyzerá nasledovne
/** * Pripojenia: * [Mic to Arduino] * - Out -> A0 * - Vcc -> 3,3 V * - Gnd -> Gnd * - Arduino: AREF -> 3,3 V * [Display to Arduino] * - Vcc - > 5V * - Gnd -> Gnd * - DIN -> D11 * - CLK -> D13 * - CS -> D9 */ #include #include
#zahrnúť
#define CS_PIN 9
#definovať N 256
#define IX_LEN 8 #define THRESHOLD 20
LEDMatrixDriver lmd (1, CS_PIN);
uint8_t vzorky [N];
volatile uint16_t samplePos = 0;
float spektrum [IX_LEN];
// Frekvencie [697,0, 770,0, 852,0, 941,0, 1209,0, 1336,0, 1477,0, 1633,0]
// Vypočítané pre 9615Hz 256 vzoriek const float cos_t [IX_LEN] PROGMEM = {0,8932243011955153, 0,8700869911087115, 0,8448535652497071, 0,8032075314806449, 0,6895405447370669, 0,6343932841636459, 0,0055570 const float sin_t [IX_LEN] PROGMEM = {0,44961132965460654, 0,49289819222978404, 0,5349976198870972, 0,5956993044924334, 0,7242470829514669, 0,7730104533627369, 0,8314696123025451, 0,198
typedef struct {
znaková číslica; uint8_t index; } digit_t;
digit_t detekovaný_číslica;
konštantná tabuľka [4] [4] PROGMEM = {
{'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', ' C '}, {'*',' 0 ','#',' D '}};
const uint8_t char_indexes [4] [4] PROGMEM = {
{1, 2, 3, 10}, {4, 5, 6, 11}, {7, 8, 9, 12}, {15, 0, 14, 13} };
bajtové písmo [16] [8] = {
{0x00, 0x38, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x38}, // 0 {0x04, 0x0c, 0x14, 0x24, 0x04, 0x04, 0x04, 0x04}, // 1 {0x00, 0x30, 0x48, 0x04, 0x04, 0x38, 0x40, 0x7c}, // 2 {0x00, 0x38, 0x04, 0x04, 0x18, 0x04, 0x44, 0x38}, // 3 {0x00, 0x04, 0x0c, 0x14, 0x24, 0x7e, 0x04, 0x0 }, // 4 {0x00, 0x7c, 0x40, 0x40, 0x78, 0x04, 0x04, 0x38}, // 5 {0x00, 0x38, 0x40, 0x40, 0x78, 0x44, 0x44, 0x38}, // 6 {0x00, 0x7c, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10}, // 7 {0x00, 0x3c, 0x44, 0x44, 0x38, 0x44, 0x44, 0x78}, // 8 {0x00, 0x38, 0x44, 0x44, 0x3c, 0x04, 0x04, 0x78}, // 9 {0x00, 0x1c, 0x22, 0x42, 0x42, 0x7e, 0x42, 0x42}, // A {0x00, 0x78, 0x44, 0x44, 0x78, 0x44, 0x44, 0x7c}, / / B {0x00, 0x3c, 0x44, 0x40, 0x40, 0x40, 0x44, 0x7c}, // C {0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78}, // D {0x00, 0x0a, 0x7f, 0x14, 0x28, 0xfe, 0x50, 0x00}, // # {0x00, 0x10, 0x54, 0x38, 0x10, 0x38, 0x54, 0x10} // *};
zrušiť initADC () {
// inicializácia ADC; f = (16 MHz/predzvárač)/13 cyklov/prevod ADMUX = 0; // Channel sel, right-adj, use AREF pin ADCSRA = _BV (ADEN) | // ADC povoliť _BV (ADSC) | // Spustenie ADC _BV (ADATE) | // Automatické spustenie _BV (ADIE) | // Povolenie prerušenia _BV (ADPS2) | _BV (ADPS1) | _BV (ADPS0); // 128: 1 /13 = 9615 Hz ADCSRB = 0; // Režim voľného chodu DIDR0 = _BV (0); // Vypnutie digitálneho vstupu pre pin ADC TIMSK0 = 0; // Časovač 0 vypnutý}
neplatný goertzel (uint8_t *vzorky, float *spektrum) {
float v_0, v_1, v_2; float re, im, amp; pre (uint8_t k = 0; k <IX_LEN; k ++) {float c = pgm_read_float (& (cos_t [k])); float s = pgm_read_float (& (sin_t [k])); plavák a = 2. * c; v_0 = v_1 = v_2 = 0; pre (uint16_t i = 0; i <N; i ++) {v_0 = v_1; v_1 = v_2; v_2 = (float) (vzorky ) + a * v_1 - v_0; } re = c * v_2 - v_1; im = s * v_2; amp = sqrt (re * re + im * im); spektrum [k] = amp; }}
float avg (float *a, uint16_t len) {
výsledok float = 0,0; pre (uint16_t i = 0; i <len; i ++) {výsledok+= a ; } vrátiť výsledok / len; }
int8_t get_single_index_above_threshold (float *a, uint16_t len, float threshold) {
if (prah <THRESHOLD) {return -1; } int8_t ix = -1; pre (uint16_t i = 0; i prah) {if (ix == -1) {ix = i; } else {return -1; }}} vrátiť ix; }
neplatné detect_digit (float *spektrum) {
float avg_row = avg (spektrum, 4); float avg_col = avg (& spektrum [4], 4); int8_t riadok = get_single_index_above_threshold (spektrum, 4, priemer_row); int8_t col = get_single_index_above_threshold (& spektrum [4], 4, avg_col); if (riadok! = -1 && col! = -1 && avg_col> 200) {detekovany_digit.digit = pgm_read_byte (& (tabuľka [riadok] [stĺp])); detekovaný_digit.index = pgm_read_byte (& (char_indexes [riadok] [stĺpec])); } else {detekovany_digit.digit = 0; }}
void drawSprite (byte* sprite) {
// Maska sa používa na získanie bitu stĺpca z masky bajtu sprite radu = B10000000; for (int iy = 0; iy <8; iy ++) {for (int ix = 0; ix <8; ix ++) {lmd.setPixel (7 - iy, ix, (bool) (sprite [iy] & mask));
// posun masky o jeden pixel doprava
maska = maska >> 1; }
// reset masky stĺpca
maska = B10000000; }}
neplatné nastavenie () {
cli (); initADC (); sei ();
Serial.begin (115200);
lmd.setEnabled (true); lmd.setIntensity (2); lmd.clear (); lmd.display ();
detekovaný_digit.digit = 0;
}
bez znamienka dlhý z = 0;
prázdna slučka () {
while (ADCSRA & _BV (ADIE)); // Počkajte na dokončenie vzorkovania zvuku goertzel (vzorky, spektrum); detect_digit (spektrum);
if (identified_digit.digit! = 0) {
drawSprite (font [detekovaný_digit.index]); lmd.display (); } if (z % 5 == 0) {for (int i = 0; i <IX_LEN; i ++) {Serial.print (spektrum ); Serial.print ("\ t"); } Serial.println (); Serial.println ((int) detekovaná_číslica.digit); } z ++;
samplePos = 0;
ADCSRA | = _BV (ADIE); // Obnovte prerušenie vzorkovania
}
ISR (ADC_vect) {
uint16_t sample = ADC;
vzorky [samplePos ++] = vzorka - 400;
if (samplePos> = N) {ADCSRA & = ~ _BV (ADIE); // Buffer plný, prerušenie vypnuté}}
Krok 3: Schémy
Mali by sa vykonať nasledujúce pripojenia:
Z mikrofónu na Arduino
Out -> A0
Vcc -> 3,3 V Gnd -> Gnd
Je dôležité pripojiť AREF na 3,3V
Zobraziť na Arduino
Vcc -> 5V
Gnd -> Gnd DIN -> D11 CLK -> D13 CS -> D9
Krok 4: Záver
Čo by sa tu dalo zlepšiť? Použil som N = 256 vzoriek pri frekvencii 9615 Hz, ktorá má určitý únik spektra, ak N = 205 a rýchlosť je 8 000 Hz, potom sa požadované frekvencie zhodujú s diskretizačnou mriežkou. Na to by sa mal ADC používať v režime pretečenia časovača.
Odporúča:
Raspberry Pi - TMD26721 Infračervený digitálny bezdotykový detektor Java Výukový program: 4 kroky
Raspberry Pi-TMD26721 Infračervený digitálny bezdotykový detektor Java Výukový program: TMD26721 je infračervený digitálny bezdotykový detektor, ktorý poskytuje kompletný systém detekcie priblíženia a logiku digitálneho rozhrania v jednom 8-kolíkovom module na povrchovú montáž. Detekcia blízkosti obsahuje vylepšený signál-šum a presnosť. Profesionál
DTMF VIDEO STREAMING ROVER: 3 kroky
DTMF VIDEO STREAMING ROVER: ahoj po mojom LINUX TERMINAL CONTROLLED ROVER a WIFI DTMF PC CONTROLLED ROBOT toto je môj tretí robot. a ako ďalšie dva aj tu som nepoužil žiadny mikrokontrolér ani programovanie, aby bola jednoduchá a ľahko vyrobiteľná. Tiež streamuje živé video cez wifi
Ako vytvoriť jednoduchý dekodér telefónnej linky DTMF (tón): 3 kroky
Ako vytvoriť jednoduchý dekodér telefónnej linky DTMF (tón): Jedná sa o jednoduchý projekt, ktorý vám umožní dekódovať signály DTMF v zásade na akejkoľvek telefónnej linke. V tomto návode používame dekodér MT8870D. Používame preddefinovaný dekodér tónov, pretože verte mi, je to bolesť v zadných partiách, pokúsiť sa to urobiť pomocou
Detektor dymu IOT: Aktualizujte existujúci detektor dymu pomocou IOT: 6 krokov (s obrázkami)
IOT Detektor dymu: Aktualizujte existujúci detektor dymu pomocou IOT: Zoznam prispievateľov, Vynálezca: Tan Siew Chin, Tan Yit Peng, Tan Wee Heng Vedúci: Dr Chia Kim Seng Katedra mechatronického a robotického inžinierstva, Fakulta elektrotechniky a elektroniky, Universiti Tun Hussein Onn Malajsie. Distribuovať
DTMF riadené auto. Nevyžadujú sa žiadne mobilné telefóny: 3 kroky
DTMF riadené auto. Nevyžadujú sa žiadne mobilné telefóny: Roboty a autá Robo sú v zásade novými hračkami pre technologických nadšencov aj vedcov po celom svete. všade nachádzajú uplatnenie. V tomto návode vám vysvetlím, ako vyrobiť robotické auto ovládané DTMF pomocou arduina a