Problem accessing COM Port FreeBasic/Firefly

Windows specific questions.
Post Reply
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Hello everybody,

Being new on his forum, I don't know exactly where to post this question concerning Com port access from something developped in FreeBasic with Firefly.
Maybe a moderator shall move it to an appropriate location...

I'm having some touble sendind data on a Serial port.
Using FreeBasic under DOS, no problem:
Open "COM2: 2400,N,8,1" as #1
Print #1, "comand to drive a Vellemen K8056 relays card"
This works.
Using the same code into a function under Firefly, it doesn't do anything since I first use another program (e.g. K8056.exe provided with the card)
So, if I start my program and try to send data to the relays card, nothing comes to the card.
I then close my program, run K856.EXE to send a "reset" command, this works.
I restart my own program and now it works fine.

Do I miss something accessing my Com port?
I tried on several computers (Win XP, Win7), always the same.

Does someone have an idea?

Thank you in advance.
Regards,
Yvan
nobozoz
Posts: 238
Joined: Nov 17, 2005 6:24
Location: Chino Hills, CA, USA

Re: Problem accessing COM Port FreeBasic/Firefly

Post by nobozoz »

Yvan,

If you were able to communicate successfully using fb (DOS), then the next logical step would be to test communications in fb (WIN).

On success using fb (WIN), then introduce FireFly. If communications now fail, then perhaps the problem is with FireFly, not with serial communications.

Help with FireFly is probably best sought through the FREEBASIC: "Projects" section of the Forum.

Hardware communications help can be found in the PROGRAMMING: "Hardware Interfaces / Communication" section of the Forum.

Jim
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Re: Problem accessing COM Port FreeBasic/Firefly

Post by phishguy »

Change

Code: Select all

Open "COM2: 2400,N,8,1" as #1
to

Code: Select all

Open Com "COM2: 2400,N,8,1" as #1
The first works for DOS
The second is for Windows
You may also need some flags in the statement to disable control lines.

Code: Select all

Open Com "COM2: 2400,N,8,1,cs0,cd0,ds0,rs" as #1
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear nobozoz,

Thank you for your suggestions.
I searched and read many topics in FREEBASIC: "Projects" and in PROGRAMMING: "Hardware Interfaces / Communication" section but didn't find anything that helps me.

I tried using a ports monitoring tool and saw nothing being transmitted unless I first use something else to access the Serial port (HyperTerm, PuTTY, RealTerm or else).

Regards,
Yvan.
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear phishguy,

Thank you for replying too. I tried several strings like using "COM2: 2400,N,8,1,cs0,cd0,ds0,rs" ... still the same result.
If I use Open Com "Com2:...." my application crashes.
As I also have a problem with errors handling under Firefly (actually I don't understand how to manage Error, Err, and so on), I can't tell tou which error I get using Open com "Com....".
I checked the documentation of the relays card again. There is nothing to "initialize first". And, as I monitored the seriel port, I can say that there is nothing going out the computer from my program.
I also tried to set a transmit buffer size ("COM2: 2400,N,8,1,cs0,cd0,ds0,rs,tb4096"). Nothing more. The problem remains.

Anyway, Thank you.
Regards,
Yvan.
nobozoz
Posts: 238
Joined: Nov 17, 2005 6:24
Location: Chino Hills, CA, USA

Re: Problem accessing COM Port FreeBasic/Firefly

Post by nobozoz »

Yvan,

Here is a short console program that I use for some timing tests of my serial ports. The program first searches backwards from COM255 to COM1 and lists all of the virtual COM ports that WINDOWS knows about. After that, the program opens the last COM port found (usually COM1) and then repeatedly toggles the DTR and RTS control lines and also transmits the current value of TIMER. This program works on my Dell 350 workstation under WINXP,SP3 when compiled with fb.90.1. The program uses the WINAPI to access the control lines so that the DTR and RTS works on register-based hardware COM ports as well as USB to RS232 COM port adapters.
Jim

Code: Select all

#Include "windows.bi"
#Include "file.bi"
On Error GoTo eh
Dim As String sComNum="COM255", sComInit="", sLastComInit=""
Dim proto as String = ":2400,N,8,1,RS,DS0,CS0,CD0" 
Dim as HANDLE hEvent
hEvent = CreateEvent( NULL, FALSE, FALSE, NULL )
Dim As HANDLE h 
Dim As String saComFound(48)
Dim As Double dTmr0, dTmr1
'DS0 present allows opening a floating COM port?
'RS to ignore RS
Dim As Integer iCOMSTAT = 0, iFileNum=FreeFile
Print "iFileNum=",iFileNum
Const cLOOPS=400
Const cSLEEPERWSO=10  '250 works with WaitForSingleObject( hEvent, cSLEEPER )?
Const cSLEEPER=10  '246, 250? '250 works with WaitForSingleObject( hEvent, cSLEEPER )?
Const cWSO = 1
'cSLEEPER=1       3       7       15      31      62      123     246     492     985     1969    3939    7877
'freq_DTR=512.00  256.00  128.00  64.000  32.000  16.000  8.0000  4.0000  2.0000  1.0000  .50000  .25000  .12500
Print "Status","Seq","COMn","COMSTAT" ',"FILENUM"
Dim As Integer iComIndex = 0
For i As Integer = 255 To 1 Step -1
  iFileNum=FreeFile
  sComNum="COM" +Trim(Str(i),Any Chr(32))
  sComInit=sComNum+proto
  iCOMSTAT=open com ( sComInit for binary as iFileNum )  '0=Exists&active;1=exists&inactive;2=nonexistent
  If iCOMSTAT = 2 Then
    'Print "NotFound: ", sComNum, iFileNum, iCOMSTAT
    'Do Nada
  Else
    iComIndex+=1
    Print "Found: ", iComIndex, sComNum, iCOMSTAT ', iFileNum
    sLastComInit=sComInit                               'Remember last existing Com port.
    Close iFileNum
  EndIf  
  Sleep 1
Next
sComInit=sLastComInit
Print "sLastComInit=",sComInit
iFileNum=FreeFile
Print "iFileNum",iFileNum
iCOMSTAT=open com ( sComInit for binary as iFileNum )  '0=Exists&active;1=exists&inactive;2=nonexistent
If( iCOMSTAT >0 ) then
  print "Unable to open '" + sComInit + "'",iCOMSTAT
  Sleep
  end 1
Else
  print "Opened:" + sComInit + ": OK", iCOMSTAT  
end If
h = cast(HANDLE, FileAttr( iFileNum, fbFileAttrHandle ))  'Get the windows handle
Dim As Integer iEscapeComm = EscapeCommFunction( h, CLRDTR )
Print "iEscapeComm:",iEscapeComm
If ( EscapeCommFunction( h, CLRDTR )) then
  print "CLRDTR OK"
else
  print "CLRDTR error: "; GetLastError()
end If
Print "cWSO, cSLEEPERWSO, cSLEEPER",cWSO,cSLEEPERWSO,cSLEEPER
dTmr0=timer
For i As Integer=1 To cLOOPS
'  Print i,
  If cWSO=0 Then
    Sleep cSLEEPER
  Else  
    WaitForSingleObject( hEvent, cSLEEPERWSO )
  EndIf  
'  print "SETDTR OK",
  EscapeCommFunction( h, SETDTR )  
  Print #iFileNum,Using "########.####";Timer  
  If cWSO Then
    Sleep cSLEEPER
  Else  
    WaitForSingleObject( hEvent, cSLEEPERWSO )
  EndIf  
'  print "CLRDTR OK",
  EscapeCommFunction( h, CLRDTR )
  'Print #iFileNum,"?"
'''
'/'  
  If cWSO Then
    Sleep cSLEEPER
  Else  
    WaitForSingleObject( hEvent, cSLEEPERWSO )
  EndIf  
'  print "SETRTS OK",
  EscapeCommFunction( h, SETRTS )
  If cWSO Then
    Sleep cSLEEPER
  Else  
    WaitForSingleObject( hEvent, cSLEEPERWSO )
  EndIf  
'  print "CLRRTS OK"
  'Print "-"
  EscapeCommFunction( h, CLRRTS )
''/  
Next i
dTmr1=Timer
close iFileNum
Print "Finished. Sleeping.",(dTmr1-dTmr0),(dTmr1-dTmr0)/cLOOPS
Sleep
End
eh:
Dim As Integer iERR_TRAPPED = Err
Print Err, iERR_TRAPPED
Sleep
End
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear nobozoz,

Thany you very much for you code. I compiled it (FB/Win32) and got the (expected) results as folows.
iFileNum= 1
Status Seq COMn COMSTAT
Found: 1 COM2 0
sLastComInit= COM2:2400,N,8,1,RS,DS0,CS0,CD0
iFileNum 1
Opened:COM2:2400,N,8,1,RS,DS0,CS0,CD0: OK 0
iEscapeComm: 1
CLRDTR OK
cWSO, cSLEEPERWSO, cSLEEPER 1 10 10
Finished. Sleeping. 43.7501595144156 0.109375398786039

After run, my program runs too, as "usually" when something accessed the serial port before...
I then had the idea to copy your code into the Function FF_WINMAIN (which is a form itself) but nothing changes - worst, it aborts seconds after started. If I set a command Exec ("FB_Com_Test.exe") into this form, my program runs correctly.
So, I'm going to write something short, inspired from your code, to hide the console window and check faster (if possible).
This is not a very clean or Orthodox solution (french expression), but until I find a better way to solve this problem, I can use the program and drive my relays (32 relays on 4 chained cards).
I'm now rather shure that the issue comes from Firefly. Should I move this post to "Projects-Firefly"?
All ideas remain welcome.
Best regards,
Yvan.
PaulSquires
Posts: 1002
Joined: Jul 14, 2005 23:41

Re: Problem accessing COM Port FreeBasic/Firefly

Post by PaulSquires »

Yvan wrote: I then had the idea to copy your code into the Function FF_WINMAIN (which is a form itself) but nothing changes - worst, it aborts seconds after started.
FF_WINMAIN is a not a form. Code in FF_WNMAIN is executed prior to any Form being created or shown. I would be interested in seeing exactly what you coded there. Maybe you should have put the code in the WM_CREATE of the main form in your program?
I'm now rather shure that the issue comes from Firefly. Should I move this post to "Projects-Firefly"?
Post the code of your FF_WINMAIN so I can see how it is affecting the functionality of FireFly as it progresses through program startup, executing FF_WINMAIN, and finally creating and showing the main form for the application. If it is a FireFly problem then I'll try to fix it for you. Thanks.
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear Paul,

First of all, thank you, and thanks to Marc Pons. You made a huge and amazing work for all of us.

Here is a part of code that should interrest you to help me. I snipped other functions because ther are quite the same and just differ in FOR - Next loops.
Forgive me for some "unclean" instructions; it' a long time I've programmed seriously and the first time I'm using API's.
I certainly missed something somewhere, but what?

Code: Select all

' ----------------------------------------------------------------
' FF_WinMain
' ----------------------------------------------------------------
Function FF_WINMAIN( ByVal hInstance     As HINSTANCE, _
                     ByVal hPrevInstance As HINSTANCE, _
                     ByRef lpCmdLine     As String, _  
                     ByVal iCmdShow      As Integer ) As Integer


   ' If this function returns TRUE (non-zero) then the actual WinMain will exit
   ' thus ending the program. You can do program initialization in this function.

Function = False    'return TRUE if you want the program to end.
' Display Welcome message
Message = " Welcome.  Change parameters if needed.   Click on ? for help."
FF_TextBox_SetText (HWND_FORM1_WARNING, Message)


myerror = Exec ("COMCHECK.exe", "")  ' Run this to "initilize" serial port, based on a post from "nobozoz"

' Set DEFAULT VALUES
RelPort = 2      ' COMn relays connected
CamPort = 3      ' COMm camera connected
TableRelay = 4   ' COM  a turntable is connected on relay#
Angle = 12.5     ' Angle to rotate the table
Lamps = 32       ' Number of lamps to switch ON/OFF and take oicture
Pictures = 30    ' Number of pictures to take when using the turntable
Delay = 5000     ' Duration of each lamps lighted, picture is taken at (duration * (4/5))
Maxcards = 4     ' Number of relays cards chained
Rotation = (60000/Lamps)  '  Check of angle to rotate the turntable
Break = 0        ' Switch to abort a sequence in case of emergency stop

'-------------- GetParameters ------------------------
f = Freefile

Open "Agora3D.prm" For Binary Access As #f
Close #f

Open "Agora3D.prm" For Input As #f
If LOF(f) = 0 Then
   myerror = 1
  Else
   Input #f, RelPort, CamPort, Lamps, Delay, Maxcards, TableRelay, Pictures
   Close #f
End If   

If RelPort < 1 Then
   myerror = 2
   RelPort = 1
End If
If CamPort < 1 Then
   myerror = 3
   CamPort = 1
End If
If ((Lamps < 1) Or (Lamps > 2040)) Then
   myerror = 4
   Lamps = 8
   MaxCards = 1
End If
If Delay < 2500 Then
   myerror = 5
   Delay = 5000
End If
If MaxCards > 255 Then
   myerror = 6
   MaxCards = 1
End If 

End Function

' -------------------------------------------------------------------------------------
' END WinMain
' -------------------------------------------------------------------------------------
' -------------------------------------------------------------------------------------
' FF_AppStart
' -------------------------------------------------------------------------------------

#Lang "FB"

#Include Once "windows.bi"
#Include Once "crt.bi         "  ' needed for FF_Parse library function
#Include Once "win\commctrl.bi"  ' needed for WinXP Theme support
#Include Once "win\commdlg.bi"
#Include Once "win\richedit.bi"
#Include Once "win\winspool.bi"
#Include Once "win\ole2.bi" 'BSTR with Function FBString_to_BSTR(mes As String)As BSTR
#Include "file.bi"
#Include Once "win\setupapi.bi"

        
'--------------------------------------------------------------------------------------------- 
'Place your defined: Declare, Constants, #Include below the line
'--------------------------------

Dim Shared f As Integer
Dim Shared RelPort As Integer
Dim Shared CamPort As Integer
Dim Shared Lamps As Integer
Dim Shared Delay As Double
Dim Shared Maxcards As Integer
Dim Shared Break As Byte
Dim Shared Pause As Byte
Dim Shared Change As Byte
Dim Shared NoParams As Byte
Dim Shared Erreur As Byte
Dim Shared Serial As String
Dim Shared Message As String
Dim Shared i As Integer
Dim Shared j As Integer
Dim Shared e As Integer
Dim Shared l As Integer
Dim Shared Total As Integer
Dim Shared Checksum As Integer
Dim Shared Msg As String
Dim Shared Outmsg As String
Dim Shared cmd As String
Dim Shared angle As Single
Dim Shared TableRelay As Integer
Dim Shared Rotation As Single
Dim Shared Pictures As Integer
Dim Shared myerror As Integer

Dim Shared hWndParent As hWnd
Dim Shared hWndFille As hWnd

' -------------------------------------------------------------------------------------
' END FF_AppStart
' -------------------------------------------------------------------------------------
' -------------------------------------------------------------------------------------
' FORM1
'  one Command button
' -----------------------------------------------------------------------------

Function FORM1_CHECKLAMPS_BN_CLICKED ( _
                                   ControlIndex     As Integer, _   ' index in Control Array
                                   hWndForm         As hWnd, _      ' handle of Form
                                   hWndControl      As hWnd, _      ' handle of Control
                                   idButtonControl  As Integer   _  ' identifier of button
                                   ) As Integer

Dim m As Integer
Dim n As Integer
Dim o As Integer
Dim Delai As Integer
Dim Total As Integer
Dim Checksum As Integer
Dim Msg As String
Dim Outmsg As String

disabuttons    ' call a sub to disable other command butons
 
RelPort = Val (FF_TextBox_GetText (HWND_FORM1_RelaysText))
Serial = "COM" + Str(RelPort) +  ":2400,n,8,1,RS,DS0,CS0,CD0"
Open Serial As #RelPort

For l = 1 To Maxcards         ' addressing all the cards one by one
    Total = 13 + l + Asc("S") + 57       ' compute a chacksum
    Checksum = 256 - (Total And 255)
    Msg = Chr(13) & Chr(l) & "S" & Chr(57) & Chr(Checksum)     ' create the command to send
    Outmsg = Msg
    For m = 1 To 4     ' According the documentation of the card: command should be repeated 3 or 4 times
        Outmsg = Outmsg + Msg
    Next
    Print #RelPort, Outmsg
    Message = " Lighting lamps on card # " & l
    FF_Control_SetText (HWND_FORM1_WARNING, Message)
    FF_DoEvents ()
    Sleep 250      ' wait 250 ms between two commands
Next

For n = 0 To 10
    If break = 1 Then    ' Check if button "Emergency STOP" was clicked
       Exit For
    End If
    If n > 0 Then   
       Sleep 1000
    End If   
    If break = 1 Then    ' Check if button "Emergency STOP" was clicked
       Exit For
    End If
    If (10 - n) = 1 Then
       Message = " Checking all lamps for 10 seconds...  " & (10 - n) & " second remaining."
      Else  
       Message = " Checking all lamps for 10 seconds...  " & (10 - n) & " seconds remaining."
    End If
    FF_Control_SetText (HWND_FORM1_WARNING, Message)
    FF_DoEvents ()
Next

Send ("E", 1, 1)   ' call a sub that computes a checksum and writes on serial port number RelPort to send a reset command to all the relay(s)
If break = 1 Then
   Message = " Emergency STOP, lamps check ABORTED."
   FF_Control_SetText (HWND_FORM1_WARNING, Message)
   FF_DoEvents ()
  Else 
   Message = " Lamps check done."
   FF_Control_SetText (HWND_FORM1_WARNING, Message)
   FF_DoEvents ()
End If

enabuttons     ' call a sub to enable other command butons

Break = 0
Send ("E", 1, 1)     ' call a sub that computes a checksum and writes on serial port number RelPort to send a reset command to all the relay(s)

Sleep 1000
Message = " "
FF_Control_SetText (HWND_FORM1_WARNING, Message)
FF_DoEvents ()

Close #RelPort

End Function
Thank you for the time you spend helping me.
Regards,
Yvan.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Problem accessing COM Port FreeBasic/Firefly

Post by D.J.Peters »

Code: Select all

f = Freefile
Open "Agora3D.prm" For Binary Access As #f
Close #f
Open "Agora3D.prm" For Input As #f

Code: Select all

f = FreeFile()
Open "Agora3D.prm" For Binary Access As #f
Close #f
f = FreeFile() ' <--- Is this are missing ?!?
Open "Agora3D.prm" For Input As #f
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear D.J.Peters,

Thank you.
f=Freefile works well without (). Parameters are correctly read and dispatched where they must be.
My problem is that the relays card(s) don't receive anything since I launch something else - out ouf my program - to access them.
Example:
Boot the computer, launch my application ... nothing.
Launch anything that addersses the serial ports (Port Monitor, RealTerm, the compiled code provided above by nobozoz,...) then run my program again and it works now.
Same on several other computers, were they WinXP or Win7.
I even tried using an old serial modem, chained with the cards and sending the command "AT" (hoping to receive an "OK" answer). But nothing, same results.
That's the mystery I'm facing.
For sure I forgot or missed something in Firefly, but what? I'm brand new with this GUI.
Maybe you wonder why two "Open". One as binary, the second for input.
This is my current way to handle errors. Open binary will create the file (size = 0) if not exists. Then Open for input doesn't give an error and I can check lenght of the file... This is my workaround to handle "missing file" and set default values. I have to practise and learn a lot about Firefly.

But thank you for your reply and your time.
Regards,
Yvan.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Re: Problem accessing COM Port FreeBasic/Firefly

Post by phishguy »

I see a couple of potential issues related to the file handle for the com port. First of all, in one portion of your program, you aren't closing a handle if you get an error.

Code: Select all

Open "Agora3D.prm" For Input As #f
If LOF(f) = 0 Then
   myerror = 1
  close #f 'add this
  Else
   Input #f, RelPort, CamPort, Lamps, Delay, Maxcards, TableRelay, Pictures
   Close #f
End If   
Second of all, I don't understand why you are using the same variable for the port and the port file handle in the following code. If the file handle is already opened previously it won't work. I suggest to use freefile at this point to get the file handle.

Code: Select all

 
RelPort = Val (FF_TextBox_GetText (HWND_FORM1_RelaysText))
Serial = "COM" + Str(RelPort) +  ":2400,n,8,1,RS,DS0,CS0,CD0"
Open Serial As #RelPort
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear phishguy,

Thank you. You put the finger on something I didn't notice: closing my file in the first case of the IF LOF(f)...
That's a stupid error of me.
I can also do this
Open ...As #f
if

else

end if
Close #f

For the second remark, I give the user the possibility to change or select another serial port on which the card(s) is (are) connected.
There is a textbox in FORM1 filled by the parameters read but the user can change it if the connexion is on COM1,2, 3, or xyz on his computer.
So, I get that text to open RelPort (Camport and TurnTable elsewhere in my program).
All this because there should be a camera connected on another port and possibly a slow turntable (1 rpm) on a third one.
Maybe you are right, I should fix all connections on Serial1, 2 and 3 once for all (should also be simpler).
But it works fine so ;-)

Regards,
Yvan.
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear all,

Don't worry if I don't reply to your posts until Oct, 6th.
I'm taking some hollidays, far from here, to disconnect a little from work and rest a little too.

Best regards to all of you,
Yvan.
Yvan
Posts: 9
Joined: Sep 23, 2013 12:56

Re: Problem accessing COM Port FreeBasic/Firefly

Post by Yvan »

Dear All,

I found a solution to my problem.
As I told, Open "Com" + str(RelPort) + ":2400,n,8,1" as #something worked if I first started some external program to access the serial port # RelPort.
Using Open Com "Com" + str(RelPort) + ":2400,n,8,1" as #something didn't generate a compiler error neither a warning but caused a program abort when launched.
Same using this syntax:
Serial = "Com" + str(RelPort)
Open Serial + ":2400,n,8,1" as #something or Open Com Serial + ":2400,n,8,1" as #something

I finally tried this:
Serial = "Com" + str(RelPort) + ":2400,n,8,1"
Open Com Serial as #something
This works fine.

Many thanks to all of you who read my post and tried to help me and/or spent time to try understanding the problem.
Best regards,
Yvan.
Post Reply