CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MikroC code to CCS

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

MikroC code to CCS
PostPosted: Fri Jul 31, 2020 5:30 am     Reply with quote

Could someone tell me what changes I would have to change to make this code compatible with CCS?

Code:
/******************************************************************************
    DTMF_remote.c     DTMF decoder using RomanBlack's triplet algorithm
    Copyright:        Open-Source, Mar 2011, www.RomanBlack.com/DTMF/DTMF_alg.htm
    MCU:              P16F675
    Dev.Board:        EasyPIC6
    Oscillator:       HS 8MHz xtal
    Compiler:         MikroC v7.0 (or MikroC PRO 4.0)

  This is a very simple but functional DTMF decoder using RomanBlack's
  DTMF triplet decoder algorithm. For simplicity it only decodes 2 DTMF
  tones, the telephone "1" key and the "0" key. If you want to decode all the
  keys the code is included.
  DTMF tones are detected on the comparator input, as a 1bit DAC.
  All the PIC does is continually check for DTMF tones using software
  decoding of the signal on the comparator input.

  Audio input hardware; Audio through a 0.1uF or 1uF capacitor to GP1,
  and a 4k7 or 10k resistor from GP1 to ground. This tested perfectly
  in hardware with DTMF waveforms anywhere from 0.4v to 2.6v peak to peak,
  somewhere about 1v peak to peak is typical.

  Detects DTMF 697 1209 (Key "1") = output ON
  Detects DTMF 941 1336 (Key "0") = output OFF
 
  PIC 12F675 pins;
   GP0  output, main output (drives a relay etc)
   GP1  input, comparator, DTMF audio in
   GP2  output, (drives a LED or speaker for confirmation beep/flash)
   GP3  input, not used
   GP4  osc 8MHz xtal
   GP5  osc 8MHz xtal
******************************************************************************/
// global vars
unsigned char i;

unsigned char cap;        // used to capture TMR0 for period testing
unsigned char cap_last;

unsigned char per;        // holds the last 3 periods values
unsigned char per1;
unsigned char per2;

unsigned char Dtone[12];  // stores points scores for the 12 DTMF tones
unsigned char Dhigh;      // will hold the highest score
unsigned char Dbest;      // which DTMF tone was scored best

unsigned char debounce;
unsigned char output_last;


//=============================================================================
//  MAKE BEEPS
//=============================================================================
void make_beeps(unsigned char beeps)
{
  //-------------------------------------------------------
  // this makes a number of beeps (like 1 or 2 beeps) and then repeats
  // it three times. This is output on GP2, and can be a LED or
  // a speaker etc to show a confimration that the DTMF decoder has
  // changed the output pin. ie for DTMF remote control use.
  //-------------------------------------------------------
  unsigned char beep_count;
  unsigned char bloop;
 
  // repeat the beeping three times with a few seconds between
  for(i=0; i<3; i++)
  {
    beep_count = beeps;
    while(beep_count)   // loop and make X beeps
    {
      // the beep is 1000 Hz and 250mS long, made by toggling a pin 
      for(bloop=0; bloop<250; bloop++)
      {
        GPIO.F2 = 1;    // 1mS per cycle
        Delay_uS(500);
        GPIO.F2 = 0;
        Delay_uS(500);
      } 
      Delay_mS(300);  // small delay between beeps
      beep_count--;
    }
    Delay_mS(2500);   // long delay before repeating beeps
  }
}
//-----------------------------------------------------------------------------


//=============================================================================
//  COMP DEBOUNCE
//=============================================================================
void comp_debounce(void)
{
  //-------------------------------------------------------
  // this is a critical part of the DTMF decoding, it makes
  // sure the DTMF signal received by the comparator input LO for a
  // period of >220uS and then is HI for >220uS. This performs a
  // synchronisation effect where the periods are synchronised to
  // the most important and reliable features of the DTMF waveform.
  // To keep the 220uS period accurate it tests TMR0 bit0 which
  // toggles every 8 uS. So 220uS / 8uS = 27 cycles
  //-------------------------------------------------------
  // loop here until comparator input has been LO for 220uS
  debounce = 0;
  while(1)
  {
    while(!TMR0.F0);    // wait for TMR0 bit 0 to go HI
    if(CMCON.F6)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
    while(TMR0.F0);     // wait for TMR0 bit 0 to go LO
    if(CMCON.F6)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
  }
  // loop here until comparator input has been LO for 220uS
  debounce = 0;
  while(1)
  {
    while(!TMR0.F0);    // wait for TMR0 bit 0 to go HI
    if(!CMCON.F6)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
    while(TMR0.F0);     // wait for TMR0 bit 0 to go LO
    if(!CMCON.F6)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
  }
}
//-----------------------------------------------------------------------------


//=============================================================================
//  DECODE TRIPLETS
//=============================================================================
void decode_triplets(void)
{
  //-------------------------------------------------------
  // this is called once for each captured period, it checks the
  // latest period to see if matches one of the 24 periods in
  // the DTMF signatures.
  // if so, it checks that period and the 2 periods before it to
  // see if they match a "triplet" and then allocate points.
  // This project only needs to test 2 DTMF tones, so tones
  // not used are commented out to save processing time and ROM.
  // These triplet tests can be optimised for speed or ROM size, this
  // current version was just thrown together for testing but is
  // fast enough.
  // For theory see; www.RomanBlack.com/DTMF/DTMF_alg.htm
  //-------------------------------------------------------
 
  // Tone 0 66 98  LLS LSL SLL (DTMF key "1")
  if(per >= 66-2 && per <= 66+2)  // ends S
  {
    if(per2 >= 98-2 && per2 <= 98+2 && per1 >= 98-2 && per1 <= 98+2) Dtone[0]+=5; // LLS
  }
  if(per >= 98-2 && per <= 98+2)  // ends L
  {
    if(per2 >= 66-2 && per2 <= 66+2 && per1 >= 98-2 && per1 <= 98+2) Dtone[0]+=5; // SLL
    if(per2 >= 98-2 && per2 <= 98+2 && per1 >= 66-2 && per1 <= 66+2) Dtone[0]+=5; // LSL
  }
 
  /*
  //-------------------------------------------------------
  // Tone 1 63 94  SLS LSL
  if(per >= 63-1 && per <= 63+1)  // ends S
  {
    if(per2 >= 63-1 && per2 <= 63+1 && per1 >= 94-1 && per1 <= 94+1) Dtone[1]+=7; // SLS
  }
  if(per >= 94-1 && per <= 94+1)  // ends L
  {
    if(per2 >= 94-1 && per2 <= 94+1 && per1 >= 63-1 && per1 <= 63+1) Dtone[1]+=3; // LSL
  }
 
  //-------------------------------------------------------
  // Tone 2 61 90  SSL SLS LSS
  if(per >= 61-1 && per <= 61+1)  // ends S
  {
    if(per2 >= 61-1 && per2 <= 61+1 && per1 >= 90-1 && per1 <= 90+1) Dtone[2]+=1; // SLS
    if(per2 >= 90-1 && per2 <= 90+1 && per1 >= 61-1 && per1 <= 61+1) Dtone[2]+=6; // LSS
  }
  if(per >= 90-1 && per <= 90+1)  // ends L
  {
    if(per2 >= 61-1 && per2 <= 61+1 && per1 >= 61-1 && per1 <= 61+1) Dtone[2]+=6; // SSL
  }
 
  //-------------------------------------------------------
  // Tone 3 58 86  SSL LSS
  if(per >= 58-1 && per <= 58+1)  // ends S
  {
    if(per2 >= 86-1 && per2 <= 86+1 && per1 >= 58-1 && per1 <= 58+1) Dtone[3]+=5; // LSS
  }
  if(per >= 86-1 && per <= 86+1)  // ends L
  {
    if(per2 >= 58-1 && per2 <= 58+1 && per1 >= 58-1 && per1 <= 58+1) Dtone[3]+=5; // SSL
  }
 
  //-------------------------------------------------------
  // Tone 4 62 92  SSS SLL LLS
  if(per >= 62-1 && per <= 62+1)  // ends S
  {
    if(per2 >= 62-1 && per2 <= 62+1 && per1 >= 62-1 && per1 <= 62+1) Dtone[0]+=1; // SSS
    if(per2 >= 92-1 && per2 <= 92+1 && per1 >= 92-1 && per1 <= 92+1) Dtone[4]+=14; // LLS
  }
  if(per >= 92-1 && per <= 92+1)  // ends L
  {
    if(per2 >= 62-1 && per2 <= 62+1 && per1 >= 92-1 && per1 <= 92+1) Dtone[4]+=14; // SLL
  }
 
  //-------------------------------------------------------
  // Tone 5 60 89  SLL LLS
  if(per >= 60-1 && per <= 60+1)  // ends S
  {
    if(per2 >= 89-1 && per2 <= 89+1 && per1 >= 89-1 && per1 <= 89+1) Dtone[5]+=5; // LLS
  }
  if(per >= 89-1 && per <= 89+1)  // ends L
  {
    if(per2 >= 60-1 && per2 <= 60+1 && per1 >= 89-1 && per1 <= 89+1) Dtone[5]+=5; // SLL
  }
 
  //-------------------------------------------------------
  // Tone 6 58 85  SLL LLS LSL
  if(per >= 58-1 && per <= 58+1)  // ends S
  {
    if(per2 >= 85-1 && per2 <= 85+1 && per1 >= 85-1 && per1 <= 85+1) Dtone[6]+=5; // LLS
  }
  if(per >= 85-1 && per <= 85+1)  // ends L
  {
    if(per2 >= 58-1 && per2 <= 58+1 && per1 >= 85-1 && per1 <= 85+1) Dtone[6]+=5; // SLL
    if(per2 >= 85-1 && per2 <= 85+1 && per1 >= 58-1 && per1 <= 58+1) Dtone[6]+=3; // LSL
  }
  */
 
  //-------------------------------------------------------
  // Tone 7 55 82  SLS SSL LSS  (DTMF key "0")
  if(per >= 55-2 && per <= 55+2)  // ends S
  {
    if(per2 >= 55-2 && per2 <= 55+2 && per1 >= 82-2 && per1 <= 82+2) Dtone[7]+=3; // SLS
    if(per2 >= 82-2 && per2 <= 82+2 && per1 >= 55-2 && per1 <= 55+2) Dtone[7]+=4; // LSS
  }
  if(per >= 82-2 && per <= 82+2)  // ends L
  {
    if(per2 >= 55-2 && per2 <= 55+2 && per1 >= 55-2 && per1 <= 55+2) Dtone[7]+=4; // SSL
  }
 
  /*
  //-------------------------------------------------------
  // Tone 8 86 114  SLS SSL LSS
  if(per >= 86-1 && per <= 86+1)  // ends S
  {
    if(per2 >= 86-1 && per2 <= 86+1 && per1 >= 114-1 && per1 <= 114+1) Dtone[8]+=7; // SLS
    if(per2 >= 114-1 && per2 <= 114+1 && per1 >= 86-1 && per1 <= 86+1) Dtone[8]+=8; // LSS
  }
  if(per >= 114-1 && per <= 114+1)  // ends L
  {
    if(per2 >= 86-1 && per2 <= 86+1 && per1 >= 86-1 && per1 <= 86+1) Dtone[8]+=8; // SSL
  }

  //-------------------------------------------------------
  // Tone 9 57 83  SLL LLS LSL
  if(per >= 57-1 && per <= 57+1)  // ends S
  {
    if(per2 >= 83-1 && per2 <= 83+1 && per1 >= 83-1 && per1 <= 83+1) Dtone[9]+=9; // LLS
  }
  if(per >= 83-1 && per <= 83+1)  // ends L
  {
    if(per2 >= 57-1 && per2 <= 57+1 && per1 >= 83-1 && per1 <= 83+1) Dtone[9]+=9; // SLL
    if(per2 >= 83-1 && per2 <= 83+1 && per1 >= 57-1 && per1 <= 57+1) Dtone[9]+=9; // LSL
  }
 
  //-------------------------------------------------------
  // Tone 10 54 80  LLS
  if(per >= 54-1 && per <= 54+1)  // ends S
  {
    if(per2 >= 80-1 && per2 <= 80+1 && per1 >= 80-1 && per1 <= 80+1) Dtone[10]+=8; // LLS
  }
 
  //-------------------------------------------------------
  // Tone 11 52 77  SLS SLL LLS
  if(per >= 52-1 && per <= 52+1)  // ends S
  {
    if(per2 >= 52-1 && per2 <= 52+1 && per1 >= 77-1 && per1 <= 77+1) Dtone[11]+=4; // SLS
    if(per2 >= 77-1 && per2 <= 77+1 && per1 >= 77-1 && per1 <= 77+1) Dtone[11]+=4; // LLS
  }
  if(per >= 77-1 && per <= 77+1)  // ends L
  {
    if(per2 >= 52-1 && per2 <= 52+1 && per1 >= 77-1 && per1 <= 77+1) Dtone[11]+=4; // SLL
  }
  */
}
//-----------------------------------------------------------------------------


//=============================================================================
//   MAIN
//=============================================================================
void main ()
{
  //-----------------------------------------------------
  // PIC 12F675  setup ports
  ANSEL = 0;            // ADC off
  CMCON =  0b00000100;  // GP1 is comp input pin
  VRCON =  0b10100000;  // CVref ON, CVref must be set to zero!

  TRISIO = 0b00001010;  // see page top for pins
  GPIO =   0b00000000;  // GP1 output OFF at startup
  WPU =    0b00000000;  // pin pullups; 1 = pullup ON
 
  OPTION_REG = 0b10000011; //  TMR0 at 1:16 prescaler

  output_last = 0;
  //-----------------------------------------------------
  // DTMF triplet decoder algorithm;
  // 1, debounce the comparator input so it must be HI and LO for 220uS each
  // 2. synchronise with that debounce to measure one input period
  // 3. after every period compare the last 3 periods to match a "triplet"
  // 4. allocate DTMF points for any triplet matches
  // 5. after 60 triplets are tested, see if there is a good winning points score
  // 6. if winning score is DTMF keys "0" or "1" set the output pin accordingly
  //-----------------------------------------------------
  // main run loop
  while(1)
  {
    //-----------------------------------------
    // clear the tone points accumulators before testing
    for(i=0; i<12; i++)  Dtone[i] = 0; 

    //-----------------------------------------
    // capture 63 periods and test 60 triplets, takes about 95mS total
    for(i=0; i<63; i++)
    {
      comp_debounce();          // sync with waveform
      cap = TMR0;               // capture timer
      per = (cap - cap_last);   // calc the period between timer captures
      per = (per >> 1);         // halve period to suit testing
      cap_last = cap;           // save capture for next test

      // after 3 initial captures we can start testing triplets
      if(i >= 3) decode_triplets();  // test triplet, and allocate points

      // store the previous periods ready for next triplet test
      per2 = per1;
      per1 = per;
    }
    //-----------------------------------------
    // now we have tested 60 triplets and allocated points, test which
    // of the 12 DTMF tones scored the most points
    Dhigh= 0;
    for(i=0; i<12; i++)
    {
      if(Dtone[i] > Dhigh)  // if this is the new best score
      {
        Dhigh = Dtone[i];   // record best score
        Dbest = i;          // and who owns it
      }
    }
   
    // now Dbest tells which DTMF tone had the best score,   
    // Dhigh is its score. A real good DTMF match score will be 120-180
    if(Dhigh > 60)    // looks like we found a real DTMF tone!
    {
      if(Dbest == 0)    // DTMF "1" key, so turn output ON
      {
        GPIO.F0 = 1;    // change the output
        if(output_last == 0) make_beeps(2);  // 2 beeps to say it toggled
        output_last = 1;
      }
      if(Dbest == 7)    // DTMF "0" key, so turn output OFF
      {
        GPIO.F0 = 0;    // change the output
        if(output_last == 1) make_beeps(1);  // 1 beep to say it toggled
        output_last = 0;
      }
    }
  }
}
//-----------------------------------------------------------------------------
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 31, 2020 6:40 am     Reply with quote

1st step is to build and confirm the code DOES work as posted.

2nd, if you want more than '0' and '1' decoded, edit the code and recompile/test. Confirm you can get all 12 or 16 keys.

3rd NOW convert to CCS C.
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Fri Jul 31, 2020 8:43 am     Reply with quote

temtronic wrote:
1st step is to build and confirm the code DOES work as posted.

2nd, if you want more than '0' and '1' decoded, edit the code and recompile/test. Confirm you can get all 12 or 16 keys.

3rd NOW convert to CCS C.


I have an ASM code(16F628) that works on the simulator, but the code posted here didn't work ...
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 31, 2020 10:30 am     Reply with quote

Doesn't surprise me at all....
'simulator' , probably Proteus, which is well KNOWN to be unreliable....

The code was designed for a PIC12F675 and you're 'simulating' a PIC16F628 so..

1st off, totally different series of PICs (think Ford vs Chevy)

2nd ,you'll have to consider proper configuration of the PIC, clock speed, register addresses, etc.

3rd, the most important. Even IF you get it to 'work' with Proteus, there's a 99.44% chance it will NOT work in the Real World. I've yet to see one Proteus schematic that will work as drawn.

Honestly if you're going to 'Play with PICs', get some and build real circuits. There's lots of development boards, PICs on a PC boards, etc. all at low cost.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Aug 01, 2020 2:05 am     Reply with quote

I converted it to CCS. You can test it to see if it works.
Code:
#include<16F628.h>
#fuses HS, NOWDT, PUT, BROWNOUT, NOLVP
#use delay(clock=8M)
#use rs232(baud=9600, UART1, ERRORS)

#byte TMR0 = getenv("SFR:TMR0")
#bit TMR0_B0 = TMR0.0

//  DTMF input pin is PIN_A0
#define RELAY_PIN     PIN_B3
#define BEEPER_PIN    PIN_B5  // This could also be an LED

/******************************************************************************
    DTMF_remote.c     DTMF decoder using RomanBlack's triplet algorithm
    Copyright:        Open-Source, Mar 2011, www.RomanBlack.com/DTMF/DTMF_alg.htm
    MCU:              P16F675
    Dev.Board:        EasyPIC6
    Oscillator:       HS 8MHz xtal
    Compiler:         MikroC v7.0 (or MikroC PRO 4.0)

  This is a very simple but functional DTMF decoder using RomanBlack's
  DTMF triplet decoder algorithm. For simplicity it only decodes 2 DTMF
  tones, the telephone "1" key and the "0" key. If you want to decode all the
  keys the code is included.
  DTMF tones are detected on the comparator input, as a 1bit DAC.
  All the PIC does is continually check for DTMF tones using software
  decoding of the signal on the comparator input.

  Audio input hardware; Audio through a 0.1uF or 1uF capacitor to GP1,
  and a 4k7 or 10k resistor from GP1 to ground. This tested perfectly
  in hardware with DTMF waveforms anywhere from 0.4v to 2.6v peak to peak,
  somewhere about 1v peak to peak is typical.

  Detects DTMF 697 1209 (Key "1") = output ON
  Detects DTMF 941 1336 (Key "0") = output OFF
 
  PIC 12F675 pins;
   GP0  output, main output (drives a relay etc)
   GP1  input, comparator, DTMF audio in
   GP2  output, (drives a LED or speaker for confirmation beep/flash)
   GP3  input, not used
   GP4  osc 8MHz xtal
   GP5  osc 8MHz xtal
******************************************************************************/
// global vars
unsigned char i;

unsigned char cap;        // used to capture TMR0 for period testing
unsigned char cap_last;

unsigned char per;        // holds the last 3 periods values
unsigned char per1;
unsigned char per2;

unsigned char Dtone[12];  // stores points scores for the 12 DTMF tones
unsigned char Dhigh;      // will hold the highest score
unsigned char Dbest;      // which DTMF tone was scored best

unsigned char debounce;
unsigned char output_last;


//=============================================================================
//  MAKE BEEPS
//=============================================================================
void make_beeps(unsigned char beeps)
{
  //-------------------------------------------------------
  // this makes a number of beeps (like 1 or 2 beeps) and then repeats
  // it three times. This is output on GP2, and can be a LED or
  // a speaker etc to show a confimration that the DTMF decoder has
  // changed the output pin. ie for DTMF remote control use.
  //-------------------------------------------------------
  unsigned char beep_count;
  unsigned char bloop;
 
  // repeat the beeping three times with a few seconds between
  for(i=0; i<3; i++)
  {
    beep_count = beeps;
    while(beep_count)   // loop and make X beeps
    {
      // the beep is 1000 Hz and 250mS long, made by toggling a pin 
      for(bloop=0; bloop<250; bloop++)
      {
        output_high(BEEPER_PIN);    // 1mS per cycle
        Delay_uS(500);
        output_low(BEEPER_PIN);
        Delay_uS(500);
      } 
      Delay_mS(300);  // small delay between beeps
      beep_count--;
    }
    Delay_mS(2500);   // long delay before repeating beeps
  }
}
//-----------------------------------------------------------------------------


//=============================================================================
//  COMP DEBOUNCE
//=============================================================================
void comp_debounce(void)
{
  //-------------------------------------------------------
  // this is a critical part of the DTMF decoding, it makes
  // sure the DTMF signal received by the comparator input LO for a
  // period of >220uS and then is HI for >220uS. This performs a
  // synchronisation effect where the periods are synchronised to
  // the most important and reliable features of the DTMF waveform.
  // To keep the 220uS period accurate it tests TMR0 bit0 which
  // toggles every 8 uS. So 220uS / 8uS = 27 cycles
  //-------------------------------------------------------
    // loop here until comparator input has been LO for 220uS
  debounce = 0;
  while(TRUE)
  {
    while(!TMR0_B0);    // wait for TMR0 bit 0 to go HI
    if(C1OUT)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
    while(TMR0_B0);     // wait for TMR0 bit 0 to go LO
    if(C1OUT)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
  }
  // loop here until comparator input has been LO for 220uS
  debounce = 0;
  while(TRUE)
  {
    while(!TMR0_B0);    // wait for TMR0 bit 0 to go HI
    if(!C1OUT)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
    while(TMR0_B0);     // wait for TMR0 bit 0 to go LO
    if(!C1OUT)  debounce = 0;  // test comparator
    else          debounce++;
    if(debounce >= 27) break;
  }
}
//-----------------------------------------------------------------------------


//=============================================================================
//  DECODE TRIPLETS
//=============================================================================
void decode_triplets(void)
{
  //-------------------------------------------------------
  // this is called once for each captured period, it checks the
  // latest period to see if matches one of the 24 periods in
  // the DTMF signatures.
  // if so, it checks that period and the 2 periods before it to
  // see if they match a "triplet" and then allocate points.
  // This project only needs to test 2 DTMF tones, so tones
  // not used are commented out to save processing time and ROM.
  // These triplet tests can be optimised for speed or ROM size, this
  // current version was just thrown together for testing but is
  // fast enough.
  // For theory see; www.RomanBlack.com/DTMF/DTMF_alg.htm
  //-------------------------------------------------------
 
  // Tone 0 66 98  LLS LSL SLL (DTMF key "1")
  if(per >= 66-2 && per <= 66+2)  // ends S
  {
    if(per2 >= 98-2 && per2 <= 98+2 && per1 >= 98-2 && per1 <= 98+2) Dtone[0]+=5; // LLS
  }
  if(per >= 98-2 && per <= 98+2)  // ends L
  {
    if(per2 >= 66-2 && per2 <= 66+2 && per1 >= 98-2 && per1 <= 98+2) Dtone[0]+=5; // SLL
    if(per2 >= 98-2 && per2 <= 98+2 && per1 >= 66-2 && per1 <= 66+2) Dtone[0]+=5; // LSL
  }
 
  /*
  //-------------------------------------------------------
  // Tone 1 63 94  SLS LSL
  if(per >= 63-1 && per <= 63+1)  // ends S
  {
    if(per2 >= 63-1 && per2 <= 63+1 && per1 >= 94-1 && per1 <= 94+1) Dtone[1]+=7; // SLS
  }
  if(per >= 94-1 && per <= 94+1)  // ends L
  {
    if(per2 >= 94-1 && per2 <= 94+1 && per1 >= 63-1 && per1 <= 63+1) Dtone[1]+=3; // LSL
  }
 
  //-------------------------------------------------------
  // Tone 2 61 90  SSL SLS LSS
  if(per >= 61-1 && per <= 61+1)  // ends S
  {
    if(per2 >= 61-1 && per2 <= 61+1 && per1 >= 90-1 && per1 <= 90+1) Dtone[2]+=1; // SLS
    if(per2 >= 90-1 && per2 <= 90+1 && per1 >= 61-1 && per1 <= 61+1) Dtone[2]+=6; // LSS
  }
  if(per >= 90-1 && per <= 90+1)  // ends L
  {
    if(per2 >= 61-1 && per2 <= 61+1 && per1 >= 61-1 && per1 <= 61+1) Dtone[2]+=6; // SSL
  }
 
  //-------------------------------------------------------
  // Tone 3 58 86  SSL LSS
  if(per >= 58-1 && per <= 58+1)  // ends S
  {
    if(per2 >= 86-1 && per2 <= 86+1 && per1 >= 58-1 && per1 <= 58+1) Dtone[3]+=5; // LSS
  }
  if(per >= 86-1 && per <= 86+1)  // ends L
  {
    if(per2 >= 58-1 && per2 <= 58+1 && per1 >= 58-1 && per1 <= 58+1) Dtone[3]+=5; // SSL
  }
 
  //-------------------------------------------------------
  // Tone 4 62 92  SSS SLL LLS
  if(per >= 62-1 && per <= 62+1)  // ends S
  {
    if(per2 >= 62-1 && per2 <= 62+1 && per1 >= 62-1 && per1 <= 62+1) Dtone[0]+=1; // SSS
    if(per2 >= 92-1 && per2 <= 92+1 && per1 >= 92-1 && per1 <= 92+1) Dtone[4]+=14; // LLS
  }
  if(per >= 92-1 && per <= 92+1)  // ends L
  {
    if(per2 >= 62-1 && per2 <= 62+1 && per1 >= 92-1 && per1 <= 92+1) Dtone[4]+=14; // SLL
  }
 
  //-------------------------------------------------------
  // Tone 5 60 89  SLL LLS
  if(per >= 60-1 && per <= 60+1)  // ends S
  {
    if(per2 >= 89-1 && per2 <= 89+1 && per1 >= 89-1 && per1 <= 89+1) Dtone[5]+=5; // LLS
  }
  if(per >= 89-1 && per <= 89+1)  // ends L
  {
    if(per2 >= 60-1 && per2 <= 60+1 && per1 >= 89-1 && per1 <= 89+1) Dtone[5]+=5; // SLL
  }
 
  //-------------------------------------------------------
  // Tone 6 58 85  SLL LLS LSL
  if(per >= 58-1 && per <= 58+1)  // ends S
  {
    if(per2 >= 85-1 && per2 <= 85+1 && per1 >= 85-1 && per1 <= 85+1) Dtone[6]+=5; // LLS
  }
  if(per >= 85-1 && per <= 85+1)  // ends L
  {
    if(per2 >= 58-1 && per2 <= 58+1 && per1 >= 85-1 && per1 <= 85+1) Dtone[6]+=5; // SLL
    if(per2 >= 85-1 && per2 <= 85+1 && per1 >= 58-1 && per1 <= 58+1) Dtone[6]+=3; // LSL
  }
  */
 
  //-------------------------------------------------------
  // Tone 7 55 82  SLS SSL LSS  (DTMF key "0")
  if(per >= 55-2 && per <= 55+2)  // ends S
  {
    if(per2 >= 55-2 && per2 <= 55+2 && per1 >= 82-2 && per1 <= 82+2) Dtone[7]+=3; // SLS
    if(per2 >= 82-2 && per2 <= 82+2 && per1 >= 55-2 && per1 <= 55+2) Dtone[7]+=4; // LSS
  }
  if(per >= 82-2 && per <= 82+2)  // ends L
  {
    if(per2 >= 55-2 && per2 <= 55+2 && per1 >= 55-2 && per1 <= 55+2) Dtone[7]+=4; // SSL
  }
 
  /*
  //-------------------------------------------------------
  // Tone 8 86 114  SLS SSL LSS
  if(per >= 86-1 && per <= 86+1)  // ends S
  {
    if(per2 >= 86-1 && per2 <= 86+1 && per1 >= 114-1 && per1 <= 114+1) Dtone[8]+=7; // SLS
    if(per2 >= 114-1 && per2 <= 114+1 && per1 >= 86-1 && per1 <= 86+1) Dtone[8]+=8; // LSS
  }
  if(per >= 114-1 && per <= 114+1)  // ends L
  {
    if(per2 >= 86-1 && per2 <= 86+1 && per1 >= 86-1 && per1 <= 86+1) Dtone[8]+=8; // SSL
  }

  //-------------------------------------------------------
  // Tone 9 57 83  SLL LLS LSL
  if(per >= 57-1 && per <= 57+1)  // ends S
  {
    if(per2 >= 83-1 && per2 <= 83+1 && per1 >= 83-1 && per1 <= 83+1) Dtone[9]+=9; // LLS
  }
  if(per >= 83-1 && per <= 83+1)  // ends L
  {
    if(per2 >= 57-1 && per2 <= 57+1 && per1 >= 83-1 && per1 <= 83+1) Dtone[9]+=9; // SLL
    if(per2 >= 83-1 && per2 <= 83+1 && per1 >= 57-1 && per1 <= 57+1) Dtone[9]+=9; // LSL
  }
 
  //-------------------------------------------------------
  // Tone 10 54 80  LLS
  if(per >= 54-1 && per <= 54+1)  // ends S
  {
    if(per2 >= 80-1 && per2 <= 80+1 && per1 >= 80-1 && per1 <= 80+1) Dtone[10]+=8; // LLS
  }
 
  //-------------------------------------------------------
  // Tone 11 52 77  SLS SLL LLS
  if(per >= 52-1 && per <= 52+1)  // ends S
  {
    if(per2 >= 52-1 && per2 <= 52+1 && per1 >= 77-1 && per1 <= 77+1) Dtone[11]+=4; // SLS
    if(per2 >= 77-1 && per2 <= 77+1 && per1 >= 77-1 && per1 <= 77+1) Dtone[11]+=4; // LLS
  }
  if(per >= 77-1 && per <= 77+1)  // ends L
  {
    if(per2 >= 52-1 && per2 <= 52+1 && per1 >= 77-1 && per1 <= 77+1) Dtone[11]+=4; // SLL
  }
  */
}
//-----------------------------------------------------------------------------


//=============================================================================
//   MAIN
//=============================================================================

#define PORT_B_PULLUPS_DISABLED 0x80

//======================
void main()     
{
setup_comparator(A0_VR_A1_VR);  //
setup_vref(VREF_LOW | 0x00);
setup_timer_0(T0_DIV_16 | T0_DIV_16 | PORT_B_PULLUPS_DISABLED);


//  //-----------------------------------------------------
//  // PIC 12F675  setup ports
//  ANSEL = 0;            // ADC off
//  CMCON =  0b00000100;  // GP1 is comp input pin
//  VRCON =  0b10100000;  // CVref ON, CVref must be set to zero!
//
//  TRISIO = 0b00001010;  // see page top for pins
//  GPIO =   0b00000000;  // GP1 output OFF at startup
//  WPU =    0b00000000;  // pin pullups; 1 = pullup ON
// 
//  OPTION_REG = 0b10000011; //  TMR0 at 1:16 prescaler

  output_last = 0;
  //-----------------------------------------------------
  // DTMF triplet decoder algorithm;
  // 1, debounce the comparator input so it must be HI and LO for 220uS each
  // 2. synchronise with that debounce to measure one input period
  // 3. after every period compare the last 3 periods to match a "triplet"
  // 4. allocate DTMF points for any triplet matches
  // 5. after 60 triplets are tested, see if there is a good winning points score
  // 6. if winning score is DTMF keys "0" or "1" set the output pin accordingly
  //-----------------------------------------------------
  // main run loop
  while(TRUE)
  {
    //-----------------------------------------
    // clear the tone points accumulators before testing
    for(i=0; i<12; i++)  Dtone[i] = 0; 

    //-----------------------------------------
    // capture 63 periods and test 60 triplets, takes about 95mS total
    for(i=0; i<63; i++)
    {
      comp_debounce();          // sync with waveform
      cap = TMR0;               // capture timer
      per = (cap - cap_last);   // calc the period between timer captures
      per = (per >> 1);         // halve period to suit testing
      cap_last = cap;           // save capture for next test

      // after 3 initial captures we can start testing triplets
      if(i >= 3) decode_triplets();  // test triplet, and allocate points

      // store the previous periods ready for next triplet test
      per2 = per1;
      per1 = per;
    }
    //-----------------------------------------
    // now we have tested 60 triplets and allocated points, test which
    // of the 12 DTMF tones scored the most points
    Dhigh= 0;
    for(i=0; i<12; i++)
    {
      if(Dtone[i] > Dhigh)  // if this is the new best score
      {
        Dhigh = Dtone[i];   // record best score
        Dbest = i;          // and who owns it
      }
    }
   
    // now Dbest tells which DTMF tone had the best score,   
    // Dhigh is its score. A real good DTMF match score will be 120-180
    if(Dhigh > 60)    // looks like we found a real DTMF tone!
    {
      if(Dbest == 0)    // DTMF "1" key, so turn output ON
      {
        output_high(RELAY_PIN);    // change the output
        if(output_last == 0) make_beeps(2);  // 2 beeps to say it toggled
        output_last = 1;
      }
      if(Dbest == 7)    // DTMF "0" key, so turn output OFF
      {
        output_low(RELAY_PIN);    // change the output
        if(output_last == 1) make_beeps(1);  // 1 beep to say it toggled
        output_last = 0;
      }
    }
  }
}
//-----------------------------------------------------------------------------
vtrx



Joined: 11 Oct 2017
Posts: 142

View user's profile Send private message

PostPosted: Mon Aug 03, 2020 4:21 am     Reply with quote

I'm going to build a piece of hardware to test, the simulator didn't work.
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Mon Aug 03, 2020 10:05 am     Reply with quote

PCM Programmer needs a PO Box for BeerMoney or PizzaCash or something.

:D
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Aug 03, 2020 2:37 pm     Reply with quote

re: the simulator didn't work....

THAT's what I've said for almost 2 decades....

NO simulator actually works 100% and YOU have to KNOW what is busted in it.
It's always best to buy a PIC and parts and see how it works in the Real World.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Mon Aug 03, 2020 4:15 pm     Reply with quote

temtronic wrote:
re: the simulator didn't work....

THAT's what I've said for almost 2 decades....

NO simulator actually works 100% and YOU have to KNOW what is busted in it.
It's always best to buy a PIC and parts and see how it works in the Real World.


I say this to my friends when I try to explain what I do for work.

Is it my design at the schematic level? Did I assemble it badly? Is it my code? Do I fix my problem in the IDE? or do I use a knife and a soldering iron?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group