Water boiler controller help needed

Hi. Have very little and very basic coding experience but my boiler controlls failed so i need to make my own. I am trying to stich multiple codes for my need. Found this code for boiler but the guy uses buttons connected to analog input and i have 16x2 lcd shield i would like to use. Here is my code:

#include <OneWire.h>
#include <DallasTemperature.h>
#include<EEPROM.h>
#include <LiquidCrystal.h>
//LCD pin to Arduino
const int pin_RS = 8;
const int pin_EN = 9;
const int pin_d4 = 4;
const int pin_d5 = 5;
const int pin_d6 = 6;
const int pin_d7 = 7;
const int pin_BL = 10;
LiquidCrystal lcd( pin_RS,  pin_EN,  pin_d4,  pin_d5,  pin_d6,  pin_d7);
int add_chk = 0;
int check_val = 10;
int c_temp = 0;
int c_temp_add = 1;

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define set       0
#define inc       1
#define dec       2
#define stsp      3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  if (adc_key_in < 60)   return set;
  if (adc_key_in < 200)  return inc;
  if (adc_key_in < 400)  return dec;
  if (adc_key_in < 600)  return stsp;
  if (adc_key_in < 800)  return btnSELECT;
  return btnNONE;  // when all others fail, return this...
}
int numberOfDevices;
int relay = 8;
int val_tol = 0;
bool exit_stsp = false;
bool exit_set = false;
bool re_heat = false;
#define ONE_WIRE_BUS 10 // Pin no
#define TEMPERATURE_PRECISION 12 // 12-bit resolution
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

//------- Temperature tolerance -------//
const int tol = 3; // in degree Celsius
//-----------------------------------//

void setup(void)
{
  lcd.begin(16, 2);
  sensors.begin();
  pinMode(stsp, INPUT_PULLUP);
  pinMode(inc, INPUT_PULLUP);
  pinMode(dec, INPUT_PULLUP);
  pinMode(set, INPUT_PULLUP);
  pinMode(relay, OUTPUT);
  digitalWrite(relay, LOW);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("  Water Heater");
  lcd.setCursor(0, 1);
  lcd.print("   Controller");
  numberOfDevices = sensors.getDeviceCount();

  if (EEPROM.read(add_chk) != check_val)
  {
    EEPROM.write(add_chk, check_val);
    EEPROM.write(c_temp_add, 50);
    c_temp = EEPROM.read(c_temp_add);
  }
  else
  {
    c_temp = EEPROM.read(c_temp_add);
  }
  delay(1500);
}

void loop(void)
{
  lcd.setCursor(0, 0);
  lcd.print("PRESS START/SET");
  lcd.setCursor(0, 1);
  lcd.print("TEMP: ");
  lcd.print(EEPROM.read(c_temp_add));
  lcd.print("C/");

  if (read_LCD_buttons(set) == LOW && exit_set == false)
  {
    exit_set = true;
    c_temp = EEPROM.read(c_temp_add);
    while (exit_set)
    {
      if (read_LCD_buttons(inc) == LOW)
      {
        c_temp += 1;
        if (c_temp > 110) c_temp = 0;
        delay(50);
      }
      if (read_LCD_buttons(dec) == LOW)
      {
        c_temp -= 1;
        if (c_temp < 0) c_temp = 110;
        delay(50);
      }
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("SET TEMPERATURE:");
      lcd.setCursor(0, 1);
      lcd.print("    ");
      lcd.print(c_temp);
      lcd.print("C/");
      delay(150);
      if (read_LCD_buttons(set) == LOW)
      {
        delay(500);
        if (read_LCD_buttons(set) == LOW)
        {
          exit_set = false;
          if (EEPROM.read(c_temp_add) == c_temp)
          {
            lcd.clear();
            lcd.print("VALUE UNCHANGED!");
            delay(1500);
          }
          else
          {
            EEPROM.write(c_temp_add, c_temp);
            lcd.clear();
            lcd.print("  VALUE SAVED!");
            lcd.setCursor(0, 1);
            lcd.print("****************");
            delay(1500);
            lcd.clear();
          }
        }
      }
    }
  }

  if (read_LCD_buttons(stsp) == LOW && exit_stsp == false)
  {
    exit_stsp = true;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SET:   ");
    lcd.print(EEPROM.read(c_temp_add));
    lcd.print("C/");
    digitalWrite(relay, HIGH);
    while (exit_stsp)
    {
      sensors.requestTemperatures();
      for (int i = 0; i < numberOfDevices; i++)
      {
        if (sensors.getAddress(tempDeviceAddress, i))
        {
          printTemperature(tempDeviceAddress);
        }
      }
      lcd.setCursor(0, 1);
      lcd.print("WATER: ");
      lcd.print(c_temp);
      lcd.print("C/");
      if (c_temp >= EEPROM.read(c_temp_add))
      {
        delay(5000);
        if (c_temp >= EEPROM.read(c_temp_add))
        {
          digitalWrite(relay, LOW);
          re_heat = true;
        }
      }
      val_tol = EEPROM.read(c_temp_add) - tol;
      if (c_temp <= val_tol && re_heat == true)
      {
        re_heat = false;
        digitalWrite(relay, HIGH);
      }

      if (read_LCD_buttons(stsp) == LOW && exit_stsp == true)
      {
        delay(1500);
        if (read_LCD_buttons(stsp) == LOW);
        {
          digitalWrite(relay, LOW);
          exit_stsp = false;
          lcd.clear();
          lcd.print("PROCESS STOPPED!");
          lcd.setCursor(0, 1);
          lcd.print("****************");
          delay(500);
          lcd.clear();
          break;
        }
      }
    }
  }
}

void printTemperature(DeviceAddress deviceAddress)
{
  c_temp = sensors.getTempC(deviceAddress);
}


I get this error:

C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino: In function 'void loop()':
boiler:95:27: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(set) == LOW && exit_set == false)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:101:31: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(inc) == LOW)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:107:31: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(dec) == LOW)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:121:31: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(set) == LOW)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:124:33: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(set) == LOW)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:148:28: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(stsp) == LOW && exit_stsp == false)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:187:32: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(stsp) == LOW && exit_stsp == true)
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
boiler:190:34: error: too many arguments to function 'int read_LCD_buttons()'
if (read_LCD_buttons(stsp) == LOW);
^
C:\Users\A.Mikutavicius\Desktop\New folder\boiler\boiler.ino:30:5: note: declared here
int read_LCD_buttons()
^~~~~~~~~~~~~~~~
exit status 1
too many arguments to function 'int read_LCD_buttons()'

Any help appreciated, thanks

Please follow the advice given in the link below when posting code . Use code tags when posting code here to make it easier to read and copy for examination

1 Like
        if (read_LCD_buttons(stsp) == LOW);

You are calling the read_LCD_buttons() function with a parameter, but it is defined as

int read_LCD_buttons()

so it does not take any parameters, hence the errors

What do you want those function calls to do ?

Just to get you started, your function definition..l

int read_LCD_buttons()…

Doesn’t want any parameters..l
BUT all your calls to read_LCD_buttons(xxx)
Have a value xxx in the call…

I am working with this code as it is made for the same purpose with most of the same components i have. He is using switches wired to analog inputs A0,A1,A2,A3 but i have lcd shield that uses one pin, A0, for the switches. I am trying to adapt the code for my hardware but sice i have no knowledge i am where i am :slight_smile:

//------------ ©Electronics-project-hub-----------//
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include<EEPROM.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
int add_chk = 0;
int check_val = 10;
int c_temp = 0;
int c_temp_add = 1;
int f_temp = 0;
int f_temp_add = 2;
int set = A3, dec = A2, inc = A1, stsp = A0;
int numberOfDevices;
int relay = 8;
int buzzer = 9;
int val_tol = 0;
bool exit_stsp = false;
bool exit_set = false;
bool buz  = true;
bool re_heat = false;
#define ONE_WIRE_BUS 10 // Pin no
#define TEMPERATURE_PRECISION 12 // 12-bit resolution
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

//------- Temperature tolerance -------//
const int tol = 3; // in degree Celsius
//-----------------------------------//

void setup(void)
{
  lcd.begin(16, 2);
  sensors.begin();
  pinMode(stsp, INPUT_PULLUP);
  pinMode(inc, INPUT_PULLUP);
  pinMode(dec, INPUT_PULLUP);
  pinMode(set, INPUT_PULLUP);
  pinMode(relay, OUTPUT);
  pinMode(buzzer, OUTPUT);
  digitalWrite(relay, LOW);
  digitalWrite(buzzer, LOW);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("  Water Heater");
  lcd.setCursor(0, 1);
  lcd.print("   Controller");
  numberOfDevices = sensors.getDeviceCount();

  if (EEPROM.read(add_chk) != check_val)
  {
    EEPROM.write(add_chk, check_val);
    EEPROM.write(c_temp_add, 50);
    f_temp = f_conv(50);
    EEPROM.write(f_temp_add, f_temp);
    c_temp = EEPROM.read(c_temp_add);
    f_temp = EEPROM.read(f_temp_add);
  }
  else
  {
    c_temp = EEPROM.read(c_temp_add);
    f_temp = EEPROM.read(f_temp_add);
  }
  delay(1500);
}

void loop(void)
{
  lcd.setCursor(0, 0);
  lcd.print("PRESS START/SET");
  lcd.setCursor(0, 1);
  lcd.print("TEMP: ");
  lcd.print(EEPROM.read(c_temp_add));
  lcd.print("C/");
  lcd.print(EEPROM.read(f_temp_add));
  lcd.print("F");

  if (digitalRead(set) == LOW && exit_set == false)
  {
    exit_set = true;
    c_temp = EEPROM.read(c_temp_add);
    f_temp = EEPROM.read(f_temp_add);
    while (exit_set)
    {
      if (digitalRead(inc) == LOW)
      {
        c_temp += 1;
        if (c_temp > 110) c_temp = 0;
        f_temp = f_conv(c_temp);
        delay(50);
      }
      if (digitalRead(dec) == LOW)
      {
        c_temp -= 1;
        if (c_temp < 0) c_temp = 110;
        f_temp = f_conv(c_temp);
        delay(50);
      }
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("SET TEMPERATURE:");
      lcd.setCursor(0, 1);
      lcd.print("    ");
      lcd.print(c_temp);
      lcd.print("C/");
      lcd.print(f_temp);
      lcd.print("F");
      delay(150);
      if (digitalRead(set) == LOW)
      {
        delay(500);
        if (digitalRead(set) == LOW)
        {
          exit_set = false;
          if (EEPROM.read(c_temp_add) == c_temp)
          {
            lcd.clear();
            lcd.print("VALUE UNCHANGED!");
            delay(1500);
          }
          else
          {
            EEPROM.write(c_temp_add, c_temp);
            EEPROM.write(f_temp_add, f_temp);
            lcd.clear();
            lcd.print("  VALUE SAVED!");
            lcd.setCursor(0, 1);
            lcd.print("****************");
            delay(1500);
            lcd.clear();
          }
        }
      }
    }
  }

  if (digitalRead(stsp) == LOW && exit_stsp == false)
  {
    exit_stsp = true;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SET:   ");
    lcd.print(EEPROM.read(c_temp_add));
    lcd.print("C/");
    lcd.print(EEPROM.read(f_temp_add));
    lcd.print("F");
    buzz();
    digitalWrite(relay, HIGH);
    while (exit_stsp)
    {
      sensors.requestTemperatures();
      for (int i = 0; i < numberOfDevices; i++)
      {
        if (sensors.getAddress(tempDeviceAddress, i))
        {
          printTemperature(tempDeviceAddress);
        }
      }
      lcd.setCursor(0, 1);
      lcd.print("WATER: ");
      lcd.print(c_temp);
      lcd.print("C/");
      lcd.print(f_temp);
      if (f_temp < 100)
      {
        lcd.print("F ");
      }
      else
      {
        lcd.print("F");
      }
      if (c_temp >= EEPROM.read(c_temp_add) && buz == true)
      {
        delay(5000);
        if (c_temp >= EEPROM.read(c_temp_add))
        {
          digitalWrite(relay, LOW);
          buz = false;
          re_heat = true;
          for (int j = 0; j < 15; j++)
          {
            digitalWrite(buzzer, HIGH);
            delay(100);
            digitalWrite(buzzer, LOW);
            delay(100);
          }
        }
      }
      val_tol = EEPROM.read(c_temp_add) - tol;
      if (c_temp <= val_tol && re_heat == true)
      {
        buz = true;
        re_heat = false;
        digitalWrite(relay, HIGH);
      }

      if (digitalRead(stsp) == LOW && exit_stsp == true)
      {
        delay(1500);
        if (digitalRead(stsp) == LOW)
        {
          digitalWrite(relay, LOW);
          exit_stsp = false;
          lcd.clear();
          lcd.print("PROCESS STOPPED!");
          lcd.setCursor(0, 1);
          lcd.print("****************");
          buzz();
          delay(500);
          lcd.clear();
          break;
        }
      }
    }
  }
}

int f_conv(int x)
{
  int temp;
  temp = x * 9;
  temp = temp / 5;
  temp = temp + 32;
  return temp;
}

void printTemperature(DeviceAddress deviceAddress)
{
  c_temp = sensors.getTempC(deviceAddress);
  f_temp = f_conv(c_temp);
}

void buzz(void)
{
  digitalWrite(buzzer, HIGH);
  delay(1000);
  digitalWrite(buzzer, LOW);
}
//------------ ©Electronics-project-hub-----------//

I thought that when pressing a button returns a value which is the used in read_LCD_buttons():

int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  if (adc_key_in < 60)   return set;
  if (adc_key_in < 200)  return inc;
  if (adc_key_in < 400)  return dec;
  if (adc_key_in < 600)  return stsp;
  if (adc_key_in < 800)  return btnSELECT;
  return btnNONE;  // when all others fail, return this...
}

e.g. this: if (read_LCD_buttons(stsp) == LOW) should map left keypad button to function as start/stop button, inc - to increase temperature, dec - to decrease, set - to set the parameter.

OK so if the range for say RIGHT button is 0-60 i can put 0-60 value in and it will correspond to that specific button? read_LCD_buttons(50) would read that RIGHT button is pressed?

you probably have several buttons connected with different value resistors to the same pin so depending on button pressed different voltage is applied and that subtoutine returns number, which indicates which button is pressed

It doesn’t take param, period

This is what i am using: Using 1602 LCD Keypad Shield w/ Arduino [w/ Examples] - Arduino Project Hub
So how can i extract the button pressed and use it later in the sketch?
I understand how it is used when individual button is wired to a separate analog input but i have no clue how this one works

So i have tried to put the values of analogRead(0) strait in and it compiled.
changed this: if (read_LCD_buttons(set) == LOW && exit_set == false)
to this: if (set == LOW && exit_set == false)
I gues i will find out if it works. need to get back home

int read_LCD_buttons()
{
  adc_key_in = analogRead(0); // read the value from the sensor
  if (adc_key_in < 60) return set;
  if (adc_key_in < 200) return inc;
  if (adc_key_in < 400) return dec;
  if (adc_key_in < 600) return stsp;
  if (adc_key_in < 800) return btnSELECT;
  return btnNONE; // when all others fail, return this...
}

The function returns an int valuethat tells you which button has been pressed so you can do something like this

if (read_LCD_buttons() == dec)
{
  //code to be executed if dec button has been pressed
}

It would compile but not going to work as expected. Are you following the project exactly, if not, you can’t just copy paste code without understanding how it works and expect it to work

Have you considered a standalone lcd with standalone buttons, each one connected to its own input pin? These shields often introduce a layer of complexity/mystery that shields you away (yeah!) from how the hardware/software combination really works. Besides, when your prototype finally runs as expected, you are going to build something more permanent and shieldless anyway, aren't you?

The main loop is a maze of nested conditions; one would be surprised if bugs didn't lurk in there! I'd start by refactoring that thing into smaller, individually testable functions.

At the moment i need something quick with what i have as i operate my boiler manually.
I will 3D print case to house all components and drop a magnet in case so it sticks to the boiler.
I found another code which has temp control and uses same shield, only thing it lacks is temperature tolerances so the relay does not work all the time

// First we include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
/********************************************************************/

// Data wire is plugged into pin 13 on the Arduino 
#define ONE_WIRE_BUS 6 
/********************************************************************/

// Setup a oneWire instance to communicate with any OneWire devices  
// (not just Maxim/Dallas temperature ICs) 
OneWire oneWire(ONE_WIRE_BUS); 
/********************************************************************/

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
/********************************************************************/ 

//Setup LCD
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);           // select the pins used on the LCD panel
/********************************************************************/
#define RELAY 5 //Lock Relay or motor
// Temp Sensor is on PIN 6
/********************************************************************/

// Value for Default Setpoint (temp for Relay) in Celsius
int SetPoint=75;
/********************************************************************/

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;

#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

int read_LCD_buttons(){               // read the buttons
    adc_key_in = analogRead(0);       // read the value from the sensor 

    // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
    // we add approx 50 to those values and check to see if we are close
    // We make this the 1st option for speed reasons since it will be the most likely result

    if (adc_key_in > 1000) return btnNONE; 

    // For V1.1 us this threshold
    if (adc_key_in < 50)   return btnRIGHT;  
    if (adc_key_in < 250)  return btnUP; 
    if (adc_key_in < 450)  return btnDOWN; 
    if (adc_key_in < 650)  return btnLEFT; 
    if (adc_key_in < 850)  return btnSELECT;   

    return btnNONE;                // when all others fail, return this.
}
/********************************************************************/
// only run once, after each powerup or reset of the Arduino board.
// (void) variables the ISR function takes no arguments & continues with it's next line after the interrupt occurs.
void setup(void) 
{ 

// Set outputs  
  pinMode(RELAY,OUTPUT);

// Initialize Relay PIN so it stays inactive at reset 
  digitalWrite(RELAY,LOW);       //Turn off Relay 

 // start serial port for debug change "lcd.print" to "Serial.print" 
 // and listen to COM port
 Serial.begin(9600); 
 // set up the LCD's number of columns and rows: 
   lcd.begin(16, 2);
   lcd.print("  WATER HEATER");
   lcd.setCursor(0,1); //Move coursor to second Line
   lcd.print("   Controller");
   
delay (8000);
 lcd.clear();
 
 // Start up the library 
 sensors.begin(); 
} 
/********************************************************************/
void loop(void) 
{ 
 
 // call sensors.requestTemperatures() to issue a global temperature 
 // request to all devices on the bus 
   sensors.requestTemperatures(); // Send the command to get temperature readings 
   lcd.setCursor(0,0);
   lcd.print("Temp:");    //Do not display entered keys 
   lcd.print(sensors.getTempFByIndex(0));
   lcd.print((char)223); // Degree Symbol
   lcd.print("F   "); 
   // You can have more than one DS18B20 on the same bus.  
   // 0 refers to the first IC on the wire 

//Get user input for setpoints 
  if(read_LCD_buttons() == btnDOWN)
   {
    if(SetPoint>0)
    {
      SetPoint--;   
    }
  }
  if(read_LCD_buttons() == btnUP)
  {
    if(SetPoint<150)
    {
      SetPoint++;
    }
  }
/********************************************************************/

//Display Set point on LCD in Fahrenheit (F).
  lcd.setCursor(0,1);
  lcd.print("Set Point:");
  lcd.print(SetPoint);
  lcd.print((char)223);
  lcd.print("F   ");
/********************************************************************/

//Check Temperature is in limit:
// I am monitoring a Hot Water Boiler, I want to turn on the heater when the water is HOT
// I use a < 
// If turning on something such as an electric heater and monitoring an environment for cold
// use >
if((sensors.getTempFByIndex(0)) > SetPoint) 
{
   digitalWrite(RELAY,LOW);    //Turn off heater
   Serial.print("HEATER OFF"); // serial port for debug
}
else
{
  digitalWrite(RELAY,HIGH);    //Turn on heater
  Serial.print("HEATER ON"); //serial port for debug
  
  lcd.clear(); // Clears the LCD Information
  
  lcd.setCursor(0,0); 
  lcd.print("Heater ON");
  lcd.setCursor(0,1);
  lcd.print("2 Min Cycle"); // Change to amount of Delay if wanted.
  
  delay (120000); // Delay 2 minutes to keep relay from recycling until temp normalizes.
}
 /********************************************************************/     
      delay(100); //Update at every 100mSeconds
 
} 

only thing it lacks is temperature tolerances so the relay does not work all the time

If I understand your sentence correctly, what you need is some hysteresis. In practice, your relay should change state at two different temperatures around your nominal setpoint, depending on whether you are coming from cold and heating up or from hot and cooling down.

In practice, with a setpoint of 50° and +/- 1° of hysteresis, this happens:

  1. The water is at 30°: relay on, no problem
  2. The water heats up, and the relay stays on until the water reaches 51° from below: relay goes off.
  3. The thermal inertia in the heating element heats the water some more, up to 54°: relay still off.
  4. The water begins to cool down and crosses 51°, then 50°, but from above: relay still off.
  5. The water cools down some more, and now reaches 49°: relay goes on.
  6. Go to point #2.

P.S. All the sensors in the world work in °C, so stick with them into you algorithm, and only convert to °F for display, if that's what you want. Either that, or, ahem, go metric.