Arduino Digital Dashboard

Hi all,

So I drive a pretty old car, a 1972 Hillman Imp in fact. This one, actually:

Anyways, as you can imagine the equipment is somewhat basic. So, as I intend to embark on some serious engine tuning so, I thought I'd make use of an arduino to improve the condition monitoring a bit!

Basically I intend to use the arduino to monitor the AFR (Air Fuel Ratio) with help from an AEM wideband controller and it's 0-5V analogue output, the induction boost level, the oil pressure/temp and coolant temp. Also, the plan is to use the arduino to control an electric water pump (such as a Davies Craig etc) using a PWM signal and a suitable transistor. At the same time it could be used to control a cooling fan mounted on the radiator.

I'm not decided yet, but I may even use the arduino to control other features in the car, such as the heater, etc.

The display will be mounted on the dash, with the button to change screen being on or near the steering wheel.... easy reach basically.

I am completely new to electronics, apart from a bit of soldering here and there, but I have used matlab at a basic level before, so am familiar with some aspects of coding! It's great fun learning though and quite rewarding when stuff gets working as you want it to!
At present, all the components are a bit cheap simple, in particular the screen. however, in order to ensure that the digital gauges are able to produce accurate and hence useful readings, the screen especially will have to be upgraded so that it is quicker and has less ghosting etc. I only have one pot too at the moment, hence AFR and water temp being hooked up to the same thing!

Here is the progress so far anyway. I have no real questions at the moment as such (but would welcome any advice) but thought I would start this thread so I have a "base" for the inevitable questions that will arise throughout the project.

and my code (excuse a lot of the comments, mainly for my own reference in case I mind blank and forget what is going on!):

/*   LCD Screen Attempt 3
     With 3 screens, selection of which is controlled by an 
     incremented variable "screen" and a digital interrupt on pin 2
     
     With PWM powered LED representing water pump
     
 * LCD pins:
   RS: Pin 8
   EN: Pin 3
   D4: Pin 4
   D5: Pin 5
   D6: Pin 6
   D7: Pin 7
   
 * Button is on Pin 2, but interrupt 0
 
*/
 
//Include the LCD library
#include <LiquidCrystal.h>

// Initialize an LCD object
LiquidCrystal lcd(8,3,4,5,6,7);

// Define some variables/constants/booleans // 
int buttonInt = 0;
int buttonPin = 2;
int ledPin = 13;
int ewpPin = 9;
int waterTemp = 0;
int potIn = 0;
volatile int screen = 0;    //Must be volatile when used in int

void setup()
{
  //Begin the LCD interface
  lcd.begin(16,2);
  
  //Display something at start
  lcd.clear();
  delay(2000);
  lcd.print("Hillman Pimpin'!");
  delay(3000);
  lcd.clear();
  
  //Pin Modes
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(ewpPin, OUTPUT);
  pinMode(waterTemp, INPUT);
  
  //Attach the Interrupt
  attachInterrupt(buttonInt, buttonPress, RISING);
  
  //Start water pump at 10% capacity
  analogWrite(ewpPin, 255/100);
  
}

void loop()
{
  int potRead = analogRead(potIn);
  int waterTemp = potRead / 10;
  if (waterTemp < 25)
  {
    analogWrite(ewpPin, 255/100);
  }
  if (waterTemp >= 25 && waterTemp < 50)
  {
    analogWrite(ewpPin, 255/10);
  }
  if (waterTemp >= 50)
  {
    analogWrite(ewpPin, 255);
  }
  
  
  if (screen == 0)
  {
    lcd.setCursor(0,0);
    lcd.print("AFR    :");
    lcd.setCursor(0,1);
    lcd.print("Boost  :");
    float AFR = (potRead / 63.94) + 7;
    lcd.setCursor(8,0);
    lcd.print("  ");
    lcd.setCursor(10,0);
    if (AFR < 10)
      {
        lcd.print(" ");
        lcd.setCursor(11,0);
      }
    lcd.print(AFR);
    delay(500);
    lcd.setCursor(0,0);
    
  }
  if (screen == 1)
  {
    lcd.setCursor(0,0);
    lcd.print("Water T:");
    lcd.setCursor(0,1);
    lcd.print("Oil   T:");
    float waterT = (potRead / 10);
    lcd.setCursor(8,0);
    lcd.print(" ");
    if (waterT < 100)
      {
        lcd.setCursor(9,0);
        lcd.print(" ");
        lcd.setCursor(10,0);
        if (waterT < 10)
        {
          lcd.print(" ");
          lcd.setCursor(11,0);
        }
      }
    else
      {
        lcd.setCursor(9,0);
      }
    lcd.print(waterT);
    delay(500);
    lcd.setCursor(0,0);
  }
  if (screen == 2)
  {
    lcd.setCursor(0,0);
    lcd.print("    Screen 3    ");
    lcd.setCursor(0,1);
    lcd.print("                ");
  }
  if (screen == 3)
  {
    lcd.setCursor(0,0);
    lcd.print("    Screen 4    ");
    lcd.setCursor(0,1);
    lcd.print("                ");
  }
  
}

void buttonPress()
{
  /* Debouncing code found using google search, thanks to 
  "Mikalhart" on the old forum */
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  /* If interrupts come faster than 200ms, assume it's a bounce 
  and ignore */
  if (interrupt_time - last_interrupt_time > 200)
  {
    screen = ++screen;
    if (screen == 4)
    {
      screen = 0;
    }
    
  }
  last_interrupt_time = interrupt_time;
}

The ghosting is probably a result of the back light. I don't see a current-limiting resistor in series with the back light LED. You seem to have connected the LCD pin 15 and 16 directly to 5V and ground. Add a resistor, say 150ohm between pin 16 and gnd, you will get it more under control.

Cheers for the tips guys.

The screen is going to be used in conjuction with the more traditional style gauges in the car. It's not going to be used for revs or speed. It's got to be subtle and discreet (more so when it's off) so that it's in keeping with the 60s designed interior.

When it goes in the car, I'll be using a 20x4 (or maybe 20x2?) screen I think, instead of the 16x2 that came with the arduino. The arduino will be replaced with a mega as well, for the extra channels, at the moment I'm just using the current setup to learn about arduinos/electronics/writing the code

First question:
Whilst I've just got a pot hooked up for the input, my value of water temp is just analogRead the input channel / 10.
i.e. it should go from 0 - 102.3
I've used a float value, but the decimal points are just coming up as zeros.

It should be in my first post?

Your division by 10 is going to be integer division, any floating component will be lost. Try this:

float waterT = (float)potRead / 10.0;

Thanks guys, was unaware that float components are lost in such a manner. Working now. Apologies for the basic questions, am doing this pretty "blind" with just here and the reference pages to go on/learn with!
Also- will include relevant code with questions in future.

Good news is that I have just bought a couple more pots, so I have all four displayed variables working now!

Your division by 10 is going to be integer division, any floating component will be lost. Try this:

Do you really think that water temperature differences of less than 1 degree are relevant? Realistically measured?

Probably not, but I'm just playing around at the moment. Familiarizing myself with the arduino, the practices/methods an deciding what I actually want from this project
Once I have actual sensors instead of pots, I will start to finalize ideas and the like. I need to decide on screen size also, which I can't do until the dash is out of the car.

1 Like