Обычный полупроводниковый прибор может с достаточной точностью и повторяемостью служить датчиком температуры. 


Прикупил на Алиэкспрессе десяток прецизионных датчиков температуры LM35, они оказались подделкой, обычные NPN транзисторы в корпусе TO-92 и с маркировкой LM35.

Но я вспомнил что когда-то в юности таких датчиков в природе не было, а температуру измеряли! Пошерстил интернет и оказалось что полупроводниковый переход имеет довольно ровную зависимость падения напряжения на переходе от температуры.

Т.е. получается что ничего не мешает использовать копеечные диоды в качестве измерителя температуры от -30 до +200 градусов. 

Диод включается последовательно с резистором, примерно так:


И подаем на АЦП вход ардуино. Падение на кремниевых переходах около 700 мВ, германиевые дают 400-450 мВ. Для точности берем среднее значение из 30 измерений. К тому же так как в Ардуино есть режим с внутренней подтяжкой, можно вообще обойтись одним диодом без обвязки, просто катод на землю, анод на измерительный вход. И скетч:

int n = 30;// кол-во измерений для среднего значения 
int t; // 0,022 мВ на 1 гр.Цельсия или 2 ед.значения А5 на 1 гр.Цельсия)
const float t0 = 27.0; // калибровка
const float t0_analog = 536; /* По показаниям эталонного градусника
задайте свое значение температуры t0, далее посмотрите значение
t0_analog в мониторе порта и укажите его */
float t_sum,t_iz,t_iz_analog,t_analog;
void setup() {
  analogReference(INTERNAL);// опорное 1,1 В 
  pinMode(A5, INPUT_PULLUP);
  Serial.begin(9600); 
}
void loop() {  
  Serial.println(t_analog,0);
  Serial.println(t_iz,1);
  t_sum = 0;
  for (int i = 0; i < n; i++) {
    t = analogRead(A5);// 545 при 26 гр
    t_sum = t_sum + t; 
    delay(33);// общее время измерения 999 мс
  }
  t_analog = t_sum / n;// среднее значение
  t_iz_analog = (t_analog-t0_analog) / 2;// отклонение гр.Цельсия от t0
  t_iz = t0 - t_iz_analog;// вычисление температуры
}


Вариант с дисплеем от Нокии 5110

 #include <LCD5110_Basic.h>
LCD5110 myGLCD(7,6,5,3,4);
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
int n = 30;// кол-во измерений для среднего значения 
int t; // 0,022 мВ на 1 гр.Цельсия или 2 ед.значения А5 на 1 гр.Цельсия)
const float t0 = 27.0; // калибровка
const float t0_analog = 537; /* По показаниям эталонного градусника
задайте свое значение температуры t0, далее посмотрите значение
t0_analog в мониторе порта и укажите его */
float t_sum,t_iz,t_iz_analog,t_analog;
void setup()
{
  myGLCD.InitLCD(75);//инициализация экрана и контрастность(75) по умолчанию 70
  analogReference(INTERNAL);// опорное 1,1 В 
  pinMode(A5, INPUT_PULLUP);
  Serial.begin(9600); 
}

void loop()

  Serial.println(t_analog,0);
  Serial.println(t_iz,1);
  t_sum = 0;
  for (int i = 0; i < n; i++) 
  {
    t = analogRead(A5);// 545 при 26 гр
    t_sum = t_sum + t; 
    delay(33);// общее время измерения 999 мс
  }
    t_analog = t_sum / n;// среднее значение
    t_iz_analog = (t_analog-t0_analog) / 2;// отклонение гр.Цельсия от t0
    t_iz = t0 - t_iz_analog;// вычисление температуры
  { 
    myGLCD.clrScr();
    myGLCD.setFont(BigNumbers);
    myGLCD.printNumF(float(t_iz), 1, RIGHT, 0);
    
    myGLCD.setFont(MediumNumbers);
    myGLCD.printNumI(t_analog, RIGHT, 26);
  }