Úvod
Tuner ELFIN je ok1ufc dálkově
řízený tuner, který využívá profesionálního serveru Elfin EW10 k
příjmu dat z TCP klientů (3 ks, štelování L, štelování C,
přepínání konfigurace LC nebo CL). Nastavení serveru Elfin EW10
a jeho vyzkoušení jsem již
popsal zde
(včetně veškerého nastavení a manuálu).
Funkce směrovače povelů Elfin EW10
Funkce
směrovače povelů Elfin EW10 byla popsána v uvedeném článku.
Zařízení pracuje jako TCP server (režim STA) v domácí WiFi síti
na své IP adrese (moje je 192.168.1.5) a naslouchá klientům na
portu 8899. Zařízení nedělá nic jiného, než že šoupe přijaté
povely do sériového rozhraní.
|
|
|
Puštěný tuner
Puštěný tuner, který
komunikuje se serverem na adrese 192.168.1.5, port 8899 je
vidět na obrázku vedle. Tato aplikace byla napsána ve Visual
Basic 2010, funguje pod Windows 10, obdobnou aplikaci mám
napsanou i v Gambasu.
Závěr
Jak jsem dříve uvedl,
pokud nepotřebujeme u směrovače povelů místní ovládání, je
Elfin asi tím nejjednodušším a v současné době též
nejmodernějším řešením, které využívá dvou základních
principů používaných v IT. Jde o přenos povelů pomocí TCP
serveru a klientů z aplikace do směrovače Elfin, který
povely pošle na sériový port. Procesor PICAXE (nebo více
čipů) podle preambule pozná, na který port pošle sadu všech
osmi bitů.
Já toto řešení preferuji před přímým
použitím komunikace po sériovém portu z aplikace. |
 |
 |
Zkušební deska s mikropočítačem a
diodami LED (obrázek vedle textu).
Programování
čipů PICAXE
Pro router elfin programujeme
rychlosti jako N2400, N4800, atd. elfin pracuje s normální
polaritou značky, nikoliv, jako USB-TTL převodník s inverzní
polaritou
Router
Elfin se dá zkoušet též z Herkules terminálu. Do okénka
napíšeme preambuli a povel v hexadecimálním tvaru,
zaškrtneme políčko HEX, pošleme data do Elfinu a
zkontrolujeme LED diody. Např. po odeslání preambule + FF se
musí rozsvítit všech 8 LED diod a po odeslání preambule
+ 00 všechny LED zhasnou.
Programování, které souvisí s přenosem dat, s TCP komunikací
nemusí být ani v amatérských podmínkách složité. Jsme
schopni se mu naučit i ve vyšším věku. Pokud zvolíme vhodně
vývojové prostředky, potom programy opravdu kreslíme, máme
je hotové za pár minut a vyzkoušené během několika málo
hodin. Přesto musíme mít vždy na paměti, že u
komunikujících zařízení spolupracuje téměř vždy více dílčích
subsystémů. Pokud zkoušíme dílčí funkcionality, až máme jistotu, že
nám i celek bude dělat to, co má. Na dílčí vyzkoušení si
rovněž během pár minut nakreslíme vhodné programy.
Obdobně komunikaci se zařízením, například dříve, než
připojím tuner, zkouším s jednoduchými HW pomůckami, jako je
LED sondička pro 8 bitů, abych viděl najednou celý port.
Procesor PICAXE mívám v patici, abych mohl upravit
algoritmus. Ale už nedělám mnoho změn a vycházím vždy z původního algoritmu. |
|
|
Listing programu Visual Basic |

 |
Tunel Elfin ve finálním designu
Ve finálním designu jsem Elfin tuner realizova úpravou SW
již dříve popsaného programu. Vzhled je tedy stejný, jako u
programu, který komunikuje s Linuxovým serverem-povelovým
směrovačem. Na obrázku jsou všechna okna programu otevřena: |
 |
Listing hlavního modulu programu:
Imports System.Net.Sockets
Module Module1
Public inductance(0 To 40) As Integer
Public capacity(0
To 40) As Integer
Public konfigurace(0 To 40) As Integer
' rozhoduje o typu konfigurace LC nebo CL
Public relay As Byte
' má hodnotu 0, relé v poloze 1 nebo hodnotu 7, relé v
poloze 2
Public povel(0 To 4) As Byte
Public banka As Integer
' paměťová banka
Public povel1 As Byte() ' povel
převedený na bajty
Public povel2 As Byte()
Public
port As Integer = 8899
Public server As String =
"192.168.1.5" ' IP adresa ve formátu 192.168.1.225
Public komunikace As Integer = 255
Public Sub
dosouboru() ' zapíše do souboru L, C, konfigurace
Dim
soubor As New IO.StreamWriter("remote_tuner.dat")
For i
As Integer = 1 To 40
soubor.WriteLine(inductance(i))
soubor.WriteLine(capacity(i))
soubor.WriteLine(konfigurace(i))
Next i
soubor.Close()
End Sub
Public Sub
TCP_makej() ' odešle na server povel 1 a povel2
If
komunikace = 255 Then
Dim client
As New TcpClient(server, port) ' otevře client
Dim stream As NetworkStream =
client.GetStream ' napojí stream
stream.Write(povel, 1, 2) ' pustí
povel() do streamu, jako bajty, číslo 1 žnamená, že začíná
indexem 1, číslice 2 znamená, že se pošlou dva bajty,
preambule a povel
client.Close() ' zavře client
End If
End Sub
End Module
Proceduru komunikace TCP klienta
jsem zvýraznil žlutou barvou. Možná je
ještě zajímavá procedura, která v okně Form1 čte hodnoty
uložené v paměti:
Private Sub LC() 'nacpe indukcnost a kapacita do
progressbarů a labelů
ProgressBar1.Value = indukcnost '
hodnota L se zobrazí graficky
ProgressBar2.Value = kapacita
' hodnota C se zobrazí graficky
Label5.Text = indukcnost
' hodnota L se zobrazí jako číslo
Label6.Text = kapacita
' hodnota C se zobrazí jako číslo
If konfig = 1 Then
' hodnota konfiguračního relé se zobrazí dle instrukcí níže
Label8.Text = "LC"
Label8.BackColor = Color.Red
relay = 7
End If
If konfig
= 0 Then
Label8.Text = "CL"
Label8.BackColor = Color.Blue
relay = 0
End If
povel(1) =
118
' hodnota preambule pro L
povel(2) = ProgressBar1.Value
' hodnota indukčnosti, vyčtená z progressbaru
TCP_makej()
' volání proceduryTCP komunikace do naslouchacího serveru
povel(1) =
119
' hodnota preambule pro C
povel(2) = ProgressBar2.Value
' hodnota kapacity, vyčtená z progressbaru
TCP_makej()
' volání procedury TCP komunikace do naslouchacího serveru
povel(1) = 121
' hodnota preambule pro relé konfigurace
povel(2) = relay
' hodnota konfigurace relé
TCP_makej()
' volání procedur TCP komunikace do naslouchacího serveru
End Sub
V programu
není nic, co by nebylo v předchozích článcích (lze je
považovat za lekce vidláckého programování) vysvětleno a
popsáno. Všechno napsáno ve Visual Basic 2010 Express, který
je zadarmo. Jsou použité zapouzdřené objekty, a to jak
vizuální, tak nevizuální (např. TCP Client). Jsou použity
procedury, jejich volání. Je použit tzv. modul s kódem i
třídy oken. Je použito imperativní programování, tedy psaní
příkazů.
Program komunikuje se serverem Elfin EW 10,
který přijímá povely a posílá je do sériového portu. Na
sériovém portu visí zařízení s jednoduchým programem, s
procesorem PICAXE, který nedělá nic jiného, než, že dekóduje
preambuli a podle její hodnoty pošle bajt s daty na
příslušný port. Port sepne relátka podle jednotlivých bitů.
|
Tuner spuštěný v Linuxu ve WINE
Kompatibilita programu v Linuxu (s Wine 1.6) není
stoprocentní. Proto mám námět na domácí úkol - napsat
program v Gambasu. Vzhled programu (Linux Mint 18.3, Wine)
je na obrázku vedle.
Co nefunguje:
1. Ukládání nastavení (dat) do souboru. Soubor zůstane
bez dat a program při pokusu o uložení zhavaruje.
Co funguje: 1. Čtení z pamětí, pokud
uložíme data do souboru jinak, než programem. 2. Ladění
tuneru ze sliderů, samozřejmě tedy i TCP Socket, TCP
komunikace s Elfinem.
Ve vyšší verzi wine jsem neměl
možnost vyzkoušet.
Napsat program v Gambasu bude
jednoduché, potřebné zapouzdřené objekty existují, syntaxe
příkazů je vyzkoušená.
|
 |
|
|
|
Aplikace pro Linux
Napsal jsem ji v
Gambasu. Provedení je vpravo. Zatím nemám napsanou verzi s
ukládáním nastavení do paměti. Jde o jednoduchý program,
jehož komentovaný listing je níže. Výhodou programu je, že
ho lze spustit na architekturách Intel (PC desktop) i na
architekturách ARM (zkoušel jsem na SBC Asus Tinker Board).
Listing uvádím rovněž pro porovnání syntaxe. Pozorný
čtenář si všimne, že v programu se bezprostředně za sebou
posílá jeden bajt preambule a jeden bajt dat. Tedy nikoliv
pole bajtů, jako ve Visual Basicu, z pole se vybírají a
posílají rovněž dva bajty. Kód pro TCP Socket jsem
použil z ukázek (Daniel Campos Fernández) a nepatrně ho
modifikoval. Využívá knihoven gb.net
Směrovač Elfin
přijme bajty a nasměruje je do UART (do sériového portu). |
 |
|
|
|
Listing programu v Gambasu
' Gambas
class file
'*****************************************************************
' ELFIN TCP Antenna Tuner ok1ufc
' TCP Socket (C) 2003-2004 Daniel
Campos Fernández
'
(danielcampos(at)netcourrier.com)
'*****************************************************************
Private CurProtocol As Integer
Private L As Integer
Private C As Integer
Public Sub Form_Open()
CurProtocol = 0
Label2.Visible = True
txtPort.Visible = True
Label1.Text = "Host :"
End
Public Sub
MySocket_Ready()
'************************************************
' When connection proccess has
finished
' successfully, "Connected" event
will raise
'************************************************
timTimeout.Enabled = False
If CurProtocol = 1 Then
lblMessage.Text = ("Connected to
path ") & MySocket.Path
Else
lblMessage.Text = ("Connected to
remote host ") & MySocket.Path
lblMessage.Text = lblMessage.Text
& (" - Using local address : ") & MySocket.LocalHost & ":" &
MySocket.LocalPort
End If
Me.Enabled = True
Set_Interface(True)
End
Public Sub
MySocket_Closed()
'********************************************
' this event will raise when
foreing host
' closes the socket by any reason
'********************************************
lblMessage.Caption = ("Connection Closed by foreign host.")
Me.Enabled = True
Set_Interface(False)
End
Public Sub
MySocket_Found()
'********************************************
' this event will raise when
foreing host
' name has been translated to IP
'********************************************
lblMessage.Caption = ("Host Found. Connecting...")
End
Public Sub
MySocket_Read()
'**********************************************
' When some data arrives from the
remote
' part of the socket,
"DataAvailable" event
' is raised
'**********************************************
Dim S As
String
If
MySocket.Status = Net.Connected Then
Read #MySocket, S, Lof(MySocket)
End If
End
Public Sub
MySocket_Error()
'**********************************
' this is the function to
' handle Errors when trying
' to read or write to the socket
'**********************************
Select
Case MySocket.Status
Case Net.CannotCreateSocket
lblMessage.Text = ("The system
does not allow to create a socket")
Case Net.HostNotFound
lblMessage.Text = ("Host not
Found")
Case Net.ConnectionRefused
lblMessage.Text = ("Unable to
Connect. Connection Refused")
Case Net.CannotRead
lblMessage.Text = ("Error Reading
Data")
Case Net.CannotWrite
lblMessage.Text = ("Error Writing
Data")
End Select
Set_Interface(False)
End
Private
Sub Set_Interface(bState As Boolean)
'****************************************
' An auxiliar method to
enable/disable
' controls in the formulary , when
' connection is stablished or
closed
'****************************************
btnConnect.Enabled = Not bState
txtHost.Enabled = Not bState
txtPort.Enabled = Not bState
timTimeout.Enabled = bState
End
Public Sub
btnConnect_Click()
'******************************************
' To connect to remote host we
call to
' connectsocket method, passing
Host Name
' and port as arguments
'******************************************
Dim RetVal As Integer
btnConnect.Enabled = False
Select Case CurProtocol
Case 0
'
Stablishing a TCP connection.
' Here we use Host and
' Port properties, we could also
' do directly
MySock.Connect(TextBox1.Text,VAL(TextBox2.Text))
MySocket.Host = txtHost.Text
MySocket.Port = Val(txtPort.Text)
MySocket.Connect()
Case 1
' Stablishing a Local connection.
' Here we use Path and
' Port properties, we could also
' do directly
MySock.Connect(TextBox1.Text,0)
MySocket.Path = txtHost.Text
MySocket.Port = Net.Local
MySocket.Connect()
End Select
If MySocket.Status > Net.Inactive
Then
If CurProtocol = 0 Then
'**************************
' TCP : connection in progress...
'**************************
lblMessage.Text = ("Looking up
host name...")
timTimeout.Delay = 10000 ' we'll
wait a maximun time of 10 seconds
timTimeout.Enabled = True
End If
End If
End
Public Sub
timTimeout_Timer()
'***************************
' timeout trying to connect
'***************************
Me.Enabled = True
timTimeout.Enabled = False
If MySocket.Status <>
Net.Connected Then
Close MySocket
Set_Interface(False)
lblMessage.Text = ("Timeout trying
to stablish connection")
End If
End
Public Sub Form_Close()
'**********************************************
' Close possible Stablished
connections
'**********************************************
If MySocket.Status > 0 Then Close
#MySocket
End
***********************************************************************
' Ovládací prvky tuneru - volání
procedur tlačítek konfigurace
***********************************************************************
Public Sub
Button1_Click()
Zap1()
End
Public Sub
Button2_Click()
Vyp1()
End
Public Sub Zap1()
'procedura posílá bajt, kterým se spíná relé konfigurace
If
MySocket.Status = Net.Connected Then
Write
#MySocket, 121 As Byte 'byte preambule relé
Write #MySocket, 007 As Byte 'byte
dat na přepnutí relé (hodnoty 000 a 007)
End If
End
Public Sub
Vyp1()
If
MySocket.Status = Net.Connected Then
Write
#MySocket, 121 As Byte 'byte preambule relé
Write #MySocket, 000 As Byte 'byte
dat přepnutí relé, bajt má jen hodnotu 000 nebo 007
End If
End
********************************************************************
' Ovládací prvky tuneru - odeslání
dat ze sliderů L a C
********************************************************************
Public Sub Slider1_MouseUp()
L =
Slider1.Value
Label6.text = L
If MySocket.Status = Net.Connected
Then
Write #MySocket, 118 As Byte 'byte
preambule L
Write #MySocket, L As Byte 'byte
data L (hodnoty 000 až 255) End If
End
Public Sub
Slider2_MouseUp()
C =
Slider2.Value
Label4.text = C
If MySocket.Status = Net.Connected
Then
Write #MySocket, 119 As Byte 'byte
preambule C
Write #MySocket, C As Byte 'byte
data C (hodnoty 000 až 255)
End If
End
|
Tuner s Elfin routerem na procesoru ARM
Program jsem vyzkoušel na jednodeskovém SBC Asus Tinker
Board. Asi neexistuje důvod, aby neběžel např. na Raspberry
Pi. Program jsem měl napsaný v Gambas 3 pod Linux Mint 19.2.
Když jsem ho přenesl na ARM zařízení, šel program spustit,
ale tuner netuneroval :-) resp. nešly do tuneru žádné
povely. Všiml jsem si, že se po pohybu sliderů ani nemění v
labelech hodnoty. Usoudil jsem, že ve verzi Gambas 3, kterou
mám na Asusu (je přeci jenom starší) pravděpodobně nejdou
události "mouse_up". Protože události "change", které
reagují na změnu mi dříve šly, vymazal jsem instrukce na
posílání bajtů z procedur sliderů. Vytvořil jsem ještě jeden
časovač (perioda asi 300 ms) a dal jsem ty instrukce do
časovače. Takže nejsou odesílané s každou jemnou změnou
slideru, ale s pravidelnou periodou. To port stíhá a funguje
to. Ale abych o tom nepsal tisíc slov,
zazipovaný program lze stáhnout zde. A vzhledove vypadá
takto. Vzhledem se liší hlavně slidery. Jsou jednodušší: |
 |
Závěry
1. Komunikace s použitím TCP
Socketu, směrováním povelů do UARTu a s přenosem málo
objemných dat (několik bajtů) je svižná a funguje
spolehlivě. 2. Použití TCP Socketu a serveru ELFIN pro
komunikaci s konkrétním zařízením (ham, měření) považuji za levné,
jednoduché, odolné a komfortní řešení. Rychle u mě nahradilo
různé USB převodníky a Bluetooth adaptéry. A to nejenom v
hamovně, ale i u všech měřicích zařízení. 3. V moderních
vývojových prostředcích se rychle naučíme snadno psát
(kreslit) své vlastní programy, kterými budeme ovládat
zařízení od TRXu, přes anténní tunery, přepínače, rotátory,
až po elektronické měřicí přístroje s různými čidly.
4. Amatérskými prostředky (jsou opravdu vidlácké?)
rychle program napíšeme pro Windows 10 (než nám Microsoft
ukončí radost a svobodu a bude nám nabízet jen sexuální
provedení programů prošlé cenzůrou MS Store), pro Linux i
pro Debian běžící na ARM SBC hračkách. |
|
|
|
|