Presentation: Nummerpresentatör med USB anslutning.
Postat: 14 april 2009, 18:08:56
Tänkte det kunde vara dags att presentera mitt första projekt här på forumet. Det är visserligen ett litet projekt men jag har i alla fall ett par bilder.
Det hela är alltså en liten nummerpresentatör utan display baserad på en attiny2313. Telelinjen tas in via en linjetrafo direkt in på den analoga komparatorn på MCU:n. Den höga ringsignalspänningen tas om hand av de interna skyddsdioderna på portarna och ett par 100k motstånd.i serie med signalen.

Nummerinformationen skickas till en PC med hjälp av en FT232R USB-TTL kabel. På PC:en snurrar ett litet program i bakgrunden som skickar upp ett litet fönster i nedre högra hörnet med nummer och namn på den som ringer. Namnet hämtas från http://www.118100.se.

Jag samplar signalen med strax under 8kHz och jämför den med internt genererade signaler för de önskade frekvenserna. Jag genererar två interna signaler för varje frekvens där den ena är förskjuten med 90 grader. Eftersom jag fick lite cykler och minne över passar jag på att jämföra med ett par frekvenser som inte är med i DTMF för att minska risken för falska träffar.
MCU-koden är skriven i C med undantag för interruptrutinen som genererar referensfrekvenserna, samplar insignalen och korrelerar den mot de genererade frekvenserna. Den är skriven i assembler. Programmet på PC-sidan är skrivet i C#.
Det var lurigare än jag trodde att generera DTMF frekvenserna. För att göra det behöver jag alltså dela ner samplingsfrekvensen till en massa olika frekvenser. Vi tar den första (697 Hz) som exempel:
Samplingsfrekvensen är 8 Mhz / 1024 = 7812,5 Hz
Jag vill ha en räknare som räknar från 0 till 3 under varje period av 697 Hz signalen för att lätt kunna generera även den fasförskjutna signalen.
Helst skulle jag alltså dela ner samplingsfrekvensen med 7812,5/(4*697) = 2,802188. Det är ju inte direkt ett heltal och inte hjälper det att ändra samplingsfrekvensen så att det gör jämnt upp för då blir det någon annan frekvens som blir drabbad. Lösningen blev att dividera med något som är lätt, t.ex. 2^12. (Detta görs effektivt genom att skippa den minst signifikanta byten och sedan swappa nibbles på den höga byten samt maska fram de minst signifikanta bitarna) , Men då måste jag naturligtvis multiplicera med 2^12 / 2,802188 = 1462 först, men det görs enkelt genom att addera detta till en räknare varje gång interruptrutinen körs. Räknarna (en för varje frekvens) behöver bara var 16 bitar. Det gör inget att den rinner över eftersom resterande bitar aldrig används i alla fall.
Programmet ryms med lite marginal i de 2kB flashminne och 128 byte ram som finns tillgängligt:
Hur fungerar det då?
Jo, över förväntan faktiskt. Vid inkommande samtal har den hittills aldrig gjort fel. Vid något tillfälle kan den rapportera en falsk knapptryckning under tiden man pratar i telefon, men det är lätt att filtrera bort på PC-sidan så länge man bara är intresserad av nummerpresantation och inte använder den för att styra någon livsuppehållande utrustning med knapptelefonen. Kanske går det att justera tröskelvärdena för när en frekvens ska betraktas som närvarande lite. För tillfället gör jag så att jag summerar ”energierna” för alla frekvenserna och anser att en frekvens vars ”energi” är större än 25 % av totalen är närvarande och en frekvens med ett ”energiinnehåll” som är mindre än 12,5 % är frånvarande. För en träff ska det alltså vara två närvarande frekvenser och resten frånvarande och inga där emellan. För säkerhets skull har jag ett minimivärde för trösklarna också ifall den totala energin är mycket liten.
Schema har jag inget på digital form ännu, men om det finns intresse kan jag rita ihop ett.
Edit: Rubrik / blueint
Edit: stavning /haklu

Det hela är alltså en liten nummerpresentatör utan display baserad på en attiny2313. Telelinjen tas in via en linjetrafo direkt in på den analoga komparatorn på MCU:n. Den höga ringsignalspänningen tas om hand av de interna skyddsdioderna på portarna och ett par 100k motstånd.i serie med signalen.
Nummerinformationen skickas till en PC med hjälp av en FT232R USB-TTL kabel. På PC:en snurrar ett litet program i bakgrunden som skickar upp ett litet fönster i nedre högra hörnet med nummer och namn på den som ringer. Namnet hämtas från http://www.118100.se.
Jag samplar signalen med strax under 8kHz och jämför den med internt genererade signaler för de önskade frekvenserna. Jag genererar två interna signaler för varje frekvens där den ena är förskjuten med 90 grader. Eftersom jag fick lite cykler och minne över passar jag på att jämföra med ett par frekvenser som inte är med i DTMF för att minska risken för falska träffar.
MCU-koden är skriven i C med undantag för interruptrutinen som genererar referensfrekvenserna, samplar insignalen och korrelerar den mot de genererade frekvenserna. Den är skriven i assembler. Programmet på PC-sidan är skrivet i C#.
Det var lurigare än jag trodde att generera DTMF frekvenserna. För att göra det behöver jag alltså dela ner samplingsfrekvensen till en massa olika frekvenser. Vi tar den första (697 Hz) som exempel:
Samplingsfrekvensen är 8 Mhz / 1024 = 7812,5 Hz
Jag vill ha en räknare som räknar från 0 till 3 under varje period av 697 Hz signalen för att lätt kunna generera även den fasförskjutna signalen.
Kod: Markera allt
___ ___
___| |___|
___ ___
_| |___| |_
0|1|2|3|0|1|2|3
Programmet ryms med lite marginal i de 2kB flashminne och 128 byte ram som finns tillgängligt:
Kod: Markera allt
avr-size DTMF.out
text data bss dec hex filename
1758 0 84 1842 732 DTMF.out
Jo, över förväntan faktiskt. Vid inkommande samtal har den hittills aldrig gjort fel. Vid något tillfälle kan den rapportera en falsk knapptryckning under tiden man pratar i telefon, men det är lätt att filtrera bort på PC-sidan så länge man bara är intresserad av nummerpresantation och inte använder den för att styra någon livsuppehållande utrustning med knapptelefonen. Kanske går det att justera tröskelvärdena för när en frekvens ska betraktas som närvarande lite. För tillfället gör jag så att jag summerar ”energierna” för alla frekvenserna och anser att en frekvens vars ”energi” är större än 25 % av totalen är närvarande och en frekvens med ett ”energiinnehåll” som är mindre än 12,5 % är frånvarande. För en träff ska det alltså vara två närvarande frekvenser och resten frånvarande och inga där emellan. För säkerhets skull har jag ett minimivärde för trösklarna också ifall den totala energin är mycket liten.
Schema har jag inget på digital form ännu, men om det finns intresse kan jag rita ihop ett.
Edit: Rubrik / blueint
Edit: stavning /haklu