User Tools

Site Tools


digispark:tutorials:temp

Temperature Sensor (1-wire) Shield Kit Tutorial

Product Description:

temp1.jpg temp8.jpgtemp7.jpg

The Temperature Sensor Shield Kit connects a DS18B20 1-wire temperature sensor to the Digispark. This allows the Digispark to read the temperature measured by the included sensor on the shield. The shield also provides a screw terminal connection to attach additional external 1-wire temperature sensors (not included), or any other 1-wire sensor. The jumper on the shield allows for one of two i/o pins to be used.

This is an unassembled kit and requires basic soldering. This is designed for use with the Digispark development board, which is not included.

Parts:

Part Quantity Identification
Temperature Sensor Shield PCB1
DS18B20 1-wire Temperature Sensor1
3.5 mm pitch 3-pin screw terminal1
4.7k ohm 1/4W 5% resistor1 Yellow - Violet - Red
0.1“ pitch Jumper/Shunt 1
1x40pin male 0.1” pitch header 12 pins worth

Soldering: If you are new to soldering we recommend the following tutorials: Soldering Basics (http://www.sparkfun.com/tutorials/106) and Soldering Crash Course from the folks at Sparkfun (http://www.sparkfun.com/tutorials/354). How to solder from the Curious Inventor: http://store.curiousinventor.com/guides/How_to_Solder

Adafruit has this excellent guide that starts with the tools needed and then shows detailed pictures, including some of the common problems that beginners experience (http://learn.adafruit.com/adafruit-guide-excellent-soldering).

We assume for these assembly instructions that you know the basics of thru-hole soldering. If you don't check out the links above, these boards are very easy to solder - we promise!

Assembly:

Empty kit bag (or if using a raw PCB, acquire parts) and verify contents. Note for Kickstarter Backers and Pre-orders: Headers are not included in each kit bag, but the entire order came with more than enough headers for all kits.

temp1.jpg

Insert the the DS18B20 Temperature Sensor, matching the shape of it with the printing on the board and solder all pins.

temp2.jpg

Insert resistor. Solder the leads and clip off the excess.

temp3.jpg

Cut a length of male headers 3 pins long and insert into the jumper location (labeled P1 DAT P5). Solder the pins on the back.

temp4.jpg

Place the jumper/shunt on top of the pins just soldered. Position it over DAT and P5 or DAT and P1 based on whether you'd like to use P1 or P5 to communicate with the sensor.

temp5.jpg

Insert the 3-pin screw terminal with the hookup openings facing outward. Solder the two pins.

temp6.jpg

Cut a length of male headers 6 pins long and one 3 pins long. Insert into corresponding positions (on the bottom of the board) and solder each pin.

temp7.jpg

Tip: Inseting the headers into a breadboard and then placing the board on top can make this process easier.

Note: If you are using stackable headers, use them here instead of the standard male headers.

Using external 1-wire deivces:

External 1-wire devices can be added to the same 1-wire bus by connecting them to the 3 pin screw terminal - following the labeled pin outs on the board.

Sensors other than the DS18B20 will not be covered in the included examples, but many examples are readily available online.

Programming:

With the newest version of the Digispark Arduino IDE goto Examples→OneWire→Digispark Example

This example uses P5 by default - to use P1 change this line: OneWire ds(5); to OneWire ds(1);



Advanced Usage with the Oak: Temperature Sensing and the 1-Wire Bus

This tutorial demonstrates how to use the Oak to read temperature data from the DS18B20 1-Wire Digital Thermometer and publish that data to the Particle.io Dashboard log. It will also demonstrate how to use the deep sleep capability of the Oak platform to minimize power requirements (if desired) between temperature readings.

Concepts:

  • Connecting the 1-Wire DS18B20 digital thermometer to the Oak platform.
  • Reading DS18S20 temperature data.
  • Publishing temperature data to the Particle.io Dashboard log.
  • Deep sleep capability of the Oak to minimize power usage between readings.

What's required:

  1. Active Particle.io account https://www.particle.io/
  2. The Oak configured with the latest firmware
  3. The Oak claimed as a device on your Particle.io account
  4. DS18B20 1-Wire Digital Thermometer http://digistump.com/products/57
  5. 4.7K Ohm resister (3.3K and 2.2K can be substituted)
  6. OneWire library supporting the ESP8622

Connecting the DS18B20 device to the Oak

The 1-Wire DS18B20 digital thermometer can operate at either 3.3 volts or 5 volts. Since the Oak is a 3.3V device, we will use the Oak's 3.3V VCC pin to power the DS18B20. The DS18B20 device Data Input/Output lead (DQ) is pulled up to 3.3V using a 4.7K resister. While the DS18B20 does support a parasitic mode, this mode will not be demonstrated in this tutorial. Parasitic mode does not require the DS18B20 VDD lead to be connected to external power, but it does require a strong pullup on the 1-Wire bus. To learn more about operating the DS18B20 in parasitic mode, see the DS18B20 device data sheet (https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf).

getTemp()

Temperature is read using the getTemp() function from the standard DS18B20 example sketch. The only changes made to getTemp() are the conversion of temperature to Fahrenheit and modified return errors.

// OneWire DS18B20 temperature reader with conversion to degrees F
float getTemp(){
  // Returns the temperature from a single 1-Wire DS18S20 in DEG Fahrenheit

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      //Serial.println("No more addresses.");
      ds.reset_search();
      return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      //Serial.println("CRC is not valid!");
      return -2000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      //Serial.print("Device is not recognized");
      return -3000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  
  // Convert to degrees Fahrenheit
  TemperatureSum = TemperatureSum * 9 / 5 + 32;
  
  return TemperatureSum; 
} //END getTemp()

Publishing Temperature Data

The example sketch (see below) uses the Particle.io function Particle.publish() to post temperature readings to the particle.io Dashboard log. In order to do this you must have an active Particle.io account, a functional Oak running the latest firmware, and the Oak claimed as an active device on Particle.io.

The actual command used is: Particle.publish(“Temp (F)”, tempFstring, 60, PRIVATE); where “Temp(F)“ is the event name and tempFstring is the actual temperature reading in string format.

Particle.io Log Example:

Code Example:

     tempF = getTemp(); // get the temperature from the DS18B20 
     sprintf(tempFstring, "%d", (int)tempF); // Convert temp to string
     Particle.publish("Temp (F)", tempFstring, 60, PRIVATE);

For more information and examples on how to use Particle.publish and other Cloud functions, see https://docs.particle.io/reference/firmware/core/

Oak Deep Sleep function

The Oak is capable of entering a deep sleep to minimize power requirements. This may be desirable if, for example, your Oak will be battery powered. The sketch demonstrates this mode of operation but also supports operating in a non-sleeping mode.

To indicate to the sketch that sleep mode is desired, we use pin 5 (pulled HIGH) as essentially a “switch”. If pin 5 is read HIGH in setup(), the sketch operates in sleep mode. For this example it is considered to be the default operating mode. As such, pin 5 is defined as INPUT_PULLUP to facilitate this default mode of operation.

To facilitate the Oak's deep sleep and wake-up capabilities, you must also connect pin 10 (WAKE) to the reset pin (RST). This allows the Oak to trigger a RESET when a user specified sleep period has expired. While in sleep mode, the sketch enters and runs setup() each time a RESET occurs. This mode never enters loop().

If you prefer to operate the Oak in non-sleep mode, or if you want to prevent it from sleeping (when in sleep mode) to allow for new sketch uploads, pin 5 simple needs to be connected to ground (GND) thus pulling pin 5 LOW. When pin 5 is LOW the sketch will not sleep and will enter loop() where it remains until a power cycle or reset occurs. While in loop() temperature is repeatedly read from the DS18B20 device and published to Particle.io. A delay is used to take readings at a user defined interval. This mode consumes more power than it does when operating in a sleep mode.

If pin 5 is HIGH at power up (sleep mode), the sketch stays in sleep mode as long as pin 5 remains HIGH. If at anytime pin 5 is pulled LOW, the sketch will enter non-sleep mode after the next RESET. Once it enters loop() in non-sleep mode, it remains in loop() as long as the Oak is powered up regardless of the state of pin 5 (HIGH or LOW).

Deep sleep logic / function in setup():

void setup(void) {
...                                    ...
... preceding code removed for example ...
...                                    ...
...                                    ...
  // Check to see if sleep mode selected
  if (digitalRead(Sleep_pin) == HIGH) {
     Particle.publish("Oak Setup", "Entering Deep Sleep", 60, PRIVATE);
     ESP.deepSleep(sleepTimeS*1000000, WAKE_RF_DEFAULT); // Sleep
  }
  else {
     Particle.publish("Oak Setup","Entering Non Sleep Mode",60,PRIVATE);
  }
} //END setup()

Sleep Mode configuration:

  1. Oak powered through USB or VIN/GND
  2. The DS18B20 is powered by Oak's VCC (3.3V)
  3. Black wires - Ground connections
  4. Red wires - VCC 3.3V connections
  5. Yellow wire - pin 10 (WAKE) to RESET (RST)
  6. White wire – pin 2 to DS18B20 DQ (note: 4.7K pull-up resister)
  7. DS18B20 leads from left to right: (1) GND, (2) DQ, (3) Vdd

In Sleep Mode (after reading and publishing temperature data) the Oak enters deep sleep and delays for a user specified number of seconds. When sleep time has expired, a RESET is triggered via pin 10 (WAKE). Following a RESET, the sketch starts from the beginning and never enters loop().

Non-Sleep logic / function in loop():

void loop(void) {

  // We are here because Non Sleep Mode selected. 
  // Will remain in loop() until a reset or power cycle occurs.

  digitalWrite(OakLEDpin,HIGH); // Turn on onboard LED
  tempF = getTemp();
  sprintf(tempFstring, "%d", (int)tempF); // Convert to string

  // Check for errors (-1000 no device, -2000 CRC error, -3000 device not recognized)
  if(tempF <= -1000) {
    Particle.publish("DS18B20 Error", tempFstring, 60, PRIVATE);
  }
  else {
    Particle.publish("Temp (F)", tempFstring, 60, PRIVATE);
  }
  digitalWrite(OakLEDpin,LOW); // Turn off onboard LED

  // Delay before next read
  for(int i=0; i<sleepTimeS; i++) {
     delay(1000); // This delay * sleepTimes slows updates to particle.io log
  }
} //END loop()

Non-Sleep Mode configuration (or how to prevent Sleep Mode after RESET)

  1. Oak powered through USB or VIN/GND
  2. The DS18B20 is powered by Oak's VCC (3.3V)
  3. Black wires - Ground connection
  4. Red wires - VCC 3.3V
  5. Yellow wire - pin 10 (WAKE) to RESET (RST)
  6. White wire – pin 2 to DS18B20 DQ (note: 4.7K pull-up resister)
  7. Blue wire – pin 5 to GND (ground)
  8. DS18B20 leads from left to right: (1) GND, (2) DQ, (3) Vdd

Note the addition of the Blue wire connecting pin 5 to ground. In non-sleep mode the Oak enters setup() and reads pin 5 to determine the desired mode. Since pin 5 is pulled to ground (LOW) the sketch will enter loop() where it continually requests temperature data from the DS18B20 and publishes that date to the particle.io Dashboard log. Data is requested at intervals set by “sleepTimeS” which specifies the number of seconds to delay between readings.

If the Oak was started in Sleep Mode (pin 5 HIGH), it can be forced into non-sleep mode by simply connecting pin 5 to ground. At the next wake-up / reset, the sketch will see pin 5 high and enter Non-Sleep mode. This mode will allow new sketches to be uploaded.

Complete Sleep/Non-Sleep Sketch:

/*********************************************************************
  Digistump Oak example reading the DS18B20 digital thermometer with
  periodic calls to particle.Publish() to log temperature readings.
  Requires:
   * Particle.io account
   * Digistump Oak with current firmware and active on particle.io
   * DS18B20 OneWire temperature probe
   * 4.7K ohm resistor
   * OneWire library with ESP8266 support
  Does:
   * Periodic temperature reads - frequency controlled by sleepTimeS
   * Publishes readings to particle.io
   * Enters deep sleep to conserve power when Sleep_pin = HIGH 
     WARNING: Pin 10-WAKE must be connected to RESET pin for wakeup to occur
     else you will enter and endless sleep.
   * Watches Sleep_pin to determine whether or not to go into deep sleep. 
     HIGH = sleep, LOW enters loop() and non sleep mode
     NOTE: Non sleep mode allows for new sketch uploads
**********************************************************************
*/ 
#include <OneWire.h> // Using OneWire lib from the Oak package

int Sleep_pin = 5;   // (Configure as INPUT_PULLUP to default HIGH)
int DS18S20_Pin = 2; // DS18S20 Signal on pin 2
int OakLEDpin = 1;   // Oak onboard LED pin 1

int sleepTimeS = 30; // 30 seconds - adjust a needed

float tempF = 0;     // Temperature in degrees F
char tempFstring[6]; // Used to store a temperature value as a string

//Temperature chip i/o
OneWire ds(DS18S20_Pin);

void setup(void) {
  pinMode(Sleep_pin, INPUT_PULLUP); // Use pullup mode to default HIGH
  pinMode(OakLEDpin, OUTPUT);
 
  digitalWrite(OakLEDpin,HIGH); // Turn on onboard LED
  //Particle.publish("Oak Setup", "Started", 60, PRIVATE);
    
  if (!ds.reset()) {
     Particle.publish("Oak Setup", "DS18B20 not found", 60, PRIVATE);
  }
  else {
     Particle.publish("Oak Setup", "DS18B20 present", 60, PRIVATE);
     // Discard first reading (sometimes in error after power up)
     tempF = getTemp(); // Ignore this one
     delay(1000);
     tempF = getTemp(); // Use this reading 
     sprintf(tempFstring, "%d", (int)tempF); // Convert to string
     Particle.publish("Temp (F)", tempFstring, 60, PRIVATE);
  }
  //Particle.publish("Oak Setup", "Complete", 60, PRIVATE);
  
  delay(1000); // Pluse stretch onboard LED
  digitalWrite(OakLEDpin,LOW);

  // Check to see if sleep mode selected
  if (digitalRead(Sleep_pin) == HIGH) {
     Particle.publish("Oak Setup", "Entering Deep Sleep", 60, PRIVATE);
     ESP.deepSleep(sleepTimeS*1000000, WAKE_RF_DEFAULT); // Sleep
  }
  else {
     Particle.publish("Oak Setup","Entering Non Sleep Mode",60,PRIVATE);
  }
} //END setup()

void loop(void) {

  // We are here because Non Sleep Mode selected. 
  // Will remain in loop() until a reset or power cycle occurs.

  digitalWrite(OakLEDpin,HIGH); // Turn on onboard LED
  tempF = getTemp();
  sprintf(tempFstring, "%d", (int)tempF); // Convert to string

  // Check for errors (-1000 no device, -2000 CRC error, -3000 device not recognized)
  if(tempF <= -1000) {
    Particle.publish("DS18B20 Error", tempFstring, 60, PRIVATE);
  }
  else {
    Particle.publish("Temp (F)", tempFstring, 60, PRIVATE);
  }
  digitalWrite(OakLEDpin,LOW); // Turn off onboard LED

  // Delay before next read
  for(int i=0; i<sleepTimeS; i++) {
     delay(1000); // This delay * sleepTimes slows updates to particle.io log
  }
} //END loop()

// OneWire DS18B20 temperature reader with conversion to degrees F
float getTemp(){
  // Returns the temperature from a single 1-Wire DS18S20 in DEG Fahrenheit

  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      //Serial.println("No more addresses.");
      ds.reset_search();
      return -1000;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      //Serial.println("CRC is not valid!");
      return -2000;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      //Serial.print("Device is not recognized");
      return -3000;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end

  byte present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE); // Read Scratchpad

  
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  
  ds.reset_search();
  
  byte MSB = data[1];
  byte LSB = data[0];

  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  
  // Convert to degrees Fahrenheit
  TemperatureSum = TemperatureSum * 9 / 5 + 32;
  
  return TemperatureSum; 
} //END getTemp()

Conclusion

This tutorial demonstrated how to connect and read temperature data from the DS18B20 thermometer. It provided an example of how to publish that data to the Particle.io Dashboard log. And finally, it demonstrated the deep sleep capabilities of the Oak.

While the example may be more complicated that necessary, it does serve as a useful example for creating new sketches using the Oak platform. Please feel free to use and modify this example to create your own sketches on the Oak platform. We hope that you have found the tutorial to be both useful and informative.

Finally, there are waterproof versions of the DS18B20 device that can be found. So if you have a pool and would like to know what the water temperature is, why not put your Oak to good use and have it tell when “The water is fine.”

digispark/tutorials/temp.txt · Last modified: 2016/06/09 12:03 (external edit)