Universele telefoonprint met/voor PIC besturing

Verbind PIC projecten met de buitenwereld via de telefoonlijn

Verschillende soorten projecten met één en dezelfde printplaat


De 140801 print.
 

Met deze telefoonprint zijn diverse PIC projecten te maken die een verbinding met een telefoonlijn nodig hebben.
De print heeft en kan ondermeer:

Een telefoonbel signaal detecteren (kijken of er gebeld wordt)
DTMF tonen decoderen (codes doorgeven aan de PIC)
Zelf telefoonnummers bellen door DTMF tonen te genereren
De telefoonlijn bezet houden
Geluiden verzenden over de telefoonlijn
Een HD44780 display aansturen
Voorziening voor in circuit (ICSP) programmeermogelijkheid van de PIC
Vele 18-pins PIC-types mogelijk (o.a. 16F628(A), 16F648A, 16F818, 16F819, 18F1220, 18F1320)
Maximaal 8 in/uitgangspoorten waar je van alles mee kan uitlezen of aansturen (uitbreidbaar)
USART of synchrone seriële verbinding met PIC op Stocko connector aanwezig
Dus aan te sluiten op de bus van het automatische huis van deze site
Galvanische scheiding tussen PIC schakeling en telefoonlijn schakeling
De huistelefoon (waarvan de telefoonlijn eigenlijk is) blijft gewoon bruikbaar

Te bedenken toepassingen van de print zijn ondermeer:

Alarm detector, print belt bij brand of inbraak naar vooraf opgegeven nummer(s) en geeft dan alarmsignaal
Afstandsbediening per telefoon, je belt naar je huis om iets in- of uit te schakelen (met pincode)
Telefoonnummer geheugen, laat de print vooraf opgegeven nummers bellen
Berichten op een HD44780 display weergeven die een opbeller intoetst op zijn telefoon
Toestand van PIC poortingangen doorgeven aan een opbeller middels bijv. geluid of DTMF code
Een machine of toestel dat zelf opbelt in geval van een storing en de foutcode doorgeeft
Humor: deurbel / telefoonbel verwisselaar
Telefoonbelgeluid van je (vaste) telefoon zelf programmeren (soort geluid zelf bepalen)
Ouderwetse kiesschijf die DTMF tonen genereert (zie ook dit project)
Meerdere van de genoemde toepassingen combineren in één print
En natuurlijk al je eigen bedachte en geprogrammeerde toepassingen in PIC Basic!


Eens in de zoveel tijd zal ik proberen een project met de telefoonprint te maken als voorbeeld.
De PIC Basic programma's zijn dan te downloaden en naar wens te wijzigen of uit te breiden.
Als je zelf een origineel project voor de telefoonprint hebt geprogrammeerd en je wilt het delen met anderen, dan kan het op deze website geplaatst worden.


De 140801 print

De printplaat zelf is maar klein van omvang.
Een 9-polige connector bevat aansluitingen naar de poorten PORTA.0 ... PORTA.3, PORTA.6, PORTA.7, PORTB.1 en PORTB.2 (USART of synchrone verbinding) en als negende een 0V (GND) aansluiting waardoor de print eenvoudig deel kan uitmaken van een grotere schakeling.

De groene LED geeft aan of de print voedingsspanning heeft.
De gele LED geeft aan of de print met de telefoonlijn is verbonden (= DIL reedrelais ingeschakeld).
De rode LED zit aan PORTB.1 en brandt als PORTB.1 HOOG is.
Deze LED is te gebruiken als hulpmiddel tijdens het programmeren en mag eventueel weggelaten worden.


De componenten, rechtsboven 2 stuks 100n in SMD behuizing (verpakt).
 

Onderdelenlijst print 140801:

Print 140801 Zelf etsen of door iemand laten maken (88mm x 54mm)
IC1 Aanbevolen 16F628(A), 16F648A, 16F818 of 16F819 (eigen keus)
IC2 CM8870, MT8870, HM9270D of UM92870C
IC3 4N25 optocoupler
VR1 7805 spanningsregelaar
B1 B250C1000 brugcel in DIL behuizing
LED1,LED2,LED3 Groene, gele en rode LED, Ø3mm, low current
T1 BD681 transistor
D1,D2,D3 1N4148 diode
ZD1,ZD2,ZD3 4V7 / 500mW zenerdiode
ZD4,ZD5 27V / 500mW zenerdiode
X1 Kristal 3,5795MHz
X2 Kristal 20MHz (optioneel, het liefst een laag model)
R1,R2 22E
R3 100E
R4,R5,R6 1k
R7 mag een waarde hebben van 100E ... 2k2 (aanbevolen: 1k)
R8 5k6
R9 6k8
R10 27k
R11,R12 100k
R13 270k
C1 470µF / 25V radiaal (staand, 0,1" of 0,2" raster)
C2 10µF radiaal (staand, 0,1" of 0,2" raster)
C3 10µF axiaal (liggend)
C4,C5 10µF / 100V(!) radiaal (staand, 0,1" of 0,2" raster) *)
C6 1µF radiaal (staand, 0,1" raster)
C7,C8 1µF tantaal **)
C9 470n / 400V(!) *)
C10,C11,C12 100n multilayer (steek 0,1" raster)
C13,C14 100n SMD (in ieder geval plaatsen, zie tekst ***) )
C15 22n (ceramisch of MKT)
C16 33n (ceramisch of MKT)
C17,C18 22p ceramisch, steek 0,1" (alleen bij plaatsing van X2)
Ry1 5V DIL reedrelais type 3570-1210-051 (Günther) (Conrad 50 45 72)
Tr1 Scheidingstrafo 1:1 (impedantie 600 : 600) (Conrad 51 66 86)
VDR S10K250V
Conn1,Conn2 2-polige printkroonsteen (5mm raster)
Conn3 9-polige connector (0,1" raster), eigen keus
IC voet 18-pins, eigen keus

*) C4 en C5 moeten minimaal 100V types zijn en C9 minimaal 250V, aanbevolen: 400V.

**) Een tantaal wordt geadviseerd voor C7 en C8, dit type zo mogelijk plaatsen, een normale elco is groter in omvang en zal slechter passen op de print.
Eventueel mogen ze vervangen worden door 100n (multilayer) condensatoren (zie foto rechts).

***) Als geen SMD uitvoering voor C13 en C14 te verkrijgen is, dan een "normale" 100n aan de soldeerzijde onder de IC's solderen (zie foto rechts).
In ieder geval altijd 100n condensatoren plaatsen, weglaten is geen optie!


 

ICSP, In Circuit Programmeren
De PIC is te programmeren in de print zelf (ICSP), hiervoor is er een voorziening op de print getroffen door D1 en R10, die ervoor zorgen dat de CM8870 (IC2) geen schade ondervindt van de 13V programmeerspanning.
Maar als de print moet werken (of getest wordt), dan moet de PIC programmer steeds afgekoppeld worden, omdat anders het Q1 signaal van de CM8870 op PORTA.5 verstoord kan worden, waardoor de ontvangen DTMF code niet goed gedecodeerd wordt.

Het "in-circuit" programmeren van de PIC zelf is eenvoudig door een DIL-clip over de PIC te plaatsen waardoor deze met de PIC-programmer is verbonden.
Als de DIL-clip niet helemaal past vanwege kristal X2 en/of C1, dan een paar IC-voetjes op elkaar stapelen zodat de PIC wat hoger komt te liggen (zie foto en daaronder een extra 8 foto).
Is de PIC eenmaal goed werkend geprogrammeerd, dan kunnen deze extra voetjes weer weggehaald worden.
Meer info over ICSP, zie Galva-Wisp PIC programmer.
 

Beldetector
De beldetector bevat een op het oog veel te grote condensator.
Toch mag deze niet vervangen worden door een condensator met een lagere werkspanning dan 250V!
Pas op met het werken met de telefoonlijn, bij een belsignaal kan de spanning tussen lijn A en B oplopen tot wel 160 volt!
Op de foto's staat overigens een 630V exemplaar, een 250V of 400V type zal kleiner van omvang zijn.

De beldetector is het enige elektronica gedeelte dat continu op de telefoonlijn blijft aangesloten.
Bij gebruik van alle andere delen van de print moet het reedrelais Ry1 worden ingeschakeld door het PIC programma.


Schema
De componentwaarden worden zichtbaar door met de muis op het schema te gaan staan.

8

8 Ga met de muis op het schema staan voor de componentwaarden.
 

De beschrijving van de blokken:
A Beldetector.
Als de telefoonbel gaat, wordt er een LAAG signaal op PORTB.5 aangeboden.
Aan de hand van dit signaal kan het PIC programma actie gaan ondernemen, bijvoorbeeld "de hoorn oppakken" door het reedrelais in te schakelen.
C3 zorgt ervoor dat tijdens het overgaan van de bel het signaal op PORTB.5 continu LAAG blijft, het belsignaal is namelijk een 25Hz wisselspanning en dus niet continu LAAG.
C9 moet minimaal een 250V type zijn!
B Voedingsstabilisator.
Stabiliseert de inkomende gelijkspanning van 9V ... 15V naar een mooie 5V.
C Galvanische scheiding.
Telefoonlijn en PIC schakeling (met op de 9-polige connector aangesloten onderdelen of externe printen) zijn volledig van elkaar gescheiden.
Elco's C4 en C5 moeten minimaal 100V types zijn!
D Lijnbezethouder.
Dit is een gyrator schakeling en simuleert een impedantie op de telefoonlijn zodra het reedrelais wordt ingeschakeld (door PORTB.4).
De KPN centrale of kabelmodem ziet dat alsof "de hoorn wordt opgenomen".
Er kunnen nu DTMF tonen worden verzonden (via signaalverzender) of worden ontvangen (via DTMF decoder).
E Signaalverzender.
Dit kunnen bijvoorbeeld DTMF tonen zijn, zodat de print zelf contact kan maken (zelf gaat "opbellen").
Het kunnen ook geluidssignalen zijn, speciaal hiervoor zit deze aan PORTB.3, zodat ook gebruik kan worden gemaakt van de PWM module dat in sommige PIC types zit.
PIC Basic instructies PWM, HPWM, SOUND, FREQOUT en DTMFOUT zijn o.a. te gebruiken.
F DTMF decoder.
Op deze manier kan de persoon die opbelt via zijn telefoontoetsen commando's doorgeven naar de print, zodat het PIC programma weer actie kan gaan nemen (bijvoorbeeld verwarming in huis aanzetten).
G ICSP voorziening.
Door dit circuitje is de PIC in de print zelf te programmeren, zonder dat de andere componenten schade ondervinden van de 13V programmeerspanning.
H Gebruikersvrij.
Het type 18-pins PIC dat afhankelijk is van de wensen van de gebruiker.
Ook het plaatsen van de soort 9-polige connector en het al dan niet plaatsen van kristal X2 en/of LED3 is volledig vrij aan de gebruiker.
Bij gebruikmaking van de signaalverzender (geluiden en/of DTMF tonen) wordt het sterk aangeraden een kristal van 20MHz te plaatsen voor een zo mooi mogelijk geluid.
En ook als er van een seriële verbinding gebruikt wordt gemaakt, is het aan te bevelen een kristal te plaatsen.


Aansluitingen van de print

Telefoonlijn
De 140801 telefoonprint kan parallel aan de huistelefoon worden aangesloten.
Hoewel op de print A en B staat aangegeven, maakt het voor de werking van de print niet uit hoe de telefoondraden op de print zijn aangesloten.
In een (PTT) telefoonstekker is normaal gesproken de rode draad lijn A, en de blauwe draad lijn B.
Bij Japanse en Amerikaanse toestellen is de kleurcodering van de draden groen voor lijn A en rood voor lijn B.
Pas overigens op met het werken met de telefoonlijn, bij een belsignaal kan de spanning tussen lijn A en B oplopen tot wel 160 volt!
 

Gelijkspanningsvoeding
De 140801 print heeft een gelijkspanning nodig van 9VDC ... 15VDC, eventueel eenvoudig uit een netadapter te halen.
Denk eraan dat + en - goed worden aangesloten, want de print is niet beveiligd tegen verkeerd om aansluiten.
De + en - aansluiting staan aan de soldeerzijde aangegeven, maar het is verstandig om dit met een stift ook op de printkroonsteen te noteren.
 

9-polige connector
De eerste aansluitpin van de connector is de GND (0V, massa).

PORTB.2 en PORTB.1 hebben op de meeste 18-pins PIC's een communicatie mogelijkheid met de buitenwereld.
Dit betreft meestal de keuze uit USART of een synchrone seriële verbinding.
Meer info hierover is te vinden in de datasheet van het gebruikte PIC type.
Maar PORTB.2 en PORTB.1 zijn natuurlijk ook als normale in- en/of uitgang te gebruiken.

PORTA.7 en PORTA.6 zijn alleen te gebruiken als de PIC draait op zijn interne oscillator.
Niet alle projecten hebben immers een kristal nodig, waardoor er twee extra in/uitgangen vrij komen.

PORTA.3 t/m PORTA.0 kunnen gebruikt worden voor aansturing van de datalijnen van een HD44780 display (in 4-draads mode).


Het type 9-polige connector is vrije keus, op de foto staat een Stocko connector.

18 pins PIC's

16Fxxx

GND
PORTB.2
PORTB.1
PORTA.6
PORTA.7
PORTA.0
PORTA.1
PORTA.2
PORTA.3

conn

1
2
3
4
5
6
7
8
9

18Fxxx

GND
PORTB.0
PORTA.3
PORTA.6
PORTA.7
PORTB.2
PORTB.3
PORTA.0
PORTA.1


De aansluitingen van de 9-polige connector staan ook aangegeven op de soldeerzijde van de print, ervan uitgaand dat er een 16Fxxx PIC in zit.
Er bestaan echter ook 18-pins PIC's die de poorten anders hebben ingedeeld (o.a. 18Fxxx) waardoor de aanduiding op de print niet overeenkomt.
Het is verder wel mogelijk om een 18-pins 18Fxxx PIC in de print te plaatsen (zie tabel hierboven).

Met elke poort is ook een seriële verbinding te maken d.m.v. PIC Basic instructie SEROUT, waarmee tevens de baudrate is in te stellen.
Zo is bijvoorbeeld de verwarming in huis op afstand op een bepaalde temperatuur in te stellen.
Meer info zie modulerende thermostaat.


Programmaatjes om de print te testen

De volgende testprogramma's zijn voor een PIC16F628(A) of 16F648A.
Met deze programmaatjes zijn delen van de print apart te testen.
Deze zijn ook met de gratis LITE versie van PIC Basic te doen.
Voor wie onderstaande programmavoorbeeldjes niet begrijpt is hier het advies om de programmeercursus eens door te nemen.


LED3 testen
Van de rode LED (LED3) wordt zodadelijk gebruik gemaakt tijdens het testen.
Maar dan moet LED3 het zelf natuurlijk wel doen, daarom eerst even checken of deze het doet.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Hoofdprogramma
WHILE 1 = 1                   ;Oneindige lus
  TOGGLE PORTB.1              ;LED toggle
  DELAYMS 1000                ;Om de seconde de LED aan of uit schakelen 
WEND                          ;Terug naar WHILE

Programmeer bovenstaand programmaatje in een PIC16F628A.
De rode LED3 dient dan elke seconde te knipperen.


Beldetector testen
Om de beldetector van de print te testen moet de print op de telefoonlijn zijn aangesloten en van een gelijkspanning zijn voorzien.
Bel met een mobiele telefoon naar het telefoonnummer waarop de print zit aangesloten.
Steeds als nu de bel overgaat, moet de rode LED (LED3) gaan oplichten.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

OUTPUT PORTB.1                ;Maak van PORTB.1 een uitgang (voor de rode LED)
PORTB_PULLUPS ON              ;Deze regel altijd plaatsen bij gebruik van de beldetector! 

;Hoofdprogramma
WHILE 1 = 1                   ;Oneindige lus
  PORTB.1 = ~PORTB.5          ;PORTB.1 (LED) is gelijk aan geinverteerd PORTB.5 (optocoupler) 
WEND                          ;Terug naar WHILE

Als de bel overgaat, krijgt PORTB.5 een LAAG signaal van de optocoupler (IC3).
Dit signaal wordt door het programmaatje rechtstreeks doorgegeven aan PORTB.1, waarop LED3 zit.
Alleen moet dit nog geïnverteerd worden, dat gebeurt door de tilde ( ~ ).
Als PORTB.5 nu LAAG is, dan wordt PORTB.1 HOOG gemaakt (en vice versa) waardoor LED3 oplicht.

De beldetector is het enige gedeelte dat continu op de telefoonlijn is aangesloten, het reedrelais hoeft dus niet ingeschakeld te zijn om een belsignaal te detecteren.

Let op: in eigen geschreven programma's moet altijd de regel PORTB_PULLUPS ON worden geplaatst als gebruik wordt gemaakt van de beldetector.


 
Lijnbezethouder testen
Degene die in het bezit is van een kabelmodem (bellen via de kabel) kan dit eenvoudig zien aan een LED op dit modem.
Een andere manier is om met een mobiel te bellen naar het telefoonnummer waarop de print zit aangesloten.
Wanneer de lijnbezethouder actief is (gele LED brandt), dan moet het mobiel een "in gesprek" toon krijgen.
Als onderstaand programma wordt uitgevoerd dan wordt de telefoonlijn voor 60 seconden bezet gehouden.
 

Kabelmodem van Essent.
Deze LED op het modem brandt als het reedrelais op de 140801 print ingeschakeld is.

 
DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

LOW PORTB.4                   ;Relais inschakelen (LAAG = relais AAN)

DELAYMS 60000                 ;Relais 60 seconden AAN (lijn 60 sec. bezet) 

HIGH PORTB.4                  ;Relais uitschakelen (HOOG = relais UIT)

END                           ;Einde programma

Na 60 seconden valt het relais weer af om te voorkomen dat de telefoonlijn per ongeluk de hele tijd bezet is.
Om nog eens te testen, even de spanning van de print halen en opnieuw inschakelen.
Wanneer het relais is ingeschakeld, licht de gele LED (LED2) op.
Tijdens het ontwerpen van een PIC Basic programma dient er rekening mee te worden gehouden dat een LAAG signaal het relais inschakelt.
Als het programma start, moet PORTB.4 dus eerst HOOG gemaakt worden en dan pas PORTB.4 worden omgeschakeld als uitgang om het relais uitgeschakeld te houden (zie programmeertips telefoonprint).


DTMF verzender testen (een telefoonnummer bellen)
In PIC Basic is het zeer eenvoudig om DTMF tonen op te wekken met de instructie DTMFOUT.
Gewoon het poortnummer (PORTB.3 bij deze print) en het telefoonnummer in het programma invoeren.
Het is hiervoor wel van belang dat er een 20MHz kristal op de print is gesoldeerd, zodat de DTMF tonen van goede kwaliteit zijn.
Om de print te testen moet nog een telefoonnummer op de plaats van de vraagtekens worden ingevoerd (06????????).
Cijfers scheiden door een komma, de 06 staat er al.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG HS_OSC, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF ;INTRC_OSC_NOCLKOUT verwijderd
ALL_DIGITAL TRUE              ;Alle ingangen digitaal
XTAL 20                       ;Kristal van 20MHz
 
LOW PORTB.4                   ;"Hoorn opnemen" (relais inschakelen (LAAG = relais AAN)) 

DELAYMS 2000                  ;Even twee seconden wachten voor KPN of het modem

DTMFOUT PORTB.3, [0,6,?,?,?,?,?,?,?,?] ;Het opgegeven (mobiele) telefoonnummer bellen

DELAYMS 30000                 ;Na 30 seconden ophangen
HIGH PORTB.4                  ;Ophangen (relais uitschakelen (HOOG = relais UIT))

END                           ;Einde programma

Als het programma in de PIC start dan wordt eerst "de hoorn opgenomen" door het reedrelais op de print in te schakelen.
Dan wordt er even 2 seconden gewacht zodat KPN of het belmodem zich kunnen klaarmaken voor DTMF nummer "intoetsing".
Na die 2 seconden begint de PIC het opgegeven telefoonnummer te bellen.
Als het goed is begint de opgegeven mobiele telefoon te bellen, die nu kan worden aangenomen.
Na 30 seconden vanaf het eerste belsignaal van de mobiele telefoon zal de print zelf de verbinding weer verbreken (gewoon even 30 seconden blijven luisteren aan de (mobiele) telefoon om dit te constateren).

Opgelet:
Als in het PIC Basic programma de instructies DTMFOUT en HPWM beide worden gebruikt, dient vóór elke DTMFOUT programmaregel, de CCP module uitgeschakeld te worden omdat de DTMF verzender op PORTB.3 (tevens HPWM uitgang) zit aangesloten.
Doe je dat niet dan zal de DTMFOUT instructie niets doen:

CCP1CON = 0                   ;Schakel de CCP module uit, anders doet DTMFOUT het niet   
DTMFOUT PORTB.3, [0,6,?,?,?,?,?,?,?,?] ;Het opgegeven (mobiele) telefoonnummer bellen

Het uitschakelen van de CCP module gebeurt in een 16F628(A) en 16F648A met CCP1CON = 0.
Voor andere PIC types kán dit anders zijn, maar hoeft niet (zie de datasheet van het gebruikte PIC type).


DTMF decoder testen
Om via het toetsenbord van een (mobiele) telefoon DTMF codes door te geven aan de PIC op de print (bijvoorbeeld voor opdrachten en/of een pincode) is de print voorzien van een DTMF decoder.
Deze kan getest worden met behulp van de huistelefoon die parallel op de telefoonlijn zit waarop ook de print is aangesloten (zie schemaatje bij aansluitingen).

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

OUTPUT PORTB.1                ;Maak van PORTB.1 een uitgang (voor de rode LED)
LOW    PORTB.4                ;Maak van PORTB.4 een LAGE uitgang (= relais inschakelen)  

;Hoofdprogramma
WHILE 1 = 1                   ;Oneindige lus
  PORTB.1 = PORTA.4           ;PORTB.1 (rode LED) is gelijk aan PORTA.4 (CM8870 StD) 
WEND                          ;Terug naar WHILE

DTMF decoder IC2 (CM8870) geeft op zijn StD pin (pin 15) een HOOG signaal aan PORTA.4 zolang het een willekeurig DTMF signaal ontvangt.
Het bovenstaand programma moet de LED laten branden zolang er op een willekeurige toets van de huistelefoon wordt gedrukt.


Kon het vorige programma alleen maar constateren óf er een (willekeurige) telefoontoets werd ingedrukt, het programma hieronder kijkt ook wélke toets er wordt ingedrukt.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal
 
DIM TelefoonToets  AS BYTE    ;Bevat het toetsnummer dat op de telefoon wordt ingedrukt

LOW PORTB.4                   ;"Hoorn opnemen" (relais inschakelen (LAAG = relais AAN)) 

GOTO Start                    ;Spring over de subroutine


;Subroutine
;Kijken welke telefoontoets de opbeller indrukt
DTMF:
  TelefoonToets = PORTA.5 + (2 * PORTB.6) + (4 * PORTB.7) + (8 * PORTB.0)
  WHILE PORTA.4 = 1 : WEND    ;Wacht tot de opbeller de telefoontoets los laat
  DELAYMS 1                   ;Wacht nog even tot de StD van de CM8870 goed LAAG is
RETURN


;Hoofdprogramma
Start:
  IF PORTA.4 = 1 THEN GOSUB DTMF ;Is er een toets ingedrukt, onderzoek dan welke toets dat is
  IF TelefoonToets = 7 THEN HIGH PORTB.1 ;Als toets 7 werd ingedrukt, dan de rode LED AAN
  IF TelefoonToets = 8 THEN LOW  PORTB.1 ;Als toets 8 werd ingedrukt, dan de rode LED UIT
GOTO Start

Door op toets 7 van de parallel op dezelfde telefoonlijn aangesloten huistelefoon te drukken moet de rode LED (LED3) oplichten.
Met telefoontoets 8 moet LED3 weer uitgezet kunnen worden.

Denk er aan dat toets '0' niet de waarde 0 geeft maar de waarde 10.
Zou in bovenstaande test de LED uit moeten gaan met toets '0', dan moet er dus staan IF TelefoonToets = 10 THEN ...

Let op dat deze test wordt gedaan met de PIC programmer afgekoppeld, anders kan DTMF verkeerd worden gedecodeerd, omdat de programmer het signaal op PORTA.5 kan verstoren.


Geluiden verzenden testen
Het volgende programma laat continu een gong horen op een parallel op de telefoonlijn aangesloten huistelefoon.
Hier is gebruik gemaakt van de CCP/PWM module in de PIC met gebruik van PIC Basic instructie HPWM.

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Variabele declareren
DIM Volume  AS BYTE           ;'Volume' is de variabele die de volume van de gong regelt 

HPWM 1, 0, 0                  ;Reset de CCP/PWM module (Op 0% = geen geluid)
OUTPUT PORTB.3                ;Maak PORTB.3 uitgang (geluidsuitgang)

LOW PORTB.4                   ;Verbinding maken met telefoonlijn (LAAG = relais aan)


;Hoofdprogramma
WHILE 1 = 1                   ;Oneindige lus (continu de gong laten horen)
  FOR Volume = 165 TO 0 STEP -1;Van 165 (=65% duty) naar continu laag (= geen geluid) 
    HPWM 1, Volume, 2100      ;Geef de frequentie van 2100Hz door aan de CCP/PWM module
    DELAYUS 60 * (~Volume / 2);Hoe zachter het volume, hoe langer de tijd duurt (nagalm) 
  NEXT 
  DELAYMS 250                 ;Wachttijd tussen de gongs 
WEND                          ;Terug naar WHILE

Na het programmeren en starten van de PIC moet de gong op de telefoon hoorbaar zijn.
Voor uitleg van het gonggeluid zie cursus deel 7.


Nog een test met geluid verzenden, alleen is nu PIC Basic instructie FREQOUT gebruikt om de geluiden op te wekken.
Meer info over FREQOUT zie de help-bestanden van Positron PIC Basic IDE.
Ook hebben de poorten hier namen gekregen zodat veel duidelijker is wat een poort doet.
Het PIC Basic programma wordt er wel groter door (het HEX bestand voor de PIC niet!)

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG HS_OSC, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal
XTAL 20                       ;Kristal van 20MHz

;Logische constanten
SYMBOL AAN          = 0       ;Omgekeerd ON
SYMBOL LAAG         = 0       ;Laag signaal
SYMBOL HOOG         = 1       ;Hoog signaal
SYMBOL OFF          = 0       ;UIT
SYMBOL ON           = 1       ;AAN
SYMBOL UIT          = 1       ;Omgekeerd OFF

;Muzieknoten met bijbehorende frequenties in Hertz
SYMBOL C = 2092               ;C noot
SYMBOL D = 2348               ;D noot
SYMBOL E = 2636               ;E noot
SYMBOL G = 3136               ;G noot
SYMBOL R = 0                  ;Rust (stilte, pauze)

;Poortnamen
'YMBOL -            = PORTA.0 ;Vrij bruikbaar als in/uitgang
'YMBOL -            = PORTA.1 ;Vrij bruikbaar als in/uitgang
'YMBOL -            = PORTA.2 ;Vrij bruikbaar als in/uitgang
'YMBOL -            = PORTA.3 ;Vrij bruikbaar als in/uitgang
SYMBOL CM8870_StD   = PORTA.4 ;
SYMBOL CM8870_Q1    = PORTA.5 ;
'YMBOL -            = PORTA.6 ;Vrij bruikbaar als in/uitgang (of 20MHz kristal)
'YMBOL -            = PORTA.7 ;Vrij bruikbaar als in/uitgang (of 20MHz kristal)
SYMBOL CM8870_Q4    = PORTB.0 ;
SYMBOL LED          = PORTB.1 ;Vrij bruikbaar als in/uitgang (USART) tevens LED3
'YMBOL -            = PORTB.2 ;Vrij bruikbaar als in/uitgang (USART)
SYMBOL Geluid       = PORTB.3 ;Tonen zijn ook te versturen door de CCP/PWM module (HPWM)
SYMBOL Relais       = PORTB.4 ;LAAG = relais actief = "telefoon opnemen"
SYMBOL BelSignaal   = PORTB.5 ;LAAG als de telefoonbel gaat (er wordt gebeld)
SYMBOL CM8870_Q2    = PORTB.6 ;
SYMBOL CM8870_Q3    = PORTB.7 ;

;Variabelen declareren
;WORD
DIM Freq1           AS WORD   ;Frequentie 1
DIM Freq2           AS WORD   ;Frequentie 2
DIM WD1             AS WORD   ;Word Dummy 1
;BYTE
DIM NootNr          AS BYTE   ;Teller die bijhoudt welke muzieknoot wordt afgespeeld
DIM TelefoonToets   AS BYTE   ;Toetsnummer (DTMF) die de opbeller op zijn telefoon indrukt
DIM Teller          AS BYTE   ;FOR...NEXT telvariabele
DIM Timer           AS BYTE
DIM BD1             AS BYTE   ;Byte Dummy 1
;BIT
DIM ID1             AS BIT    ;bIt Dummy 1

;        76543210
PORTA = %00000000             ;PORTA poorten laag
PORTB = %00100000             ;PORTB poorten laag, (behalve B.5; HOOG = reedrelais uit)
TRISA = %11111111             ;
TRISB = %11100101             ;B.4 uitgang reedrelais, B.3 uitgang geluid, B.1 uitgang LED

Relais = AAN                  ;Maak verbinding met de telefoonlijn

GOTO Start                    ;Spring over de subroutine


;Subroutine
DTMF:                         ;Kijk welke telefoontoets de opbeller indrukt
  TelefoonToets = CM8870_Q1 + (2 * CM8870_Q2) + (4 * CM8870_Q3) + (8 * CM8870_Q4)
  WHILE CM8870_StD = HOOG : WEND ;Wacht tot de opbeller de telefoontoets los laat
  DELAYMS 1                   ;Wacht nog even tot CM8870_StD goed LAAG is
RETURN


;Hoofdprogramma
Start:
  WHILE CM8870_StD = LAAG : WEND ;Wacht tot de opbeller op een toets drukt
  GOSUB DTMF                  ;Ga kijken welke toets de opbeller heeft ingedrukt

  SELECT TelefoonToets        ;Afhankelijk van ingedrukte toets (eventueel) actie ondernemen 
    CASE 10                   ;Bij telefoontoets '0' indrukken... LET OP: 10 staat voor '0'
      LED = OFF               ;...de rode LED uitzetten
      
    CASE 1                    ;Bij telefoontoets '1' indrukken...
      LED = ON                ;...de rode LED aanzetten
      
    CASE 5                    ;Als telefoontoets '5' wordt ingedrukt dan muziek afspelen
      FOR NootNr = 0 TO 28    ;Speel de 29 noten na elkaar af (29 = 0 t/m 28)
        Freq1 = LOOKUPL NootNr, [E,D,C,D,E,E,E,R,D,D,D,R,E,G,G,R,E,D,C,D,E,E,E,E,D,D,E,D,C]
        IF Freq1 > 8 THEN Freq2 = Freq1 - 8 ;Dit geeft een speciaal geluidseffect
        FREQOUT Geluid, 225, Freq1, Freq2   ;Speel de noten af op de telefoon
      NEXT
      
    CASE 9                    ;Bij telefoontoets '9' indrukken...
      Relais = UIT            ;... de verbinding verbreken
      
  ENDSELECT
GOTO Start

Door een druk op toets '5' van de parallel aangesloten telefoon zal de PIC een vrolijk deuntje laten horen.

Wanneer op toets '9' wordt gedrukt, zal het reedrelais uitschakelen en de verbinding verbreken.
Om verder te gaan met testen dient dan de print opnieuw opgestart te worden zodat het relais weer wordt ingeschakeld.

Als extraatje is met toets '1' van de telefoon de rode LED op de print AAN- en met toets '0' weer UIT te zetten.

Let op dat ook deze test wordt gedaan met de PIC programmer afgekoppeld.

Opgelet:
Als in het PIC Basic programma geluidsinstructies zoals SOUND, FREQOUT en DTMFOUT gelijktijdig met HPWM worden gebruikt, dient vóór elk geluidsgedeelte van het programma, de CCP module uitgeschakeld te worden omdat geluiden via PORTB.3 (tevens HPWM uitgang) worden verzonden.
Doe je dat niet dan zal de geluidsinstructie niets doen:

    CASE 5                    ;Als telefoontoets '5' wordt ingedrukt dan muziek afspelen
      CCP1CON = 0             ;Schakel de CCP module uit, anders heb je geen geluid
      FOR NootNr = 0 TO 28    ;Speel de 29 noten na elkaar af (29 = 0 t/m 28)
        Freq1 = LOOKUPL NootNr, [E,D,C,D,E,E,E,R,D,D,D,R,E,G,G,R,E,D,C,D,E,E,E,E,D,D,E,D,C]
        IF Freq1 > 8 THEN Freq2 = Freq1 - 8 ;Dit geeft een speciaal geluidseffect
        FREQOUT Geluid, 225, Freq1, Freq2   ;Speel de noten af op de telefoon
      NEXT

Het uitschakelen van de CCP module gebeurt in een 16F628(A) en 16F648A met CCP1CON = 0.
Voor andere PIC types kán dit anders zijn, maar hoeft niet (zie de datasheet van het gebruikte PIC type).


Programmeertips telefoonprint

Tijdens het ontwerpen van een PIC Basic programma dient er rekening mee te worden gehouden dat een LAAG signaal het relais inschakelt (= verbinding maken met de telefoonlijn).
Als het programma start, moet PORTB.4 dus eerst HOOG gemaakt worden en dan pas van PORTB.4 een uitgang worden gemaakt om het relais uitgeschakeld te houden.

;        76543210
PORTB = %00010000             ;PORTB.4 eerst HOOG maken bij begin van een programma... 
TRISB = %11101111             ;... en dan pas PORTB.4 omschakelen van ingang naar uitgang 

Dit kan dus bovenaan bij het instellen van de poortrichtingen (met TRIS) meteen gedaan worden.


Bij gebruik van de beldetector moet PORTB_PULLUPS = ON altijd in het programma staan.
Ingang PORTB.5 die met de optocoupler (IC3) van de beldetector is verbonden moet namelijk HOOG zijn in rust.
Bovendien is de ontlaadtijd van C3 anders als de pull-up van deze poort uitgeschakeld zou zijn.
Als geen gebruik wordt gemaakt van het beldetectorgedeelte dan mogen de interne pull-ups eventueel uitgeschakeld blijven.


Als geen gebruik wordt gemaakt van de instructies DTMFOUT en FREQOUT dan is het 20MHz kristal niet per se nodig.
Hierdoor komen er 2 poorten (PORTA.6 en A.7) extra vrij op de PIC (en 9-polige connector).


Heeft de telefoonprint te weinig in- en/of uitgangen?
Met schuifregister 74HC595 is het aantal uitgangen (theoretisch) oneindig uit te breiden.
Voor uitbreiding van het aantal ingangen gebruik je de 74HC165.
Deze IC's zijn aan te sturen / uit te lezen via de 9-polige connector met PIC Basic instructies SHIN en SHOUT.


De (4-bits) DTMF decoder op de print geeft de volgende waarden bij de mogelijke toetsindrukken:

Telefoontoets:
DTMF waarde:

1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
0
10
*
11
#
12
A
13
B
14
C
15
D
0

Speciale aandacht voor toets '0', deze geeft niet de waarde 0 (dat doet toetscode 'D'), maar geeft de waarde 10.
Eventueel kun je in de DTMF subroutine plaatsen: IF TelefoonToets = 10 THEN TelefoonToets = 0 waardoor deze afwijking recht wordt gezet.

Toetsen * en # kun je voor speciale instructies gebruiken, helemaal naar eigen keus.
De # kun je bijvoorbeeld als [ENTER] toets gebruiken na ingeven van bijvoorbeeld een pincode.
En * zou bijvoorbeeld een [BACKSPACE] of [DELETE] functie kunnen krijgen om een foutief ingetoetste cijfer te wissen, maar dat hangt dus helemaal van jezelf af hoe je je eigen PIC Basic programma schrijft.
 
Een voorbeeld van een programma met aangepaste DTMF routine:

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Logische constanten
SYMBOL FALSE        = 0       ;Niet waar
SYMBOL HOOG         = 1       ;HOOG signaal
SYMBOL LAAG         = 0       ;LAAG signaal
SYMBOL TRUE         = 1       ;Waar

;Poortnamen
SYMBOL CM8870_StD   = PORTA.4 ;De StD Uitgang van de CM8870 zit op PORTA.4
SYMBOL CM8870_Q1    = PORTA.5 ;Uitgang Q1 van de CM8870 zit op PORTA.5
SYMBOL CM8870_Q4    = PORTB.0 ;Uitgang Q4 van de CM8870 zit op PORTB.0
SYMBOL LED          = PORTB.1 ;LED3
SYMBOL Relais       = PORTB.4 ;DIL reedrelais die op de print zit (voor verbinding maken) 
SYMBOL CM8870_Q2    = PORTB.6 ;Uitgang Q2 van de CM8870 zit op PORTB.6
SYMBOL CM8870_Q3    = PORTB.7 ;Uitgang Q3 van de CM8870 zit op PORTB.7

;BYTE
DIM TelefoonToets  AS BYTE    ;Bevat het toetsnummer dat op de telefoon wordt ingedrukt
;BIT
DIM Delete         AS BIT     ;Is TRUE als de '*' telefoontoets als laatste is ingedrukt
DIM Enter          AS BIT     ;Is TRUE als de '#' telefoontoets als laatste is ingedrukt

LOW Relais                    ;"Hoorn opnemen" (relais inschakelen (LAAG = relais AAN)) 

GOTO Start                    ;Spring over de subroutine


;Subroutine
;Kijken welke telefoontoets de opbeller indrukt
DTMF:
  TelefoonToets = CM8870_Q1 + (2 * CM8870_Q2) + (4 * CM8870_Q3) + (8 * CM8870_Q4)
  WHILE CM8870_StD = HOOG : WEND ;Wacht tot de opbeller de telefoontoets los laat
  DELAYMS 1                   ;Wacht nog even tot CM8870_StD goed LAAG is
  Delete = FALSE              ;Voordat de SELECT wordt binnengegaan moet Delete 0 zijn
  Enter  = FALSE              ;Voordat de SELECT wordt binnengegaan moet Enter  0 zijn

  SELECT TelefoonToets
    CASE  0 : TelefoonToets = 10   ;De 'D' toetscode krijgt nu de waarde 10 (ipv. 0)
    CASE 10 : TelefoonToets = 0    ;De '0' toets moet ook werkelijk de waarde 0 hebben
    CASE 11 : Delete        = TRUE ;De '*' toets krijgt een [DELETE] functie
    CASE 12 : Enter         = TRUE ;De '#' toets krijgt een [ENTER] functie
  END SELECT
RETURN


;Hoofdprogramma
Start:
  IF CM8870_StD = 1 THEN      ;Als er een toets op de telefoon wordt ingedrukt dan... 
    GOSUB DTMF                ;Ga kijken welke toets dat is
    IF TelefoonToets = 0 THEN LOW  LED ;Als toets 0 werd ingedrukt de rode LED UIT
    IF Enter = TRUE      THEN HIGH LED ;Als toets # werd ingedrukt de rode LED AAN
  ENDIF
GOTO Start                    ;Oneindige lus

Bovenstaande voorbeeldroutine zorgt ervoor dat als er op telefoontoets '0' wordt gedrukt, de variabele 'TelefoonToets' ook daadwerkelijk de waarde 0 krijgt.
Aangezien de waarde 0 eigenlijk van de 'D' toetscode is, moet ervoor worden gezorgd dat als er een 'D' toetscode wordt ontvangen deze niet de waarde 0 meer krijgt maar de waarde 10.
De toetscodes '0' en 'D' zijn door de SELECT CASE instructie in de DTMF subroutine dus van plaats verwisseld.


Voorbeeldprogramma

Tot slot een voorbeeld programma in PIC Basic.
Met het programma kan op afstand met een (mobiele) telefoon PORTA.0 en PORTA.1 afzonderlijk HOOG of LAAG gemaakt worden (het aantal poorten is natuurlijk uit te breiden).
LED3 is met één en dezelfde telefoontoets (toets '8') aan en uit te zetten (togglen).
Om ook gebruik te kunnen blijven maken van de huistelefoon zelf, moet deze telefoon binnen een bepaalde tijd worden opgenomen als de telefoonbel gaat.
Is de huistelefoon nog steeds niet opgenomen nadat de telefoonbel 7 keer is overgegaan, dan neemt de telefoonprint de lijn aan.
Dit is door de opbellende (mobiele) telefoon te horen door een één seconde lang durende geluidstoon, waarna het mogelijk is om de genoemde poorten AAN of UIT te zetten via de toetsen van de opbellende (mobiele) telefoon.
Nadat de telefoonprint heeft opgenomen blijft het overigens gewoon mogelijk om de telefoon alsnog aan te nemen en een gesprek te voeren.
Het aantal belsignalen dat moet overgaan voordat de print zelf opneemt is overigens in het PIC Basic programma naar wens in te stellen.
Er is in dit voorbeeldprogramma geen beveiliging aanwezig waardoor in feite iedereen die opbelt de poorten AAN of UIT kan zetten.
Beveiliging is mogelijk door bijvoorbeeld een pincode routine in het PIC Basic programma te plaatsen (zie cursus deel 9), waardoor de opbeller eerst een pincode moet intoetsen, voordat er poorten AAN of UIT gezet kunnen worden.

Het voorbeeldprogramma is helaas te groot voor de LITE versie.

;PRINT 140801-A  Universele telefoonprint
;                  PIC16F628A:                 +--v--+
;                             vrije poort A.2<>[     ]<>A.1 vrije poort
;                             vrije poort A.3<>[     ]<>A.0 vrije poort 
;                                  CM8870 StD >[     ]<>A.7 vrije poort / kristal 20MHz
;                                   CM8870 Q1 >[     ]<>A.6 vrije poort / kristal 20MHz
;                                         GND  [     ]  +5V
;                                   CM8870 Q4 >[     ]< CM8870 Q3      
;LED3 / USART RX / synch DT / vrije poort B.1<>[     ]< CM8870 Q2      
;       USART TX / synch CK / vrije poort B.2<>[     ]< Optocoupler ontvangst belsignaal
;(o.a. DTMF en HPWM) Geluid voor telefoonlijn <[     ]> Reedrelais "opnemen/ophangen"
;                                              +-----+
;www.picbasic.nl/telefoonprint.htm / Frits Kieftenbelt, Raalte, Netherlands (Frizie)

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

;Algemene constanten
SYMBOL AantalBellen = 7       ;Aantal maal dat bel moet klinken voordat aangenomen wordt
SYMBOL BelToggleTijd= 70      ;0,1sec: Binnen deze tijd moet belsignaal van niveau veranderen
SYMBOL MaxToetsTijd = 3000    ;0,1sec: Binnen deze tijd moet toets op de telefoon zijn gedruk

;Logische constanten
SYMBOL FALSE        = 0       ;Niet waar
SYMBOL HOOG         = 1       ;HOOG signaal
SYMBOL LAAG         = 0       ;LAAG signaal
SYMBOL TRUE         = 1       ;Waar

;Poortnamen
'YMBOL -            = PORTA.0 ;Vrij bruikbaar als in/uitgang
'YMBOL -            = PORTA.1 ;Vrij bruikbaar als in/uitgang
'YMBOL -            = PORTA.2 ;Vrij bruikbaar als in/uitgang
'YMBOL -            = PORTA.3 ;Vrij bruikbaar als in/uitgang
SYMBOL CM8870_StD   = PORTA.4 ;De StD Uitgang van de CM8870 zit op PORTA.4
SYMBOL CM8870_Q1    = PORTA.5 ;Uitgang Q1 van de CM8870 zit op PORTA.5
'YMBOL -            = PORTA.6 ;Vrij bruikbaar als in/uitgang (of 20MHz kristal)
'YMBOL -            = PORTA.7 ;Vrij bruikbaar als in/uitgang (of 20MHz kristal)
SYMBOL CM8870_Q4    = PORTB.0 ;Uitgang Q4 van de CM8870 zit op PORTB.0
SYMBOL LED          = PORTB.1 ;Vrij bruikbaar als in/uitgang (USART) tevens LED3
'YMBOL -            = PORTB.2 ;Vrij bruikbaar als in/uitgang (USART)
SYMBOL Geluid       = PORTB.3 ;Tonen zijn ook te versturen door de CCP/PWM module (HPWM)
SYMBOL Relais       = PORTB.4 ;DIL reedrelais die op de print zit (voor verbinding maken) 
SYMBOL BelSignaal   = PORTB.5 ;LAAG als de telefoonbel gaat (er wordt dan gebeld)
SYMBOL CM8870_Q2    = PORTB.6 ;Uitgang Q2 van de CM8870 zit op PORTB.6
SYMBOL CM8870_Q3    = PORTB.7 ;Uitgang Q3 van de CM8870 zit op PORTB.7

;Variabelen declareren
;WORD
DIM Timer          AS WORD    ;Telt tot bepaalde waarde, simulatie tijdmeting is zo mogelijk
;BYTE
DIM TelefoonToets  AS BYTE    ;Bevat het toetsnummer dat op de telefoon wordt ingedrukt
DIM Teller         AS BYTE    ;Teller van de FOR...NEXT lus
;BIT
DIM Delete         AS BIT     ;Is TRUE als de '*' telefoontoets als laatste is ingedrukt
DIM Enter          AS BIT     ;Is TRUE als de '#' telefoontoets als laatste is ingedrukt
DIM ID1            AS BIT     ;BIt Dummy 1

HPWM 1, 0, 0                  ;Reset de CCP/PWM module (Op 0% = geen geluid)

;        76543210
PORTA = %00000000             ;PORTA allen LAAG 
PORTB = %00010000             ;PORTB.4 HOOG maken zodat reedrelais blijft uitgeschakeld 
TRISA = %11111100             ;PORTA.1 en A.0 omschakelen als uitgang 
TRISB = %11100101             ;PORTB.4 uitgang (voor reedrelais) / B.3 voor geluid / B.1 LED

PORTB_PULLUPS ON              ;Deze regel altijd plaatsen bij gebruik van de beldetector! 
CLEAR                         ;Wis alle RAM geheugen

GOTO Start                    ;Spring over de subroutine


;Subroutine
;Kijken welke telefoontoets de opbeller indrukt
DTMF:
  TelefoonToets = CM8870_Q1 + (2 * CM8870_Q2) + (4 * CM8870_Q3) + (8 * CM8870_Q4)
  WHILE CM8870_StD = HOOG : WEND   ;Wacht tot de opbeller de telefoontoets los laat
  DELAYMS 1                        ;Wacht nog even tot CM8870_StD goed LAAG is
  Delete = FALSE                   ;Voordat de SELECT wordt binnengegaan moet Delete 0 zijn
  Enter  = FALSE                   ;Voordat de SELECT wordt binnengegaan moet Enter  0 zijn

  SELECT TelefoonToets
    CASE  0 : TelefoonToets = 10   ;De 'D' toetscode krijgt nu de waarde 10 (ipv. 0)
    CASE 10 : TelefoonToets = 0    ;De '0' toets moet ook werkelijk de waarde 0 hebben
    CASE 11 : Delete        = TRUE ;De '*' toets krijgt een [DELETE] functie
    CASE 12 : Enter         = TRUE ;De '#' toets krijgt een [ENTER] functie
  ENDSELECT
RETURN


;Hoofdprogramma
Start:
  Relais = HOOG                      ;GEEN verbinding met de telefoonlijn

  WHILE BelSignaal = HOOG : WEND     ;Wacht op een belsignaal (wacht tot iemand opbelt)
  DELAYMS 200
  IF BelSignaal = HOOG THEN Start    ;Blijkbaar een glitch geweest, terug naar Start dus

  FOR Teller = 0 TO AantalBellen * 2 ;Tel hoe vaak telefoon overgaat, voordat opgenomen wordt
    ID1 = BelSignaal                 ;Geef huidig niveau van belsignaal door aan dummy ID1
    FOR Timer = 1 TO BelToggleTijd   ;Meet of er nog steeds opgebeld wordt
      DELAYMS 100                    ;Meet het belsignaal om de 100mSec
      IF BelSignaal <> ID1 THEN BREAK;Belsignaal weer binnen de tijd veranderd, belt dus nog
    NEXT
    IF Timer > BelToggleTijd THEN Start ;Dan is de telefoon opgenomen OF opbeller opgehangen
  NEXT

  Relais = LAAG                  ;Maak verbinding met de telefoonlijn
  HPWM 1, 127, 1800              ;Geef een frequentie van 1800Hz door aan de CCP/PWM module
  DELAYMS 1000                   ;Geluidstoon 1 seconde aanhouden
  HPWM 1, 0, 0                   ;Reset de CCP/PWM module (Op 0% = geen geluid)

  WHILE Timer < MaxToetsTijd     ;Voer WHILE...WEND lus uit zolang de tijd niet voorbij is
    INC Timer                    ;Verhoog timer (die telt tijd vanaf laatste toetsindruk)
    DELAYMS 10                   ;Meet om de 10mSec of er een telefoontoets wordt ingedrukt
    IF CM8870_StD = HOOG THEN    ;Als er een toets op de telefoon wordt ingedrukt dan... 
      GOSUB DTMF                 ;Ga kijken welke toets dat is
      SELECT TelefoonToets       ;Neem eventueel actie afhankelijk van welke toets is gedrukt
        CASE  0 : PORTA.0 = LAAG ;Als toets '0' werd ingedrukt dan PORTA.0 UIT (LAAG)
        CASE  1 : PORTA.0 = HOOG ;Als toets '1' werd ingedrukt dan PORTA.0 AAN (HOOG)
        CASE  5 : PORTA.1 = LAAG ;Als toets '5' werd ingedrukt dan PORTA.1 UIT (LAAG)
        CASE  6 : PORTA.1 = HOOG ;Als toets '6' werd ingedrukt dan PORTA.1 AAN (HOOG)
        CASE  8 : LED     = ~LED ;Als toets '8' werd ingedrukt dan toggle PORTB.1 (= LED3)
        CASE 11 : GOTO Start     ;Toets '*' verbreekt de verbinding
      ENDSELECT
      CLEAR Timer                ;Timer begint weer vooraan te tellen omdat toets was gedrukt
    ENDIF
  WEND
GOTO Start                    ;Oneindige lus

Na het initiëren van diverse zaken springt het programma naar label Start waar het hoofdprogramma begint.
Hier blijft de PIC meteen wachten, totdat er iemand opbelt (dus tot het een belsignaal ontvangt).

Als er nu gebeld wordt, is het de bedoeling dat de telefoonprint pas verbinding maakt met de telefoonlijn nadat de telefoonbel een ingesteld aantal maal is overgegaan, zodat het altijd mogelijk blijft om ook de huistelefoon te blijven gebruiken.
Pas wanneer de telefoonbel 7 maal is overgegaan en de huistelefoon is nog steeds niet opgenomen, dán pas maakt de telefoonprint verbinding met de telefoonlijn.
Het aantal maal dat gebeld wordt, wordt geteld met behulp van een FOR...NEXT lus.
In deze FOR...NEXT lus, zit een tweede FOR...NEXT lus, die een ingesteld aantal maal meet wanneer het niveau van het belsignaal veranderd.
Als het belsignaal te lang HOOG of LAAG blijft, dan wordt de binnenste FOR...NEXT lus helemaal doorlopen, waardoor de PIC weet dat er geen belsignaal meer is, en dus óf de telefoon die parallel aan de telefoon staat is opgenomen, óf de opbellende telefoon heeft opgehangen.
De programmaregel die meteen na de binnenste FOR...NEXT lus staat, kijkt of 'Timer' groter is dan 'BelToggleTijd' en is dat het geval, dan is het belsignaal niet meer aanwezig.
Is dat het geval dan springt het terug naar label Start en wacht de telefoonprint weer tot er gebeld wordt.

Het aantal belsignalen dat door de beldetector wordt gedetecteerd voordat de PIC het reedrelais inschakelt, wordt bepaalt door programmaregel FOR Teller = 0 TO (AantalBellen * 2).

Door de eerste FOR...NEXT lus met 0 te beginnen wordt het reedrelais ingeschakeld op een moment dat er geen belsignaal is, dat komt het relaiscontact ten goede.
De *2 is nodig omdat je per belsignaal 2 maal een signaalverandering hebt (1x van HOOG naar LAAG (= bel gaat) en 1x van LAAG naar HOOG (= bel rust)).

Als er na het opnemen door de telefoonprint niet binnen een halve minuut een DTMF signaal wordt ontvangen (dus niet binnen 30 seconden een toets op de telefoon is ingedrukt), dan zal de telefoonprint zelf de verbinding verbreken.
Ook toets '*' op de telefoon laat de telefoonprint de verbinding onmiddellijk doen verbreken.

De SELECT TelefoonToets in de subroutine zorgt er onder andere voor dat variabele 'TelefoonToets' ook echt de waarde 0 krijgt als er op telefoontoets '0' wordt gedrukt.

De SELECT TelefoonToets in het hoofdprogramma regelt het volgende bij het indrukken van een telefoontoets:

toets functie
0 PORTA.0 LAAG maken  (uitzetten)
1 PORTA.0 HOOG maken (aanzetten)
5 PORTA.1 LAAG maken  (uitzetten)
6 PORTA.1 HOOG maken (aanzetten)
8 PORTB.1 togglen (en daarmee dus LED3)
* Verbreekt de telefoonverbinding

Telefoontoetsen 2, 3, 4, 7, 9 en # hebben hier geen functie, die kun je zelf toevoegen.

TRUE en FALSE zijn gewone constanten waarbij TRUE de waarde '1' heeft en FALSE de waarde '0'.
TRUE en FALSE worden vet en in de kleur teal weergegeven in de laatste paar voorbeeld- en testprogrammaatjes, zie hier hoe je dat kan instellen (ook voor je eigen sleutelwoorden).

In de toekomst zullen er meerdere PIC Basic programma's en toepassingen komen voor deze telefoonprint.



 

Download blokschema als PDF bestand
Download schema als PDF bestand
Printlayout 140801 + componentwaarden als PDF bestand 88 × 54mm >> Afdruk tips <<
Componenten opstelling 140801 als PDF bestand
Datasheet CM8870.pdf
Datasheet 4N25.pdf
Datasheet BD681.pdf
Datasheet DIL reedrelais 3570-1210.pdf
Ouderwetse kiesschijf die DTMF tonen genereert (puls naar toon omzetter)
Nummermelder (oud project)