Serial Port
Serial Port
I work in CNC machining industry and would like to program a simple CNC send/receive program that gets the data from the serial port on the CNC control and sends data to it. I have searched the forum and have all the sample serial port code but I can't make sense of it, specifically hitting receive on my program and then waiting for the user to hit send on the control, and hitting send on my program and sending the program data from the file to the control. I have all the settings of the control and know the Open Serial Port command, but after that I am lost when it comes to the actual process of sending or receiving data. Anyone with experience with input would be most welcome, I am missing something simple I know, but if pointed in the right direction I don't think I am that far off.
Re: Serial Port
Hi.
if you wait for serial input of the CNC, you have to use AvailableSerialInput() in a loop.
To avoid an unusable GUI, you should do all the serial stuff in an own thread.
For further hints I need a piece of code from you.
Bernd
if you wait for serial input of the CNC, you have to use AvailableSerialInput() in a loop.
To avoid an unusable GUI, you should do all the serial stuff in an own thread.
For further hints I need a piece of code from you.
Bernd
Re: Serial Port
Thank You for replying, after reading your explanation a light went on and I figured out the following code which works except for how to finish, the code uses the percent sign which signifies start and end of the program but I would rather wait until it is done sending and then strip the excess characters. I haven't done sending yet as I thought it would be the easier of the two.
Code: Select all
comID.l=0
a.l=0
b.l=0
c.l=0
Text.s=""
Buffer.b=0
Enumeration
#Window_0
EndEnumeration
Enumeration
#Text01
#Label01
#Gadget_50
EndEnumeration
Procedure Open_Window_0()
If OpenWindow(#Window_0, 0, 0, 370, 200, "Serial Communications", #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
TextGadget(#Text01, 10, 30, 310, 20, "")
;EditorGadget(#Label01, 50, 30, 310, 100, #PB_Editor_ReadOnly)
ButtonGadget(#Gadget_50, 10, 10, 80, 20, "Receive File")
EndIf
EndProcedure
Open_Window_0()
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
GadgetID = EventGadget()
If GadgetID = #Gadget_50
If OpenSerialPort(comID, "COM1", 9600, #PB_SerialPort_EvenParity, 7, 2, #PB_SerialPort_XonXoffHandshake, 1024, 1024)
SetGadgetText(#Text01, "Ready to Receive")
If CreateFile(1, "c:\Text.txt")
Repeat
While AvailableSerialPortInput(comID) > 0
If ReadSerialPortData(comID, @Buffer, 1) ; Read Byte
SetGadgetText(#Text01, "Receiving")
Text = Text + Chr(Buffer)
Receive = 1
If Right(Text,1)="%"
a=a+1
If a=2
WriteString(1, Text)
Break 2
EndIf
EndIf
If Right(Text,1)=Chr(13)
b=b+1
If b=2
c=Len(Text)
Text=RemoveString(Text, Chr(13),c, 1)
b=0
WriteString(1, Text)
Text=""
EndIf
EndIf
EndIf
Wend
Until a=2
CloseFile(1)
SetGadgetText(#Text01, "Finished")
Else
MessageRequester("Information","Can not create the file!")
EndIf
Else
MessageRequester("Error", "Can't open the serial port: "+Port$)
EndIf
CloseSerialPort(0)
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
End
Last edited by Dano on Tue Jul 29, 2014 5:21 am, edited 1 time in total.
Re: Serial Port
I just made similar project, here is the code:
HTH
HTH
Code: Select all
EnableExplicit
Import ""
PB_Gadget_SendGadgetCommand(hWnd, EventType)
EndImport
Define comport.s, fname.s, ligne.s, a.s, b.s
Global xcur.f, ycur.f
Define.l Event, WindowID, GadgetID, EventType, EventMenu
Global Dim buftx.a(100)
Global Dim bufrx.a(100)
Global nrecv.a
Declare wait(x.a, str.s)
Declare sendincx(x.a)
Declare senddecx(x.a)
Declare sendincy(x.a)
Declare senddecy(x.a)
Declare sendincz(x.a)
Declare senddecz(x.a)
Declare sendincxl(x.u)
Declare senddecxl(x.u)
Declare sendincyl(x.u)
Declare senddecyl(x.u)
Declare sendinczl(x.u)
Declare senddeczl(x.u)
Declare gotoxy(x.f, y.f)
If Not OpenPreferences("config.txt")
MessageRequester("Error","config.txt not found",#PB_MessageRequester_Ok)
End
EndIf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
comport= ReadPreferenceString("COMPORT","comx")
If Not OpenSerialPort(0, comport, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
MessageRequester("Error","Can't open Serial Port",#PB_MessageRequester_Ok)
End
EndIf
SerialPortTimeouts(0,100,100,10,10,100)
SetGadgetFont(#PB_Default, LoadFont(0, "Arial", 11))
OpenWindow(0, 100, 100, 800,600,"ROBOT DRILL 2014",#PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_SystemMenu)
ButtonGadget(0,50, 50,100,30,"AUTO", #PB_Button_Toggle)
ButtonGadget(1,200, 50,150,30,"GOTO ORIGIN")
TextGadget(2,400, 50,150,30,"")
ButtonGadget(10,50, 100,100,30,"X ++")
ButtonGadget(11,150, 100,100,30,"X - -")
ButtonGadget(12,50, 150,100,30,"Y ++")
ButtonGadget(13,150, 150,100,30,"Y - -")
ButtonGadget(14,50, 200,100,30,"Z ++")
ButtonGadget(15,150, 200,100,30,"Z - -")
TextGadget(#PB_Any, 275,105,100,30,"STEPs X:")
TextGadget(#PB_Any, 275,155,100,30,"STEPs Y:")
TextGadget(#PB_Any, 275,205,100,30,"STEPs Z:")
StringGadget(20,355,100,50,25,"100")
StringGadget(21,355,150,50,25,"100")
StringGadget(22,355,200,50,25,"100")
ButtonGadget(16,50, 250,200,30,"LOAD DRILL DATA")
PB_Gadget_SendGadgetCommand(GadgetID(0), #PB_EventType_LeftClick)
Repeat
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadget() ; Is it a gadget event?
EventType = EventType() ; The event type
Select Event
Case #PB_Event_Gadget ;Event = WaitWindowEvent()
If GadgetID=0
If GetGadgetState(0)=1
SetGadgetText(0,"MANUAL")
DisableGadget(10,0)
DisableGadget(11,0)
DisableGadget(12,0)
DisableGadget(13,0)
DisableGadget(14,0)
DisableGadget(15,0)
DisableGadget(16,0)
DisableGadget(20,0)
DisableGadget(21,0)
DisableGadget(22,0)
Else
SetGadgetText(0,"AUTO")
DisableGadget(10,1)
DisableGadget(11,1)
DisableGadget(12,1)
DisableGadget(13,1)
DisableGadget(14,1)
DisableGadget(15,1)
DisableGadget(16,1)
DisableGadget(20,1)
DisableGadget(21,1)
DisableGadget(22,1)
EndIf
ElseIf GadgetID=10
sendincxl(Val(GetGadgetText(20)))
ElseIf GadgetID=11
senddecxl(Val(GetGadgetText(20)))
ElseIf GadgetID=12
sendincyl(Val(GetGadgetText(21)))
ElseIf GadgetID=13
senddecyl(Val(GetGadgetText(21)))
ElseIf GadgetID=14
sendinczl(Val(GetGadgetText(22)))
ElseIf GadgetID=15
senddeczl(Val(GetGadgetText(22)))
ElseIf GadgetID=16
fname = OpenFileRequester("Drill data file", "drill_data.dri", "Drill (*.dri)|*.dri", 0)
SetGadgetText(2,"Waiting origin")
Delay(100)
buftx(0)= %11000000
WriteSerialPortData(0,@buftx(),1)
xcur=0
ycur=0
wait($39,"origin reached")
ReadFile(0,fname)
ligne=ReadString(0)
a=StringField(ligne, 1, " ")
b=StringField(ligne, 3, " ")
sendincz(100)
gotoxy(Val(a),0)
gotoxy(Val(a),Val(b))
gotoxy(0,Val(b))
gotoxy(0,0)
senddecz(100)
While Not Eof(0)
ligne=ReadString(0)
a=StringField(ligne, 1, " ")
b=StringField(ligne, 3, " ")
gotoxy(Val(a),Val(b))
sendincz(100)
senddecz(100)
Wend
SetGadgetText(2,"End")
buftx(0)= %11000001
WriteSerialPortData(0,@buftx(),1)
ElseIf GadgetID=1
SetGadgetText(2,"Waiting origin")
Delay(100)
buftx(0)= %11000000
WriteSerialPortData(0,@buftx(),1)
xcur=0
ycur=0
wait($39,"origin reached")
EndIf
EndSelect
Until Event = #PB_Event_CloseWindow ; End of the event loop
Procedure wait(x.a, str.s)
Repeat
nrecv=AvailableSerialPortInput(0)
If nrecv <> 0
ReadSerialPortData(0,@bufrx(),1)
If bufrx(0)=x
SetGadgetText(2,str)
Beep_(500,300)
Break
EndIf
EndIf
Delay(100)
ForEver
EndProcedure
Procedure sendincx(x.a)
buftx(0)= %10000001
buftx(1)=x
WriteSerialPortData(0,@buftx(),2)
SetGadgetText(2,"Waiting inc x")
wait($31,"inc x reached")
EndProcedure
Procedure senddecx(x.a)
buftx(0)= %10000010
buftx(1)=x
WriteSerialPortData(0,@buftx(),2)
SetGadgetText(2,"Waiting dec x")
wait($32,"dec x reached")
EndProcedure
Procedure sendincy(x.a)
buftx(0)= %10000100
buftx(1)=x
WriteSerialPortData(0,@buftx(),2)
SetGadgetText(2,"Waiting inc y")
wait($33,"inc y reached")
EndProcedure
Procedure senddecy(x.a)
buftx(0)= %10001000
buftx(1)=x
WriteSerialPortData(0,@buftx(),2)
SetGadgetText(2,"Waiting dec y")
wait($34,"dec y reached")
EndProcedure
Procedure sendincz(x.a)
buftx(0)= %10010000
buftx(1)=x
WriteSerialPortData(0,@buftx(),2)
SetGadgetText(2,"Waiting inc z")
wait($35,"inc z reached")
EndProcedure
Procedure senddecz(x.a)
buftx(0)= %10100000
buftx(1)=x
WriteSerialPortData(0,@buftx(),2)
SetGadgetText(2,"Waiting dec z")
wait($36,"dec z reached")
EndProcedure
Procedure sendincxl(x.u) ; x en 0.1 mm
Define i.a, q.a, r.a
x=4*x
q=0
r=x
If x> 125
q=x/125
r= x % 125
EndIf
Debug "x="+Str(x)
Debug "incx q="+Str(q)
Debug "incx r="+Str(r)
For i=1 To q
sendincx(125)
Next
If r <> 0 : sendincx(r) : EndIf
EndProcedure
Procedure senddecxl(x.u)
Define i.a, q.a, r.a
x=4*x
q=0
r=x
If x> 125
q=x/125
r= x % 125
EndIf
Debug "x="+Str(x)
Debug "decx q="+Str(q)
Debug "decx r="+Str(r)
For i=1 To q
senddecx(125)
Next
If r <> 0 : senddecx(r) : EndIf
EndProcedure
Procedure sendincyl(x.u)
Define i.a, q.a, r.a
x=4*x
q=0
r=x
If x> 125
q=x/125
r= x % 125
EndIf
Debug "y="+Str(x)
Debug "incy q="+Str(q)
Debug "incy r="+Str(r)
For i=1 To q
sendincy(125)
Next
If r <> 0 : sendincy(r) : EndIf
EndProcedure
Procedure senddecyl(x.u)
Define i.a, q.a, r.a
x=4*x
q=0
r=x
If x> 125
q=x/125
r= x % 125
EndIf
Debug "y="+Str(x)
Debug "decy q="+Str(q)
Debug "decy r="+Str(r)
For i=1 To q
senddecy(125)
Next
If r <> 0 : senddecy(r) : EndIf
EndProcedure
Procedure sendinczl(x.u)
Define i.a, q.a, r.a
x=4*x
q=0
r=x
If x> 125
q=x/125
r= x % 125
EndIf
Debug "z="+Str(x)
Debug "incz q="+Str(q)
Debug "incz r="+Str(r)
For i=1 To q
sendincz(125)
Next
If r <> 0 : sendincz(r) : EndIf
EndProcedure
Procedure senddeczl(x.u)
Define i.a, q.a, r.a
x=4*x
q=0
r=x
If x> 125
q=x/125
r= x % 125
EndIf
Debug "z="+Str(x)
Debug "decz q="+Str(q)
Debug "decz r="+Str(r)
For i=1 To q
senddecz(125)
Next
If r <> 0 : senddecz(r) : EndIf
EndProcedure
Procedure gotoxy(x.f, y.f)
Define dx.f, dy.f
dx=x-xcur
dy=y-ycur
Debug "dx="+Str(dx)
Debug "dy="+Str(dy)
If dx > 0
sendincxl(dx*10)
ElseIf dx < 0
senddecxl(-dx*10)
EndIf
If dy > 0
sendincyl(dy*10)
ElseIf dy < 0
senddecyl(-dy*10)
EndIf
xcur=x
ycur=y
EndProcedure
PureBasic: Surprisingly simple, diabolically powerful
Re: Serial Port
Morosh,
Looks like you are actually controlling a drill through the serial port, but doesn't look like you need to receive a program like I do.
That should help when I get to the send part of my program. Thanks for sharing your code.
My next steps are the send part and putting them in a thread, which should allow me to keep it active in memory just waiting for
my cnc control to send a program to it.
I haven't used the thread part of purebasic yet so any hints from anyone would be appreciated.
Looks like you are actually controlling a drill through the serial port, but doesn't look like you need to receive a program like I do.
That should help when I get to the send part of my program. Thanks for sharing your code.
My next steps are the send part and putting them in a thread, which should allow me to keep it active in memory just waiting for
my cnc control to send a program to it.
I haven't used the thread part of purebasic yet so any hints from anyone would be appreciated.
Re: Serial Port
Hi Dano,
try this (no guaranty, since I can not test it) :
Bernd
try this (no guaranty, since I can not test it) :
Code: Select all
EnableExplicit
#Port$ = "COM1"
#XON = $11
#XOFF = $13
#TextFile$ = "C:\Text.txt"
Enumeration
#Text01
#SendButton
#ReceiveButton
#Editor01
EndEnumeration
Enumeration #PB_Event_FirstCustomValue
#OpenSerialPortFailure
#FileError
#SetStatusBarField_1
#SetStatusBarField_2
#ShowContent
#ReceiveFinished
#SendFinished
EndEnumeration
Structure ThreadParameterStructure
Thread.i
Port$
FileName$
FileContent$
StatusText_01$
StatusText_02$
Exit.i
EndStructure
Procedure Receive(*p.ThreadParameterStructure)
Protected.a Byte
Protected.i Port, State, Count, File
Protected Text$
Port = OpenSerialPort(#PB_Any, *p\Port$, 9600, #PB_SerialPort_EvenParity, 7, 2, #PB_SerialPort_XonXoffHandshake, 1024, 1024)
If Port
While AvailableSerialPortInput(Port)
ReadSerialPortData(Port, @Byte, 1) ; to remove available rubbish
Wend
*p\StatusText_01$ = "Waiting for file ..."
PostEvent(#SetStatusBarField_1)
Byte = #XON
WriteSerialPortData(Port, @Byte, 1) ; to be sure :)
Repeat
If AvailableSerialPortInput(Port)
While AvailableSerialPortInput(Port) And Not *p\Exit
If ReadSerialPortData(Port, @Byte, 1) ; Read Byte
Select State
Case 0
If Byte = '%'
*p\StatusText_01$ = "receiving file ..."
PostEvent(#SetStatusBarField_1)
State = 1
Text$ + Chr(Byte)
EndIf
Case 1
If Byte <> '%'
Text$ + Chr(Byte)
Count + 1
*p\StatusText_02$ = Str(Count)
PostEvent(#SetStatusBarField_2)
Else
Text$ + Chr(Byte)
Text$ = ReplaceString(Text$, #LF$ + #CR$ + #CR$, #CRLF$)
*p\FileContent$ = Text$
PostEvent(#ShowContent)
File = CreateFile(#PB_Any, #TextFile$)
If File
WriteString(File, Text$, #PB_Ascii)
CloseFile(File)
*p\StatusText_01$ = "File received"
PostEvent(#SetStatusBarField_1)
Else
*p\StatusText_01$ = "File error !!!"
PostEvent(#SetStatusBarField_1)
EndIf
*p\Exit = #True
EndIf
EndSelect
EndIf
Wend
Else
Delay(10)
EndIf
Until *p\Exit
*p\StatusText_02$ = ""
PostEvent(#SetStatusBarField_2)
CloseSerialPort(Port)
Else
PostEvent(#OpenSerialPortFailure)
EndIf
PostEvent(#ReceiveFinished)
EndProcedure
Procedure Send(*p.ThreadParameterStructure)
Protected.a Byte
Protected.i Port, State, Count, File, FileSize
Protected Text$
Repeat
Port = OpenSerialPort(#PB_Any, *p\Port$, 9600, #PB_SerialPort_EvenParity, 7, 2, #PB_SerialPort_XonXoffHandshake, 1024, 1024)
If Port
File = ReadFile(#PB_Any, *p\FileName$)
If File
FileSize = Lof(File)
Text$ = ReadString(File, #PB_Ascii|#PB_File_IgnoreEOL, FileSize)
CloseFile(File)
*p\FileContent$ = Text$
PostEvent(#ShowContent)
If Len(Text$)
*p\StatusText_01$ = "sending file ..."
PostEvent(#SetStatusBarField_1)
Repeat
If AvailableSerialPortOutput(Port) < 1024
WriteSerialPortData(Port, @Text$ + Count, 1)
Count + 1
*p\StatusText_02$ = Str(Count) + " / " + Str(FileSize)
PostEvent(#SetStatusBarField_2)
Else
Delay(1)
EndIf
Until Count = FileSize Or *p\Exit
EndIf
*p\Exit = #True
Else
PostEvent(#FileError)
*p\Exit = #True
EndIf
*p\StatusText_02$ = ""
PostEvent(#SetStatusBarField_2)
CloseSerialPort(Port)
Else
PostEvent(#OpenSerialPortFailure)
EndIf
Until *p\Exit
PostEvent(#SendFinished)
EndProcedure
Procedure TerminateThread(*TP.ThreadParameterStructure)
If IsThread(*TP\Thread)
*TP\Exit = #True
If WaitThread(*TP\Thread, 500) = 0
KillThread(*TP\Thread) ; should never happen
EndIf
EndIf
EndProcedure
;-Main
Define.i Event, Exit, Thread, ParaCount, i
Define ThreadParameter.ThreadParameterStructure
CompilerIf Not #PB_Compiler_Thread
MessageRequester("Hint", "You have to enable 'Thread-Safe' in compiler settings")
End
CompilerEndIf
ThreadParameter\Port$ = #Port$
ThreadParameter\Exit = #False
OpenWindow(0, 0, 0, 370, 200, "Serial Communications", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
TextGadget(#Text01, 10, 30, 310, 20, "")
ButtonGadget(#SendButton, 40, 10, 80, 20, "Send File", #PB_Button_Toggle)
ButtonGadget(#ReceiveButton, 210, 10, 80, 20, "Receive File", #PB_Button_Toggle)
EditorGadget(#Editor01, 10, 50, 310, 100, #PB_Editor_ReadOnly)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(150)
AddStatusBarField(100)
ParaCount = CountProgramParameters() - 1
For i = 0 To ParaCount
Select LCase(ProgramParameter(i))
Case "s"
i + 1
ThreadParameter\FileName$ = ProgramParameter(i)
SetGadgetState(#SendButton, 1)
PostEvent(#PB_Event_Gadget, 0, #SendButton)
;ThreadParameter\Thread = CreateThread(@Send(), @ThreadParameter)
Case "r"
i + 1
ThreadParameter\FileName$ = ProgramParameter(i)
SetGadgetState(#ReceiveButton, 1)
PostEvent(#PB_Event_Gadget, 0, #ReceiveButton)
;ThreadParameter\Thread = CreateThread(@Receive(), @ThreadParameter)
EndSelect
Next i
;-Main loop
Repeat
Event = WaitWindowEvent()
Select Event
Case #OpenSerialPortFailure
MessageRequester("Error", "Was not able to open " + ThreadParameter\Port$)
Case #FileError
MessageRequester("Error", "Was not able to open " + ThreadParameter\FileName$)
Case #ShowContent
SetGadgetText(#Editor01, ThreadParameter\FileContent$)
Case #SetStatusBarField_1
StatusBarText(0, 0, ThreadParameter\StatusText_01$, #PB_StatusBar_Center)
Case #SetStatusBarField_2
StatusBarText(0, 1, ThreadParameter\StatusText_02$, #PB_StatusBar_Center)
Case #ReceiveFinished
SetGadgetState(#ReceiveButton, 0)
PostEvent(#PB_Event_Gadget, 0, #ReceiveButton)
Case #SendFinished
SetGadgetState(#SendButton, 0)
PostEvent(#PB_Event_Gadget, 0, #SendButton)
Case #PB_Event_Gadget
Select EventGadget()
Case #ReceiveButton
If GetGadgetState(#ReceiveButton)
If Len(ThreadParameter\FileName$) = 0
ThreadParameter\FileName$ = #TextFile$
EndIf
ThreadParameter\Port$ = #Port$
ThreadParameter\Exit = #False
ThreadParameter\Thread = CreateThread(@Receive(), @ThreadParameter)
DisableGadget(#SendButton, #True)
Else
TerminateThread(@ThreadParameter)
DisableGadget(#SendButton, #False)
StatusBarText(0, 0, "")
ThreadParameter\FileName$ = ""
EndIf
Case #SendButton
If GetGadgetState(#SendButton)
If Len(ThreadParameter\FileName$) = 0
ThreadParameter\FileName$ = OpenFileRequester("Choose a file ...", "", "*.*|*.*", 0)
EndIf
If Len(ThreadParameter\FileName$)
ThreadParameter\Port$ = #Port$
ThreadParameter\Exit = #False
ThreadParameter\Thread = CreateThread(@Send(), @ThreadParameter)
DisableGadget(#ReceiveButton, #True)
Else
SetGadgetState(#SendButton, 0)
EndIf
Else
TerminateThread(@ThreadParameter)
DisableGadget(#ReceiveButton, #False)
StatusBarText(0, 0, "")
ThreadParameter\FileName$ = ""
EndIf
EndSelect
Case #PB_Event_CloseWindow
TerminateThread(@ThreadParameter)
Exit = #True
EndSelect
Until Exit
Last edited by infratec on Mon Jul 28, 2014 7:24 am, edited 2 times in total.
Re: Serial Port
Infratec,
You have a much better grasp of the advanced parts of Purebasic than I do, your use of pointers and threading leaves me in the dust. I can't wait to try the code on monday( I have been sick the last few days)
I was so happy when I finally got my program to receive a program from the control, this code makes it so much more eloquent, it clears the buffer to be sure first, then receives the program in a thread safe way,
I feel like a professional touch has just been added. Much appreciation goes to you, I'm sure as well as my program worked this will work a thousand times better.
Thanks again,
Dan
You have a much better grasp of the advanced parts of Purebasic than I do, your use of pointers and threading leaves me in the dust. I can't wait to try the code on monday( I have been sick the last few days)
I was so happy when I finally got my program to receive a program from the control, this code makes it so much more eloquent, it clears the buffer to be sure first, then receives the program in a thread safe way,
I feel like a professional touch has just been added. Much appreciation goes to you, I'm sure as well as my program worked this will work a thousand times better.
Thanks again,
Dan
Re: Serial Port
Infratec,
Your code worked good, I needed to do some processing with the carriage return/ linefeed so I need to still modify it to bring the code in one line at a time but other than that it worked great. The threading was really good, no unnecessary slowdown of the computer while it was waiting for code. I thought the sending would be easier, but I am struggling again, I wonder if I could avail myself of your expertise, do you have some sample code for sending? Here is what I have started,
including an editor that shows the code as I bring it in/send it
Thanks,
Dan
Your code worked good, I needed to do some processing with the carriage return/ linefeed so I need to still modify it to bring the code in one line at a time but other than that it worked great. The threading was really good, no unnecessary slowdown of the computer while it was waiting for code. I thought the sending would be easier, but I am struggling again, I wonder if I could avail myself of your expertise, do you have some sample code for sending? Here is what I have started,
including an editor that shows the code as I bring it in/send it
Code: Select all
EnableExplicit
#Port$ = "COM1"
#XON = $11
#XOFF = $13
#TextFile$ = "C:\Text.txt"
Enumeration
#Text01
#Gadget_50
#Gadget_51
#Editor01
EndEnumeration
Enumeration #PB_Event_FirstCustomValue
#OpenSerialPortFailure
#SetStatusBarField_1
#SetStatusBarField_2
#ReceiveFinished
EndEnumeration
Structure ThreadParameterStructure
StatusText_01$
StatusText_02$
Exit.i
EndStructure
Procedure Receive(*p.ThreadParameterStructure)
Protected.a Byte
Protected.i Port, State, Count, File
Protected Text$, orig.s, news.s
Port = OpenSerialPort(#PB_Any, #Port$, 9600, #PB_SerialPort_EvenParity, 7, 2, #PB_SerialPort_XonXoffHandshake, 1024, 1024)
If Port
While AvailableSerialPortInput(Port)
ReadSerialPortData(Port, @Byte, 1) ; to remove available rubbish
Wend
*p\StatusText_01$ = "Waiting for file ..."
PostEvent(#SetStatusBarField_1)
Byte = #XON
WriteSerialPortData(Port, @Byte, 1) ; to be sure :)
Repeat
If AvailableSerialPortInput(Port)
While AvailableSerialPortInput(Port) And Not *p\Exit
If ReadSerialPortData(Port, @Byte, 1) ; Read Byte
Select State
Case 0
If Byte = '%'
*p\StatusText_01$ = "receiving file ..."
PostEvent(#SetStatusBarField_1)
State = 1
Text$ + Chr(Byte)
EndIf
Case 1
If Byte <> '%'
Text$ + Chr(Byte)
Count + 1
*p\StatusText_02$ = Str(Count)
PostEvent(#SetStatusBarField_2)
Else
Text$ + Chr(Byte)
orig=Chr(10)+Chr(13)+Chr(13)
news=Chr(13)+Chr(10)
Text$ = ReplaceString(Text$,orig,news)
AddGadgetItem(#Editor01,-1, Text$)
File = CreateFile(#PB_Any, #TextFile$)
If File
WriteString(File, Text$)
CloseFile(File)
*p\StatusText_01$ = "File received"
PostEvent(#SetStatusBarField_1)
Else
*p\StatusText_01$ = "File error !!!"
PostEvent(#SetStatusBarField_1)
EndIf
*p\Exit = #True
EndIf
EndSelect
EndIf
Wend
Else
Delay(10)
EndIf
Until *p\Exit
*p\StatusText_02$ = ""
PostEvent(#SetStatusBarField_2)
CloseSerialPort(Port)
Else
PostEvent(#OpenSerialPortFailure)
EndIf
PostEvent(#ReceiveFinished)
EndProcedure
Procedure Send()
Protected.a Byte
Protected.i Port, State, Count, File
Protected Text$, orig.s, news.s
Repeat
If Port = OpenSerialPort(#PB_Any, #Port$, 9600, #PB_SerialPort_EvenParity, 7, 2, #PB_SerialPort_XonXoffHandshake, 1024, 1024)
While AvailableSerialPortOutput(Port)
If File
Else
EndIf
Wend
Else
MessageRequester("Error", "Can't open the serial port: "+Port)
EndIf
Until File
EndProcedure
Define.i Event, Exit, Thread
Define ThreadParameter.ThreadParameterStructure
CompilerIf Not #PB_Compiler_Thread
MessageRequester("Hint", "You have to enable 'Thread-Safe' in compiler settings")
End
CompilerEndIf
OpenWindow(0, 0, 0, 370, 200, "Serial Communications", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
TextGadget(#Text01, 10, 30, 310, 20, "")
ButtonGadget(#Gadget_50, 210, 10, 80, 20, "Receive File")
ButtonGadget(#Gadget_51, 40, 10, 80, 20, "Send File")
EditorGadget(#Editor01, 10, 50, 310, 100, #PB_Editor_ReadOnly)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(150)
AddStatusBarField(100)
Repeat
Event = WaitWindowEvent()
Select Event
Case #OpenSerialPortFailure
MessageRequester("Error", "Was not able to open " + #Port$)
Case #SetStatusBarField_1
StatusBarText(0, 0, ThreadParameter\StatusText_01$, #PB_StatusBar_Center)
Case #SetStatusBarField_2
StatusBarText(0, 1, ThreadParameter\StatusText_02$, #PB_StatusBar_Center)
Case #ReceiveFinished
; do something or not :)
Case #PB_Event_Gadget
Select EventGadget()
Case #Gadget_50 ;Receive Button
If GetGadgetState(#Gadget_50)
Thread = CreateThread(@Receive(), @ThreadParameter)
Else
If IsThread(Thread)
ThreadParameter\Exit = #True
If WaitThread(Thread, 500) = 0
KillThread(Thread) ; should never happen
EndIf
EndIf
StatusBarText(0, 0, "")
EndIf
EndSelect
Case #Gadget_51 ;Send Button
Send()
Case #PB_Event_CloseWindow
If IsThread(Thread)
ThreadParameter\Exit = #True
If WaitThread(Thread, 500) = 0
KillThread(Thread) ; should never happen
EndIf
EndIf
Exit = #True
EndSelect
Until Exit
Dan
Last edited by Dano on Tue Jul 29, 2014 5:20 am, edited 1 time in total.
Re: Serial Port
Hi,
I changed my listing above.
As usual: untested.
Bernd
I changed my listing above.
As usual: untested.
Bernd
Re: Serial Port
I wrote this program, maybe you like to use it: https://www.dropbox.com/s/e430dr068y3c1 ... x_0818.zip
I suggest to download the "com2com driver". It installs a virtual serial port connection to your os so you can
test your code with it (just start two instances of your program, one to send data and the other one to receive...)
com2com:
http://sourceforge.net/projects/com0com/
ncmax source:
https://www.dropbox.com/s/cm65h6i4lqpe2wj/Source.zip
Greets
Alexander
I suggest to download the "com2com driver". It installs a virtual serial port connection to your os so you can
test your code with it (just start two instances of your program, one to send data and the other one to receive...)
com2com:
http://sourceforge.net/projects/com0com/
ncmax source:
https://www.dropbox.com/s/cm65h6i4lqpe2wj/Source.zip
Greets
Alexander
Repeat
PureBasic
ForEver
PureBasic
ForEver
Re: Serial Port
Infratec,
Your code works beautifully, I have to pour through it so I can understand it a bit better. I still want the EditorGadget to update as I'm bringing in or sending the code, rather than all at once. It seems that the only way to update
the gadget is with AddGadgetItem, which adds a whole line, I don't think there is a way to add each single character while I am bringing in the text. Probably there is an api call to do so. Anyways failing
that I must then use ReadSerialPortString instead of ReadSerialPortData and then update the EditorGadget after the CRLF. Another way might be using the Scintilla Editor, I'm sure if I check their docs there must be a
way to add individual characters rather than a whole line, which would mean I don't have to touch your code. Anyways I think I can handle the rest. You don't know what you've done for me, sitting in the forum is a post from 8 years
ago when I attempted serial port communications using the MVCom library and couldn't get it to work. I gave up thinking it too hard and stopped programming in Purebasic for many years(unrelated). Now I have come back and see native serialport commands (Thanks Fred and team) and many other nice improvements to the language, and thought I'd try again, and now thanks to your help I have a working program, and have other projects I am undertaking with PB. I greatly appreciate it!
Alexander,
Looking at your program, a freeware serial communications program, I think it is just what I was looking for before I decided to try programming the serial ports myself. I wonder if you might consider translating it to english? I can't
understand what is going on there in the code and in the help file.
Your code works beautifully, I have to pour through it so I can understand it a bit better. I still want the EditorGadget to update as I'm bringing in or sending the code, rather than all at once. It seems that the only way to update
the gadget is with AddGadgetItem, which adds a whole line, I don't think there is a way to add each single character while I am bringing in the text. Probably there is an api call to do so. Anyways failing
that I must then use ReadSerialPortString instead of ReadSerialPortData and then update the EditorGadget after the CRLF. Another way might be using the Scintilla Editor, I'm sure if I check their docs there must be a
way to add individual characters rather than a whole line, which would mean I don't have to touch your code. Anyways I think I can handle the rest. You don't know what you've done for me, sitting in the forum is a post from 8 years
ago when I attempted serial port communications using the MVCom library and couldn't get it to work. I gave up thinking it too hard and stopped programming in Purebasic for many years(unrelated). Now I have come back and see native serialport commands (Thanks Fred and team) and many other nice improvements to the language, and thought I'd try again, and now thanks to your help I have a working program, and have other projects I am undertaking with PB. I greatly appreciate it!
Alexander,
Looking at your program, a freeware serial communications program, I think it is just what I was looking for before I decided to try programming the serial ports myself. I wonder if you might consider translating it to english? I can't
understand what is going on there in the code and in the help file.
Re: Serial Port
Hi,
nice that it works for you
I would stay with ReadSerialPortData().
Since it is used byte by byte, you can simply check for Byte = #LF or soemthing like that.
You can also write directly in Gadgets or in the StatusBar inside of the thread, but ...
If you close the program it can happen that your thread hangs, because he want to some of this stuff,
but it is not proccessed anymore.
But I think you can manage the rest.
One of the best things with PB is not only the language, it is this forum.
Bernd
nice that it works for you

I would stay with ReadSerialPortData().
Since it is used byte by byte, you can simply check for Byte = #LF or soemthing like that.
You can also write directly in Gadgets or in the StatusBar inside of the thread, but ...
If you close the program it can happen that your thread hangs, because he want to some of this stuff,
but it is not proccessed anymore.
But I think you can manage the rest.
One of the best things with PB is not only the language, it is this forum.
Bernd
Re: Serial Port
Hi Dano!
I will translate my program to english language, not sure if i have time to do it right now, but i'll translate it as soon as possible.
I had the same problem with adding single letters to the editor gadget, but its possible with SetGadgetItemText(#Gadget, Pos, Text.s) :
Greets
Alexander
I will translate my program to english language, not sure if i have time to do it right now, but i'll translate it as soon as possible.
I had the same problem with adding single letters to the editor gadget, but its possible with SetGadgetItemText(#Gadget, Pos, Text.s) :
Code: Select all
...
programdata = programdata + dat.s ; i store my data here
Bytes = Bytes + Len(dat.s) ; count bytes transmitted
SetGadgetItemText(#Editor_73, g, dat.s) : g + Len(dat.s) ;sets at position g new arrived data + increment g (position)
SendMessage_(GadgetID(#Editor_73), #EM_SETSEL,-1,-1) ;scroll editor gadget down
...
Alexander
Repeat
PureBasic
ForEver
PureBasic
ForEver
Re: Serial Port
Alexander,
I didn't even think of the SetGadgetItemText, but it makes sense that it would work, thanks for the tip, and for translating your program to english, whenever you have time,
no hurry. I appreciate that.
Bernd,
I have a question. I am passing parameters to the program, an S or R for send/receive, and a filename. I now can't use the constant #TextFile$ as it will change every time.
I'm wondering if I can use Global for a string say TextFile$ which I can get from ProgramParameter and use in my thread Procedure. Or is it because of the threading you can't do this?
Do you have an elegant solution without using the constant #TextFile$? Sorry probably simple question, I tried a few things and they didn't work, but I will try again tomorrow.
I didn't even think of the SetGadgetItemText, but it makes sense that it would work, thanks for the tip, and for translating your program to english, whenever you have time,
no hurry. I appreciate that.
Bernd,
I have a question. I am passing parameters to the program, an S or R for send/receive, and a filename. I now can't use the constant #TextFile$ as it will change every time.
I'm wondering if I can use Global for a string say TextFile$ which I can get from ProgramParameter and use in my thread Procedure. Or is it because of the threading you can't do this?
Do you have an elegant solution without using the constant #TextFile$? Sorry probably simple question, I tried a few things and they didn't work, but I will try again tomorrow.
Re: Serial Port
Hi,
I extended my listing above.
Bernd
I extended my listing above.
Bernd