Forum » Programiranje » [VB] Komunikacija s serijskimi napravami
[VB] Komunikacija s serijskimi napravami
mNeRo ::
pozdravljeni! Imam nalogo za naredit program v VB, ki bo komuniciral z zunanjo napravo. (ta bo na racunalnik prikljucena preko RS232). Rad bi dobil kaksne napotke kako se tega lotiti...v kaksno knjigo kaj pogledati...kakšen nasvet nasploh! LP
- spremenilo: CCfly ()
Tutankhamun ::
simpl, mau poglej v help za tem
System.IO.Ports.SerialPort
System.IO.Ports.SerialPort
AMD Phenom QUAD 9950 Black Edition, 8GB
wishmaster ::
En primercek ti dam
MSComm1.CommPort = 1
MSComm1.Settings = "4800,N,8,1"
MSComm1.InputLen = 0
Odpres pa port z pomocjo:
MSComm1.PortOpen = True
Zapres pa z:
MSComm1.PortOpen = False
MSComm1.CommPort = 1
MSComm1.Settings = "4800,N,8,1"
MSComm1.InputLen = 0
Odpres pa port z pomocjo:
MSComm1.PortOpen = True
Zapres pa z:
MSComm1.PortOpen = False
GIGABYTE GA-K8NXP-SLI,AMD ATHLON 64 X2 4200+,4x1024 RAM (GEIL)
5xWD2000JS(200 GB),Gigabyte Radeon 3870 ...
5xWD2000JS(200 GB),Gigabyte Radeon 3870 ...
Zgodovina sprememb…
- spremenil: wishmaster ()
mNeRo ::
se nekaj vprasanj: kako bi mi VB "sam" izbral ravno tisti port, kjer mam jst prikljucek RS232? ima kdo ksno idejo? zazeljen tudi primer s kodo...
zanima me tudi:
With mySerialPort
.Open()
.write(" bla bla bla")
End With
s kaksnimi ukazi nato sprejemam odziv-podatke te naprave? tega nisem nikjer zasledil...
oprostite za butasta vprasanja. LP
zanima me tudi:
With mySerialPort
.Open()
.write(" bla bla bla")
End With
s kaksnimi ukazi nato sprejemam odziv-podatke te naprave? tega nisem nikjer zasledil...
oprostite za butasta vprasanja. LP
darkolord ::
OK,
pri serijskem portu ne moreš vedet, na katerega je tvoja naprava priključena. Lahko samo na vsakega pošlješ ukaz in čakaš na odziv tvoje naprave.
S funkcijo SerialPort.GetPortNames() pa dobiš spisek serijskih portov, ki so prisotni na sistemu.
Za sprejemanje uporabiš dogodek DataReceived:
pri serijskem portu ne moreš vedet, na katerega je tvoja naprava priključena. Lahko samo na vsakega pošlješ ukaz in čakaš na odziv tvoje naprave.
S funkcijo SerialPort.GetPortNames() pa dobiš spisek serijskih portov, ki so prisotni na sistemu.
Za sprejemanje uporabiš dogodek DataReceived:
Public Sub mySerialPort_DataReceived(ByVal sender as Object, ByVal e as SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived ' MsgBox mySerialPort.ReadExisting End Sub
Zgodovina sprememb…
- spremenilo: darkolord ()
mNeRo ::
zopet tezava...
prej al selj sv vedu da bom naletew tudi na ta problem: kako izbran element iz comboboxa in ga nato vkljucim nekam drugam? u mojem primeru izberem enega imed izpisanih COM-portov in tega uporabljam.... glejte odspodaj-kjer so vprasaji!
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.AddRange(IO.Ports.SerialPort.GetPortNames()) ==> mi izpise porte in si enga iberem iz delujocega programa
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim mySerialPort As IO.Ports.SerialPort = New IO.Ports.SerialPort(??????????????tle morem sedaj nekako dodat moj izbran COM port, 56000, IO.Ports.Parity.None, 8,IO.Ports.StopBits.One)
With mySerialPort
.Close()
End With
If mySerialPort.IsOpen Then
Label1.Text = ("Port still Opened")
Else
Label1.Text = ("Port closed")
End If
End Sub
prej al selj sv vedu da bom naletew tudi na ta problem: kako izbran element iz comboboxa in ga nato vkljucim nekam drugam? u mojem primeru izberem enega imed izpisanih COM-portov in tega uporabljam.... glejte odspodaj-kjer so vprasaji!
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.AddRange(IO.Ports.SerialPort.GetPortNames()) ==> mi izpise porte in si enga iberem iz delujocega programa
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim mySerialPort As IO.Ports.SerialPort = New IO.Ports.SerialPort(??????????????tle morem sedaj nekako dodat moj izbran COM port, 56000, IO.Ports.Parity.None, 8,IO.Ports.StopBits.One)
With mySerialPort
.Close()
End With
If mySerialPort.IsOpen Then
Label1.Text = ("Port still Opened")
Else
Label1.Text = ("Port closed")
End If
End Sub
mNeRo ::
komunikacija z mojim GSM umesnikom ( Siemens TC35 ), sevedno ne stece.
Koda:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
With mySerialPort
.Open()
.Write("AT" + vbCr) => posiljam AT ukaze+ ukaz za odziv
End With
If mySerialPort.IsOpen = True Then
Label1.Text = ("Port odprt")
Else
Label1.Text = ("Port zaprt")
End If
End Sub
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
Label2.Text = (mySerialPort.ReadExisting)
End Sub
v VB posiljam ukaze na ta GSM umesnik vendar se mi ta sevedno ne odziva. port imam pravilno nastavljen ( BaudRate...) in tudi koda mislim da je uredu, sai mi ukaz AT poslje ( preverjeno z programom "serial monitor" ) a ne dobim odziva.
a ima kdo se kaksno idejo, kai bi lahko bilo narobe ali kai se manjka? bilo kaksen nasvet je dobrodosel
LP vsem
Koda:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
With mySerialPort
.Open()
.Write("AT" + vbCr) => posiljam AT ukaze+ ukaz za odziv
End With
If mySerialPort.IsOpen = True Then
Label1.Text = ("Port odprt")
Else
Label1.Text = ("Port zaprt")
End If
End Sub
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
Label2.Text = (mySerialPort.ReadExisting)
End Sub
v VB posiljam ukaze na ta GSM umesnik vendar se mi ta sevedno ne odziva. port imam pravilno nastavljen ( BaudRate...) in tudi koda mislim da je uredu, sai mi ukaz AT poslje ( preverjeno z programom "serial monitor" ) a ne dobim odziva.
a ima kdo se kaksno idejo, kai bi lahko bilo narobe ali kai se manjka? bilo kaksen nasvet je dobrodosel
LP vsem
mNeRo ::
se eno vpr..
MsgBox(mySerialPort.ReadExisting)
tale ukaz mi sicer lepo izpise kai dobivam nazaj,ampak ko bi pa sprejemanje rad preselil v Labelo ( ali textbox ), se pojavi napaka. Vem da sprejemam bite in da bi mogu moj sprejem spremenit zopet u string a mi to s tem ukazom ne uspe:
Label2.Text = CStr(mySerialPort.ReadExisting)
kasen nasvet? zopet..zopet.....
MsgBox(mySerialPort.ReadExisting)
tale ukaz mi sicer lepo izpise kai dobivam nazaj,ampak ko bi pa sprejemanje rad preselil v Labelo ( ali textbox ), se pojavi napaka. Vem da sprejemam bite in da bi mogu moj sprejem spremenit zopet u string a mi to s tem ukazom ne uspe:
Label2.Text = CStr(mySerialPort.ReadExisting)
kasen nasvet? zopet..zopet.....
darkolord ::
A imaš obe vrstici (msgbox in label=...) ali ti ne deluje ko imaš tudi samo eno od teh dveh?
mNeRo ::
ko imam msgbox ..stvar deuje. a jst bi zelew da mi podatke izpisuje v labeli ali textboxu...to mi ne vspe ker nevem kako kodo morem napisat, da bo delalo. najbrz je treba convertirat u string...
darkolord ::
Če imaš obe vrstici eno za drugo, ne bo delalo:
MsgBox(mySerialPort.ReadExisting)
Label2.Text = mySerialPort.ReadExisting
Če imaš pa samo drugo, mora delat. ReadExisting vrne string, tako da ni treba ničesar pretvarjati
MsgBox(mySerialPort.ReadExisting)
Label2.Text = mySerialPort.ReadExisting
Če imaš pa samo drugo, mora delat. ReadExisting vrne string, tako da ni treba ničesar pretvarjati
mNeRo ::
no ko zazenem program mi javi tole napako:
Cross-thread operation not valid: Control 'Label2' accessed from a thread other than the thread it was created on.
kai naj bi tole pomenlo???
Cross-thread operation not valid: Control 'Label2' accessed from a thread other than the thread it was created on.
kai naj bi tole pomenlo???
mNeRo ::
pa se eno vpr: dobro bi blo da bi posiljaw in sprejem v nekih dolocenih intervalih. tu bi lahko uporabil timer... a bi vedel kako se glasi koda za povavljanje nekega dogotka.
primer:
ce kliknem na timer u VB, si me ze opre koda:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Label2.Text = mySerialPort.ReadExisting .....to bi ponavljal ( a rabim zopet private sub...)
end sub
samo je tu problem ker morem za branje iz porta zopet klicat private sub.... in private sub v private sub ne gre
iscem in iscem...ne najdem. kaksna ideja?
primer:
ce kliknem na timer u VB, si me ze opre koda:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Label2.Text = mySerialPort.ReadExisting .....to bi ponavljal ( a rabim zopet private sub...)
end sub
samo je tu problem ker morem za branje iz porta zopet klicat private sub.... in private sub v private sub ne gre
iscem in iscem...ne najdem. kaksna ideja?
darkolord ::
Spremeniš private v public.
Tista zgornja napaka pa pomeni, da poskušaš dostopati do labele iz druge niti, kjer je bila ustvarjena, kar za biti "nevarno"... To rešiš tako, da uporabiš metodo Me.Invoke in z njo pokličeš metodo v istem threadu kot je UI, tam pa lahko vsebino labele updejtaš
Tista zgornja napaka pa pomeni, da poskušaš dostopati do labele iz druge niti, kjer je bila ustvarjena, kar za biti "nevarno"... To rešiš tako, da uporabiš metodo Me.Invoke in z njo pokličeš metodo v istem threadu kot je UI, tam pa lahko vsebino labele updejtaš
mNeRo ::
se opravicujem... bi se dalo bol tocno napisat?
Label2.Text = mySerialPort.ReadExisting .... kje kai dodam?
im still a noob in VB
Label2.Text = mySerialPort.ReadExisting .... kje kai dodam?
im still a noob in VB
darkolord ::
Približno tako
Delegate Sub UpdateLabelHandler(ByVal sText As String) Public Sub UpdateLabel(ByVal sText As String) Label2.Text = sText End Sub Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {strMessage}) End Sub
mNeRo ::
se vedno ne dela.... labela ostane prazna,najbrz zato ker se modem niti ne odzove.
Dim strmessage As String
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
With mySerialPort
.PortName = ComboBox1.SelectedItem
.Open()
.Write("AT" + vbCr)
System.Threading.Thread.Sleep(200)
End With
end sub
Delegate Sub UpdateLabelHandler(ByVal sText As String)
Public Sub UpdateLabel(ByVal sText As String)
Label2.Text = sText
End Sub
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived
Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {strmessage})
End Sub
z spodnjo kodo se mi modem lepo odzove, a pride pa do napake ki sm jo ze prej navedu...
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived
TextBox1.Text = mySerialPort.ReadExisting
end Sub
Dim strmessage As String
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
With mySerialPort
.PortName = ComboBox1.SelectedItem
.Open()
.Write("AT" + vbCr)
System.Threading.Thread.Sleep(200)
End With
end sub
Delegate Sub UpdateLabelHandler(ByVal sText As String)
Public Sub UpdateLabel(ByVal sText As String)
Label2.Text = sText
End Sub
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived
Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {strmessage})
End Sub
z spodnjo kodo se mi modem lepo odzove, a pride pa do napake ki sm jo ze prej navedu...
Private Sub mySerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mySerialPort.DataReceived
TextBox1.Text = mySerialPort.ReadExisting
end Sub
darkolord ::
pardon,
tole vrstico
Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {strmessage})
zamenjaj v
Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {mySerialPort.ReadExisting})
tole vrstico
Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {strmessage})
zamenjaj v
Me.Invoke(New UpdateLabelHandler(AddressOf UpdateLabel), New Object() {mySerialPort.ReadExisting})
mNeRo ::
jeeesss!! dela! zakon! hvala hvala!
imas se mogoce idejo, kako bi se sedaj ta srting obdelalo? vsak byte u temu stringu mi predstawlja en znak...jst ne rabim vseh...rabim recimo samo 6 in 7 byte. ker ene bi rad daju v labele, druge u textboxe...itd.
imas se mogoce idejo, kako bi se sedaj ta srting obdelalo? vsak byte u temu stringu mi predstawlja en znak...jst ne rabim vseh...rabim recimo samo 6 in 7 byte. ker ene bi rad daju v labele, druge u textboxe...itd.
mNeRo ::
uporabil sem ukaz: sText.Substring(0, 4) in dela!
nova tezava
'primerjam:
If sText = "OK" Then
Label1.Text = ("Port odprt, modem povezan")
Else
Label1.Text = ("Port zaprt, modem ni povezan")
End If
a se to sploh tako primerja? sicer jaz dobivam nazaj ATOK ampak tudi ce dam sText = "ATOK", se mi labela ne spremeni, oz pokaze port zaprt...
mogoce se kaksna ideja kako bi primerjal ta moj sText in na podlagi primerjave potem obdeloval podatke. jaz sem mislil delat if stavke enega pod drugim a se mi ne zdi lepo...
za ciscenje bufferjev uporabljam:
.DiscardOutBuffer()
.DiscardInBuffer()
...vsakic predem kaj posljem
nova tezava
'primerjam:
If sText = "OK" Then
Label1.Text = ("Port odprt, modem povezan")
Else
Label1.Text = ("Port zaprt, modem ni povezan")
End If
a se to sploh tako primerja? sicer jaz dobivam nazaj ATOK ampak tudi ce dam sText = "ATOK", se mi labela ne spremeni, oz pokaze port zaprt...
mogoce se kaksna ideja kako bi primerjal ta moj sText in na podlagi primerjave potem obdeloval podatke. jaz sem mislil delat if stavke enega pod drugim a se mi ne zdi lepo...
za ciscenje bufferjev uporabljam:
.DiscardOutBuffer()
.DiscardInBuffer()
...vsakic predem kaj posljem
mNeRo ::
tole dela super:
If InStr(sText, "OK") Then
..vendar se mi sText ne odziva vedno enako na moj poslani ukaz, zato je zgornji del kode neuporaben ko dobim samo "K" ali "O"....
kaj naj naredim da bom imel vedno enak odziv-tisti ki mi ga posilja modem? a morem pri posiljanju kaj ocistit...kaksen buffer...ali naj delam to po sprejemu?
zopet se obracam na potrpezljive, dobre ljudi
If InStr(sText, "OK") Then
..vendar se mi sText ne odziva vedno enako na moj poslani ukaz, zato je zgornji del kode neuporaben ko dobim samo "K" ali "O"....
kaj naj naredim da bom imel vedno enak odziv-tisti ki mi ga posilja modem? a morem pri posiljanju kaj ocistit...kaksen buffer...ali naj delam to po sprejemu?
zopet se obracam na potrpezljive, dobre ljudi
mNeRo ::
ojej...sevedno nc
sm daw RtsEnable na true in Handshake na requesttosend ( na myserialport-u nastavitvah )...ampak sevedno ne dela. najbrz sta input in output bufferja za postimat a s temi ukazi mi ni ratalo... still searching...
sm daw RtsEnable na true in Handshake na requesttosend ( na myserialport-u nastavitvah )...ampak sevedno ne dela. najbrz sta input in output bufferja za postimat a s temi ukazi mi ni ratalo... still searching...
darkolord ::
RTS in handshake tle nima veze... Bufferjev ti pa drugače ni treba čistit... Poskusi z ukazom ReadLine, v bistvu mi ni točno jasno, zakaj uporabljaš ReadExisting?
mNeRo ::
uporabljam ukaz ReadLine ze nekai casa...a ni dosti boljse. sevedno mi vcasih NE vrne vse kar rabim,vcasih pa samo del...in drugi del nevem kje se izgubi, vcasih mi drugi del vrne kasneje in mi zje** vse if stawke.. . jst bi pa seveda rabu vedno vse, ker drugace nemorem obdelovat podatkov.
Zgodovina sprememb…
- spremenil: mNeRo ()
darkolord ::
Prebere ti ne zaradi tega, ker pač ne prebere, ampak ker modem do takrat ne pošlje... Če ne gre drugače, shranjuj podatke v en string in jih potem sprocesiraj... z ReceivedBytesThreshold nastavljaš, koliko bajtov je pri sprejemu potrebnih, da se sproži dogodek DataReceived
mNeRo ::
tesko je nastavljat ReceivedBytesThreshold, saj se ne ve kaksen bo odgovor (koliko bytov bo vseboval)
pa se eno vpr.:
rad bi poslal CTRL+Z... kako to posljem?
With mySerialPort
.Write("AT+CMGS=" & Chr(34) & (TextBox1.Text) & Chr(34) + vbCrLf) 'najprej posljem stevilko
'nato pa se text in na koncu texta morem stisniti CTRL+Z
'tisti controlC nevem kako se napise da velja kot ukaz
.Write((RichTextBox1.Text) & (Keys.ControlKey) & "z" + vbCr) 'tole ne dela
End With
pa se eno vpr.:
rad bi poslal CTRL+Z... kako to posljem?
With mySerialPort
.Write("AT+CMGS=" & Chr(34) & (TextBox1.Text) & Chr(34) + vbCrLf) 'najprej posljem stevilko
'nato pa se text in na koncu texta morem stisniti CTRL+Z
'tisti controlC nevem kako se napise da velja kot ukaz
.Write((RichTextBox1.Text) & (Keys.ControlKey) & "z" + vbCr) 'tole ne dela
End With
darkolord ::
tesko je nastavljat ReceivedBytesThreshold, saj se ne ve kaksen bo odgovor (koliko bytov bo vseboval)
veš, da bo vsaj en... če imaš nastavljeno na 8 in pride 7 bajtov, se ne bo zgodilo nič
rad bi poslal CTRL+Z... kako to posljem?
poglej s kakim com port monitorjem, kaj ta shortuct pošlje... če hočeš poslat control, je tko kot da bi rad poslal levi miškin klik na com port
veš, da bo vsaj en... če imaš nastavljeno na 8 in pride 7 bajtov, se ne bo zgodilo nič
rad bi poslal CTRL+Z... kako to posljem?
poglej s kakim com port monitorjem, kaj ta shortuct pošlje... če hočeš poslat control, je tko kot da bi rad poslal levi miškin klik na com port
mNeRo ::
hmmm modem se mi vedno lepo odziva na moje ukaze...vendar mi moj ListBox ( oz. kjer cem gledat odziv v VB ) tega ne pravilno pokaze. recimo: posljem ukaz AT in dobim nazaj ATOK, alpa OKAT... pravilno bi bilo AT OK. tudi ko preverjam jakost signala s casovikom in ga nato ustavim ter posljem kaksen drug ukaz, mi ListBox sevedno nekaj casa prejema odziv za jakost signala ceprow nebi smelo. modem pa mi daje pravilno...vedno pravilno.
ReceivedBytesThreshold imam na 1, in invoke sem spremenil na begininvoke, a sevedno mi Listbox ne dela pravilno.
ReceivedBytesThreshold imam na 1, in invoke sem spremenil na begininvoke, a sevedno mi Listbox ne dela pravilno.
mNeRo ::
no in koncno tudi resitev problema! ker readline() bere do prvega CR, mi prebere pac do tam, vhodni buffer ma lahko vsebuje vec stringov z vec CR-ji ki so posledica istega ukaza...zato nisem dobival popolnih odgovorov-ker nism bral celega bufferja. to se resi z zanko:
While mySerialPort.ReadBufferSize
Me.Invoke(New UpdateListBoxHandler(AddressOf UpdatelistBox), New Object() {mySerialPort.ReadLine})
End While
While mySerialPort.ReadBufferSize
Me.Invoke(New UpdateListBoxHandler(AddressOf UpdatelistBox), New Object() {mySerialPort.ReadLine})
End While
mNeRo ::
mogoce se nekaj z me.ivoke....
ali je treba obvezno dat tudi: end invoke??? in ce je to treba...kam in kako se to da?
LP
ali je treba obvezno dat tudi: end invoke??? in ce je to treba...kam in kako se to da?
LP
mNeRo ::
Obstaja kaksna dobra slovenska razlaga kaj kej pomeni oz. kaj kej dela, kdo koga klice... Mislim na me.invoke...delegate....
????
????
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Odpiranje programa v Visual StudioOddelek: Programiranje | 918 (776) | darkolord |
» | [WPF] Vrednost Textbox kot "angle" v AxisAngleRotation3DOddelek: Programiranje | 790 (725) | saule |
» | vb.net: dynamic textboxOddelek: Programiranje | 1186 (1076) | saule |
» | Visual Studio - koda za prikaz OS?Oddelek: Programiranje | 1086 (853) | detroit |
» | [C#] problem z branjem COM portaOddelek: Programiranje | 1871 (1693) | iNN |