Shop OBEX P1 Docs P2 Docs Learn Events
VB.net to Prop communication — Parallax Forums

VB.net to Prop communication

ShawnaShawna Posts: 508
edited 2013-01-09 16:26 in Propeller 1
Does anyone have any good links for VB.net tutorials? I want to write a quick debugging program to receive data from a Prop. I am using PST right now and I would like to arrange the data into a little more user friendly format for viewing. I am working on a quadcopter control board and the PST is not getting it done. I took 2 semesters of VB6 back in school but I am pretty rusty I found. Is there an easier language to play with? I found a tutorial on you tube for serial com ports that I followed and it works, but I am not sure how to break up the received data on the vb.net side. I need to start with the basics I think. VB for dummies maybe in my future, ha ha. I wouldn't mind playing with C a little since that can be used to program all kinds of micro controllers. Is C easier to learn than VB?
Thanks
Shawn

Comments

  • ShawnaShawna Posts: 508
    edited 2013-01-06 19:33
    Some how I managed to post this twice, is there a way to delete one of these posts?
    Shawn
  • Cluso99Cluso99 Posts: 18,069
    edited 2013-01-06 21:10
    Just edit your first post (provided noone has posted a reply) using the advanced option and you can delete it (here to also change the title)

    DrAcula probably has done this. VB6 would be much easier for you I think and it has been done here somewhere. If not, I can dig out a VB6 program that uses the serial port from my backups.

    Please don't start the C vs VB debate ;)
  • jmgjmg Posts: 15,173
    edited 2013-01-07 01:34
    Shawna wrote: »
    ... and I would like to arrange the data into a little more user friendly format for viewing.

    What sort of data, and what does 'arrange' mean ?

    Depending on exactly what that statement means, you could look along the lines of the basics that come with Open Office Spreadsheets etc.

    A quick google gives this
    [Solved] Macro to read serial port and write to OOo Calc
    http://forum.openoffice.org/en/forum/viewtopic.php?t=30999

    Another pathway, for long-graph multi-line style Data is to stream into a formatted .RAW file, which is the format used by LTSpice et al.
    Then you load that file, using LTSpice as the Graphical viewer.
  • ShawnaShawna Posts: 508
    edited 2013-01-07 09:16
    Lets say I have 20 longs in my Spin program that I want to continually monitor, write now I am sending these 20 longs out with P.S.T object to the Parallax Serial Terminal. It just makes a mess with 20 variables being splatted all over the window. All I want to do for now, is take those 20 longs and put each one in a text box or some thing to break them up and put a label next to the text boxes so I know what I am looking at. I know I could format that within the Prop but I don't want to waste the resources trying to format the P.S.T. window. I have 1 cog running constantly dumping those 20 longs to the pc. I think I am going to lean towards C since it can be applied to more things that I work on.
    Thanks
    Shawn
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2013-01-07 09:55
    Hi if you have VB .Net installed already I could help with the serial interface, plus wanting to go from Vb .net to C# or visa versa is not a big deal as apart from the syntax the code of each is virtually identical.

    I could also help to integrate the Propellent Dll into your application which you might find to be useful.

    Jeff T.
  • ShawnaShawna Posts: 508
    edited 2013-01-07 10:46
    Hi, Jeff
    What is the Propellent Dll?
    Shawn
  • ShawnaShawna Posts: 508
    edited 2013-01-07 10:49
    Is the Propellent DLL kind of like a plugin for windows based programs? I know what a DLL is but not how to use one. I read that with the Propellent DLL one does not need to use the Propeller Tool to load software to a prop, that is pretty cool. Is that something that can be used with visual studios?
    Shawn
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2013-01-07 11:14
    Is that something that can be used with visual studios?

    Yes it sure is whether your using C# or Vb .Net. This link has the Dll and documentation regarding the Propellent Library http://www.parallax.com/tabid/832/Default.aspx

    If you are using the Proptool then you already have the DLL

    Jeff T.
  • cavelambcavelamb Posts: 720
    edited 2013-01-07 14:44
    Hi Shawna,

    Read down to the very end of this and find PST.PX() and PST.PY()
    A screen for 20 variables shouldn't be a problem.


    Richard


    PST.Methods:
    The following are some of the more useful methods found in the Propeller Serial Terminal File (PST for short?)
    [h=2]START[/h]The start method will be found in most objects as it is used to launch the object in a different cog. It is also used to pass I/O or configuration.
    PST.start(9600) ‘ start serial terminal at 9600 baud
    PST.start(12)
    PST.start(my_variable,my_variable2)

    [h=2]STOP[/h]The stop method stops the object and frees the cog.
    [h=2] [/h][h=2]INIT[/h]The init method sets up variables for objects that don’t use their own cog. It is used instead of start in those instances.
    (Some objects may require a call to init before calling start. Any necessary set-up calls will be clearly described in the object’s source file).

    [h=2]STR [/h][h=2]The str method displays text or the contents of a variable or array.[/h]PST.str(string(“Display a line of text”))
    PST.str(string(“Display a line of text with a carriage return”,13))
    PST.str(my_multibyte_variable)
    PST.str(@my_variable_array)
    PST.str(@my_variable_array[X])


    [h=2]
    DEC [/h][h=2]The dec method display variables as a decimal numbers.[/h]PST.dec(my_variable)


    [h=2]
    HEX [/h][h=2]The hex method displays a variable in hexadecimal. [/h]The second item (2 in this example) tells how many places to display.
    PST.hex(my_variable,2)


    [h=2]
    BIN [/h]The bin method displays a variable in binary.
    The second item is the number of digits to
    PST.bin ( some_variable, 8 )

    [h=2]OUT (or TX)[/h]The PST.out (sometimes called .tx) method will be found in various display and communication objects to handle serial communications.

    For video drivers out( ) should interpret the variable instead of displaying the character itself. For example: out ( $08 ) would cause a backspace, instead of displaying the box corner character.


    [h=2]NEWLINE[/h]The PST.newline method sends a carriage return.
    Same function as pst.out ( 13 ) or out ( $0D ).
    As you can see there are a lot of useful methods in the Serial Terminal program. And, as your programs become more involved you will find this tool to be a life saver.



    For control of the screen layout ASCII control codes can be defined and used with the Parallax Serial Terminal.

    Define these in the CON section

    HM = 1 'HM: HoMe cursor
    PC = 2 'PC: Position Cursor in x,y
    ML = 3 'ML: Move cursor Left
    MR = 4 'MR: Move cursor Right
    MU = 5 'MU: Move cursor Up
    MD = 6 'MD: Move cursor Down
    BP = 7 'BP: BeeP speaker
    BS = 8 'BS: BackSpace
    TB = 9 'TB: TaB
    LF = 10 'LF: Line Feed
    CE = 11 'CE: Clear to End of line
    CB = 12 'CB: Clear lines Below
    NL = 13 'NL: New Line
    PX = 14 'PX: Position cursor in X
    PY = 15 'PY: Position cursor in Y
    CS = 16 'CS: Clear Screen
    To use, simply add a line to your code like…

    PST.CS clear the screen
    PST.NL move to the next line
    PST.PX(10) move the cursor to column 10
    PST.PY(10) move the cursor to line 10
    PST.TB move cursor to the next tab stop
    Click the "Prefs..." button in Parallax Serial Terminal and then click the "Function" tab in the Preferences dialog box, you can view/select the ASCII control characters it recognizes.
  • ShawnaShawna Posts: 508
    edited 2013-01-08 18:31
    OK,
    I am still struggling with this guys and I thank you all for your input so far. I am way off on a tangent here, and off coarse from my original project which is the quadcopter. But everything is a learning process so I am going to continue on this vb.net thing. I have written a basic spin program to send 2 longs out the serial port any time an "a" is received on the Props Serial Port. This works well enough for now. Here is the code, it is very simple.
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    MHZ = 80
    obj
    PST : "Parallax Serial Terminal"
    var
    long IN
    PUB Debug
    PST.Start(115_200)
    repeat
    IN:=PST.CharIn
    If In == "a"
    PST.Bin(1,32)
    PST.NewLine
    PST.Bin(2,32)

    Now, I realize that this is not a VB forum but you guys are very helpful. This is the code I have for VB and it works but it throws everything into 1 rich text box and for the life of me I can not figure out how to separate the data.
    I can't even figure out how to manipulate this code to display it as integer instead of a string. I do not understand delegates and it seems like I have to do that in order to read the serial input buffer. I even added a button so that when it is pressed vb sends an "a" to the prop which tells the prop to send its data, and it works. How ever it still just dumps it into a rich text box. The rich text box is all I have on the form, but I tried to dump the receive buffer into a array and from there I was going to add more text boxes. I failed at the array and I am stuck. I posted a question on one of the VB forums and my lack of terminology and knowledge of VB sank me. I have attached my VB file if anyone is board and would be willing to look at it.
    Thanks Shawn

    Serial Com1 Test1 VB.zip
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2013-01-09 04:11
    Some useful vb.net serial code.

    1) at the beginning
    Imports System.IO
    Imports System.Windows.Forms
    Imports System.IO.Ports
    Imports Strings = Microsoft.VisualBasic ' so can use things like left( and right( for strings
    

    2) In the main form declare the serial port and also a couple of global arrays and also the sleep statement and a few global parameters for the serial port. (You can declare some of these in the object on the screen or in code)
    Public Class Form1
        Dim WithEvents SerialPortName As New IO.Ports.SerialPort ' generic serial port
        Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Integer) ' for sleep statements
        Dim InPacket(0 To 2000) As Byte ' Major bug with serial.write strings like chr(255) won't go out
        Dim OutPacket(0 To 2000) As Byte
        Public SerialPortFound As Boolean = True
        Public Baud As String
        Public ComPort As String
    

    3) When the form first loads, set some of these values
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Timer1.Interval = 150 ' check for new characters every 150ms
            ComPort = "COM1" ' can change later if needed
            Baud = 115200
    

    4) A useful routine to reset the propeller if you happen to be using the same port for downloading
        Sub ResetPropeller()
            SerialPortName.PortName = ComPort
            SerialPortName.Open()
            SerialPortName.DtrEnable = False
            SerialPortName.DtrEnable = True ' toggle the dtr line
            SerialPortName.DtrEnable = False
            SerialPortName.Close()
        End Sub
    

    Add a timer, and the code from the form1 load will set it to check for port updates every n milliseconds (I set it at 150 milliseconds) and then call this routine to collect any bytes. This is for a simple terminal program - I think you have something similar already working adding things to a richtext box. Further down we can input the data into the array and feed it into other things such as a string, or convert it to data. (try typing "strings." and you can see all the things the strings class can do, like convert strings to numbers and vice versa)
       Private Sub UpdateTerminal()
            Dim BytesToRead As Integer
            Dim i As Integer
            Dim Character As String
            ' called from the timer
            BytesToRead = SerialPortName.BytesToRead
            If BytesToRead > 2000 Then BytesToRead = 2000
            SerialPortName.Read(InPacket, 0, BytesToRead) ' read in a packet
            For i = 1 To BytesToRead
                Character = Strings.Chr(InPacket(i - 1))
                If Character <> Strings.Chr(10) Then ' otherwise double space
                    RichTextBox8.AppendText(Character) ' add to the rich text box
                End If
            Next i
        End Sub
    

    This is an example of reading in some bytes. Borrowed from the catalina driver. Discard the bits you don't need. This "runs" a program on the propeller and so it is useful to see this happening. I've left in bits you won't need as it shows a method of collecting text that may not arrive in the time you expect it to, and moving that text from the input buffer into a string and then into a label on the screen. I think these are some of the processes you are looking to use. There are little tricks like "doevents" that force an update of the label as sometimes the data is actually in a textbox or a label but it isn't being refreshed.
            Dim i As Integer
            Dim c As String
            Dim BytesToRead As Integer
                SerialPortName.BaudRate = 38400 ' catlyst2 talks at 38400 baud
                SerialPortName.Open()
                Label1.Text = "Running catlyst2.exe"
                System.Windows.Forms.Application.DoEvents() ' display on screen
                Sleep(4000) ' time to start up catalyst
                Label1.Text = ""
                Do
                    If SerialPortName.BytesToRead = 0 Then Exit Do ' no more bytes
                    BytesToRead = SerialPortName.BytesToRead
                    If BytesToRead > 2000 Then BytesToRead = 2000
                    SerialPortName.Read(InPacket, 0, BytesToRead) ' read in a packet
                    For i = 1 To BytesToRead
                        c = Strings.Chr(InPacket(i - 1))
                        If Strings.Asc(c) > 32 Then Label1.Text += c
                    Next i
                Loop
                System.Windows.Forms.Application.DoEvents() ' display on screen
                LineOfText = UCase(filename_noextension) + vbCr ' and run the program
                Call StringToPacket(LineOfText) ' talk to catalyst and run this program
                Label1.Text += LineOfText ' display on screen
                System.Windows.Forms.Application.DoEvents() ' display on screen
                SerialPortName.Close()
    

    Sometimes you might want to clear the input buffer
        Sub ClearInputBuffer()
            ' eg for running pip no need to display all the background information
            Dim BytesToRead As Integer
            Dim i As Integer
            Dim Character As String
            If SerialPortFound = True Then
                Do
                    If SerialPortName.BytesToRead = 0 Then Exit Do ' no more bytes
                    BytesToRead = SerialPortName.BytesToRead
                    If BytesToRead > 2000 Then BytesToRead = 2000
                    SerialPortName.Read(InPacket, 0, BytesToRead) ' read in a packet
                    For i = 1 To BytesToRead
                        Character = Strings.Chr(InPacket(i - 1))
                        'Call DisplayCharacter(Character)
                    Next i
                Loop
            End If
            System.Windows.Forms.Application.DoEvents() ' update the display
        End Sub
    


    Routine to test a port is actually available
        Sub TestComPort()
            MsgBox("Com port " + ComPort + " Baud " + Baud + " trying to open...")
            Try
                SerialPortName.PortName = ComPort
                SerialPortName.BaudRate = Baud '38400
                SerialPortName.Parity = IO.Ports.Parity.None ' no parity
                SerialPortName.DataBits = 8 ' 8 bits
                SerialPortName.StopBits = IO.Ports.StopBits.One ' one stop bit
                SerialPortName.Open()
                SerialPortName.Close()
                MsgBox("Success")
            Catch ex As Exception
                MsgBox("Fail")
            End Try
        End Sub
    

    Routine to display ports you actually have
        Sub PortsAvailable()
            Dim ports As String() = SerialPort.GetPortNames()
            Dim PortsAvailable As String
            ' Display each port name to the console.
            Dim port As String
            For Each port In ports
                PortsAvailable += port + " "
            Next port
            MsgBox(PortsAvailable)
        End Sub
    

    Warts and all, this is a routine to send a file to a propeller chip running Kyedos (a simple operating system). It uses the xmodem protocol and illustrates all the error checking and timing hacks needed to get reliable data comms. Maybe there are some bits of code you can use for other things?
        Sub XModemKyeSend(ByRef FName As String, ByVal Delay1 As Integer)
            Dim Filenamepath As String
            Dim a, j, i As Integer
            Dim k As Integer
            Dim LineOfText As String
            Dim SerialString As String
            Dim Counter As Integer
            Dim ErrorString As String
            Dim Packetnumber As Integer
            Dim Checksum As Long
            Dim OnesComplement As Byte
            Dim ByteRead As Byte
            Dim BinaryFileLength As Long
            Dim BinaryFileCounter As Long
            Dim Percent As Single
            Dim ErrorCounter As Byte ' 0 to 10
            Dim CPMFilename As String
            Dim Timeout As Boolean
            ProgressBar1.Maximum = 100
            ProgressBar1.Minimum = 0
            ' timer restart =true for sending via menu. False for auto send
            Filenamepath = FName
            Packetnumber = 1 ' 1 for the first packet (not zero)
            ' Try
            Dim Input As New FileStream(Filenamepath, FileMode.Open, FileAccess.Read)
            Dim br As New BinaryReader(Input)
            OpenSerialPort() ' open the serial port
            Label3.Text = "Error Count"
            Label2.Text = "0%"
            BinaryFileLength = br.BaseStream.Length() - 1
            'i = Len(Filepath) + 1 + 1  ' eg c:\n8vem and a \ = 9 and 1 more for start of name only
            Call Get_CPM_Filename(Filenamepath, CPMFilename)
            CPMFilename = Strings.UCase(CPMFilename)
            LineOfText = "XMODEM R " + CPMFilename + vbCr
            Call StringToPacket(LineOfText) ' 
            Call ClearInputBuffer()  ' clear the buffer into the PC
            For i = 1 To Delay1 ' 50 for kyedos need to wait for kyedos to run the xmodem program
                Sleep(100) ' wait for the xmodem text to come back so the next one is a 21
                Label3.Text = Str$(i)
                Call ClearInputBuffer()  ' clear the buffer into the PC
            Next i
            Call ClearInputBuffer()  ' clear the buffer into the PC
            Do
                SerialString = ""
                If SerialPortFound = True Then
                    If SerialPortName.BytesToRead > 0 Then
                        SerialPortName.Read(InPacket, 0, 1) ' get one byte
                        SerialString = Chr(InPacket(0)) ' get a single character/string/byte
                    End If
                End If
                If InPacket(0) = 21 Then
                    ErrorString = "NAK"
                    Exit Do ' got a ^U
                End If
                If SerialString <> "" Then
                    'LineOfText = SerialString
                    'Call TextLines(LineOfText) ' print it out unless it is a chr21
                End If
                Counter = Counter + 10
                Sleep(10) ' don't change this one - this is waiting for NAK
                Label1.Text = "Waiting for NAK to start" + Strings.Str(Counter) + "ms" ' display in milliseconds
                System.Windows.Forms.Application.DoEvents() ' update the label1 message
                ' add a counter and timeout if nothing
                If Counter > 5000 Then
                    ErrorString = "Bypass wait for NAK - xmodem failed"
                    Exit Do
                End If
                If ErrorString <> "" Then Exit Do
            Loop
            Label1.Text = ErrorString
            System.Windows.Forms.Application.DoEvents() ' update the label1 message
            Do
                ' act on each byte in the buffer array here
                XOut(0) = 1 'SOH ^A
                XOut(1) = Packetnumber
                OnesComplement = 255 - Packetnumber
                XOut(2) = OnesComplement
                Packetnumber = Packetnumber + 1
                If Packetnumber > 255 Then Packetnumber = Packetnumber - 256
                Checksum = 0
                For i = 0 To 127 ' get 128 bytes from file
                    If BinaryFileCounter <= BinaryFileLength Then
                        ByteRead = br.ReadByte ' get a byte
                    Else
                        ByteRead = 26 ' pad with char 26 = hex 1A because hyperterm does this ? why but it works
                    End If
                    XOut(i + 3) = ByteRead
                    Checksum = Checksum + ByteRead
                    BinaryFileCounter = BinaryFileCounter + 1
                Next
                ' create checksum
                Do
                    If Checksum < 256 Then Exit Do ' work out checksum
                    Checksum = Checksum - 256
                Loop
                XOut(131) = Checksum
                Call OutputXout()
                System.Windows.Forms.Application.DoEvents() ' update the label
                Timeout = False
                Do
                    k = 0
                    Do
                        If SerialPortFound = True Then
                            j = SerialPortName.BytesToRead
                        End If
                        If j >= 1 Then
                            If SerialPortFound = True Then
                                SerialPortName.Read(InPacket, 0, 1) ' get one byte
                            End If
                            Exit Do
                        End If
                        k += 1
                        If k > 5000 Then
                            Timeout = True ' 5 second delay for timeout, must be more than the Rx side timeout
                            Exit Do
                        End If
                        Sleep(1) ' 1ms delay
                    Loop
                    If InPacket(0) = 6 Then Exit Do ' remote got the packet so exit
                    If InPacket(0) = 21 Then
                        ' remote didn't get it so try sending again - does up to 10x
                        ErrorCounter = ErrorCounter + 1
                        Call ClearInputBuffer() ' clear the input buffer to the PC
                        Sleep(1000) ' let the remote get itself sorted before resending the packet
                        Call OutputXout() ' resend the packet
                        Label3.Text = "Nak: " + Strings.Str(ErrorCounter)
                        System.Windows.Forms.Application.DoEvents() ' update the label
                    End If
                    If Timeout = True Then
                        Label3.Text = "Timeout waiting for Ack"
                        ErrorCounter = 20 'force an exit now
                        System.Windows.Forms.Application.DoEvents() ' update the label
                    End If
                    If ErrorCounter >= 10 Then Exit Do ' more than 10 errors
                Loop
                If ErrorCounter >= 10 Then
                    Label1.Text = "10 or more errors - aborting"
                    Label2.Text = "0%"
                    OutPacket(0) = 24 ' send a ^X cancel
                    If SerialPortFound = True Then
                        SerialPortName.Write(OutPacket, 0, 1) ' send 1 byte
                        OutPacket(0) = 3 ' send a ^C
                        SerialPortName.Write(OutPacket, 0, 1) ' send 1 byte
                    End If
                    Exit Do
                End If
                If BinaryFileCounter > BinaryFileLength Then Exit Do ' finish up
                Label1.Text = "Sent packet: " + Strings.Str(Packetnumber) + " = OK"
                Percent = BinaryFileCounter / BinaryFileLength
                Percent = Percent * 100
                Percent = Int(Percent)
                Label2.Text = Strings.Str(Percent) + "%"
                ProgressBar1.Value = Percent
            Loop
            If ErrorCounter < 10 Then
                OutPacket(0) = 4 ' finish byte
                If SerialPortFound = True Then
                    SerialPortName.Write(OutPacket, 0, 1) ' send 1 byte
                End If
                Label2.Text = "100%"
                Label1.Text = "Finished"
                ProgressBar1.Value = 0 'done
                Call StringToPacket(vbCrLf) ' back to kyedos
            End If
            Input.Close()
            Sleep(200) ' wait for next file
            System.Windows.Forms.Application.DoEvents() ' update the labels
            'Catch ex As Exception
            '    Close()
            '    Label1.Text = Filenamepath + " not found"
            '    System.Windows.Forms.Application.DoEvents() ' update the labels
            '    Sleep(1000) ' so time to read message
            'End Try
            SerialPortName.Close() ' close the serial port
        End Sub
    

    and this is the routine to receive a file
        Sub XModemKyeReceive(ByRef Filenamepath As String)
            ' pass full path eg C:\n8vem\FILE.TXT
            ' true for calls from menu bar, false for calls from pip
            'Dim Filepath As String
            Dim FileName As String
            Dim XModemIn(0 To 131) As Byte
            Dim PacketSave(0 To 127) As Byte
            Dim i As Integer
            Dim LineOfText As String
            Dim Packetnumber As Integer
            Dim OnesComplement As Byte
            Dim BinaryFileLength As Long
            Dim ErrorCounter As Byte ' give up if gets to 10
            Dim Checksum As Long
            Dim ValidPacket As Boolean
            Dim ErrorType As String
            Dim BytesToRead As Integer
            Dim RetryCounter As Integer
            OpenSerialPort() ' open the serial port
            Packetnumber = 1 ' I think it is 1 for the first packet
            Dim Output As New FileStream(Filenamepath, FileMode.Create, FileAccess.Write)
            Dim br As New BinaryWriter(Output)
            BinaryFileLength = br.BaseStream.Length() - 1
            FileName = Strings.Mid(Filenamepath, 33) ' strip off the directory
            FileName = Strings.UCase(FileName) ' upper case
            'LineOfText = Strings.Chr(13)
            'Call StringToPacket(LineOfText)
            'Sleep(300) ' to process the return
            ' run xmodem on the board
            'System.Windows.Forms.Application.DoEvents() ' update the label1 message
            LineOfText = "XMODEM S " + FileName
            Call StringToPacket(LineOfText) ' start xmodem
            LineOfText = vbCrLf
            Call StringToPacket(LineOfText) ' send a return/LF
            System.Windows.Forms.Application.DoEvents() ' update the label1 message
            Sleep(3500) ' wait a 3.5  seconds for kyedos to run xmodem
            System.Windows.Forms.Application.DoEvents() ' update the label1 message
            Call ClearInputBuffer()  ' clear the buffer into the PC
            OutPacket(0) = 21 ' send a NAK
            If SerialPortFound = True Then
                SerialPortName.Write(OutPacket, 0, 1) ' send it out
            End If
            Sleep(1000) ' wait for xmodem to put the line together
            Packetnumber = 1
            Label2.Text = ""
            Do
                ' get first byte back
                ValidPacket = True ' start with true but errors could make it false
                RetryCounter = 0
                Do
                    Try
                        If SerialPortFound = True Then
                            SerialPortName.Read(InPacket, 0, 1)
                            RetryCounter = 255 ' set so it restarts
                        End If
                    Catch
                        RetryCounter += 1
                        Sleep(10)
                    End Try
                Loop Until RetryCounter > 100
                If RetryCounter <> 255 Then
                    ValidPacket = False
                    ErrorCounter = ErrorCounter + 1
                    ErrorType = "Serial port timeout"
                End If
                If InPacket(0) = 4 Then
                    Label1.Text = "Finished transfer"
                    Label2.Text = "100%"
                    Exit Do
                End If
                If InPacket(0) = 1 Then
                    ' valid packet so read the rest in
                    XModemIn(0) = InPacket(0) ' already got the 1st byte so put it in xmodemin array
                    If SerialPortFound = True Then
                        For i = 1 To 131
                            SerialPortName.Read(InPacket, 0, 1)
                            XModemIn(i) = InPacket(0)
                        Next
                    End If
                    Label1.Text = "Packet " + Strings.Str(Packetnumber) ' display packet
                    System.Windows.Forms.Application.DoEvents() ' update the label1 message
                End If
                If XModemIn(0) <> 1 And ValidPacket = True Then ' first number should be a 1
                    ValidPacket = False
                    ErrorType = "First # not ^A SOH"
                    ErrorCounter = ErrorCounter + 1
                End If
                Do
                    If Packetnumber < 256 Then Exit Do
                    Packetnumber = Packetnumber - 256
                Loop
                OnesComplement = 255 - Packetnumber ' ones complement must match
                If Packetnumber <> XModemIn(1) And ValidPacket = True Then ' packet number should be the next one
                    ValidPacket = False
                    ErrorType = "Packet number mismatch"
                    ErrorCounter = ErrorCounter + 1
                End If
                If XModemIn(2) <> OnesComplement And ValidPacket = True Then
                    ValidPacket = False
                    ErrorType = "Ones complement not valid"
                    ErrorCounter = ErrorCounter + 1
                End If
                Checksum = 0
                For i = 3 To 130
                    Checksum = Checksum + XModemIn(i)
                Next
                Do
                    If Checksum < 256 Then Exit Do ' work out checksum
                    Checksum = Checksum - 256
                Loop
                If Checksum <> XModemIn(131) And ValidPacket = True Then
                    ValidPacket = False
                    ErrorType = "Checksum invalid"
                    ErrorCounter = ErrorCounter + 1
                End If
                If ValidPacket = True Then ' got a good packet
                    'Sleep(50) ' 50 at 4800 wait a tick then acknowledge that got it
                    ' no sleeps needed now with RetryCounter variable - that keeps trying till a byte arrives
                    OutPacket(0) = 6 ' got the packet ^F=ACK
                    If SerialPortFound = True Then
                        SerialPortName.Write(OutPacket, 0, 1) ' send it out
                    End If
                    'Sleep(50) ' 400 at 4800 wait for next packet to all come through - at least 200ms in pauses, plus the data, 200 does work but make it 400
                    For i = 3 To 130
                        PacketSave(i - 3) = XModemIn(i) ' read for save
                    Next
                    Output.Write(PacketSave, 0, 128) ' save 128 bytes
                    Packetnumber = Packetnumber + 1
                Else ' an error
                    ' don't add one to packet number
                    ' send a NAK
                    ' try again
                    Sleep(50) ' wait a tick then ask to send again
                    OutPacket(0) = 21 ' NAK
                    If SerialPortFound = True Then
                        SerialPortName.Write(OutPacket, 0, 1) ' send it out
                    End If
                    Sleep(3000) ' wait for next packet to all come through - at least 200ms in pauses, plus the data, 200 does work but make it 400
                End If
                Label3.Text = "Error: " + Strings.Str(ErrorCounter) + " " + ErrorType
                System.Windows.Forms.Application.DoEvents() ' update the label1 message
                If ErrorCounter >= 10 Then Exit Do
            Loop
            If ErrorCounter < 10 Then
                ' tell board got it all ok
                OutPacket(0) = 21
                If SerialPortFound = True Then
                    SerialPortName.Write(OutPacket, 0, 1)
                End If
                Sleep(100)
                ' expect back a 4, and then send a 6
                OutPacket(0) = 6
                If SerialPortFound = True Then
                    SerialPortName.Write(OutPacket, 0, 1)
                End If
            Else
                Label1.Text = "File transfer failed"
                Label2.Text = "0%"
                System.Windows.Forms.Application.DoEvents() ' update the label1 message
                For i = 1 To 10
                    OutPacket(0) = 24 ' ^X cancel send 10 times
                    If SerialPortFound = True Then
                        SerialPortName.Write(OutPacket, 0, 1) ' send it out
                    End If
                    Sleep(200)
                Next i
                OutPacket(0) = 3 ' ^C
                If SerialPortFound = True Then
                    SerialPortName.Write(OutPacket, 0, 1) ' send it out
                End If
            End If
            Output.Close() ' close the file
            SerialPortName.Close()
        End Sub
    
  • ShawnaShawna Posts: 508
    edited 2013-01-09 04:48
    Wow,
    That is a lot of info Dr_ Acula, that will take some time to process.
    Thank You
    Shawn
  • Mike GMike G Posts: 2,702
    edited 2013-01-09 05:31
    The BitConverter converts a byte array to a hex string
    BitConverter.ToString(buff)
    
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2013-01-09 16:26
    Here is something very simple to try. In the Spin file I initialized a 20 byte long array for test purposes. The VB program "fetches" the 80 byte packet and parses them back into the original 20 longs. To start the transaction the character "a" is transmitted to the Prop using a button, alternatively the button could be replaced with a timer for automatic refresh. In addition to the code you already have for opening the serial port you will need to include 1 button for writing the "a" and a Richtextbox for display. If this works out then the Richtextbox can be replaced with something that displays the data more in line with your expectations.

    Note the baud rate is 38400 and the serial Object is Extended_FDSerial although you can change that to your preference.

    VB code
    Dim inbuff(80) As Byte
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
            SerialPort1.DiscardOutBuffer()    'make sure our output buffer is flushed clear
    
            SerialPort1.Write("a")   'write "a" to port
    
            txt_out() 'call the display sub routine
    
        End Sub
    
        Private Sub txt_out()
    
            Dim value As UInt32
            RichTextBox1.Clear()
            Threading.Thread.Sleep(45) 'give time for the data to arrive at the port buffer
            SerialPort1.Read(inbuff, 0, 80) 'read 80 bytes
    
            For idx = 0 To 76 Step 4  'parse the byte array back to longs
    
                value = BitConverter.ToUInt32(inbuff, idx)
                RichTextBox1.AppendText(value.ToString & vbCr) 'display
    
            Next
    
    
        End Sub
    
Sign In or Register to comment.