keyboard controlling arduino rc car with UDP packets (VB 2008)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kickpuncher
    New Member
    • Mar 2013
    • 1

    #1

    keyboard controlling arduino rc car with UDP packets (VB 2008)

    Hi, this is my first post on these forums. Hope this is in the right place.

    Doing a college project where we control an rc car wired into an Arduino over the network from a computer.

    It's been brilliant doing this project and all the stuff I've learned from the electronics to the coding, and I've gotten pretty well as far as I thought I could with a lot of help from this forum and many others, so thanks for that.

    Decided to do the coding in VB 2008 cos of how quick and easy it was to get things running with VB in first year, but there was no constraint on language choice, and if anyone thinks another language is better suited to this I'd love to hear thoughts on that too. Anyway, having not used VB in a couple of years this forum and a few others were invaluable for rooting out which methods and things I needed to put this together, couldn't have even gotten started without it. But I wanted to postpone posting for as long as possible and get as much done on my own as I could first, which I think I have.

    I have a solution pretty much working, and I wanted to get more expert opinions on how it could be improved or implemented better (even if it should be scrapped and a different approach taken, I'm sure it's far from perfect).

    Here's the skiinny:

    VB app checks for held keys with GetAsyncKeyStat e, and various combos (of arrow keys) cause particular character to be sent in UDP packet to Arduino, which does it's thing based on the character in the packet. The held keys was chosen as the most intuitive method of controlling an rc car from the pc, and I'm using a timer's tick to run the GetAsyncKeyStat e, and what I suspect might be a somewhat convoluted system of variable comparisons to prevent a packet from being sent until the state of the held keys changes.
    UDP was chosen for speed, though I'm really not sure what difference it would make in the real world if trying to control the rc over the internet say with live keyboard control, and whether it would be viable with UDP and not an alternative, or whether it wouldn't make a practical difference, or whether it wouldn't be viable at all!

    Anyway, the thing is working, and sending packets only on initial press or release of key(s). The one glitch I've so far detected is that when releasing all the keys, which should send the "z" character and stop the car, the same character that was previously sent is re-sent, rather than the 'stop' character "z".

    So here's the code, VB 2008:

    _______________ _______________ _______________ _________

    Code:
    Imports System.Text
    Imports System.Net
    Imports System.Net.Sockets
    
    Public Class Form1
    
        Dim GLOIP As IPAddress
        Dim GLOINTPORT As Integer
        Dim bytCommand As Byte() = New Byte() {}
        Dim udpClient As New UdpClient
        Dim controlChoice As New Integer
        Dim controlChoicePrev As New Integer
        Dim cc As String = "z"
    
    
    
        Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
        Dim WithEvents Tmr As New Timer
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            controlChoice = 0
            controlChoicePrev = controlChoice
    
            Tmr.Interval = 100
            Tmr.Start()
        End Sub
        Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
            Tmr.Stop()
    
            If Not controlChoice = controlChoicePrev Then
    
                'UDP_______________________________________________________
    
                Try
                    GLOIP = IPAddress.Parse("192.168.1.177")
                    GLOINTPORT = 8888
                    udpClient.Connect(GLOIP, GLOINTPORT)
                    bytCommand = Encoding.ASCII.GetBytes(cc)
                    udpClient.Send(bytCommand, bytCommand.Length)
    
                Catch ex As Exception
                    Console.WriteLine(ex.Message)
    
                End Try
    
                'UDP_______________________________________________________
    
            End If
    
    
            If GetAsyncKeyState(Keys.Up) Or GetAsyncKeyState(Keys.Down) Then
    
    
                Select Case True
    
                    Case GetAsyncKeyState(Keys.Up)
    
                        If (GetAsyncKeyState(Keys.Up)) And (GetAsyncKeyState(Keys.Left)) Then
                            Label1.Text = "Forwards Left"
                            controlChoicePrev = controlChoice
                            controlChoice = 11
                            cc = "b"
    
                        ElseIf (GetAsyncKeyState(Keys.Up)) And (GetAsyncKeyState(Keys.Right)) Then
                            Label1.Text = "Forwards Right"
                            controlChoicePrev = controlChoice
                            controlChoice = 12
                            cc = "c"
    
                        Else
                            Label1.Text = "Forwards"
                            controlChoicePrev = controlChoice
                            controlChoice = 10
                            cc = "a"
    
                        End If
    
    
                    Case GetAsyncKeyState(Keys.Down)
    
    
    
    
                        If (GetAsyncKeyState(Keys.Down)) And (GetAsyncKeyState(Keys.Left)) Then
                            Label1.Text = "Backwards Left"
                            controlChoicePrev = controlChoice
                            controlChoice = 21
                            cc = "e"
    
                        ElseIf (GetAsyncKeyState(Keys.Down)) And (GetAsyncKeyState(Keys.Right)) Then
                            Label1.Text = "Backwards Right"
                            controlChoicePrev = controlChoice
                            controlChoice = 22
                            cc = "f"
    
                        Else
                            Label1.Text = "Backwards"
                            controlChoicePrev = controlChoice
                            controlChoice = 20
                            cc = "d"
    
                        End If
    
                End Select
    
            Else
                Label1.Text = "Stopped"
                controlChoicePrev = controlChoice
                controlChoice = 0
    
            End If
    
            Tmr.Start()
    
        End Sub
    End Class
    _______________ _______________ _______________ ____________





    So like I said, I'm just wondering if anyone would comment on this and make suggestions/crits.

    Many TIA

    PS. I'm still pretty code illiterate, so if layman's terms and really explicit and comprehensive and well commented code snippets is not too big an ask... like when people start using terms like call and pass, invoke, etc, I can just about follow things but not always. Sorry...
    Last edited by Rabbit; Mar 21 '13, 06:47 PM. Reason: Please use code tags when posting code.
  • IronRazer
    New Member
    • Jan 2013
    • 83

    #2
    Hey kickpuncher,
    I hope you don`t mind but, i rewrote some of your code and got it so it does not send the key again on release and so that when all keys are released it will send z once to stop the car. I think that`s what you where looking for.

    Code:
    Option Strict On
    Imports System.Text
    Imports System.Net
    Imports System.Net.Sockets
    
    Public Class Form1
    
        Dim GLOIP As IPAddress
        Dim GLOINTPORT As Integer
        Dim bytCommand As Byte() = New Byte() {}
        Dim udpClient As New UdpClient
        Dim cc As String = "z"
        Dim cclast As String = ""
    
        Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer
        Dim WithEvents Tmr As New Timer
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Tmr.Interval = 100
            Tmr.Start()
        End Sub
    
        Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
            Tmr.Stop()
    
            If CBool(GetAsyncKeyState(Keys.Up) Or GetAsyncKeyState(Keys.Down)) Then
    
                Select Case True
    
                    Case CBool(GetAsyncKeyState(Keys.Up))
    
                        If CBool((GetAsyncKeyState(Keys.Up)) And (GetAsyncKeyState(Keys.Left))) Then
                            Label1.Text = "Forwards Left"
                            cc = "b"
    
                        ElseIf CBool((GetAsyncKeyState(Keys.Up)) And (GetAsyncKeyState(Keys.Right))) Then
                            Label1.Text = "Forwards Right"
                            cc = "c"
    
                        Else
                            Label1.Text = "Forwards"
                            cc = "a"
    
                        End If
    
                    Case CBool(GetAsyncKeyState(Keys.Down))
    
                        If CBool((GetAsyncKeyState(Keys.Down)) And (GetAsyncKeyState(Keys.Left))) Then
                            Label1.Text = "Backwards Left"
                            cc = "e"
    
                        ElseIf CBool((GetAsyncKeyState(Keys.Down)) And (GetAsyncKeyState(Keys.Right))) Then
                            Label1.Text = "Backwards Right"
                            cc = "f"
    
                        Else
                            Label1.Text = "Backwards"
                            cc = "d"
    
                        End If
    
                End Select
    
            ElseIf Not cc = "z" And Not CBool(GetAsyncKeyState(Keys.Down)) And Not CBool(GetAsyncKeyState(Keys.Up)) Then
                cc = "z"
                Label1.Text = "Stopped"
            End If
    
            If Not cclast = cc Then
                'UDP______________________________________________ _________
    
                Try
                    GLOIP = IPAddress.Parse("192.168.1.177")
                    GLOINTPORT = 8888
                    udpClient.Connect(GLOIP, GLOINTPORT)
                    bytCommand = Encoding.ASCII.GetBytes(cc)
                    udpClient.Send(bytCommand, bytCommand.Length)
    
                Catch ex As Exception
                    Console.WriteLine(ex.Message)
    
                End Try
    
                'UDP______________________________________________ _________
            End If
    
            cclast = cc
    
            Tmr.Start()
    
        End Sub
    
    End Class
    Also just a Tip you should use this line as the very first line of code in the program.
    Code:
    Option Strict On
    It will catch all the errors of type conversion. By placing it in the code it will put a little blue line with a red spot on the end under each error. Then you can put your mouse over the red spot and it will pop up a little red box. You can then click on the red box and it will tell you how to fix the error. It is a very very handy option to use.

    Comment

    Working...