Results 1 to 16 of 16

Thread: VB2010: Automatic identification of model trains

  1. #1
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    VB2010: Automatic identification of model trains

    hi

    i'm workin on a project using linear barcodes to automatically identify individual trains and rolling stock as they pass by the barcode reader.
    can i get help on how i can use VB2010 to write a file containing engine information and rolling stock information that i can load into my code so t that as the barcode is read i can display the appropriate information of the windows application i'm building please help!!

  2. #2
    .NUT jmcilhinney's Avatar
    Join Date
    May 05
    Location
    Sydney, Australia
    Posts
    80,872

    Re: VB2010: Automatic identification of model trains

    The most logical option would be to use a database. You would have one or more tables with the appropriate columns to store the data you need. When you read a barcode you query the database for the data related to that value and display it as desired. There is tons of information on the web about creating data-driven applications so there's no need for us to repeat the same stuff yet again. There are some links in my signature that you might find useful, particularly the Data Walkthroughs and Videos.

  3. #3
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,880

    Re: VB2010: Automatic identification of model trains

    Not sure that a database is necessary here. A CSV file (or similar) would allow for easy editing outside of the application, and not require building an interface inside the application to manage the data.

    What you would need to do, however, is read the data into a data structure that allows for retrieving a value by specifying a key.

    In other words:
    • You'll need a class to represent the data for a single engine/stock (this should be able to represent either - if you do need slightly different details, it is possible to create two different classes but this would require a few additional steps so I'll go the less complex route for now).
    • You'll need an 'initialisation' routine in your application that can:
      • Create an instance of a Dictionary
      • Read the data file line by line
      • Parse each line and create an instance of the data class with the information from that line of data
      • Add each of those instances to the dictionary instance
    • When you read a barcode, use the data as the key into the dictionary instance to retrieve the full information from the dictionary

  4. #4
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    Quote Originally Posted by jmcilhinney View Post
    The most logical option would be to use a database. You would have one or more tables with the appropriate columns to store the data you need. When you read a barcode you query the database for the data related to that value and display it as desired. There is tons of information on the web about creating data-driven applications so there's no need for us to repeat the same stuff yet again. There are some links in my signature that you might find useful, particularly the Data Walkthroughs and Videos.
    thanks i have decided to use the database to store the trains info, i used sql to build the tables and am using LINQ to SQL to load the tables my code.
    i am facing a problem right now please help. i am trying to display the row of data that corresponds to the barcode i am reading to display in a datagridview table but i am not getting anything to show. here is my code could you please point me in the right direction please.



    Public Class Form1
    Dim s As String = ""
    Dim ctx As TrainsInfoDataContext




    Private Function TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Brcd.KeyPress
    If Asc(e.KeyChar) = 13 Then
    Brcd.Text = (s + vbCrLf)
    s = ""
    Else
    s = s + e.KeyChar
    End If
    Return s
    End Function


    Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
    ctx.Log = Console.Out
    Dim first_train = From Engine In ctx.Train_Engines
    Where Engine.Serial_Number = Function TextBox1_KeyPress

    End Sub


    End Class

  5. #5
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,880

    Re: VB2010: Automatic identification of model trains

    I think you've misunderstood how the event-driven model of Windows Forms applications work. When the barcode reader reads a barcode, it simply types the text of the barcode followed by the Return key. So you've presumably set it up so that the TextBox has keyboard focus, then when a barcode is read, the TextBox is typed into. Each time a 'key' is 'pressed' by the barcode reader, the KeyPress event is fired - I'm not entirely sure

    You appear to be thinking that you 'pull' the keyboard presses from some kind of buffer when you call the event handler from within the DGV's CellContentClick event handler?

    If I were you, I would start by writing a method that takes an identifier string as an argument and to start with maybe just adds it to a listbox:

    vbnet Code:
    1. Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    2.     ' For now, just log that we saw an identifier
    3.     ListBox1.Items.Add(String.Format("Saw identifier {0} at {1}", identifier, DateTime.Now))    
    4. End Sub

    Now we can look at that KeyPress event handler. We're looking for the Return key being pressed, to indicate the end of the barcode reader's input. The normal way of doing this is to use the KeyDown event instead. That gives you the KeyCode property that is an enumeration of the keys on a keyboard and is a slightly better fit:

    vbnet Code:
    1. Private Sub TextBox1_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
    2.     If e.KeyCode = Keys.Return Then
    3.         ' Do something
    4.     End If
    5. End Sub

    Remember that the TextBox has been typed into, so the preceeding input from the barcode reader is sitting in the TextBox. We can simply read the Text property, no need to handle each keypress and store in a string buffer. So what to do with our identifier? Pass it to the method that will process it. The only other thing we need to do is clear the TextBox so that we don't have the preceeding identifiers still in the TextBox when the barcode reader starts typing the next identifier it sees:

    vbnet Code:
    1. Private Sub TextBox1_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
    2.     If e.KeyCode = Keys.Return Then
    3.         ProcessTrainIdentifier(TextBox1.Text)
    4.         TextBox1.Clear()
    5.     End If
    6. End Sub

  6. #6
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    thanks alot mate, but i have a few question i would like u to help me with. firstly is a good idea to try and diplay the data from my database using the DGV?? cos when i connected the DGV to my database directly it just showed all the data in the database at the same time but i want to query the data corresponding to the read barcode and display the rows one at a time in real time.

    secondly i tried getting the read barcode and using it in another subroutine , i tried calling it with the ProcessTrainIdentifier(TextBox.Text) but it says there is no value to return.

    sorry i'm a bit of a blockhead on this coding and thanks for the help

  7. #7
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,880

    Re: VB2010: Automatic identification of model trains

    I wouldn't go down the route of the DGV. As you've seen, it is designed to display a grid of data. I would simply stick to some labels/read-only textboxes to hold each field.

    As to your second issue, I wonder how you're trying to call the ProcessTrainIdentifier sub? That is not designed to return anything. With the code I posted that sub is executed everytime an engine's barcode is read, so it should retrieve the train details from the database and then display them. I'd expect it to look something like this when you're done (you'll need to correct the TrainInfo type name to whatever your type is called):

    vbnet Code:
    1. Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    2.     Dim trainInfo = GetTrainInfo(identifier)
    3.     DisplayTrainInfo(trainInfo)
    4. End Sub

    Obviously, that calls for two new methods you need to write:
    vbnet Code:
    1. Private Function GetTrainInfo(ByVal identifier As String) As TrainInfo
    2.     ' LINQ To SQL code goes here
    3. End Function
    4.  
    5. Private Sub DisplayTrainInfo(ByVal trainInfo As TrainInfo)
    6.     ' Write the data in trainInfo to the UI
    7. End Sub

  8. #8
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,880

    Re: VB2010: Automatic identification of model trains

    [snip]
    Last edited by Evil_Giraffe; Aug 15th, 2012 at 09:09 AM. Reason: double post

  9. #9
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    hi mate i tried this but when i'm running it, once i scan a barcode it throws an errorr and an unhandled exception . and p.s in the LINQ TO SQL how will i use the where to point to the location to read the barcode?? thanks.......

    Public Class Form1
    Dim s As String = ""
    Dim ctx As TrainsInfoDataContext

    'Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Brcd.KeyPress
    ' If Asc(e.KeyChar) = 13 Then
    ' TextBox1.Text = (s + vbCrLf)
    ' s = ""
    'Else
    ' s = s + e.KeyChar
    'End If
    'End Sub

    'Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    ' For now, just log that we saw an identifier
    ' ListBox1.Items.Add(String.Format("Saw identifier {0} at {1}", identifier, DateTime.Now))
    'End Sub

    Private Sub TextBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown

    If e.KeyCode = Keys.Return Then
    ProcessTrainIdentifier(TextBox1.Text)
    TextBox1.Clear()
    End If
    End Sub

    Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    Dim trainInfo = GetTrainInfo(identifier)
    DisplayTrainInfo(trainInfo)
    End Sub

    Private Function GetTrainInfo(ByVal identifier As String) As TrainsInfoDataContext
    ' LINQ To SQL code goes here
    Dim engines = From trn In ctx.Train_Engines
    Where trn.Serial_Number = "1101" Or "1102"
    Select trn
    For Each trn In engines
    ListBox1.Items.Add(trn.Serial_Number & vbTab & trn.Running_Number & vbTab & trn.Manufacturer & vbTab &
    trn.Engine_Type & vbTab & trn.Purpose & vbTab & trn.Class & vbTab & trn.Group & vbTab & trn.Weight)

    Next
    Return engines
    End Function

    Private Sub DisplayTrainInfo(ByVal trainInfo As TrainsInfoDataContext)
    ' Write the data in trainInfo to the UI

    End Sub

    End Class

  10. #10
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,880

    Re: VB2010: Automatic identification of model trains

    I think you've misunderstood. You don't need to read the barcode in the LINQ to SQL code - the barcode has already been read, and it is sitting in the identifier variable. The GetTrainInfo method is not supposed to return the TrainsInfoDataContext, it is supposed to use the TrainsInfoDataContext to grab the TrainsInfo object for the identifier.

    Each time a barcode is read, the following happens:
    TextBox1 is populated with the barcode data.
    ProcessTrainIdentifier is called with the contents of the TextBox in the identifier variable
    GetTrainInfo is called, passing that identifier through.
    GetTrainInfo uses the identifier to return a record representing a single train
    DisplayTrainInfo is called with the returned traininfo value
    DisplayTrainInfo writes values from the traininfo object on to the UI.

  11. #11
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    ok i think i get where u're coming from cheers, this is what i've modified so far, hope the first parts make sense . the DisplayTraininfo though is giving me a tough time on how to use the traininfo to display the tables that have been quired y the identifier


    Private Sub TextBox1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown

    If e.KeyCode = Keys.Return Then
    ProcessTrainIdentifier(TextBox1.Text)
    TextBox1.Clear()
    End If
    End Sub

    Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    Dim trainInfo = GetTrainInfo(identifier)
    DisplayTrainInfo(trainInfo)
    End Sub


    Private Function GetTrainInfo(ByVal identifier As String) As TrainsInfoDataContext
    ' LINQ To SQL code goes here
    Dim engines = From trn In ctx.Train_Engines
    Where trn.Serial_Number = identifier
    Select trn

    Dim rolling_stock = From rollstck In ctx.Rolling_Stocks
    Where rollstck.Serial_Number = identifier
    Select rollstck
    End Function

    Private Sub DisplayTrainInfo(ByVal trainInfo As TrainsInfoDataContext)
    ' Write the data in trainInfo to the UI
    ' Dim dsply_Eng As String
    'Dim dsply_Rollstock As String

    EngInfoLbl = trainInfo.Train_Engines.ToString((ctx.Train_Engines.Serial_Number & vbTab & trn.Running_Number & vbTab & trn.Manufacturer & vbTab &
    trn.Engine_Type & vbTab & trn.Purpose & vbTab & trn.Class & vbTab & trn.Group & vbTab & trn.Weight)

    End Sub

  12. #12
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    hi mate, i've worked through it again and it seems not to throw in any errors anymore but it does not show any data when i read the barcode??

    Public Class Form1
    Dim s As String = ""
    Dim ctx As New TrainsInfoDataContext

    'Private Sub TextBox1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Brcd.KeyPress
    ' If Asc(e.KeyChar) = 13 Then
    ' TextBox1.Text = (s + vbCrLf)
    ' s = ""
    'Else
    ' s = s + e.KeyChar
    'End If
    'End Sub

    'Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    ' For now, just log that we saw an identifier
    ' ListBox1.Items.Add(String.Format("Saw identifier {0} at {1}", identifier, DateTime.Now))
    'End Sub

    Private Sub Brcs_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Brcd.KeyDown

    If e.KeyCode = Keys.Return Then
    ProcessTrainIdentifier(Brcd.Text)
    Brcd.Clear()
    End If

    End Sub

    Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    Dim trainInfo = GetTrainInfo(identifier)
    'DisplayTrainInfo(trainInfo)
    ' DisplayTrainInfo(trainInfo)
    End Sub


    Private Function GetTrainInfo(ByVal identifier As String) As String
    ' LINQ To SQL code goes here
    Dim engines = From trn In ctx.Train_Engines
    Where trn.Serial_Number Like identifier
    Select trn
    Me.Train_EngineBindingSource.DataSource = engines

    'Dim rolling_stock = From rollstck In ctx.Rolling_Stocks
    'Where(RollStck.Serial_Number Like identifier)
    ' Select RollStck
    End Function

    Private Sub DisplayTrainInfo(ByVal trainInfo As TrainsInfoDataContext)
    ' Write the data in trainInfo to the UI

    End Sub

  13. #13
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    Quote Originally Posted by Evil_Giraffe View Post
    I think you've misunderstood. You don't need to read the barcode in the LINQ to SQL code - the barcode has already been read, and it is sitting in the identifier variable. The GetTrainInfo method is not supposed to return the TrainsInfoDataContext, it is supposed to use the TrainsInfoDataContext to grab the TrainsInfo object for the identifier.

    Each time a barcode is read, the following happens:
    TextBox1 is populated with the barcode data.
    ProcessTrainIdentifier is called with the contents of the TextBox in the identifier variable
    GetTrainInfo is called, passing that identifier through.
    GetTrainInfo uses the identifier to return a record representing a single train
    DisplayTrainInfo is called with the returned traininfo value
    DisplayTrainInfo writes values from the traininfo object on to the UI.
    thanks i understand it now, i have got the code working , reading the barcodes ans displaying the appropriate data in a DGV, but a problem has developed in that it only shows the engine information but when i scan a rolling stock or cart it does not show it.... here is the code pls if u can see where the cause of this is pls help me point it out thanks.


    Public Class Form1
    Dim s As String = ""
    Dim ctx As New TrainsInfoDataContext


    Private Sub Brcs_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Brcd.KeyDown

    If e.KeyCode = Keys.Return Then
    ProcessTrainIdentifier(Brcd.Text)
    Brcd.Clear()
    End If

    End Sub

    Private Sub ProcessTrainIdentifier(ByVal identifier As String)
    Dim trainInfo = GetTrainInfo(identifier)
    Dim rollinfo = GetRollingStockInfo(identifier)
    'DisplayTrainInfo(trainInfo)
    ' DisplayTrainInfo(trainInfo)
    End Sub


    Private Function GetTrainInfo(ByVal identifier As String) As DataGridView
    ' LINQ To SQL code for engine
    Dim engines = From trn In ctx.Train_Engines
    Where (trn.Serial_Number = identifier)
    Select trn
    Me.Train_EngineBindingSource.DataSource = engines

    End Function

    Private Function GetRollingStockInfo(ByVal identifier As String) As DataGridView
    ' LINQ TO SQL code for rolling stock
    Dim rolling = From rollstck In ctx.Rolling_Stocks
    Where (rollstck.Serial_Number Like identifier)
    Select rollstck
    Me.Rolling_StockBindingSource.DataSource = rolling

    End Function

    End Class

  14. #14
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    i was trying to compare succesive barcodes as they are read cos i put two barcodes on each train and cart so i can know the direction of travel..

    i used this piece of code to do it but its not workin pls can u give me an input??

    Private Sub TrainDirection(ByVal identifier As String)
    Dim direc() As String = {"identifier", "idnetifier++"}
    Dim direction As String
    If identifier < identifier++ then
    TextBox1.Text = "Forward"
    Else if identifier > identifier ++ then
    TextBox1.Text = "Reverse"
    End If

    secondly pls can u give me an idea on how i can log the train informations as they are read into another database so i can have a history of all the trains that have passed along with timestamps for each thanks alot

  15. #15
    Frenzied Member Evil_Giraffe's Avatar
    Join Date
    Aug 02
    Location
    Suffolk, UK
    Posts
    1,880

    Re: VB2010: Automatic identification of model trains

    Quote Originally Posted by Eng_Mc View Post
    i was trying to compare succesive barcodes as they are read cos i put two barcodes on each train and cart so i can know the direction of travel..
    Okay, this ups the complexity of your problem a degree. Now you need to separate the concept of 'a barcode was read' from the concept of 'an engine/piece of stock has gone past the sensor' - because now you have two barcode events for each engine.

    I think my initial approach would be to be able to look up the train info from either barcode, and if it's for a record with a 'front' and 'back' identifier, you can assume this is the first one you've seen and therefore know the direction of travel, and then indicate that if the next seen barcode is the 'other' code for this engine then ignore it.

    Quote Originally Posted by Eng_Mc View Post
    secondly pls can u give me an idea on how i can log the train informations as they are read into another database so i can have a history of all the trains that have passed along with timestamps for each thanks alot
    Well, you have code that is fired whenever a barcode is read, you can use Date.Now to get a timestamp, then it's a simple case of inserting into an appropriate table in the database, surely?

  16. #16
    Junior Member
    Join Date
    Aug 12
    Posts
    22

    Re: VB2010: Automatic identification of model trains

    Quote Originally Posted by Evil_Giraffe View Post
    Okay, this ups the complexity of your problem a degree. Now you need to separate the concept of 'a barcode was read' from the concept of 'an engine/piece of stock has gone past the sensor' - because now you have two barcode events for each engine.

    I think my initial approach would be to be able to look up the train info from either barcode, and if it's for a record with a 'front' and 'back' identifier, you can assume this is the first one you've seen and therefore know the direction of travel, and then indicate that if the next seen barcode is the 'other' code for this engine then ignore it.
    okay, i wrote this code to determine the train direction, it works... but i often get reverse inter of forward and then it skips back to the correct direction. i don't know why it does that?? is there anything i can add to the code to full proof it againt such mistakes ocurring??

    Private Sub Brcs_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Brcd.KeyDown
    If e.KeyCode = Keys.Return Then
    ProcessTrainIdentifier(Brcd.Text)
    barcodes.Add(Brcd.Text)
    Brcd.Clear()
    End If

    If barcodes.Count = 2 Then
    CompareBarcodes(barcodes(0), barcodes(1))
    barcodes.Clear()
    End If
    End Sub
    'this function receives two succesive barcode values converts them to integer values and compares the values to determine direction of travel
    Private Function CompareBarcodes(ByVal stringA As Int64, ByVal stringB As Int64)
    If Convert.ToInt64(stringA) < Convert.ToInt64(stringB) Then
    TextBox1.Text = "Forward"
    ElseIf Convert.ToInt64(stringA) > Convert.ToInt64(stringB) Then
    TextBox1.Text = "Reverse"
    Else
    TextBox1.Text = ""
    End If

    End Function


    [/QUOTE]Well, you have code that is fired whenever a barcode is read, you can use Date.Now to get a timestamp, then it's a simple case of inserting into an appropriate table in the database, surely?[/QUOTE]

    okay yeah, but the address i could pass for the add is what is gettin me confused .... see the code i've written but i'm stuck here not knowing how to pass the data .....

    the first code reads the barcode and shows the data :

    Private Function GetTrainInfo(ByVal identifier As String) As DataGridView
    ' LINQ To SQL code for trains
    Dim engines = From trn In ctx.Trainsses
    Where (trn.Serial_Number = identifier)
    Select trn
    Me.TrainssBindingSource.DataSource = engines
    Return TrainssDataGridView

    End Function

    this second code is in another form i created and used a button to open it from the first form so that this table would be in the new form. but i am lost for code on how to populate the table with the data from the first table as it is being read....

    Public Class TrainLog
    Dim ctx As New TrainsInfoDataContext
    Private Sub TrainLog_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim P As New Train_Log
    P.Date_and_Time = Today()
    P.Serial_Number =
    P.Running_Number =
    P.Manufacturer =
    P.Engine____Cart_Type =
    P.Purpose =
    P.Load_Size =
    P.Class =
    P.Group =
    P.Weight =
    Me.Train_LogBindingSource.DataSource = P

    End Sub

    End Class

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •