|
|
View previous topic :: View next topic |
Author |
Message |
vtrx
Joined: 11 Oct 2017 Posts: 142
|
MikroC code to CCS |
Posted: Fri Jul 31, 2020 5:30 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Jul 31, 2020 6:40 am |
|
|
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
|
|
Posted: Fri Jul 31, 2020 8:43 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Jul 31, 2020 10:30 am |
|
|
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
|
|
Posted: Sat Aug 01, 2020 2:05 am |
|
|
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
|
|
Posted: Mon Aug 03, 2020 4:21 am |
|
|
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
|
|
Posted: Mon Aug 03, 2020 10:05 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Aug 03, 2020 2:37 pm |
|
|
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
|
|
Posted: Mon Aug 03, 2020 4:15 pm |
|
|
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? |
|
|
|
|
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
|