Announcement

Collapse
No announcement yet.

Serial port

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Serial port

    Hi all,
    I'm converting an old app from QB45 to PBWin, and have been fairly successful so far, with one exception - trying to send a short text string to a serial port.
    The string is sent to "wake up" a device connected to COM1.

    The computer has been upgraded from DOS6.22 to XP/SP3, and the old DOS app no longer works, hence the rewrite.

    I can use Hyperterminal (not running at the same time as PB!) etc, set to 9600 baud/8/N/1 on COM1, type in the string SINAR, hit Enter, and it works every time.
    No luck in PB. The answer is probably fairly simple, but I couldn't see anything obvious in the help.

    All it has to do is open the port, send the string, then close the port.
    No other apps are running.

    Code:
    Code:
    SUB SerialSend
    
    LOCAL ComChannel AS INTEGER
    LOCAL ComPort AS STRING
    
    'open the comm port and send the string "SINAR" to it
    ComChannel = FREEFILE
    ComPort = "COM1"
    COMM OPEN ComPort AS ComChannel
    COMM SET ComChannel, BAUD     = 9600   '9600 baud
    COMM SET ComChannel, BYTE     = 8      '8 bits
    COMM SET ComChannel, PARITY   = 0      'No parity
    COMM SET ComChannel, STOP     = 0      '1 stop bit
    COMM SET ComChannel, TXBUFFER = 4096   '4 Kb transmit buffer
    COMM SET ComChannel, RXBUFFER = 4096   '4 Kb receive buffer
    COMM PRINT ComChannel,"SINAR"
    
    'Temporary line - show a message box to see if we have an error
    MSGBOX ERROR$(ERRCLEAR),,"Sending"
    '
    '*** Message box displays "No Error" ***
    '
    
    'Finished - close the serial port
    COMM CLOSE ComChannel
    
    END SUB
    The messagebox displays "No Error".
    Any help on this one gratefully appriciated.

  • #2
    Try setting the Hardware flow and XON/XOFF to off.

    COMM SET #hComm, XINPFLOW = 0 ' Disable XON/OFF
    ' input flow control
    COMM SET #hComm, XOUTFLOW = 0 ' Disable XON/XOFF
    ' output flow control
    COMM SET #hComm, CTSFLOW = 0 ' disable CTS
    COMM SET #hComm, RTSFLOW = 0 ' disable RTS

    Also send a Null char before sending any other text.
    COMM PRINT #hComm, $NUL ; 'Note the ; (no CRLF)

    Comment


    • #3
      Hi Klaus,
      I tried disabling CTS and RTS, although these are not connected (it's using a 3-wire serial cable).
      Turning off input and output flow control, as well as sending a null char, had no effect.

      I tried two other comms programs (Procomm and TeraTerm) set to 9600 baud/8/N/1, with the same result - they work first time, unlike my app that refuses to cooperate.

      Regards, Chris

      Comment


      • #4
        Maybe you have to wait for the transmit buffer to be empty before closing the comm port?

        If PB just places the transmit string into the tx buffer then leaves it do its own thing, it is possible the comm close command could occur before the transmission has begun, and therefore cut it short. At 9600 baud 5 char transmission would take about 5 ms, a long time. Try a small delay before closing the comm port, or check the comm port tx buffer for it to become empty. The delay is probably the easiest, ie sleep 1000.

        Hopefully this helps - but I do not know the inner workings of PB.
        ========================================
        Program testing can be a very effective way to show the presence of bugs,
        but it is hopelessly inadequate for showing their absence. Edsger W. Dijkstra
        ========================================

        Comment


        • #5
          Tried both:

          Code:
          LOCAL TxBytes AS LONG  
          
          <rest of code>
          
          COMM PRINT ComChannel,"SINAR" 
          
          DO
          TxBytes = COMM(ComChannel, TXBUFFER) - COMM(ComChannel, TXQUE)
          LOOP UNTIL TxBytes = 0
          
          SLEEP 1000
          This should wait 1 second after the tx buffer has emptied, but still no go

          Regards,
          Chris

          Comment


          • #6
            Try using the Comm.bas prog at Samples\Comms directory
            "The trouble with quotes on the Internet is that you can never know if they are genuine." - Abraham Lincoln.

            Comment


            • #7
              I changed the sample program to the correct baudrate etc, and it half works.
              I can see the boot message from the device, so the PC is receiving OK.
              However, the sample program cannot transmit information that the serial device recognizes.
              As Hyperterminal etc works OK with the serial device, it's fairly safe to assume the device, cable, and serial port are all OK.

              Regards,
              Chris.

              Comment


              • #8
                The Comm.bas sample sends a cr/lf at the beginning - comment this line and see if it works
                "The trouble with quotes on the Internet is that you can never know if they are genuine." - Abraham Lincoln.

                Comment


                • #9
                  Hi Chris

                  I have just tested the following code which is a cut down taken from the comms.bas program recommended by Arthur. I tested the bare minimum, on "COM1" which is a hardware serial port on my computer, then on "COM5" which is a Virtual Com port through an FTDI USB to Serial converter, then on "COM100" which is the same USB converter shifted to Virtual Com Port 100, and they all transmit correctly.

                  It does not require the delay that I originally suggested, as I slowed it down to 1200 baud with 50 bytes to TX and still pushed out all the data, so my assumption that it may terminate the TX was false.

                  In this little test I did not assert any control signals.
                  The only comm setting was the baud rate.


                  Can you jumper pins 2 and 3 of the DB9 connector, and run the full comms.bas program suggested by Arthur in the samples directory, as it will echo anything back to the screen that you enter


                  Regards

                  Gordon Slater

                  PS I sent you a private message regarding terminal programs.








                  #Compile Exe

                  #Dim All

                  #Include "WIN32API.INC"

                  Global hComm As Long

                  Function PBMain

                  hComm = FreeFile

                  '----------------------------------- if using above port 9 then use this 'command with the correct port number to replace 100
                  ' Comm Open "\\.\COM100" As #hComm
                  '-----------------------------------

                  Comm Open "COM1" As #hComm
                  ' Comm Open "COM5" As #hComm

                  If ErrClear Then
                  MsgBox "Error opening comm port"
                  Close #hComm
                  ' Port problem?
                  Else

                  Comm Set #hComm, Baud = 9600
                  'Comm Set #hComm, Baud = 1200

                  'Comm Set #hComm, DtrFlow = 1 ' Enable CTS flow control

                  'Comm Set #hComm, RtsFlow = 1 ' Enable RTS flow control

                  'Comm Set #hComm, XInpFlow = 0 ' Disable XON/OFF Input

                  'Comm Set #hComm, XOutFlow = 0 ' Disable XON/XOFF output

                  Comm Print #hComm,"12345678901234567890123456789012345678901234567890"

                  ' Sleep 5000


                  Close #hComm
                  ' msgbox "finish"

                  End If





                  End Function








                  ' Minimum recommended settings

                  'Comm Set #hComm, Baud = 9600 ' 9600 baud

                  'Comm Set #hComm, Byte = 8 ' 8 bits

                  'Comm Set #hComm, Parity = %FALSE ' No parity

                  'Comm Set #hComm, Stop = 0 ' 1 stop bit

                  'Comm Set #hComm, TxBuffer = 2048 ' 2 Kb transmit buffer

                  'Comm Set #hComm, RxBuffer = 4096 ' 4 Kb receive buffer



                  ' Optional settings for flow control

                  'Comm Set #hComm, CtsFlow = 1 ' Enable CTS flow control

                  'Comm Set #hComm, RtsFlow = 1 ' Enable RTS flow control

                  'Comm Set #hComm, XInpFlow = 0 ' Disable XON/OFF Input

                  ' flow control

                  'Comm Set #hComm, XOutFlow = 0 ' Disable XON/XOFF output

                  ' flow

                  'When we have finished using our communication channel, we can terminate it using the COMM CLOSE function:

                  'Comm Close #hComm



                  ========================================
                  Program testing can be a very effective way to show the presence of bugs,
                  but it is hopelessly inadequate for showing their absence. Edsger W. Dijkstra
                  ========================================

                  Comment


                  • #10
                    Hi ,
                    Tried that, without success.

                    However, I found some code by Gary Peek, from way back in 2004,while searching the forums for a solution. His code worked!

                    Unfortunately it's relatively complex code (multiple windows, file I/O, etc) so it could take a while to work my way through it to find out why his code works, and why mine and the comms example doesn't. At least not I can be sure it's not a PB issue, not that I ever had thoughts along those lines.

                    Regards

                    Comment


                    • #11
                      Hi Gordon,
                      Got your PM (and replied) OK.

                      Your code has no effect on the hardware, however. I'm looking at the one I mentioned before (from 2004) that does work to see if I can find why his works and nothing else in PB does.

                      The "device" in question is a direct connection to a real serial port, via a 3 wire cable. It works fine in any DOS or Win comms app.

                      If you are familiar with embedded hardware, it's connected to the serial port of an Atmel controller via one of those little Maxim level shifting ICs, either a MAX202 or a MAX232 from memory.

                      Regards

                      Comment


                      • #12
                        You can try the Mr. Peek's SENDPORT prog.
                        "The trouble with quotes on the Internet is that you can never know if they are genuine." - Abraham Lincoln.

                        Comment


                        • #13
                          Hi Chris

                          I connected up two computers, using the little program I sent you, and monitored on the other computer with DockLight. I also used a scope to monitor the signals.

                          The PC with DockLight receives all OK, except that PB appears to add <CR><LF> to the end of line sent by COMM PRINT.

                          Is the added <CR><LF> affecting the serial device (ATMEL). Have you written the ATMEL program? How does it delimit messages. Some people (like me) just use <CR> OR <LF>, not both - I cannot remember which, so if it is only looking for an <LF> then that could confuse the ATMEL. Depending upon how the terminal programs (hyperterminal) are setup, it could affect the EOL transmission. I never use the dual <CR><LF> myself, but only the <LF> as far as I can remember, but I would have to check one of my programs. ie if the terminal program (Hyperterminal) is setup to send only <LF> yet PB is sending <CR><LF>, you could have a problem as to why the Hyperterminal works but PB does not (from the ATMEL point of view), and I don't (yet) know how to suppress that in PB. I will be using PB as my "PC user interface" to the embedded ATMEL , but have only just started working with PB. I will therefore also need to communicate using the serial port, most likely a Virtual Comm Port using the Windows comm port or using a DLL from FTDI to drive their USB to serial chips. I have been using ATMEL for about 10 years. I tested the serial ports (Virtual Comm Ports up to 100).

                          Yes I do know the ATMEL AVR reasonably well, and my work appears similar to yours in that I do industrial control/logging, using the PC to interface to an MEGA128 and soon the MEGA2560 in the embedded system. I write all the code in the ATMEL. I am more familiar with hardware and embedded programming than with Windows programming, at which I am a novice.

                          I just worked it out how to suppress the <CR><LF> and tested it.

                          - the next two lines will send SINAR<LF>
                          Comm Print #hComm,"SINAR";
                          Comm Print #hComm,Chr$(10) ;

                          - the next two lines will send SINAR<CR>
                          Comm Print #hComm,"SINAR";
                          Comm Print #hComm,Chr$(13) ;

                          - the next one line will send SINAR<CR><LF>
                          Comm Print #hComm,"SINAR"


                          Hope this helps - it has helped me as I needed to work out how to suppress the <CR>


                          There is a bit of repetition in the above messages - apologies for that!
                          But it is almost 1 early Monday morning here.

                          Regards

                          Gordon Slater
                          ========================================
                          Program testing can be a very effective way to show the presence of bugs,
                          but it is hopelessly inadequate for showing their absence. Edsger W. Dijkstra
                          ========================================

                          Comment


                          • #14
                            Hi,
                            Thanks again for the reply, I'll have a look at it in the morning, as its gone past 1AM here and I need my shuteye...

                            The controller, by the way, is a commercially made unit, I don't have any code for it (source or compiled), just a schematic (circuit) diagram and a programming manual.

                            Will try your suggestions in about 8 hours, when I get up - its the labour day public holiday here (Melbourne, Australia) on Monday.

                            Regards

                            Comment


                            • #15
                              Had a similar problem once using a "light weight" Atmel AT90S2313 - I set the TXbuffer to 256 bytes (PBWin 7).

                              Also try and set the file handle as a global and set it only once in PBmain:
                              ComChannel = FREEFILE

                              I normally declare the filehandle as a long (or Dword) i.s.o an integer.

                              Gordon could have a point there with CF & LF thing.
                              If the AVR chip terminates the string after a CR and a CRLF was sent then then LF will remain in the UART buffer (of the AVR) and the next incoming string would have a LF attached as the leading byte.

                              Have a relaxing holiday tomorrow.

                              Comment


                              • #16
                                Have you issued a Comm Reset {port handle}, Flow? Here is code that I used to open a 9600 Baud connection to a hardware device and it works well.

                                Code:
                                ' Open a Serial Port: Returns handle to opened port.
                                Function OpenSerPort(ByVal cPort As Dword) As Dword
                                 
                                   Local hPort As Dword
                                   Local cStr  As String
                                 
                                   ErrClear  ' Clear any existing errors
                                 
                                   If cPort < 1 Then Exit Function  ' Invalid Port
                                 
                                   cStr = "COM" & Format$(cPort)
                                 
                                   hPort = FreeFile
                                 
                                   Comm Open cStr As hPort
                                 
                                   If ErrClear Then Exit Function  ' Oops!  Couldn't Open the port
                                 
                                   Comm Reset hPort, Flow        ' Disable ALL Flow Control to Port!
                                 
                                   Comm Set hPort, Baud = 9600   ' 9600 Baud
                                   Comm Set hPort, Byte = 8      ' 8 Bits (8/N/1)
                                   Comm Set hPort, Parity = 0    ' None (8/N/1)
                                   Comm Set hPort, Stop = 0      ' 1 Stop Bit (8/N/1)
                                   Comm Set hPort, RxBuffer = 4096 ' 4K
                                   Comm Set hPort, TxBuffer = 2048 ' 2K
                                 
                                   ' No Flow Control at all
                                   Comm Set hPort, CtsFlow = 0   ' No CTS
                                   Comm Set hPort, RtsFlow = 0   ' No RTS
                                   Comm Set hPort, XInpFlow = 0  ' XON/XOFF Inbound Disabled
                                   Comm Set hPort, XOutFlow = 0  ' XON/XOFF Outbound Disabled
                                 
                                   ' 
                                   '
                                   'if WinXP then
                                   '   APIhCOM&=FileAttr(hPort,2)
                                   '   LL&=EscapeCommFunction(APIhCOM&,%CLRBREAK)
                                   'end if
                                 
                                   Function = hPort   ' Return handle to caller
                                 
                                End Function
                                Scott Slater
                                Summit Computer Networks, Inc.
                                www.summitcn.com

                                Comment


                                • #17
                                  Serial port

                                  Hi Chris,

                                  I have now tested HyperTerminal, and by default it does NOT attach a <LF> to the message unless explicitly requested to under

                                  File ->Properties -> Settings -> ASCII setup -> Send line ends with line feeds.

                                  (Using DOCKLIGHT on the second PC to monitor exactly what gets sent out)

                                  Your COMM PRINT CommChannel,"SINAR" will send a <CRLF> unless you block it using a semicolon. then adding your own COMM PRINT CommChannel,chr$(13); 'don't forget the semicolon on this line also

                                  So to be compatible to what Hyperterminal is sending by default

                                  COMM PRINT CommChannel,"SINAR";
                                  COMM PRINT CommChannel,CHR$(13);




                                  Note both command lines must end with semicolons else you will send
                                  "SINAR<CR><LF><CR>"
                                  when you may only want
                                  "SINAR<CR>"


                                  I checked one of my programs and I only use a <CR> to terminate lines, not the <CRLF>. As mentioned in an earlier post I could not remember if I used <LF> OR <CR> but it is only <CR> - just like the Hyperterminal default.

                                  I am using XP Professional Edition SP3

                                  Regards

                                  Gordon Slater
                                  ========================================
                                  Program testing can be a very effective way to show the presence of bugs,
                                  but it is hopelessly inadequate for showing their absence. Edsger W. Dijkstra
                                  ========================================

                                  Comment


                                  • #18
                                    Hi Chris

                                    A mistake in my earlier post


                                    Note both command lines must end with semicolons else you will send
                                    "SINAR<CR><LF><CR>"
                                    when you may only want
                                    "SINAR<CR>"
                                    The above code should read as below


                                    Note both command lines must end with semicolons else you will send
                                    "SINAR<CR><CR><LF>"
                                    when you may only want
                                    "SINAR<CR>"

                                    regards

                                    Gordon Slater
                                    ========================================
                                    Program testing can be a very effective way to show the presence of bugs,
                                    but it is hopelessly inadequate for showing their absence. Edsger W. Dijkstra
                                    ========================================

                                    Comment


                                    • #19
                                      Hi Gordon,
                                      I put this one on hold for a day to make up a dummy terminal that is a bit more convenient and a bit safer than having a full blown controller on the desk.
                                      Finished it tonight - a MEGA8, a MAX232, and a few LEDS / switches in a box about the size of a cigarette packet. Runs off a 4.8V internal rechargeable battery...

                                      I'm a lot more comfortable coding these than I am in PB.

                                      It has exactly the same issues as the "big" controller - works fine in any terminal program, and very hit and miss (mostly miss) in my PB app.

                                      I'll have a look at all your suggestions and the app of Gary Peek's tomorrow, and hopefully find out where I'm going wrong.

                                      Thanks very much for the info, I'll let you know how I got on in a day or so.

                                      Regards,
                                      Chris

                                      Comment


                                      • #20
                                        Serial Port

                                        Hi Chris

                                        A possible difference between using a terminal program and PB is that a terminal program, unless you have the facility to transmit strings in one shot, will send out the characters individually as you type, whereas PB will burst the string in about 6 ms.

                                        Try putting a gap between each byte when transmitted by PB and vary the sleep time in order to emulate the terminal program.


                                        Comm Print #hComm,"S";
                                        Sleep 1000
                                        Comm Print #hComm,"I";
                                        Sleep 1000
                                        Comm Print #hComm,"N";
                                        Sleep 1000
                                        Comm Print #hComm,"A";
                                        Sleep 1000
                                        Comm Print #hComm,"R";
                                        Sleep 1000
                                        Comm Print #hComm,chr$(13);
                                        Sleep 1000


                                        I don't know if Hyperterminal allows sending predetermined sequences, the terminal program I use allows you to set up a whole heap of strings and send them out by double clicking on a string in a list box.

                                        Now to clutch at a few straws -

                                        I guess you have tried changing the rs232 cable. This is a long shot, but if the for example the ground is bad, sending character by character may get through, but strings because of their length can cause some undesirable and unpredictable level shifting, and corrupt the string, which appears to be happening to you, as you say it sometimes gets through with PB, but always gets through with a terminal program.

                                        regards

                                        Gordon Slater
                                        ========================================
                                        Program testing can be a very effective way to show the presence of bugs,
                                        but it is hopelessly inadequate for showing their absence. Edsger W. Dijkstra
                                        ========================================

                                        Comment

                                        Working...
                                        X