Close

Mapping Temperatures

A project log for Trinket LED Thermometer

Espy room temps with a Trinket, a battery, a 1-wire sensor and an RGB LED

ethandicksethan.dicks 12/30/2014 at 23:220 Comments

The simplest color map would be a table with one entry per temperature increment available from the sensor. Given a spread of room temps from -20°C to +40°C, that's a table of longwords well under 1K even at 0.5° intervals. There's no need for that much redundancy, and it might be advisable to keep the entire memory footprint down in case there's reason to scale back to, say, a Tiny 4313 where a 1K table has a noticeable impact on space left for code. Computers are good at math, so the usual trick is a small table of inflection points and a handful of statements to interpolate between them...

// temp_to_color - convert temp x 10 to ready-to-use color value for RGB LED

Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN, NEO_GRB + NEO_KHZ800);

uint8_t cmap[] = {
  0xff, 0xff, 0xff, // -9C - white
  0x00, 0x00, 0xff, //  3C - blue
  0xff, 0x00, 0x00, // 15C - green
  0xc0, 0xff, 0x00, // 27C - orange
  0x00, 0xff, 0x00, // 39C - red
}

uint32_t temp_to_color(int degree_tenths)
{
    uint32_t c;
    uint8_t i;
    int floor_t;
    float scale;

    // Grab extremes (colder than -9C and warmer than 39C) and return max colors 
    if (degree_tenths <= -90)
        c = strip.Color(cmap[0], cmap[1], cmap[2]);
    else if (degree_tenths >= 390)
        c = strip.Color(cmap[12], cmap[13], cmap[14]);
    else {
        i = ((degree_tenths + 90) / 120) * 3; // set floor at -9C and scale range
        floor_t = (i * 40) - 90; // get the bottom temp of this range
        scale = (degree_tenths - floor_t)/ 120.0; // calc how far along this range

        // get colors by interpolating this range and adding it to the base color
        c = strip.Color(cmap[i] + (cmap[i+3]-cmap[i])*scale,
                        cmap[i+1] + (cmap[i+4]-cmap[i+1])*scale,
                        cmap[i+2] + (cmap[i+5]-cmap[i+2])*scale);
    }
    return(c);
}

This should take care of temps below and above what the table can handle, and gradiate the colors along the continuum. It has the additional advantage of being easier to tweak than editing a massive table.

Discussions