Find all our projects in development below.
All source code is GNU General Public License (GPL)
Browsing frmMain.vb (14.88 KB)
Option Explicit On
Imports System.BitConverter
Imports System.Collections
Imports System.IO
Imports System.Xml
Public Class frmMain
Private bAllowClose As Boolean = False
Private _inPort As String = ""
Private _outPort As String = ""
Private _afrMultiplier As Short = 0
Private _lambdaOffset As Short = 0
Private _inCount As Double = 0
Private _outCount As Double = 0
Private _inBuff(15) As Byte
Private _outBuff(15) As Byte
Private comImg_off As Bitmap = Nothing
Private comImg_on As Bitmap = Nothing
Private comImg_err As Bitmap = Nothing
Private comIco_off As Icon = Nothing
Private comIco_on As Icon = Nothing
Private comIco_err As Icon = Nothing
Private Const XML_CONFIG_FILE As String = "config.xml"
Private Const XML_CONFIG_PATH As String = "/plx2lm1/config"
Private Enum StatusCodes
StatusError
StatusOff
StatusOn
End Enum
Private Function LoadXmlConfig(ByVal xmlFile As String) As Boolean
Try
If Not File.Exists(xmlFile) Then _
Return False
Dim xmlDoc As New XmlDocument
' load the xml file
xmlDoc.Load(xmlFile)
' load configuration
Dim cfgNode As XmlNode = xmlDoc.SelectSingleNode(XML_CONFIG_PATH)
Dim thisNode As XmlNode = cfgNode.Item("incoming_port")
_inPort = thisNode.InnerText
thisNode = cfgNode.Item("outgoing_port")
_outPort = thisNode.InnerText
thisNode = cfgNode.Item("afr_multiplier")
_afrMultiplier = CShort(Val(thisNode.InnerText) * 10)
thisNode = cfgNode.Item("lambda_offset")
_lambdaOffset = Short.Parse(thisNode.InnerText)
Return True
Catch
Return False
End Try
End Function
Private Function GetResImg(ByVal imgName As String) As Bitmap
Try
Return My.Resources.ResourceManager.GetObject(imgName)
Catch
Return Nothing
End Try
End Function
Private Function GetResIcon(ByVal iconName As String) As Icon
Try
Return My.Resources.ResourceManager.GetObject(iconName)
Catch
Return Nothing
End Try
End Function
Private Sub SetStatus(ByVal status As StatusCodes)
If status = StatusCodes.StatusError Then
' set status icons
lblIco.Image = comImg_err
appNotifyIcon.Icon = comIco_err
lblInfo.Text = "Error"
timerUpdate.Enabled = False
ElseIf status = StatusCodes.StatusOff Then
' set status icons
lblIco.Image = comImg_off
appNotifyIcon.Icon = comIco_off
lblInfo.Text = "No connection"
timerUpdate.Enabled = False
ElseIf status = StatusCodes.StatusOn Then
' set status icons
lblIco.Image = comImg_on
appNotifyIcon.Icon = comIco_on
lblInfo.Text = "Connected"
timerUpdate.Enabled = True
End If
appNotifyIcon.Text = Me.Text + " :: " + lblInfo.Text
lblIco.ToolTipText = "Status: " + lblInfo.Text
End Sub
Private Sub ConnectPorts()
_inCount = 0
_outCount = 0
Try
' close open ports
If spIn.IsOpen Then spIn.Close()
If spOut.IsOpen Then spOut.Close()
Catch
End Try
SetStatus(StatusCodes.StatusOff)
Application.DoEvents()
Try
spIn.PortName = _inPort
spIn.Open()
spOut.PortName = _outPort
spOut.Open()
SetStatus(StatusCodes.StatusOn)
Catch ex As Exception
SetStatus(StatusCodes.StatusError)
MessageBox.Show(ex.Message, Application.ProductName, _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub spIn_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles spIn.DataReceived
' determine if there is data to be read
If e.EventType = IO.Ports.SerialData.Chars Then
' read incoming data (plx protocol)
' http://www.plxdevices.com/AppNotes/PLXApp016.pdf
'
' Speed1Low � LSB 8Bit of Speed Input #1 (First Byte Transmitted)
' Speed1High � MSB 8Bit of Speed Input #1
' Speed2Low � LSB 8Bit of Speed Input #2
' Speed2High � MSB 8Bit of Speed Input #2
' Analog1 � 8Bit of Analog Input #1
' Analog2 � 8Bit of Analog Input #2
' Analog3 � 8Bit of Analog Input #3
' Analog4 � 8Bit of Analog Input #4
' EventPacket � Decimal value of 255 (Binary value 11111111) (9th Byte Transmitted)
'
' (Sequence is repeated)
spIn.Read(_inBuff, 0, _inBuff.Length)
_inCount += 1
' discard any extra data (if necessary)
If spIn.BytesToRead > 0 Then spIn.DiscardInBuffer()
' find the event packet
Dim i As Integer = 0
For i = 0 To _inBuff.Length - 1
If _inBuff(i) = &HFF Then Exit For
Next
' validate index
If (i > 0 And i < _inBuff.Length) AndAlso _
(_inBuff(i - 1) > 0 And _inBuff(i - 1) < 254) Then
' build the lm-1 protocol
' http://www.innovatemotorsports.com/resources/serial-protocol.php
' ---------------------------------------------
' WORD Bit
' 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
'
' 0 1 R F3 F2 F1 F0 0 AF7 0 AF6 AF5 AF4 AF3 AF2 AF1 AF0
' 1 0 0 L12 L11 L10 L9 L8 L7 0 L6 L5 L4 L3 L2 L1 L0
' 2 0 0 mb2 mb1 mb0 bv9 bv8 bv7 0 bv6 bv5 bv4 bv4 bv2 bv1 bv0
' 3..7 0 0 0 0 0 Aux9 Aux8 Aux7 0 Aux6 Aux5 Aux4 Aux3 Aux2 Aux1 Aux0
' ---------------------------------------------
' 2.1 Function/Status Word (Word 0)
'
'
' Bit 15 of always set
'
' Bit 14 (R) is set if currently recording to Flash in LM-1
'
' Bit 13..10 (Func3..0) are function/status bits how interpret the next word (Lambda Word).
'
' Func3..0
'
' 0000 Lambda valid and Aux data valid, normal operation.
' 0001 Lambda value contains O2 level in 1/10%
' 0010 Free air Calib in progress, Lambda data not valid
' 0011 Need Free air Calibration Request, Lambda data not valid
' 0100 Warming up, Lambda value is temp in 1/10% of operating temp.
' 0101 Heater Calibration, Lambda value contains calibration countdown.
' 0110 Error code in Lambda value
' 0111 Lambda Value is Flash level in 1/10%
' 1xxx reserved
'
' Bit 8 contains high bit (bit 7) of AFR multiplier (AF7)
'
' Bit 7 always 0
'
' Bit 6..0 contain remaining 7 bits of AFR multiplier (AF6..AF0).
'
' AFR multiplier is stochiometric AFR value of current fuel setting in the LM-1 times 10. E.g. 147 for gasoline (14.7).
' Air/Fuel Ratio = ((L12..L0) + 500)* (AF7..0) / 10000
' build word 0
Dim w0() As Boolean = {True, False, False, False, False, False, False, False, _
False, False, False, False, False, False, False, False}
Dim word0 As New BitArray(w0)
' apply afr multiplier to word 0
Dim afr_bits As New BitArray(GetBytes(_afrMultiplier))
word0(7) = afr_bits(0)
word0(9) = afr_bits(1)
word0(10) = afr_bits(2)
word0(11) = afr_bits(3)
word0(12) = afr_bits(4)
word0(13) = afr_bits(5)
word0(14) = afr_bits(6)
word0(15) = afr_bits(7)
' ---------------------------------------------
' 2.2 Lambda Word (Word 1)
'
' Lambda in 0.001 Lambda increments when F3..F0 is 0000, offset by 0.5 Lambda.
'
' L = 0 -> 0.5 Lambda
' L = 1022 -> 1.522 Lambda
' L = 1023 Lambda = 1.523
' L = 8191 Lambda = 8.691
Dim multiplier As Double = _inBuff(i - 1) / 255
Dim lambda As Short = ((1760 - 312) * multiplier) + 312 + _lambdaOffset
' get the bytes of the lambda
Dim lambda_bytes() As Byte = GetBytes(lambda)
' drop last 2 bytes and reverse (for big endian)
Dim b(1) As Byte
b(0) = lambda_bytes(1)
b(1) = lambda_bytes(0)
Dim word1 As New BitArray(b)
' ---------------------------------------------
' 2.3 Battery Voltage (Word 2)
'
' Battery voltage digitized to 10 bit (bv9..bv0) and battery divider (mb2..mb0).
' Calculate battery voltage in Volt as bv * 5 * mb / 1023.
' word2 reserved for battery voltage
Dim word2 As New BitArray(16)
' ---------------------------------------------
' 2.4 Aux Input (Word 3..7)
'
' Aux Inputs digitized to 10 bits. 0 = 0V, 1023 = 5V.
'
' If RPM converter is used, Multiply WORD 3 value by 10 to get rpm.
' word3 reserved for aux input
'Dim word3 As New BitArray(16)
' create output packet
word0.CopyTo(_outBuff, 0)
word1.CopyTo(_outBuff, 2)
word2.CopyTo(_outBuff, 4)
'word3.CopyTo(_outBuff, 6)
' discard any unsent data (if necessary)
If spOut.BytesToWrite > 0 Then spOut.DiscardOutBuffer()
Try
' write the packet to the output port
spOut.Write(_outBuff, 0, _outBuff.Length)
_outCount += 1
Catch
End Try
End If
End If
End Sub
Private Sub appNotifyIcon_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles appNotifyIcon.MouseDoubleClick
If (e.Button = Windows.Forms.MouseButtons.Left And _
Not SystemInformation.MouseButtonsSwapped) Or _
(e.Button = Windows.Forms.MouseButtons.Right And _
SystemInformation.MouseButtonsSwapped) Then
' display the main form
Me.Show()
Me.WindowState = FormWindowState.Normal
End If
End Sub
Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If Not bAllowClose And _
e.CloseReason = CloseReason.UserClosing Then
' stop the form from closing
e.Cancel = True
Me.Hide()
Exit Sub
End If
Try
' close open ports
If spIn.IsOpen Then spIn.Close()
If spOut.IsOpen Then spOut.Close()
Catch
End Try
' destroy resources
If Not (comImg_off Is Nothing) Then _
comImg_off.Dispose()
If Not (comImg_on Is Nothing) Then _
comImg_on.Dispose()
If Not (comImg_err Is Nothing) Then _
comImg_err.Dispose()
If Not (comIco_off Is Nothing) Then _
comIco_off.Dispose()
If Not (comIco_on Is Nothing) Then _
comIco_on.Dispose()
If Not (comIco_err Is Nothing) Then _
comIco_err.Dispose()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' load config from xml
If Not LoadXmlConfig(XML_CONFIG_FILE) Then
timerLoad.Enabled = False
MessageBox.Show("Unable to load config from xml.", _
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
bAllowClose = True
Me.Close()
Exit Sub
End If
' validate config
If _inPort.Trim = "" Or _outPort.Trim = "" Then
timerLoad.Enabled = False
MessageBox.Show("Please set the correct ports in the config xml.", _
Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error)
bAllowClose = True
Me.Close()
Exit Sub
End If
' load resources
comImg_off = GetResImg("com_off")
comImg_on = GetResImg("com_on")
comImg_err = GetResImg("com_err")
comIco_off = GetResIcon("transfer_blk")
comIco_on = GetResIcon("transfer_grn")
comIco_err = GetResIcon("transfer_red")
' set initial tray icon
appNotifyIcon.Icon = comIco_off
lblInPort.Text = "IN: " + _inPort
lblOutPort.Text = "OUT: " + _outPort
End Sub
Private Sub frmMain_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
' check for windowstate change
If Me.WindowState = FormWindowState.Minimized Then _
Me.Hide()
End Sub
Private Sub mnuOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOpen.Click
' display the main form
Me.Show()
Me.WindowState = FormWindowState.Normal
End Sub
Private Sub mnuExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuExit.Click
bAllowClose = True
Me.Close()
End Sub
Private Sub mnuReconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuReconnect.Click
ConnectPorts()
End Sub
Private Sub timerLoad_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerLoad.Tick
timerLoad.Enabled = False
ConnectPorts()
End Sub
Private Sub timerUpdate_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timerUpdate.Tick
lblIn.Text = Format(_inCount, "###,###,###,##0")
lblOut.Text = Format(_outCount, "###,###,###,##0")
End Sub
End Class