GM Coolant Sensor #12146312 Interface

I see posts on occasion about using automotive sensors with the Arduino.

I have tested a popular GM coolant sensor, part #12146312 with my Uno and tested it on the bench. This sensor mounts using 3/8 pipe and has a 2-wire connector. The datasheet is here and lists the mating connector:
DELPHI COOLANT TEMPERATURE SENSOR PART NUMBER 12146312

I thought I’d share the info if anyone in the future wants to use this sensor. I started with a basic temperature sketch I found online.

Doing some resistor calcs and tests using the expected operating range, I found the combination that worked was a 2.2K and 550 ohm in serial. It was < 1 degree from ambient at 80 degrees F room temp. I tested it by briefly heating the tip with a soldering iron. It responded and then returned to ambient. I’m attaching a basic diagram as a JPG.

The sensor has 2 wires and it looks for 5V from the GM controller. The ground leg goes to the Arduino ground, while the data wire connects to the Arduino’s 5V outlet via the aforementioned resistors. They are connected with one end to the sensor’s data output wire and the other end to the 5V inlet at the sensor. The data wire in the sketch terminates at analog pin 0. Of course, any other analog pin could be used.

I hope this is helpful for those searching by the part number.

Here’s the code:

// This was used to read the popular GM coolant sensor 12146312 
// The serial print is for oil temperature change this as needed
// The sensor needed 2.2K and 550 ohm resistors in series
// No display options are used here other than serial print for testing
// This sketch uses analog pin 0 to read the sensor
// The serial rate was bumped up to 115200 from 9600
// Output is in fahrenheit

#include <math.h>         //loads the more advanced math functions
 
void setup() {            //This function gets called when the Arduino starts
  Serial.begin(115200);   //This code sets up the Serial port at 115200 baud rate
}
 
double Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}
 
void loop() {             //This function loops while the arduino is powered
  int val;                //Create an integer variable
  double temp;            //Variable to hold a temperature value
  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.print ("Oil Temperature: "); // Change this if monitoring another type of fluid
  Serial.println(temp);   //Print the value to the serial port
  delay(1000);            //Wait one second before we do it again
}

1 Like

I want to thank you for this awesome info you shared but I also have an issue, and I know this thread is 1.5 years old but I hope you're still around to answer it. I ran your code with the same sensor, wired the same way as your schematic. The problem I'm having is that, as I increase the temperature, the temp reading goes down. At about 75 degrees F it is accurate. As I increase the water temp, the serial reading goes down. I am using a pot of water with a calibrated thermometer for reference. As I heat the water, the calibrated one goes up to 85 degrees while the serial reading goes down to 65 degrees. Also, I tested the sensor with an OHM meter and it is within specs. Any thoughts would be very helpful Thank you!!

OK, just to update, in case someone else needs this info, in the future. The diagram he has included shows the resistors installed on the data side of the circuit. This will result in backwards readings. However, if you reverse the data and ground connections (connect the yellow wire to 5v and then the black wire to A0 and to ground, through the resistors), it will work perfectly! Thanks again for the info!!!!!

Was able to make this work thanks to diablo’s suggestion to switch the wires.

Attached an updated schematic showing the wiring change that worked for me.

How I wired the oled:

GND- GND
VCC- 3.3V
SCL- A5
SDA- A4

Also added some code to display the values to an oled display

#include <U8g2lib.h>
#include <U8x8lib.h>



// This was used to read the popular GM coolant sensor 12146312 
// The serial print is for oil temperature change this as needed
// The sensor needed 2.2K and 550 ohm resistors in series
// No display options are used here other than serial print for testing
// This sketch uses analog pin 0 to read the sensor
// The serial rate was bumped up to 115200 from 9600
// Output is in fahrenheit

#include <math.h>         //loads the more advanced math functions

// Address for your oled display. Use "hello world" example to find your display address
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

#define potmeterPin A1 

void setup() {            //This function gets called when the Arduino starts
  Serial.begin(115200);   //This code sets up the Serial port at 115200 baud rate
 //u8x8.begin();
  //u8x8.setPowerSave(0);
  u8g2.begin();
}
 
double Thermister(int RawADC) {  //Function to perform the fancy math of the Steinhart-Hart equation
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
 Temp = Temp - 273.15;              // Convert Kelvin to Celsius
 Temp = (Temp * 9.0)/ 5.0 + 32.0; // Celsius to Fahrenheit - comment out this line if you need Celsius
 return Temp;
}
 
void loop() {             //This function loops while the arduino is powered
  int val;                //Create an integer variable
  double temp;            //Variable to hold a temperature value
  val=analogRead(0);      //Read the analog port 0 and store the value in val
  temp=Thermister(val);   //Runs the fancy math on the raw analog value
  Serial.print ("WATER TEMP: "); // Change this if monitoring another type of fluid
  Serial.println(round(temp));   //Print the value to the serial port
  delay(1000);            //Wait one second before we do it again
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_profont22_tf);
  u8g2.drawStr(6,64,"WATER TEMP"); // Change this for another type of fluid
  u8g2.setFont(u8g2_font_profont29_tf);
  u8g2.setCursor(28,33);
  u8g2.print(round(temp));
  u8g2.print((char)176); //Degree unit symbol
  u8g2.print("F");
  //u8g2.print("%");
  u8g2.sendBuffer();  
}

I can seek, but I don't understand fully.

This topic shows a GM Temp Sensor and associated resistors to generate a voltage signal thru a Uno, yes? It does not explain the output strategy or the pin outs to connect to a temp gauge or a controller. Can anyone explain?

I used a 1.3" OLED to output from the Arduino. I did a digital readout along with a bar graph. It worked very well. I suppose you could do whatever you want with the data, once it's in the Arduino. Hooking it up just depends on what you are hooking it up to.

Thanks for this post! :slight_smile:

I was battling with the same problem trying to get a reading from a different kind of thermistor type sensor branded Koso BF140125 (for motorcycles).

I got it working with the same code. Only difference I made was to play around with the resistor values til I found the right combo.

I put the thermistor type sensor in a boiling pot of water together with a DS18B20 temperature sensor for calibration. Then I swapped around different resistors to get to the sweet spot. I got it working within 2 degrees Celsius accuracy in the range of 70-110 °C.

I ended up using 3 resistors in series - 10k + 3.3k + 100.

I attached the schema I used to connect my Arduino Nano to the sensor: