Read Temperature from attiny

A cool feature is that every attiny45 (and others) has an internal temperature sensor, which can be a little bit tweaked and used as primary sensor. I wrote a small sample function which can be used to sample various ADC Settings:

uint16_t sample(uint8_t admux){
    uint16_t res;
    ADMUX = admux;
    set_sleep_mode(SLEEP_MODE_ADC);
    ADCSRA |= _BV(ADEN) | _BV(ADSC);
    while(ADCSRA & _BV(ADSC))
            sleep_mode();
    res = ADC;
    ADCSRA &= ~(_BV(ADEN));
    return res;
}

Then you can use the temperature sensor with using 0x8F as ADMUX register value: uint16_t temperature = sample(0x8F);

Calibration

On some site i found a good way to calibrate. They propagate to make 81 samples and then do some math. I tried it:

uint16_t tem = 0;
for(int i = 0; i < 81; i++){
        tem += sample(0x8F);
}
data.temp = (tem) - 2150;

The -2150 should be better done at host, because it does not have any effect at the sensor (see offset for each Sensor) but this gives us only some crazy values. So i did two mesaurements (one outside = 10°C and one inside = 23°C) and did some math. The value i got from the sensor now had to be converted like this:

(value-21050.0)/94.0 = °C

The Math behind this is: 23126-21990/12=~94. because 23126 is the value ad 22°C and 21990 is the value at 10°C and 12 is the difference of 22 and 10. That means that every degree are 94 samples. Now do 21990-(94*10) to get the value at 0°C and your sensor is calibrated!

When i now do even more math, i come to the result, that 86 Probes would be better, because then i just can divide by 100.

Offset for each Sensor

One big Problem and disadvantage against digital sensors like SHT11 is that you need to calibrate every sensor for its own, like analog sensor. For that reason i read in my host app the Sensor-ID and have an offset variable which is used for best calibration.

    uint16_t temp = mes->temp;
    uint16_t offset_one = 21050;
    uint16_t offset_two = 0;
    uint16_t offset_three = 20520;

    switch(mes->sender){
            case 1: temp -= offset_one; break;
            case 2: temp -= offset_two; break;
            case 3: temp -= offset_three; break;
    }

this could be better done with an array and automaticly substraction or something else, but my C is little bit rusty and my try with a struct was a catastrophal fail ;)