Na tegoroczny konkurs PUK, czyli przydatne urządzenie krótkofalarskie przygotowałem prosty sterownik DTMF. Sterownik ten może być wykorzystany do sterowania wszelkimi urządzeniami do których jest utrudniony dostęp. W zamierzeniu powstał jako urządzenie do kontrolowania przemiennika, oraz komputerów obsługujących Echolink i Igate w sieci APRS. Urządzenie jest prostym rozwiązaniem opartym o sprzętowe dekodowanie DTMF-u oraz najpopularniejszy procesor ATTiny 2313. Projekt jest udostępniany na licencji GPL.
Sterownik może kontrolować maksymalnie do 6-ciu urządzeń i składa się z płytki podstawowej (3 linie) oraz płytki rozszerzeń (kolejne 3 linie). Funkcje sterowania są zabezpieczone cztero cyfrowym pinem.
Sterownik ten dzięki udostępnieniu źródeł może posłużyć jako baza do konstruowania innych urządzeń, lub do zaimplementowania w swoim rozwiązaniu części funkcjonalności.
W projekcie przewidziałem możliwość rozszerzenia funkcjonalności poprzez rozbudowę o port RS-232 i możliwość wyrzucania tam, zdekodowanych kodów DTMF, na przykład do sterowania Echolinkiem. Jeśli jest ktos chętny to zapraszam do rozbudowy i opisania tego na forum.
Wszystkie pliki źródłowe można pobrać ze strony:
sq9mdd.qrz.pl
Film prezentujący
działanie sterownika.
Poniżej źródło programu a w załącznikach rysunki płytek w SprintLayout
Kod:
'-------------------------------------------------------------------------------
' DTMF Controler DC1 v.1.2 Stable
'
'
' SQ9MDD <rlabus@luxmat.com> 2011
'
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program; if not, write to the Free Software
' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
' MA 02110-1301, USA.
'-------------------------------------------------------------------------------
' ustawienia kompilatora i konfiguracja
$regfile = "Attiny2313.dat"
$crystal = 4000000
$hwstack = 32
$swstack = 0
$framesize = 50
'-------------------------------------------------------------------------------
'konfiguracja portów, patrz schemat
Config Portb.0 = Output 'L6 Conn 3
Config Portb.1 = Output 'L5
Config Portb.2 = Output 'L4
Config Portb.3 = Output 'func led
Config Portb.4 = Input 'Q4
Config Portb.5 = Input 'Q3
Config Portb.6 = Input 'Q2
Config Portb.7 = Input 'Q1
Config Portd.0 = Output 'RS 232
Config Portd.1 = Output 'RS 232
Config Portd.2 = Input 'StD
Config Portd.3 = Input 'ResetKey
Config Portd.4 = Output 'L1
Config Portd.5 = Output 'L2
Config Portd.6 = Output 'L3
Config Porta.0 = Output 'UNUSED
Config Porta.1 = Output 'UNUSED
Portb = &B00000000
Portd = &B0001000 'ResetKey domyślnie w stanie wysokim
L1 Alias Portd.4
L2 Alias Portd.5
L3 Alias Portd.6
L4 Alias Portb.2
L5 Alias Portb.1
L6 Alias Portb.0
Q1 Alias Pinb.7
Q2 Alias Pinb.6
Q3 Alias Pinb.5
Q4 Alias Pinb.4
Funcled Alias Portb.3
Resetkey Alias Pind.3
Dim Cyfra As Integer
Dim Kod As String * 8
Dim Znak As String * 1
Dim Pin As String * 4
Dim Mypin As String * 4
Dim Savedpin As Eram String * 4
Dim Temppin As String * 4
Dim Linia As String * 1
Dim Akcja As String * 1
Dim Zmianapinu As Bit
Enable Interrupts 'odpalam przerwania
Config Int0 = Rising 'reagujemy na zbocze narastajace
Enable Int0
On Int0 Dtmfin 'jesli przyjdzie sygnal ze zdekodowano dtmf odpalamy procedure dtmfin
'-------------------------------------------------------------------------------
'inicjalizacja programu zczytuje zapisany pin
Zmianapinu = 0
Cyfra = 0
Mypin = Savedpin 'wczytuje pin z eepromu
Wait 5
'wlasciwa petla
Do
If Resetkey = 0 Then 'procedurk resetu i ustawienia domyslnego pinu
Funcled = 1
Wait 5 'po pieciu sekundach od zwarcia zworki reset sprawdzam czy nadal jest zwarta jesli tak to wykonuje akcje.
If Resetkey = 0 Then
Mypin = "2222" 'ustawiamy domyslny pin w urzadzeniu
Savedpin = "2222"
Funcled = 0
Wait 5
End If
End If
Loop
End 'koniec programu glównego
'-------------------------------------------------------------------------------
Dtmfin:
Cyfra = 0 ' reset cyfry zaczynamy od zera
Waitms 5 ' czekamy czy nadal jest kod
If Q1 = 1 Then ' zamiana binarki z 8870 na dziesietne
Cyfra = Cyfra + 1
End If
If Q2 = 1 Then
Cyfra = Cyfra + 2
End If
If Q3 = 1 Then
Cyfra = Cyfra + 4
End If
If Q4 = 1 Then
Cyfra = Cyfra + 8
End If
Znak = Lookupstr(cyfra , Kody) ' zamiana cyferek na string z liczbami
If Znak = "#" Then ' znaki specjalne resetuja bufor
Kod = ""
Znak = ""
Zmianapinu = 1
End If
If Znak = "*" Then ' znaki specjalne resetuja bufor
Kod = ""
Znak = ""
Zmianapinu = 0
End If
Kod = Kod + Znak ' tutaj sklejam stringa z poszczegolnych znakow
If Zmianapinu = 0 Then
If Len(kod) = 6 Then ' jesli string ma 6 znakow przystepujemy do analizy
Pin = Left(kod , 4) ' wycinamy PIN
Linia = Mid(kod , 5 , 1) ' wycinamy ktora linia bedziemy sterowac
Akcja = Right(kod , 1) ' wycinamy jaka akcja
Kod = ""
If Pin = Mypin Then ' jesli pin jest ok przystepujemy do dzialania
If Linia = "1" Then
If Akcja = "1" Then 'wlacz
L1 = 1
Elseif Akcja = "0" Then 'wylacz
L1 = 0
Elseif Akcja = "2" Then 'reset
L1 = 1
Wait 30
L1 = 0
End If
Elseif Linia = "2" Then
If Akcja = "1" Then
L2 = 1
Elseif Akcja = "0" Then
L2 = 0
Elseif Akcja = "2" Then
L2 = 1
Wait 30
L2 = 0
End If
Elseif Linia = "3" Then
If Akcja = "1" Then
L3 = 1
Elseif Akcja = "0" Then
L3 = 0
Elseif Akcja = "2" Then
L3 = 1
Wait 30
L3 = 0
End If
Elseif Linia = "4" Then
If Akcja = "1" Then
L4 = 1
Elseif Akcja = "0" Then
L4 = 0
Elseif Akcja = "2" Then
L4 = 1
Wait 30
L4 = 0
End If
Elseif Linia = "5" Then
If Akcja = "1" Then
L5 = 1
Elseif Akcja = "0" Then
L5 = 0
Elseif Akcja = "2" Then
L5 = 1
Wait 30
L5 = 0
End If
Elseif Linia = "6" Then
If Akcja = "1" Then
L6 = 1
Elseif Akcja = "0" Then
L6 = 0
Elseif Akcja = "2" Then
L6 = 1
Wait 30
L6 = 0
End If
Elseif Linia = "9" Then 'obsluga wszystkich linii jednoczesnie
If Akcja = "1" Then
L1 = 1
L2 = 1
L3 = 1
L4 = 1
L5 = 1
L6 = 1
Elseif Akcja = "0" Then
L1 = 0
L2 = 0
L3 = 0
L4 = 0
L5 = 0
L6 = 0
Elseif Akcja = "2" Then
L1 = 1
L2 = 1
L3 = 1
L4 = 1
L5 = 1
L6 = 1
Wait 30
L1 = 0
L2 = 0
L3 = 0
L4 = 0
L5 = 0
L6 = 0
End If
End If
End If
Gosub Komendaok
End If
Elseif Zmianapinu = 1 Then 'procedura zmiany pinu
If Len(kod) = 8 Then 'dlugosc dwoch pinow
Pin = Left(kod , 4) 'stary pin
If Pin = Mypin Then 'jesli obecny pin zgadza sie z zapamietanym
Temppin = Right(kod , 4)
Savedpin = Temppin
Mypin = Temppin
End If
End If
End If
Return
Komendaok:
Funcled = 1
Waitms 125
Funcled = 0
Waitms 50
Funcled = 1
Waitms 125
Funcled = 0
Return
Komendaerr:
Funcled = 1
Waitms 300
Funcled = 0
Return
Kody:
Data "D" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "0" , "*" , "#" , "A" , "B" , "C"
'-------------------------------------------------------------------------------