Category Archives: Formula Student

UWE Formula Student consists of a team of highly motivated students who are striving for success in the international Formula Student competition. As an extra-curricular activity, it provides a great opportunity for practical application to students studying a variety of degree disciplines.

During my time at University, I worked on many different parts of the project including electrical systems, website design and media.

Steering Wheel – rFactor

Testing the electronic dash using rFactor required a method of transfering the game data to the Arduino. Fortunately creating custom displays for racing simulators has become a popular DIY hobby over the last few years. Therefore there are plenty of examples to be found online of various approaches. A great project by João Ubaldo provided detailed information and instructions for creating the display.

The Arduino is connected to the computer using a USB connection. Data is taken from the game using a plugin; converted to serial and then transfered to the Arduino where it is re-assembled. Initially I used the plugin rfactor2python which provided a great basis to improve on. This plugin is easy to install and modify as it is written using a language called python.

Breadboard assembled electronics being tested using rFactor for input data
Reposted image because there’s a metric **** tonne of code to follow…

As I was using an LCD in addition to the 7 segment display and range of LEDs, a larger amount of data needed to be converted and transfered. This resulted in the following python plugin which breaks everything into byte sized chucks.

Python Serial

"""
rfactor2python - UWE Racing Electronic Dash Test
Credit: Joao C. <me@joaoubaldo.com>
Author: D. Nicklin <danicklin.co.uk>

This example uses PySerial (http://pyserial.sourceforge.net) module.
"""

#  Configuration
# Look inside RF2PyPlugin.__init__
#  /

import serial
import struct

class RF2PyPlugin(object):
    def __init__(self):
        self.PORT = "COM4"
        self.BPS = 9600
        self.RPM_LED_COUNT = 7  # number of LEDs to display RPMs

        self.ser = None

    # game startup
    def Startup(self):
        pass

    # game shutdown
    def Shutdown(self):
        pass

    # entering realtime (where the vehicle can be driven)
    def EnterRealtime(self):
        self.ser = serial.Serial(self.PORT,self.BPS)

# exiting realtime
    def ExitRealtime(self):
        self.ser.close()

    # session started
    def StartSession(self):
        pass

    # session ended
    def EndSession(self):
        pass

    # update plugin with scoring info (approximately once per second)
    #   'info' is a dictionary with scoring data
    def UpdateScoring(self, info):
        pass

    # update plugin with telemetry info
    #   'info' is a dictionary with telemetry data
    def UpdateTelemetry(self, info):
        g = info["mGear"]
        r = info["mEngineRPM"]
        mr = info["mEngineMaxRPM"]
        wt = info["mEngineWaterTemp"]
        ot = info["mEngineOilTemp"]

        val = struct.pack("I", r)
        g = g & 0xFF

        self.ser.write(chr(int(mr/1000)))
        self.ser.write(chr(int(g)))
        self.ser.write(chr(int(ot)))
        self.ser.write(chr(int(wt)))
        self.ser.write(val)
        self.ser.write('\n')

    # See if the plugin wants to take over a hardware control.  If the plugin takes over the
    # control, this method returns true and sets the value of the float pointed to by the
    # second arg.  Otherwise, it returns false and leaves the float unmodified.
    #
    # Important: fRetVal is a list with only one value.
    # In order to modify this value you should do something like:
    # fRetVal[0] = newValue
    def CheckHWControl(self, controlName, fRetVal):
        return False

The Arduino code reads the incoming serial data, byte by byte, these are placed into a buffer. The gear value is too large for a single byte and instead is split into four. The displays are refreshed every time it recieves a newline character. A little maths is performed to ensure that the full LED RPM range is utilised.

Arduino Sketch

/*
UWE RACING
Daniel Nicklin
Formula Student Steering Wheel Display

Reads data from rfactor using a python plugin
Dsplays important variables on LCD, 7 segment and range of leds
Created 26/03/2013
Last Modified 26/03/2013
*/
  void setup() {
  // Setup - run once
  //Serial
  Serial.begin(9600);
  }

  void loop() {
    while (Serial.available()) {
   char c = (char)Serial.read();
    //Check for end of carriage
    if (c == '\n') {
  //asign values to variables
   rpmMaxValue =(buffer[0]*1000);
   newGear = constrain(buffer[1], -1, 7); // gear value between -1 (R) and 7
   oilTemp = byte(buffer[2]);
   waterTemp = byte(buffer[3]);

    //Convert bytes in buffer to long integer for currrent rpm value
    union u_tag {
    byte b[4];
    unsigned long ulval;
    } u;
    u.b[0] = buffer[4];
    u.b[1] = buffer[5];
    u.b[2] = buffer[6];
    u.b[3] = buffer[7];
    newRpmValue = u.ulval;

   //rpmLedLevel = (newRpmValue/(rpmMaxValue/7));

   // Sets rpm value range for which leds are lit
   rpmLedStart = rpmMaxValue*0.8; //Sets minimum

   rpmMaxValue = rpmMaxValue * 1.05; //Game max value is set too low

   rpmLedLevel = map(constrain(newRpmValue,rpmLedStart,rpmMaxValue), rpmLedStart, rpmMaxValue, 0, 7);

      //Update shift registers if current gear or rpm has changed
   if (newGear != gear || newRpmValue != rpmValue){
       digitalWrite(latchPin, LOW);             //Pull latch LOW to start sending data
       shiftOut(dataPin, clockPin, MSBFIRST,gearArray[newGear]);          //Send the data
      shiftOut(dataPin, clockPin, MSBFIRST,rpmArray[rpmLedLevel]);          //Send the data
      digitalWrite(latchPin, HIGH);            //Pull latch HIGH to stop sending data
      gear = newGear;
      rpmValue = newRpmValue;
   }
      pos = 0; //Reset position in buffer to start
    }
    else {
      //Add serial read data to buffer and increment position
      buffer[pos] = c;
      pos++;
       //check buffer size has not been exceeded
       if (pos >= sizeof(buffer))
         pos = 0;
   }
  }
  }

I attempted to display only the important sections of code in this post as there is rather a lot of it! I have attached the full code included start-up tests as a ZIP file.  I’d be happy to know if you use this project and it’s code for Formula Student or a racing simulator of your own.

Requirements:

Steering Wheel – Electronics Prototyping

The steering wheel electronics were the first part of the steering wheel and electronic dash design to be researched and prototyped. The selected electronic components were assembled on a breadboard to allow for alterations to be made easily during the research and development stage of this project. As we didn’t have access to a running engine, the electronic dash was tested using car telemetry provided by the racing game rFactor.

Arduino

The Arduino Uno is an open-source microcontroller and simple I/O board. Due to its simplicity and low-cost it is a popular development environment for stand-alone and computer connected projects. Arduino is programmed using a Wiring-based language which is similar to C++.

RPM indicator

Located on either the top of the steering wheel or on the dash, a row of LEDs will represent the RPM range. The range will consist of a number of green, yellow and red LEDs and will light up from the outside inwards. Optional is the addition of a shift light.

Selected Gear Indicator

A 7 segment led display will be located in the middle of the steering wheel and be used to indicate the current gear. When no gear is selected (neutral) then “n.” will be displayed.

LCD Display

A small LCD display may be used to display important temperatures and current car states. This would be useful to the driver and car mechanics to monitor conditions without having to plug in a laptop. It will display a number of screen or menus that can be changed by directional buttons.

List of Steering Wheel Components

  • RPM indication LED array (6 x Green, 6 x Yellow, 3 x Red)
  • Selected gear indicator (0.8” Character size)
  • LCD display (20 x 2)
  • Warning LED (High Power Blue)
  • Push Button

Steering Wheel and Electronic Dash

Over the past year I have been involved in designing, manufacturing and building a bespoke steering wheel and electronic dash display for a formula student car along with other members of the UWE Racing team. After taking the majority of our designs and manufactured components to this year’s Formula Student event at Silverstone to be judged. Although we achieved an 8th place finish, we were surprised with some of the feedback from the judges regardling simple principles and major oversights.

Work has now begun using the information gained from the event to modify, refine and improve our designs for the car that will be built over this coming year. I will be recovering all of the decision making and design work for the steering wheel and display from the last year, in order to design and build a much improved version.

The start of the design process started with making a comparision of steering wheels available on the market and a feasible product that could be manufactured and assembled within University. The design of our steering wheel evolved in shape, size and complexity from the standard Momo design (1) to the final design we used for the prototype (9). This was due to tailoring to our needs in terms of; available cockpit space, driver ergonomics, loading requirements, material selection and positioning of the electronic display components.

Steering Wheel Collage
Collage of the steering wheel design progression. From standard Momo design to our final wheel.