Compare commits
26 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 077b123620 | |||
| bd1e361446 | |||
| 83585910f9 | |||
| ab0e8cce86 | |||
| c33804c747 | |||
| bc9381627c | |||
| 1bf8b589a3 | |||
| 9f0d7120ee | |||
| b60b053aed | |||
| 231862f06b | |||
| ba50a8ce69 | |||
| 8cc959504f | |||
| e1474b162c | |||
| f54e0d2fdb | |||
| 3215bb2733 | |||
| 2dd1612ec8 | |||
| 44ef5ce6cb | |||
| eb116803d0 | |||
| 8f0661a73d | |||
| df6e27783e | |||
| ac60af82a0 | |||
| f085cd8e8b | |||
| ceb2f538b8 | |||
| aa96a3b3c2 | |||
| 3f6aedffbc | |||
| c6cd1c0b99 |
9 changed files with 192 additions and 70 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
/build
|
/build
|
||||||
/dist
|
/dist
|
||||||
OutGaugeInterpreter.spec
|
OutGaugeInterpreter.spec
|
||||||
|
*.csv
|
||||||
17
.vscode/tasks.json
vendored
Normal file
17
.vscode/tasks.json
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "echo",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "echo Hello"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "build exe windows",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "pyinstaller.exe --add-data .\\GAME_METHODS\\*:.\\GAME_METHODS\\ --onefile --noconsole --optimize 2 .\\OutGaugeInterpreter.py"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -28,9 +28,9 @@ def unpackData(unpackedData):
|
||||||
carData = {"time":unpackedData[0],
|
carData = {"time":unpackedData[0],
|
||||||
"carName":unpackedData[1].decode("utf-8"),
|
"carName":unpackedData[1].decode("utf-8"),
|
||||||
"flags": decodeFlag(unpackedData[2]),
|
"flags": decodeFlag(unpackedData[2]),
|
||||||
"gear": unpackedData[3],
|
"Gear": unpackedData[3],
|
||||||
"PLID": unpackedData[4],
|
"PLID": unpackedData[4],
|
||||||
"speed": unpackedData[5],
|
"Speed": unpackedData[5],
|
||||||
"rpm": unpackedData[6],
|
"rpm": unpackedData[6],
|
||||||
"turboPressure":unpackedData[7],
|
"turboPressure":unpackedData[7],
|
||||||
"engTemp":unpackedData[8],
|
"engTemp":unpackedData[8],
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,18 +1,25 @@
|
||||||
#please use python 3.11
|
#please use python 3.11
|
||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
|
import tkinter.ttk
|
||||||
import serial
|
import serial
|
||||||
import time
|
import time
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
|
import threading
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
import tkinter
|
||||||
from GAME_METHODS import *
|
from GAME_METHODS import *
|
||||||
|
import functools #used for passing variables into callbacks
|
||||||
|
|
||||||
##check if python 3.11 is running code and exit if not
|
##check if python 3.11 is running code and exit if not
|
||||||
|
|
||||||
if not(sys.version_info[0] == 3 and sys.version_info[1] == 11):
|
if not(sys.version_info[0] == 3 and sys.version_info[1] == 11):
|
||||||
raise Exception("code must be run in python verion 3.11.\ninput struct for network needs to be changed per python version.")
|
raise Exception("code must be run in python verion 3.11.\ninput struct for network needs to be changed per python version.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##system init
|
||||||
runningOs = platform.system()
|
runningOs = platform.system()
|
||||||
|
|
||||||
UDP_IP = "0.0.0.0"
|
UDP_IP = "0.0.0.0"
|
||||||
|
|
@ -20,21 +27,42 @@ BEAMNG_UDP_PORT = 4444
|
||||||
FORZA_UDP_PORT= 4843
|
FORZA_UDP_PORT= 4843
|
||||||
SERIAL_PORT = ""
|
SERIAL_PORT = ""
|
||||||
firstRun= True #used to do the headers for csv files
|
firstRun= True #used to do the headers for csv files
|
||||||
|
pushingToArduino = False
|
||||||
|
stopThread = False
|
||||||
|
|
||||||
|
class outputValue(Enum):
|
||||||
|
SPEED = "Speed"
|
||||||
|
GEAR = "Gear"
|
||||||
|
|
||||||
class GameType(Enum):
|
class GameType(Enum):
|
||||||
NONE=0
|
NONE=0
|
||||||
BEAMNG = "BEAMNG"
|
BEAMNG = "BEAMNG"
|
||||||
FORZA = "FORZA"
|
FORZA = "FORZA"
|
||||||
|
|
||||||
|
class ProgramState(Enum):
|
||||||
|
PUSHING_DATA = 1
|
||||||
|
WAITNG = 2
|
||||||
|
ERROR = 3
|
||||||
|
|
||||||
|
appState =ProgramState.WAITNG
|
||||||
connectedArduino = False
|
connectedArduino = False
|
||||||
connectedWebSocket = False
|
connectedWebSocket = False
|
||||||
gameSelected = False
|
gameSelected = False
|
||||||
portToConnect= 0
|
portToConnect= 0
|
||||||
gameType= GameType.NONE
|
|
||||||
carData = 0
|
carData = 0
|
||||||
csvOut = False
|
csvOut = False
|
||||||
|
|
||||||
#Functions <-------------------------------------------------------------------------------------------
|
#Functions <-------------------------------------------------------------------------------------------
|
||||||
|
def checkBoxChange():
|
||||||
|
if tkLoggingEnabled.get()==True:
|
||||||
|
loggingLocationEntry.config(state='normal')
|
||||||
|
loggingLocationText.set(value= "./"+ tkGametype.get()+"_"+str(int(time.time()))+".csv")
|
||||||
|
loggingLocationEntry.insert(0,loggingLocationText.get())
|
||||||
|
else:
|
||||||
|
loggingLocationText.set(value="")
|
||||||
|
loggingLocationEntry.delete(0,tkinter.END)
|
||||||
|
loggingLocationEntry.config(state='disabled')
|
||||||
|
|
||||||
def csvWriteOut(firstRun,carData,csvFile):
|
def csvWriteOut(firstRun,carData,csvFile):
|
||||||
if firstRun == True:
|
if firstRun == True:
|
||||||
out=""
|
out=""
|
||||||
|
|
@ -46,6 +74,66 @@ def csvWriteOut(firstRun,carData,csvFile):
|
||||||
outString = outString + str(num) +","
|
outString = outString + str(num) +","
|
||||||
csvFile.write(outString+"\n")
|
csvFile.write(outString+"\n")
|
||||||
|
|
||||||
|
def runningThread():
|
||||||
|
global stopThread
|
||||||
|
gameType= tkGametype.get()
|
||||||
|
|
||||||
|
#check everything is connected
|
||||||
|
if gameType==GameType.BEAMNG.value:
|
||||||
|
portToConnect=BEAMNG_UDP_PORT
|
||||||
|
elif gameType==GameType.FORZA.value:
|
||||||
|
portToConnect=FORZA_UDP_PORT
|
||||||
|
|
||||||
|
try:
|
||||||
|
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||||
|
sock.bind((UDP_IP,portToConnect))
|
||||||
|
except:
|
||||||
|
print("please check you are able to open the socket on this system\ntired to open port: "+str(portToConnect))
|
||||||
|
exit()
|
||||||
|
|
||||||
|
try:
|
||||||
|
toPi=serial.Serial(SERIAL_PORT,115200,timeout=2) #connect to arduino
|
||||||
|
except:
|
||||||
|
print("please check connection to arduino and verify the correct serial port")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
csvOut = tkLoggingEnabled.get()
|
||||||
|
|
||||||
|
if csvOut == True:
|
||||||
|
csvFile = open(loggingLocationText.get(),"a")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
while not stopThread:
|
||||||
|
data, addr = sock.recvfrom(1024)
|
||||||
|
if gameType == GameType.BEAMNG.value:
|
||||||
|
unpackedData = struct.unpack(BEAMNG_METHODS.BEAMNG_DATA_FORMAT,data)
|
||||||
|
carData = BEAMNG_METHODS.unpackData(unpackedData)
|
||||||
|
kmh=carData[tkDataTypeOut.get()]
|
||||||
|
if tkDataTypeOut.get() == "Gear":
|
||||||
|
kmh = kmh -1
|
||||||
|
if csvOut == True:
|
||||||
|
csvWriteOut(firstRun,carData,csvFile)
|
||||||
|
firstRun=False
|
||||||
|
elif gameType == GameType.FORZA.value:
|
||||||
|
unpackedData = struct.unpack(FORZA_METHODS.FORZA_DATA_FORMAT,data)
|
||||||
|
carData = FORZA_METHODS.unpackData(unpackedData)
|
||||||
|
kmh = carData[tkDataTypeOut.get()]
|
||||||
|
if csvOut == True:
|
||||||
|
csvWriteOut(firstRun,carData,csvFile)
|
||||||
|
firstRun=False
|
||||||
|
|
||||||
|
try:
|
||||||
|
if (tkDataTypeOut.get() == outputValue.SPEED.value):
|
||||||
|
kmh = kmh*3.6
|
||||||
|
|
||||||
|
toPi.write(str(kmh).encode()+":".encode())
|
||||||
|
except:
|
||||||
|
print("arduino disconnected please check connection\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#code runs from here<-----------------------------------------------------------------------------------------------------------
|
#code runs from here<-----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
if runningOs == 'Windows':
|
if runningOs == 'Windows':
|
||||||
|
|
@ -58,71 +146,86 @@ else:
|
||||||
print("OS detection failed setting serial port to 'COM5'\n")
|
print("OS detection failed setting serial port to 'COM5'\n")
|
||||||
SERIAL_PORT = 'COM5'
|
SERIAL_PORT = 'COM5'
|
||||||
|
|
||||||
#select game
|
def startStopButtonFunc():
|
||||||
while gameSelected == False:
|
global appState
|
||||||
gameNo = input("1:BEAMNG\n2:FORZA\n\n7:Toggle CSV out ("+str(csvOut)+")\n9:SET SERIAL PORT ("+SERIAL_PORT+")\n")
|
if appState == ProgramState.WAITNG:
|
||||||
if gameNo == "1":
|
startStopButton.config(text="stop")
|
||||||
portToConnect = BEAMNG_UDP_PORT
|
appState = ProgramState.PUSHING_DATA
|
||||||
gameSelected = True
|
stopThread=False
|
||||||
gameType=GameType.BEAMNG
|
workThread = threading.Thread(target=runningThread)
|
||||||
print("BeamNG Selected")
|
workThread.start()
|
||||||
elif gameNo == "2":
|
statusTextVar.set("Running...")
|
||||||
portToConnect = FORZA_UDP_PORT
|
|
||||||
gameType=GameType.FORZA
|
|
||||||
gameSelected=True
|
|
||||||
print("Forza Selected")
|
|
||||||
elif gameNo == "7":
|
|
||||||
if csvOut == True:
|
|
||||||
csvOut=False
|
|
||||||
elif csvOut ==False:
|
|
||||||
csvOut =True
|
|
||||||
elif gameNo == "9":
|
|
||||||
SERIAL_PORT = input("set serial port: ")
|
|
||||||
else:
|
|
||||||
print("please select a number from the list")
|
|
||||||
|
|
||||||
#check everything is connected
|
elif appState == ProgramState.PUSHING_DATA:
|
||||||
while connectedWebSocket == False:
|
startStopButton.config(text="start")
|
||||||
try:
|
appState = ProgramState.WAITNG
|
||||||
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
statusTextVar.set("Waiting...")
|
||||||
sock.bind((UDP_IP,portToConnect))
|
stopThread = True
|
||||||
connectedWebSocket = True
|
|
||||||
except:
|
|
||||||
print("please check you are able to open the socket on this system\ntired to open port: "+portToConnect)
|
|
||||||
exit()
|
|
||||||
|
|
||||||
while connectedArduino == False:
|
|
||||||
try:
|
|
||||||
toPi=serial.Serial(SERIAL_PORT,115200,timeout=2) #connect to arduino
|
|
||||||
connectedArduino = True
|
|
||||||
except:
|
|
||||||
print("please check connection to arduino and verify the correct serial port")
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
if csvOut == True:
|
|
||||||
csvFile = open(gameType.value+"_"+str(int(time.time()))+'.csv',"a")
|
|
||||||
|
|
||||||
|
|
||||||
|
##GUI init
|
||||||
|
rootFrameGui= tkinter.Tk()
|
||||||
|
rootFrameGui.title("Car speed to arduino")
|
||||||
|
##rootFrameGui.geometry("400x200")
|
||||||
|
|
||||||
print("ready:\n")
|
bottomBarFrameGui = tkinter.ttk.Frame(rootFrameGui,padding=0,relief="groove",borderwidth=2,)
|
||||||
while True:
|
bottomBarFrameGui.pack(anchor="se",side="bottom",fill="x")
|
||||||
data, addr = sock.recvfrom(1024)
|
firstFrameGui=tkinter.ttk.Frame(rootFrameGui,padding=2,relief="groove",borderwidth=2)
|
||||||
if gameType == GameType.BEAMNG:
|
firstFrameGui.pack(anchor="ne",side="left",expand=True)
|
||||||
unpackedData = struct.unpack(BEAMNG_METHODS.BEAMNG_DATA_FORMAT,data)
|
secondFrameGui=tkinter.ttk.Frame(rootFrameGui,padding=2,relief="groove",borderwidth=2)
|
||||||
carData = BEAMNG_METHODS.unpackData(unpackedData)
|
secondFrameGui.pack(anchor="nw",side="right",expand=True)
|
||||||
kmh=carData["speed"]*3.6
|
serialFrameGui = tkinter.ttk.Frame(firstFrameGui,padding=5,relief="groove",borderwidth=2)
|
||||||
if csvOut == True:
|
serialFrameGui.pack(anchor="nw")
|
||||||
csvWriteOut(firstRun,carData,csvFile)
|
serialLableText =tkinter.StringVar()
|
||||||
firstRun=False
|
serialLableText.set("Serial Port:")
|
||||||
elif gameType == GameType.FORZA:
|
serialLable = tkinter.Label(serialFrameGui,textvariable=serialLableText)
|
||||||
unpackedData = struct.unpack(FORZA_METHODS.FORZA_DATA_FORMAT,data)
|
serialLable.pack(side="top")
|
||||||
carData = FORZA_METHODS.unpackData(unpackedData)
|
serialEntry=tkinter.Entry(serialFrameGui)
|
||||||
kmh = carData["Speed"]*3.6
|
serialEntry.insert(0,SERIAL_PORT)
|
||||||
if csvOut == True:
|
serialEntry.pack(side="left")
|
||||||
csvWriteOut(firstRun,carData,csvFile)
|
tkGametype = tkinter.StringVar()
|
||||||
firstRun=False
|
tkGametype.set(GameType.BEAMNG.value)
|
||||||
try:
|
gameSelectFrame= tkinter.ttk.Frame(secondFrameGui,padding=5,relief="groove",borderwidth=2)
|
||||||
toPi.write(str(kmh).encode()+":".encode())
|
gameSelectFrame.pack(anchor="se")
|
||||||
except:
|
gameSelectText= tkinter.StringVar()
|
||||||
print("arduino disconnected please check connection\n")
|
gameSelectText.set("Select Game:")
|
||||||
|
gameSelectLable = tkinter.Label(gameSelectFrame,textvariable=gameSelectText)
|
||||||
|
gameSelectLable.pack(side="top")
|
||||||
|
tkinter.Label(gameSelectFrame,textvariable=gameSelectText)
|
||||||
|
gameSelectLOptions= [GameType.BEAMNG,GameType.FORZA]
|
||||||
|
##gameSelectRadioButtons
|
||||||
|
##space after text is so the buttons are the same size
|
||||||
|
tkinter.Radiobutton(gameSelectFrame,text="BeamNG ",variable=tkGametype,value=GameType.BEAMNG.value,command=checkBoxChange).pack(anchor="w")
|
||||||
|
tkinter.Radiobutton(gameSelectFrame,text="Forza ",variable=tkGametype,value=GameType.FORZA.value,command=checkBoxChange).pack(anchor="w")
|
||||||
|
tkDataTypeOut = tkinter.StringVar()
|
||||||
|
tkDataTypeOut.set(outputValue.SPEED.value)
|
||||||
|
dataTypeFrame = tkinter.ttk.Frame(secondFrameGui,padding=5,relief="groove",borderwidth=2)
|
||||||
|
dataTypeFrame.pack()
|
||||||
|
dataTypeLableText = tkinter.StringVar()
|
||||||
|
dataTypeLableText.set(value="Select Data Type:")
|
||||||
|
dataTypeLable = tkinter.Label(dataTypeFrame,textvariable=dataTypeLableText).pack(side="top")
|
||||||
|
tkinter.Radiobutton(dataTypeFrame,text="Speed",variable=tkDataTypeOut,value=outputValue.SPEED.value).pack(anchor="w")
|
||||||
|
tkinter.Radiobutton(dataTypeFrame,text="Gear",variable=tkDataTypeOut,value=outputValue.GEAR.value).pack(anchor="w")
|
||||||
|
loggingFrameGui= tkinter.ttk.Frame(firstFrameGui,padding=5,relief="groove",borderwidth=2)
|
||||||
|
loggingFrameGui.pack(anchor="nw")
|
||||||
|
tkLoggingEnabled=tkinter.BooleanVar()
|
||||||
|
tkLoggingEnabled.set(False)
|
||||||
|
tkinter.Checkbutton(loggingFrameGui,text="Enable Logging",variable=tkLoggingEnabled,onvalue=True,offvalue=False,command=checkBoxChange).pack(side="top")
|
||||||
|
loggingLocationText = tkinter.StringVar(value="")
|
||||||
|
loggingLocationEntry = tkinter.Entry(loggingFrameGui)
|
||||||
|
loggingLocationEntry.insert(0,loggingLocationText.get())
|
||||||
|
loggingLocationEntry.config(state='disabled')
|
||||||
|
loggingLocationEntry.pack(side="bottom")
|
||||||
|
startStopButton= tkinter.Button(bottomBarFrameGui,text= "start",command= startStopButtonFunc)
|
||||||
|
startStopButton.pack(side="right",fill="x")
|
||||||
|
statusTextVar = tkinter.StringVar(value="waiting...")
|
||||||
|
statusLable = tkinter.Label(bottomBarFrameGui,textvariable= statusTextVar)
|
||||||
|
statusLable.pack(anchor="w")
|
||||||
|
arduinoConnectedFrameGui = tkinter.ttk.Frame(secondFrameGui,padding=5,relief="groove",borderwidth=2)
|
||||||
|
arduinoConnectedFrameGui.pack()
|
||||||
|
arduinoConnectedStatusText=tkinter.StringVar(value="Connected OK")
|
||||||
|
arduinoConnectedLable = tkinter.Label(arduinoConnectedFrameGui,textvariable=arduinoConnectedStatusText)
|
||||||
|
arduinoConnectedLable.pack()
|
||||||
|
|
||||||
|
|
||||||
|
rootFrameGui.mainloop()
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
pyinstaller.exe --add-data .\GAME_METHODS\*:.\GAME_METHODS\ --onefile .\OutGaugeInterpreter.py
|
pyinstaller.exe --add-data .\GAME_METHODS\*:.\GAME_METHODS\ --onefile .\OutGaugeInterpreter.py
|
||||||
|
pyinstaller.exe --add-data .\GAME_METHODS\*:.\GAME_METHODS\ --onefile --noconsole --optimize 2 .\OutGaugeInterpreter.py
|
||||||
|
pyinstaller --add-data ./GAME_METHODS/*:./GAME_METHODS/ --onefile ./OutGaugeInterpreter.py
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
pyserial==3.5
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue