-
1Step 1
Any digital I/O pins can be used for the WS2812 LED or the DS1822 OneWire temperature sensor. For easy placement, the code expects to see the LED on D6 and the sensor on D8. If you decide to move them, just change the constants in the code.
Besides running +5V and GND to both the LED and the sensor, you'll need a 4.7K pullup on the DS1822 data line per the OneWire spec.
That's it! Three components. -
2Step 2
Here's a functional program to initialize the hardware, read temps, and display temps as colors. Enhancements such as multiple sensors/LEDs per Trinket are possible but left as an exercise for the reader.
/* trinket_thermo --------------------------------------------------------------------------------- Trinket-based therometer with color output When Who What 30-Dec-2014 erd Incorporate basic color conversion process 2-Jan-2015 erd Update color conversion process 2-Jan-2015 erd Final changes for production hardware */ #include <Adafruit_NeoPixel.h> #include <OneWire.h> #define LEDNUM 1 #define LEDPIN 6 #define TEMPPIN 8 Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDNUM, LEDPIN, NEO_RGB + NEO_KHZ800); OneWire ds(TEMPPIN); // function prototypes uint32_t temp_to_color(int); // set up hardware void setup() { uint32_t i; // init LED strip.setPixelColor(0, 0); // one LED for now strip.begin(); strip.show(); // Initialize color to 'off' } // // collect temp, display temp, repeat forever // void loop() { uint8_t i; uint32_t color; // OneWire storage byte present = 0; byte type_s; byte data[12]; byte addr[8]; float celsius, fahrenheit; // scan OneWire bus if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; // holdover from vendor example } // the first ROM byte indicates which chip switch (addr[0]) { case 0x10: //Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: //Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: //Serial.println(" Chip = DS1822"); type_s = 0; break; default: while(1) // loop forever if no DS182x found ; } // reset OneWire and tell DS182x to acquire temperature ds.reset(); ds.select(addr); ds.write(0x44,1); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad // read data from OneWire bus for ( i = 0; i < 9; i++) // we need 9 bytes data[i] = ds.read(); // convert the data to actual temperature unsigned int raw = (data[1] << 8) | data[0]; if (type_s) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // count remain gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms // default is 12 bit resolution, 750 ms conversion time } celsius = (float)raw / 16.0; // set pixel color color = temp_to_color(int(celsius*10)); // color routine takes int of 10X temp strip.setPixelColor(0,color); strip.show(); } // Ranges of colors in RGB order uint8_t cmap[] = { 0xff, 0xff, 0xff, // -9C - white 0x00, 0x00, 0xff, // 3C - blue 0x00, 0xff, 0x00, // 15C - green 0x80, 0x66, 0x00, // 27C - orange 0xff, 0x00, 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); }
-
3Step 3
Download the OneWire library and the NeoPixel library then install them for your platform. Compile and upload the sketch to your Trinket.
-
4Step 4
Attach a battery and test your Trinket LED Thermometer by walking from warm places to cold places or by pinching the DS1822 with your fingers to warm it up to about 30C. The LED should change from cool colors to warm colors as the temps go up and down.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.