Dtmf gsm

Малек
Offline
Зарегистрирован: 15.08.2017

Чем заменить телефон в схеме dtmf?

Здравствуйте дорогие форумчане ! Я уже год пытаюсь создать свой проект dtmf но есть одна проблема , я не хочу чтобы в проекте участвовал телефон привязанный к ардуино .чем можно его заменить (gsm модуль например)? Заранее огромное спасибо.

b707
Offline
Зарегистрирован: 26.05.2017

gsm модем с поддержкой dtmf, например sim800

Хотя. если вы за год не сумели в гугле набрать что-то типа "arduino gsm dtmf" - шансы, что вы что-то сумеете сделать минимальны.

Малек
Offline
Зарегистрирован: 15.08.2017

Извините я не правильно написал , ардуино в принципе я занимался всего год а конкретно темой gsm около двух месяцев. И если вас не затруднит , посоветуйте скетч и схему подключения, еще раз заранее благодарен.:-)

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Запишитесь на курсы обучения пользования гуглом

https://www.google.com/search?q=arduino+gsm+dtmf

https://www.google.com/search?q=arduino+dtmf

Малек
Offline
Зарегистрирован: 15.08.2017

Извините пожалуйста. Я хочу использовать не готовый шилд а только модем. Если вам не сложно подскажите пожалуйста схему подключения к ардуино. Просто темой gsm не так долго занимаюсь . :-\

Малек
Offline
Зарегистрирован: 15.08.2017

В google даны примеры подключения шилда а не модема и если искать arduino gsm нахожу только про sms (которое я не хочу использовать). заранее спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

Малек, а для чего Жека в сообщении #3 даже строки для поиска за вас набрал? Ну зайдите же туда! Там даже ролики на Ютубе есть - для полных идиотов, что читать не умеют, а только кино смотреть.

Почитайте, посмотрите, как люди DTMF декодируют, какими модемами пользуются, с какими проблемами сталкиваются. Вникните в задачу. Выберите модем. Потом изучите, как его подключать - пока без DTMF. Начитесь коннектить его к ардуине, отправлять команды и получать ответы. Затем начинайте изучать DTMF.

Учитесь находить информацию самостоятельно! А вот когда вы будете почти все знать - тогда приходите с вопросами, вам помогут.

Малек
Offline
Зарегистрирован: 15.08.2017

спасибо я с dtmf работать умею у меня все получалось но с телефоном, а в gsm я ничего не знаю и хотел получить что то проверенное чтобы не сталкиваться с проблемами . Но видимо надо самому искать и натыкатся на проблемы.
Но если кто-то может избавить меня от этого и предложить что-то готовое то буду очень признателен! Заранее благодарю :-)

Малек
Offline
Зарегистрирован: 15.08.2017

Ещё раз здравствуйте! Вот нашел по вашим ссылкам— http://arduinolab.pw/index.php/2016/07/26/dekodirovanie-dtmf-signala-gsm... . Первое: будет ли устройство само поднимать трубку (автоответчик) ? Второе : можно ли заменить gsm модуль на другой (sim 800c , sim 800 )? Спасибо за любую помощь!

b707
Offline
Зарегистрирован: 26.05.2017

Малек, опять то же самое...  вы совершенно не умеете пользоваться информацией... На первый вопрос ответ в той самой ссылке. что вы привели - в скетче есть команда подъема трубки, смотрите внимательно

На второй - достаточно спросить у Гугля. есть ли в sim800c DTMF ? - ответ есть.

 

Я вообще замечаю, что есть такой тип людей, которые не верят написанному. Типа, в книжке любую хрень написать можно, а уж если сосед Вася сказал - то это точно! :)

Малек
Offline
Зарегистрирован: 15.08.2017

Это я :-[ . И не чего с этим не поделаешь :-) спасибо за помощь!

Logik
Offline
Зарегистрирован: 05.08.2014

DTMF отлично генерится и распознается самой ардуиной, без аппаратных прибамбасов совершенно програмным путем. Например тут я игрался.

#include <fix_fft.h>
#include "SSD1306.h"
#define OLED_SCL_PIN A2
#define OLED_SDA_PIN A3
#define OLED_VCC_PIN A1
#define OLED_GND_PIN A0

 uint16_t dF_A;  
 uint16_t dF_B;
 volatile word inpCount;
 volatile byte Arr[512];
 volatile bool FlInternal;
 volatile bool FlDiscr;
 byte F_8k;
 byte dF_8k;
 byte bpfN=7;
  
ISR(TIMER1_OVF_vect) 
{
 static uint16_t F_A;  
 static uint16_t F_B;

 F_A=dF_A?F_A+dF_A:0; 
 F_B=dF_B?F_B+dF_B:0; 

  unsigned int w=127+TabSin(F_A>>8)/2+TabSin(F_B>>8)/2;

  OCR1A=w>255?255:w;
  w=FlInternal?w:ADCH;
  byte y=F_8k+dF_8k;
  if(inpCount<sizeof(Arr)&&((y<F_8k)||(dF_8k==0))) //набираем данные в буфер 254 значения (кроме 0-го и 255-го) и останавливаемся
  {
   Arr[inpCount]=w;
   inpCount++;
  }

  F_8k=y;
  ADCSRA|=_BV(ADSC);// Запускаем преобразование 
}

#define PERIOD(f) ((0x10000*f)/62500)

#define PERIOD_1209 PERIOD(1209)
#define PERIOD_1336 PERIOD(1336)
#define PERIOD_1477 PERIOD(1477)
#define PERIOD_1633 PERIOD(1633)
#define PERIOD_697 PERIOD(697)
#define PERIOD_770 PERIOD(770)
#define PERIOD_852 PERIOD(852)
#define PERIOD_941 PERIOD(941)

struct FRIQ
{
  char key;
  uint16_t F1;
  uint16_t F2;  
};

FRIQ Friq[24]=
{
 {'Q',PERIOD_1209,0}, 
 {'W',PERIOD_1336,0}, 
 {'E',PERIOD_1477,0}, 
 {'R',PERIOD_1633,0}, 
 {'T',PERIOD_697,0}, 
 {'Y',PERIOD_770,0}, 
 {'U',PERIOD_852,0}, 
 {'I',PERIOD_941,0}, 
 {'1',PERIOD_1209,PERIOD_697}, 
 {'4',PERIOD_1209,PERIOD_770}, 
 {'7',PERIOD_1209,PERIOD_852}, 
 {'*',PERIOD_1209,PERIOD_941}, 
 {'2',PERIOD_1336,PERIOD_697},
 {'5',PERIOD_1336,PERIOD_770},
 {'8',PERIOD_1336,PERIOD_852},
 {'0',PERIOD_1336,PERIOD_941},
 {'3',PERIOD_1477,PERIOD_697},
 {'6',PERIOD_1477,PERIOD_770},
 {'9',PERIOD_1477,PERIOD_852},
 {'#',PERIOD_1477,PERIOD_941},
 {'A',PERIOD_1633,PERIOD_697},
 {'B',PERIOD_1633,PERIOD_770},
 {'C',PERIOD_1633,PERIOD_852},
 {'D',PERIOD_1633,PERIOD_941}
};
 


ssd1306_i2c(OLED_SCL_PIN, OLED_SDA_PIN, myOLED) ;

void setup()
{
  pinMode(OLED_GND_PIN, OUTPUT);
  digitalWrite(OLED_GND_PIN, LOW);
  pinMode(OLED_VCC_PIN, OUTPUT);
  digitalWrite(OLED_VCC_PIN, HIGH);
  delay(1);
  	
  Serial.begin(57600);
  myOLED.begin();
  myOLED.clrScr();
  //myOLED.setFont( SSD1306::FONT_SIZE_2); 
  //myOLED.drawString(2,5,"Аналог");

  pinMode(9, OUTPUT);

  TIMSK1|=1; //TOIE1
  
 /* clear OC1A on Compare Match, set OC1A at TOP */
 TCCR1A =   _BV(COM1A1); 
 /* fast PWM, 8 bit */
 TCCR1A |=  _BV(WGM10);
 TCCR1B = _BV(WGM12) ;
 /* no prescaling */
 TCCR1B |= _BV(CS10) ;

  dF_A=PERIOD_1477;
  dF_B=PERIOD_941;
  dF_8k=33;
  

 DIDR0 =  _BV(ADC4D); // отключаем цифровые входы
 ADMUX = _BV(REFS0)  | _BV(ADLAR) | _BV(MUX2);// измеряем на ADC4, используем опорное напр.= 5В
 //ADMUX = _BV(REFS0) | _BV(REFS1) | _BV(ADLAR) | _BV(MUX2);// измеряем на ADC4, используем внутреннее опорное напр.= 1.1В
 ADCSRA = 0x84; // включаем АЦП, разрешаем прерывания, делитель = 16
 ADCSRB = 0x40; 
}


signed char TabSin(unsigned char x)
{
// byte TabSin[32]={0, 13, 25, 37, 50, 62, 74, 86, 98,109,120,131,142,152,162,171,  180,
//               189,197,204,212,219,225,230,235,240,244,247,250,252,253,254,255};
 
// const byte TabSin_[32]={0, 6, 12, 18, 25, 31, 37, 43, 49, 55, 60, 66, 71, 76, 81, 86, 
//                 90,94, 98,102,106,110,113,115,118,120,122,124,125,126,126,127};
const byte TabSin[64]={0, 3,  6,  9, 12, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49,
                       51, 54, 57, 60, 63, 65, 68, 71, 73, 76, 78, 81, 83, 85, 88, 90,
                       92, 94, 96, 98,100,102,104,106,107,109,111,112,113,115,116,117,
                      118,120,121,122,122,123,124,125,125,126,126,126,127,127,127};

signed char r=TabSin[((x&0x40)?-x-1:x)&0x3f];
 if(x&0x80)
   return -r;
 return r;
 
  
}

// алгоритма Гёрцеля 36мксек
byte Gyorcely(byte aa)
{
  static uint16_t arrS[7*2];
  //частота Гц:       1209, 1336, 1477, 697, 770, 852, 941
  const int8_t arrK[7]={21,    0,  -26,  27,  19,   9,  -3 }; //коєфф определяется для i=0..2  K=1+arrK[i], для остальных K=1,5+arrK[i]

 uint16_t x=aa;//analogRead(A1);

 uint8_t res;
 uint16_t* p = arrS;
 res=0;
 for(byte i=0;i<7;i++)
 {
   uint16_t tmp=*p;
   *p=*(p+1);
   p++;
    
   //тут вывод
   long int l=(*p)*tmp;
   l+=(i>2?l>>1:0)+(((*p)*(arrK[i]))>>7);
   l=-l;
   l+=tmp*tmp+(*p)*(*p);
   if(l&0x02000000)
      res|=1;
   res<<1;
    
   *p+=x+(i>2?(*p)>>1:0)+(((*p)*(arrK[i]))>>7)-tmp;
   p++;
 }
 return res;
}

byte sinxro; 

byte OscilFn(uint16_t a)
{
  static bool flagBlym;
  byte i=a&0x7f;
  byte y=a>>7;
  byte v=Arr[i+sinxro]>>3;
  byte r=(v>>3)==y?_BV(v&7):0; 
  // сетка, границы, мигаем 
  if((i&0x0f)==0) r|=0x55;
  if((i==0) | (i==127) | ((i==64) && (flagBlym))) r|=0xff;
  switch(y)
  {
   case 0: r|=1;break;
   case 2: r|=flagBlym?1:i>>2&1;break;
   case 3: r|=0x80;break;
  }

  if (!a) flagBlym=!flagBlym;
  return r;
}

void loop(void)
{

  //    Ищем синхронизацию по переходу через середину при нарастании
   for(sinxro=2;sinxro<127;sinxro++)
   {
     if((Arr[sinxro-1]<127)&&(Arr[sinxro]>=127)) break;
   }
   
 //   Выводим осцилограмму
   myOLED.InitFrame(0,0,128,4, myOLED.FRAME_MODE_CALLBACK, (byte*) OscilFn);
   myOLED.update(); // на экран
  
   if(FlInternal)
   {
     myOLED.setFont( SSD1306::FONT_SIZE_1); 
     myOLED.drawString(4,3,"Внутрений сигнал");
   }
  
  
  for(;inpCount<sizeof(Arr);){};
  
  byte Amax;
  Amax=0;

  {
    char* im=new char[_BV(bpfN)];
    char* pdd=(char*)(Arr+1);
    memset(im, 0, sizeof(im));
    
    fix_fft(pdd,im,bpfN,0);  //БПФ по 128 точкам начиная с первой, не нулевой
    
   // Считаем модуль и попутно ищем максимум 
    for (byte i=0; i<30*(bpfN-6);i++)
    {
      pdd[i]=sqrt(pdd[i] * pdd[i]+im[i]*im[i]);
      if(pdd[i]>Amax) Amax=pdd[i];
    }
    delete[] im;
   

  // Вывод БПФ на экран
   if(bpfN<9)
   {
    uint8_t bufg[128*2];
    myOLED.InitFrame(0,4,128,2, myOLED.FRAME_MODE_BUFER, bufg);
    memset(bufg, 0, 128*2);
    for(byte i=0;i<128;i+=16)
    {
      bufg[i+1]=0x44;bufg[i+1+128]=0x44;
    }

    for (byte i=0; i<30*(bpfN-6);i++)
    {
      byte v=15-(pdd[i]*15)/Amax;
        myOLED.drawLine(i*_BV(9-bpfN),15,i*_BV(9-bpfN),v);
        if(bpfN==7)
         myOLED.drawLine(i*4+1,15,i*4+1,v);
    }
    myOLED.update();
    
   }
  }
    myOLED.setFont( SSD1306::FONT_SIZE_1); 
    char s[10];
    itoa(Amax, s, 10);
    myOLED.drawString(19,5,s);
 
  byte resGyorc;
  for(byte i=0;i<255;i++)
  {
    resGyorc=Gyorcely(Arr[i]);
  }
    itoa(resGyorc, s, 2);
    myOLED.drawString(0,6,s);

  
   /* Запускаем захват отсчетов  */
  inpCount=0;
 
 
  
  if(Serial.available())
  {
    char r=toupper( Serial.read());
    switch(r)
    {
     case '/': FlInternal=!FlInternal;break;
     case '+': dF_8k=dF_8k?0:33;break;
     case '-': bpfN=bpfN==7?8:(bpfN==8?9:7);break;
     default:
         for(byte i=0;i<24;i++)
         {
           if(Friq[i].key==r)
           {
            dF_A=Friq[i].F1;
            dF_B=Friq[i].F2;
            break; 
           }
         }
    }
  }
}

Рабочее все, кроме БПФ512, если разумеется либы докинуть, но по dtmf там все в основном файле. Сигнал на алгоритм Герцеля можна завернуть одним из 2-х путей: внутри контролера или соединив вывод ШИМ таймера с АЦП. Код писал для поигратся, функционального назначения у него нет как такового.

Малек
Offline
Зарегистрирован: 15.08.2017

Я ноль в программировании так что объясните пожалуйста доступно .:-)

b707
Offline
Зарегистрирован: 26.05.2017

Logik пишет:

DTMF отлично генерится и распознается самой ардуиной, без аппаратных прибамбасов совершенно програмным путем.

Код писал для поигратся, функционального назначения у него нет как такового.

Logik, ТС ваш код явно не поможет. Да и писался этот код, очевидно, не для детектирования DTMF :)

Код вызывает уважение, но для данной задачи он явно избыточен. Сама программа, навскидку, займет процентов 50% флеша Уно-Нано, данные, особенно для БПФ 512 - весь RAM "под завязку" - и все это ради детектирования DTMF. которое на большинстве модемов делается аппаратно?

Logik
Offline
Зарегистрирован: 05.08.2014

Мой код поможет только тому, кто хочет чтоб этот код ему помог;)

Не займет она 50%. Если интересует точней - собиру дома и сообщу.

Код писался, как выше сказано, для поигратся - экспериментальной проверки возможности генерации и детектирования dtmf 328 контролером. Он справился. До этого мне не приходилось пользоватся алгоритмом Герцеля, в коде строки 151-181. Оказался вполне рабочим и не сложным. Попутно интересно было оценить насколько повлияет на работу использование ШИМ при выводе аналогового синуса  на процесс его последующей оцифровки и распознавания. Ну и сравнить Герцеля с БПФ тоже любопытно было. Для БПФ512 действительно ОЗУ под завязку. Но он не для детектирования вобще, так, для сравнения подхода. пробовал БПФ512 т.к. БПФ256 не обеспечивает надежное распознавание, но запустить БПФ512 не удалось. Герцель рулит, БПФ не нужен здесь.

Малек
Offline
Зарегистрирован: 15.08.2017

И ещё вопрос ,где купить этот модуль желательно в Волгограде или с доставкой в Волгоград.можно Ali express только что бы доставка не более 2 недель . Спасибо :-)

b707
Offline
Зарегистрирован: 26.05.2017

Малек пишет:
Это я :-[ . И не чего с этим не поделаешь :-) спасибо за помощь!

Ну если вы так верите случайным советчикам и не верите Гуглю - от меня сразу предупреждение - все мои ответы вам из гугля, сам я DTMF еще не занимался.

Но если потребуется - в форуме спрашивать не буду, буду искать в гугле и пробовать.