Subversion Repositories HomeAutomation

Rev

Rev 925 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /**
  2.  * dtmf decoder.
  3.  * http://en.wikipedia.org/wiki/DTMF
  4.  * http://en.wikipedia.org/wiki/Goertzel_algorithm
  5.  *
  6.  * @date    2007-03-14
  7.  * @author  Anders Runeson arune at sf dot net
  8.  *  
  9.  */
  10.  
  11. /*-----------------------------------------------------------------------------
  12.  * Includes
  13.  *---------------------------------------------------------------------------*/
  14. #include "dtmfdecode.h"
  15.  
  16. /*-----------------------------------------------------------------------------
  17.  * Globals
  18.  *---------------------------------------------------------------------------*/
  19. static uint8_t      buf[BUFFER_SIZE+1]; //buffer for storing samples
  20. static uint8_t      bufPointAD = 0;     //bufferpointer for bufferwriter (AD-converter)
  21. static uint8_t      bufPoint = 0;       //bufferpointer for bufferreader (algoritm)
  22. static int32_t      r[MAX_BINS];        //frequncy amplitude
  23. static int32_t      coefs[MAX_BINS];   
  24. static int32_t      q1[MAX_BINS];
  25. static int32_t      q2[MAX_BINS];
  26. static uint16_t     freqs[MAX_BINS] = {697, 770, 852, 941, 1209, 1336, 1477, 1633};
  27. static uint8_t      receiverState = RSPAUSE;
  28. static uint8_t      noSignalCnt = 0;
  29. static uint8_t      signalCnt = 0;
  30. static uint8_t      toneBuf[TONE_BUFFER_SIZE+1];    //buffer for storing received tones
  31. static uint8_t      toneBufPoint = 0;               //bufferpointer for tonebuffer
  32.  
  33.  /*-----------------------------------------------------------------------------
  34.  * Prerequisites
  35.  *---------------------------------------------------------------------------*/
  36.  
  37.  
  38. /*-----------------------------------------------------------------------------
  39.  * Public Functions
  40.  *---------------------------------------------------------------------------*/
  41.  
  42.  
  43. //inline int32_t max(int32_t a, int32_t b) { return a > b ? a : b; }
  44. //inline int32_t min(int32_t a, int32_t b) { return a < b ? a : b; }
  45.  
  46. uint8_t DTMFIN_Init(void) {
  47.  
  48. //init ad and timer1
  49.     /* Enable ADC4 */
  50.     ADMUX |= (1<<MUX2);
  51.     ADMUX &= ~((1<<MUX3)|(1<<MUX0)|(1<<MUX1));
  52.    
  53.     /* Set AD prescaler */
  54.     ADCSRA |= (1<<ADPS1)|(1<<ADPS0);
  55.     ADCSRA &= ~((1<<ADPS2));
  56.    
  57.     /* Enable AVcc as Voltage Reference */
  58.     ADMUX |= (1<<REFS0);
  59.     ADMUX &= ~(1<<REFS1);
  60.    
  61.     /* Left adjust the result (only use 8bit) */
  62.     ADMUX |= (1<<ADLAR);
  63.    
  64.     /* Wake up ADC and enable it */
  65.     PRR &= ~(1<<PRADC);
  66.     ADCSRA |= (1<<ADEN)|(1<<ADIE);
  67.  
  68.     //timer
  69.     TCCR1B = (1<<CS10);
  70.     TCNT1 = CLK_RELOAD;
  71.     TIFR1   |= (1<<TOV1);
  72.     TIMSK1 |= (1<<TOIE1);
  73.  
  74. /* This is where we calculate the correct co-efficients.
  75.  * coef = 2.0 * cos( (2.0 * PI * k) / (float)GOERTZEL_N)) ;
  76.  * Where k = (int) (0.5 + ((float)GOERTZEL_N * target_freq) / SAMPLING_RATE));
  77.  *
  78.  * More simply: coef = 2.0 * cos( (2.0 * PI * target_freq) / SAMPLING_RATE );
  79.  */
  80.     int n;
  81.  
  82.     for(n = 0; n < MAX_BINS; n++) {
  83.     coefs[n] = COEFFSPREC * 2.0 * cos(2.0 * 3.141592654 * freqs[n] / SAMPLING_RATE);
  84.     //printf("%i\t", coefs[n]);
  85.     }
  86.     //printf("\n");
  87.    
  88.     return 1;
  89. }
  90.  
  91. /*----------------------------------------------------------------------------
  92.  *  post_testing
  93.  *----------------------------------------------------------------------------
  94.  * This is where we look at the bins and decide if we have a valid signal.
  95.  */
  96. uint8_t post_testing(void) {
  97.     uint8_t      row, col, see_digit;
  98.     uint8_t      peak_count, max_index;
  99.     int32_t     maxval, t;
  100.     uint8_t      i;
  101.  
  102.     uint8_t row_col_codes[4][4] = {
  103.     {'1', '2', '3', 'A'},
  104.     {'4', '5', '6', 'B'},
  105.     {'7', '8', '9', 'C'},
  106.     {'*', '0', '#', 'D'}};
  107. //  {0x1, 0x2, 0x3, 0xA},
  108. //  {0x4, 0x5, 0x6, 0xB},
  109. //  {0x7, 0x8, 0x9, 0xC},
  110. //  {0xE, 0x0, 0xF, 0xD}};
  111.    
  112.  
  113.     /* Find the largest in the row group. */
  114.     row = 0;
  115.     maxval = 0;
  116.     for ( i=0; i<4; i++ ) {
  117.         if ( r[i] > maxval ) {
  118.             maxval = r[i];
  119.             row = i;
  120.         }
  121.     }
  122.  
  123.     /* Find the largest in the column group. */
  124.     col = 4;
  125.     maxval = 0;
  126.     for ( i=4; i<8; i++ ) {
  127.         if ( r[i] > maxval ) {
  128.             maxval = r[i];
  129.             col = i;
  130.         }
  131.     }
  132.    
  133.     /* Check for minimum energy */
  134.     //if ( r[row]/SAMPLEPREC < 4.0e5 )  /* 2.0e5 ... 1.0e8 no change */
  135.     if ( r[row] < 4.0e5 ) {
  136.         /* energy not high enough */
  137.         return 0;
  138.     //} else if ( r[col]/SAMPLEPREC < 4.0e5 )
  139.     } else if ( r[col] < 4.0e5 ) {
  140.         /* energy not high enough */
  141.         return 0;
  142.     }
  143.     see_digit = 1;
  144.  
  145.     /* Twist check
  146.      * CEPT => twist < 6dB
  147.      * AT&T => forward twist < 4dB and reverse twist < 8dB
  148.      *  -ndB < 10 log10( v1 / v2 ), where v1 < v2
  149.      *  -4dB < 10 log10( v1 / v2 )
  150.      *  -0.4  < log10( v1 / v2 )
  151.      *  0.398 < v1 / v2
  152.      *  0.398 * v2 < v1
  153.      */
  154.     if ( r[col] > r[row] ) {
  155.         /* Normal twist */
  156.         max_index = col;
  157.         if ( r[row] < (r[col] >>2) )    /* twist > 4dB, error */
  158.         see_digit = 0;
  159.     } else {
  160.         /* Reverse twist */
  161.         max_index = row;
  162.         if ( r[col] < (r[row] >>2) )    /* twist > 8db, error */
  163.         see_digit = 0;
  164.     }
  165.    
  166.     /* Signal to noise test
  167.      * AT&T states that the noise must be 16dB down from the signal.
  168.      * Here we count the number of signals above the threshold and
  169.      * there ought to be only two.
  170.      */
  171.     t = r[max_index] >>2;
  172.  
  173.     peak_count = 0;
  174.     for ( i=0; i<8; i++ ) {
  175.         if ( r[i] > t ) {
  176.             peak_count++;
  177.         }
  178.     }
  179.     if ( peak_count > 2 ) {
  180.         see_digit = 0;
  181.     }
  182.  
  183.     if ( see_digit ) {
  184.         i = (row_col_codes[row][col-4]);
  185.         return i;
  186.     } else {
  187.         return 0;
  188.     }
  189. }
  190.  
  191. uint8_t majority(uint8_t* returntone) {
  192.     uint8_t     counttones[TONE_BUFFER_SIZE] = {0,0,0,0,0,0,0,0};
  193.     uint8_t     tones[TONE_BUFFER_SIZE] = {0,0,0,0,0,0,0,0};
  194.    
  195.     for (uint8_t i = 0; i<toneBufPoint; i++) {
  196.         for (uint8_t j = 0; j<TONE_BUFFER_SIZE; j++) {
  197.             if (tones[j] == toneBuf[i]) {
  198.                 counttones[j]++;
  199.                 break;
  200.             } else if (tones[j] == 0) {
  201.                 tones[j] = toneBuf[i];
  202.                 counttones[j]=1;
  203.                 break;
  204.             }
  205.         }
  206.     }
  207.    
  208.     uint8_t maxindex=0;
  209.     for (uint8_t j = 0; j<TONE_BUFFER_SIZE; j++) {
  210.         if (counttones[j] > counttones[maxindex]) {
  211.             maxindex = j;
  212.         }
  213.     }
  214.    
  215.     if (counttones[maxindex] > (toneBufPoint>>1)) {
  216.         *returntone = tones[maxindex];
  217.         return 1;   //success
  218.     }
  219.    
  220.     *returntone = 'x';
  221.     return 1;   //during testing
  222.     //return 0; //failed
  223. }
  224.  
  225. uint8_t DTMFIN_GetData(uint8_t* returntone) {
  226.     //uint16_t time2;   //for time measure
  227.     //uint16_t time1;
  228.  
  229.     // calculate while there is data in buffer
  230.     if (bufPoint<bufPointAD) {
  231.         int32_t q0;
  232.         uint8_t i;
  233.         uint8_t sample = buf[bufPoint];
  234.         //uint8_t sample = samples[bufPoint];
  235.         for ( i=0; i<MAX_BINS; i++ ) {
  236.                 q0 = q1[i] * coefs[i] / COEFFSPREC;
  237.                 q0 -= q2[i];
  238.                 //q0 += (sample-127)*SAMPLEPREC;        //use this row instead of next to filter DC
  239.                 q0 += sample*SAMPLEPREC;
  240.             q2[i] = q1[i];
  241.             q1[i] = q0;
  242.         }
  243.        
  244.         bufPoint++;
  245.         //when buffer is full do the final calculation and call post_testing()
  246.         if (bufPoint == BUFFER_SIZE) {
  247.            
  248.             //printf("\n");
  249.             //printf("current power:\n\t697\t770\t852\t941\t1209\t1336\t1477\t1633\n");
  250.             for ( i=0; i<MAX_BINS; i++ ) {
  251.  
  252.                 q1[i] = q1[i]>>SAMPLEPRECSHIFT;
  253.                 q2[i] = q2[i]>>SAMPLEPRECSHIFT;
  254.                 r[i] = (q1[i] * q1[i]);
  255.                 r[i] += (q2[i] * q2[i]);
  256.                 r[i] -= ((coefs[i] * (q1[i])>>COEFFSPRECSHIFT) * q2[i]);
  257.                 q1[i] = 0;
  258.                 q2[i] = 0;
  259.                
  260.                 //printf("\t%li", r[i]);
  261.             }
  262.             //printf("\n");
  263.            
  264. //time1 = TCNT1;
  265. //time2 = TCNT1;
  266. //printf("\n%u\t%u\n", time1, time2);
  267.  
  268.             bufPoint = 0;
  269.             bufPointAD = 0;
  270.             uint8_t tone = post_testing();
  271.  
  272.             if (tone) {
  273.                 //tone &= 0x0F;
  274.                 if (toneBufPoint<TONE_BUFFER_SIZE) {
  275.                     toneBuf[toneBufPoint] = tone;
  276.                     toneBufPoint++;
  277.                 }
  278.                  
  279.                 //printf("%x", tone);
  280.             }
  281.         }
  282.     }
  283.        
  284.     if (toneBufPoint>0 && receiverState==RSPAUSE) {
  285.         //gå inom buffer och kolla, majoritetsbeslut, om ok så returnera med valet
  286.         uint8_t majtone;
  287.         if (majority(&majtone)) {
  288.             *returntone = majtone;
  289.             //*returntone = toneBuf[0];
  290.             toneBufPoint = 0;
  291.             return 1;
  292.         }
  293.        
  294.         toneBufPoint = 0;
  295.         //uint8_t data = toneBuf[0];
  296.         //*returntone = data;
  297.         //return 1;
  298.     }
  299.    
  300.     return 0;
  301. }
  302.  
  303. //Timer1 overflow, should occur at 8kHz
  304. ISR(SIG_OVERFLOW1) {
  305.     TCNT1 = CLK_RELOAD;
  306.     //start ad-conversion
  307.     ADCSRA |= (1<<ADSC);
  308. }
  309.  
  310. //ADC-overflow, occurs when an AD-conversion is done (also at 8kHz)
  311. ISR(ADC_vect) {
  312.     //save value if buffer is not full
  313.     if (bufPointAD<BUFFER_SIZE) {
  314.         uint8_t ADCvalue = ADCH;
  315.        
  316.         if (ADCvalue < UPPERSILENCELIMIT && ADCvalue > LOWERSILENCELIMIT) {
  317.             if (receiverState == RSRECEIVING) {
  318.                 noSignalCnt++;
  319.             }
  320.         } else {
  321.             if (receiverState == RSPAUSE) {
  322.                 signalCnt++;
  323.             }
  324.         }
  325.        
  326.         if (signalCnt > 4) {
  327.             if (receiverState == RSPAUSE) {
  328.                 noSignalCnt = 0;
  329.             }
  330.             buf[bufPointAD] = ADCvalue;
  331.             bufPointAD++;
  332.             receiverState = RSRECEIVING;        //no longer signal pause
  333.         }
  334.  
  335.         if (noSignalCnt > 60) {
  336.             if (receiverState == RSRECEIVING) {
  337.                 signalCnt = 0;
  338.             }
  339.             bufPointAD = 0;
  340.             receiverState = RSPAUSE;        //signal pause
  341.         }
  342.        
  343.         //only save value if there is a signal
  344. /*      if (bufPointAD>0 || ADCvalue > UPPERSILENCELIMIT || ADCvalue < LOWERSILENCELIMIT) {
  345.             buf[bufPointAD] = ADCvalue;
  346.             bufPointAD++;
  347.             receiverState = RSRECEIVING;        //no longer signal pause
  348.         } else {
  349.             noSignalCnt++;
  350.             if (noSignalCnt==40) {
  351.                 //printf(".");
  352.                 receiverState = RSPAUSE;        //signal pause
  353.                 noSignalCnt = 0;
  354.             }
  355.         }*/
  356.     }
  357. }
  358.