Code:
/*
=====================
= Pcars_udp_rx_v2.1 =
=====================
Version Control
===============
V1 - Copy of esp8266/WiFiscan & WiFiUDPsendrecievestring merged..
scan for finding Hotspot, udp for UDP.
Recieves packet of size 1367 (Pcars packet size)
V1.1 Tidy code & reformat.
Changed packet size from 255 to 1367.
*V2 - Retrieve packets and move to struct for analysis.
V2.1 Removed Arduino-dash code..
V2.2 Decode ParticipantInfoString
* NOTE - ESP 44% Full...
*
Program Desciption
==================
Connects to Hotspot (my S5 at present), reads UDP stream on Port 5606.
Port 5606 is the default port for Pcars on all platforms.
I/Os
====
Just ESP8266 at mo.
Rx/Tx - serial (Tx > Tx / Rx > Rx on UNO) - Teensy probably opposite..
*** Move GPIO 0 to Gnd "BEFORE" rebooting, for flash mode.
CH_PD & RST & GPIO2 pulled to VCC with 3k3.
*/
//============================================================================
//= Libraries
//============================================================================
// ESP8266 Wifi
#include <ESP8266WiFi.h>
// Standard Wifi UDP Lib
#include <WiFiUdp.h>
// Data struct for Pcars
//#include "data_struct_arduino.h"
//============================================================================
//= Setup Definitions
//============================================================================
//unsigned int localPort = 2390; // local port to listen on
unsigned int localPort = 5606; // Pcars UDP Port on all platforms
//============================================================================
//= Storage section
//============================================================================
int status = WL_IDLE_STATUS;
char ssid[] = "S5 Hotspot"; // your network SSID (name)
char pass[] = "*********"; // your network password (use for WPA, or use as key for WEP)
char packetBuffer[1367]; //buffer to hold incoming packet
//============================================================================
//= Original Struct's, re-done as fields
// struct sParticipantInfoStrings
//static const unsigned long sPacketSize = 1347;
unsigned int ParticipantInfoStrings = 1347; // Is a sParticipantInfoStrings packet
unsigned int ParticipantInfoStringsBuild; // 0
byte ParticipantInfoStringsPacketType; // 2
char CarName[64]; // 3
char CarClassName[64]; // 67
char TrackLocation[64]; // 131
char TrackVariation[64]; // 195
char Name[16][64]; // 259
float FastestLapTime[16]; // 1283
// 1347
//struct sTelemetryData
// static const unsigned long sPacketSize = 1367;
unsigned int Telemetry = 1347; // Is a sParticipantInfoStrings packet
unsigned int TelemetryBuild; // 0
byte TelemetryPacketType; // 2
// Game states
byte GameSessionState; // 3
// Participant info
char ViewedParticipantIndex; // 4
char NumParticipants; // 5
// Unfiltered input
byte UnfilteredThrottle; // 6
byte UnfilteredBrake; // 7
char UnfilteredSteering; // 8
byte UnfilteredClutch; // 9
byte RaceStateFlags; // 10
// Event information
byte LapsInEvent; // 11
// Timings
float BestLapTime; // 12
float LastLapTime; // 16
float CurrentTime; // 20
float SplitTimeAhead; // 24
float SplitTimeBehind; // 28
float SplitTime; // 32
float EventTimeRemaining; // 36
float PersonalFastestLapTime; // 40
float WorldFastestLapTime; // 44
float CurrentSector1Time; // 48
float CurrentSector2Time; // 52
float CurrentSector3Time; // 56
float FastestSector1Time; // 60
float FastestSector2Time; // 64
float FastestSector3Time; // 68
float PersonalFastestSector1Time; // 72
float PersonalFastestSector2Time; // 76
float PersonalFastestSector3Time; // 80
float WorldFastestSector1Time; // 84
float WorldFastestSector2Time; // 88
float WorldFastestSector3Time; // 92
unsigned int JoyPad; // 96
// Flags
byte HighestFlag; // 98
// Pit info
byte PitModeSchedule; // 99
// Car state
int OilTempCelsius; // 100
unsigned int OilPressureKPa; // 102
int WaterTempCelsius; // 104
unsigned int WaterPressureKpa; // 106
unsigned int FuelPressureKpa; // 108
byte CarFlags; // 110
byte FuelCapacity; // 111
byte Brake; // 112
byte Throttle; // 113
byte Clutch; // 114
char Steering; // 115
float FuelLevel; // 116
float Speed; // 120
unsigned int Rpm; // 124
unsigned int MaxRpm; // 126
byte GearNumGears; // 128
byte BoostAmount; // 129
char EnforcedPitStopLap; // 130
byte CrashState; // 131
float OdometerKM; // 132
float Orientation[3]; // 136
float LocalVelocity[3]; // 148
float WorldVelocity[3]; // 160
float AngularVelocity[3]; // 172
float LocalAcceleration[3]; // 184
float WorldAcceleration[3]; // 196
float ExtentsCentre[3]; // 208
// Wheels / Tyres
byte TyreFlags[4]; // 220
byte Terrain[4]; // 224
float TyreY[4]; // 228
float TyreRPS[4]; // 244
float TyreSlipSpeed[4]; // 260
byte TyreTemp[4]; // 276
byte TyreGrip[4]; // 280
float TyreHeightAboveGround[4]; // 284
float TyreLateralStiffness[4]; // 300
byte TyreWear[4]; // 316
byte BrakeDamage[4]; // 320
byte SuspensionDamage[4]; // 324
int BrakeTempCelsius[4]; // 328
unsigned int TyreTreadTemp[4]; // 336
unsigned int TyreLayerTemp[4]; // 344
unsigned int TyreCarcassTemp[4]; // 352
unsigned int TyreRimTemp[4]; // 360
unsigned int TyreInternalAirTemp[4]; // 368
float WheelLocalPositionY[4]; // 376
float RideHeight[4]; // 392
float SuspensionTravel[4]; // 408
float SuspensionVelocity[4]; // 424
unsigned int AirPressure[4]; // 440
// Extras
float EngineSpeed; // 448
float EngineTorque; // 452
// Car damage
byte AeroDamage; // 456
byte EngineDamage; // 457
// Weather
char AmbientTemperature; // 458
char TrackTemperature; // 459
byte RainDensity; // 460
char WindSpeed; // 461
char WindDirectionX; // 462
char WindDirectionY; // 463
//sParticipantInfo
char ParticipantInfo[56]; // 464 ** Has a separate Struct that this will need breaking down into
// 56*16=896
float TrackLength; // 1360
byte Wings[2]; // 1364
byte DPad; // 1366
// 1368 struct is padded to
/*
struct sParticipantInfo
{
int sWorldPosition[3]; // 0
unsigned int sCurrentLapDistance; // 6
byte sRacePosition; // 8
byte sLapsCompleted; // 9
byte sCurrentLap; // 10
byte sSector; // 11
float sLastSectorTime; // 14
// 16
*/
unsigned int loop16 = 0;
unsigned int loop64 = 0;
//============================================================================
//= Setup objects
//============================================================================
WiFiUDP Udp; // Create Udp object
//============================================================================
//= Setup
//============================================================================
void setup() {
//Initialize serial and wait for port to open:
delay(2000);
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();
Serial.println("Starting UDP");
Udp.begin(localPort);
}
//============================================================================
//= Main Loop
//============================================================================
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
// Serial.print(" - From ");
// IPAddress remoteIp = Udp.remoteIP();
// Serial.print(remoteIp);
// Serial.print(", port ");
// Serial.println(Udp.remotePort());
if (packetSize == ParticipantInfoStrings) {
Serial.println("***** Received Participant Info Strings ***** ");
Udp.read(packetBuffer, 1347);
// read packetbuffer(x) into correct fields.
// build is an uint. word is same as uint
ParticipantInfoStringsBuild = word(packetBuffer[0], packetBuffer[1]);
ParticipantInfoStringsPacketType = packetBuffer[2];
for (int carname = 0; carname <=63; carname++) {
CarName[carname] = packetBuffer[(carname+3)];
// int temp_name = carname + 3;
// Serial.print("Carname [");Serial.print(carname);
// Serial.print("] is packetbuffer no");Serial.println(temp_name);
}
for (int carclassname = 0; carclassname <= 63; carclassname++) {
CarClassName[carclassname] = packetBuffer[(67 + carclassname)];
}
for (int tracklocation = 0; tracklocation <= 63; tracklocation++) {
TrackLocation[tracklocation] = packetBuffer[(131 + tracklocation)];
}
for (int trackvariation = 0; trackvariation <= 63; trackvariation++) {
TrackVariation[trackvariation] = packetBuffer[(195 + trackvariation)];
}
int packetno = 259;
for (int name16 = 0; name16 <= 15; name16++) {
for (int name64 = 0; name64 <= 63; name64++) {
Name[name16][name64] = packetBuffer[packetno];
packetno++;
}
}
int packetno_2 = 1283;
for (int fastestlaptime = 0; fastestlaptime <= 15; fastestlaptime++) {
unsigned long highWord = word(packetBuffer[packetno_2], packetBuffer[(packetno_2+1)]);
unsigned long lowWord = word(packetBuffer[(packetno_2+2)], packetBuffer[(packetno_2+3)]);
unsigned long newlong = highWord << 16 | lowWord;
FastestLapTime[fastestlaptime] = float(newlong);
packetno_2 += 4;
}
Serial.print("Raw Contents of ParticipantInfoStrings packetBuffer:");
Serial.println(packetBuffer);
Serial.print("Build:"); Serial.println(ParticipantInfoStringsBuild);
Serial.print("Packet Type:"); Serial.println(ParticipantInfoStringsPacketType);
Serial.print("Car Name:"); Serial.println(CarName);
Serial.print("Car Class Name:"); Serial.println(CarClassName);
Serial.print("Track Location:"); Serial.println(TrackLocation);
Serial.print("Track Variation:"); Serial.println(TrackVariation);
for (int nameloop = 0; nameloop <= 15; nameloop++) {
Serial.print("Name "); Serial.print(nameloop);
Serial.print(" is:"); Serial.println(Name[nameloop]);
}
for (int fastestlap = 0; fastestlap <= 15; fastestlap++) {
Serial.print("Participant no "); Serial.print(fastestlap);
Serial.print(" Fastest Lap :"); Serial.println(FastestLapTime[fastestlap]);
}
}
else if (packetSize == Telemetry) {
Udp.read(packetBuffer, 1367);
}
/*
// read the packet into packetBufffer
int len = Udp.read(packetBuffer, 1367);
if (len > 0) packetBuffer[len] = 0;
Serial.print(" - Contents:");
Serial.println(packetBuffer);
*/
}
}
//============================================================================
//= Serial print WiFi details
//============================================================================
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
// END OF PROGRAM
Hope that helps...
Luv
Chrisie..