DS18B20

Everything about programming the platform and using the Waspmote API
libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: DS18B20

Post by libelium-dev » Thu Sep 25, 2014 2:15 pm

Herrero and mfv,

would you mind to describe your hardware connections? are u using the pull up resistor?

can you ensure good electrical connections?

mfv
Posts: 24
Joined: Tue Jul 15, 2014 1:32 pm

Re: DS18B20

Post by mfv » Thu Sep 25, 2014 2:33 pm

Hi!

We're using the same setup as Jareth (http://i61.tinypic.com/2n8q9w1.jpg). All connections are good and we're observing the same problem at multiple waspmotes/tmp sensors after upgrading from api v09 to api v11. Have you made any changes in the API that may causes this?

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: DS18B20

Post by libelium-dev » Fri Sep 26, 2014 1:01 pm

Dear all,

we made some test and we discovered the source of this issue. It is just a timing issue, coming from the delay microseconds function.

We adjusted that function since API V010 because it was an old function inherited from arduino.

If you just replace this function on the wiring.c file on the Waspmote core, the sensor will be read as expected.

See the ring function extracted from API V009 below:
/* Delay for the given number of microseconds.  Assumes a 16 MHz clock. 
 * Disables interrupts, which will disrupt the millis() function if used
 * too frequently. */
void delayMicroseconds(unsigned int us)
{
  uint8_t oldSREG;

  // calling avrlib's delay_us() function with low values (e.g. 1 or
  // 2 microseconds) gives delays longer than desired.
  //delay_us(us);

#if F_CPU >= 16000000L
  // for the 16 MHz clock on most Arduino boards

  // for a one-microsecond delay, simply return. the overhead
  // of the function call yields a delay of approximately 1 1/8 us.
  if (--us == 0)
    return;

  // the following loop takes a quarter of a microsecond (4 cycles)
  // per iteration, so execute it four times for each microsecond of
  // delay requested.
  us <<= 2;

  // account for the time taken in the preceeding commands.
  us -= 2;
#else
  // for the 8 MHz internal clock on the ATmega168

  // for a one- or two-microsecond delay, simply return. the overhead of
  // the function calls takes more than two microseconds. can't just
  // subtract two, since us is unsigned; we'd overflow.
  if (--us == 0)
    return;
  if (--us == 0)
    return;

  // the following loop takes half of a microsecond (4 cycles)
  // per iteration, so execute it twice for each microsecond of
  // delay requested.
  us <<= 1;

  // partially compensate for the time taken by the preceeding commands.
  // we can't subtract any more than this or we'd overflow w/ small delays.
  us--;
#endif

  // disable interrupts, otherwise the timer 0 overflow interrupt that
  // tracks milliseconds will make us delay longer than we want.
  oldSREG = SREG;
  cli();

  // busy wait
  __asm__ __volatile__ (
  "1: sbiw %0,1" "\n\t" // 2 cycles
"brne 1b" :
  "=w" (us) :
  "0" (us) // 2 cycles
    );

  // reenable interrupts.
  SREG = oldSREG;
}

Let us know your progress.

We will fix it for next API version

mfv
Posts: 24
Joined: Tue Jul 15, 2014 1:32 pm

Re: DS18B20

Post by mfv » Fri Sep 26, 2014 1:15 pm

Thanks!
We'll do the implementation and let you know our results next week.

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: DS18B20

Post by libelium-dev » Fri Sep 26, 2014 1:20 pm

just to clarify,

if you use the example code of next link, connecting the sensor as follows

http://www.libelium.com/development/was ... g-ds18b20/

GND - GND
Vcc - 3V3 sensor power
OUT - DIGITAL8

with the 4K7 pull up resistor between output and VCC

and replacing the definition of delaymicroseconds on wiring.c, then it would work.
/*
 *  ------ [BS_05] Waspmote reading DS1820 temperature sensor --------
 *
 *  Explanation: This example shows how to read the DS1820 temperature sensor
 *
 *  Copyright (C) 2012 Libelium Comunicaciones Distribuidas S.L. 
 *  http://www.libelium.com 
 *  
 *  This program is free software: you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation, either version 3 of the License, or 
 *  (at your option) any later version. 
 *  
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details. 
 *  
 *  You should have received a copy of the GNU General Public License 
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 *  
 *  Version:           0.1 
 *  Design:            David Gascón 
 *  Implementation:    Marcos Yarza
 */

// Variables

float temp = 0;
 
 
void setup()
{
  // Init USB
  USB.ON();
  
}

void loop()
{
  // Reading the DS1820 temperature sensor connected to DIGITAL8
  temp = Utils.readTempDS1820(DIGITAL8);
  USB.print(F("DS1820 Temperature: "));
  USB.print(temp);
  USB.println(F(" degrees"));
  delay(1000);
}

mfv
Posts: 24
Joined: Tue Jul 15, 2014 1:32 pm

Re: DS18B20

Post by mfv » Fri Sep 26, 2014 2:35 pm

We have now tested to replace the delayMicroseconds function and it solved our problem.
Thanks again!

Herrero
Posts: 11
Joined: Fri Sep 19, 2014 4:14 pm

Re: DS18B20

Post by Herrero » Fri Sep 26, 2014 3:00 pm

Now, it works fine. Thank you

libelium-dev
Posts: 27967
Joined: Mon Sep 28, 2009 1:06 pm

Re: DS18B20

Post by libelium-dev » Mon Sep 29, 2014 10:45 am

glad to hear that.

subrilog
Posts: 2
Joined: Tue Mar 22, 2016 8:33 pm

Re: DS18B20

Post by subrilog » Tue Mar 22, 2016 9:08 pm

I observed a similar readout problem with two out of three DS18B20 I bought. They are all connected by 2m of cable to three different digital inputs with a 4.7k pull-up each and are read using calls to Utils.readTempDS1820(...); I got all of them working reliably at the same time by changing the timing in the function delayMicroseconds() in wiring.c to:

Code: Select all

// Delay for the given number of microseconds.  Assumes a 16 MHz clock. 
// Disables interrupts, which will disrupt the millis() function if used
// too frequently. 
// This version is updated according to 
// https://www.libelium.com/forum/viewtopic.php?f=28&t=12684&p=41895&hilit=ds18b20#p41895
// and extra empirically modified, see -----/+++++ comments 

void delayMicroseconds(unsigned int us)
{
  uint8_t oldSREG;

  // calling avrlib's delay_us() function with low values (e.g. 1 or
  // 2 microseconds) gives delays longer than desired.
  //delay_us(us);

#if F_CPU >= 16000000L
  // for the 16 MHz clock on most Arduino boards

  // for a one-microsecond delay, simply return. the overhead
  // of the function call yields a delay of approximately 1 1/8 us.
  if (--us == 0)
    return;

  // the following loop takes a quarter of a microsecond (4 cycles)
  // per iteration, so execute it four times for each microsecond of
  // delay requested.
  us <<= 2;

  // account for the time taken in the preceeding commands.
  us -= 2;   
  #else
  // for the 8 MHz internal clock on the ATmega168

  // for a one- or two-microsecond delay, simply return. the overhead of
  // the function calls takes more than two microseconds. can't just
  // subtract two, since us is unsigned; we'd overflow.
  if (--us == 0)
    return;
  if (--us == 0)
    return;

  // the following loop takes half of a microsecond (4 cycles)
  // per iteration, so execute it twice for each microsecond of
  // delay requested.
  // us <<= 1;     // -----
  us <<= 2;        // +++++
  
  // partially compensate for the time taken by the preceeding commands.
  // we can't subtract any more than this or we'd overflow w/ small delays.
  //  us--;        // -----
  if (--us == 0)   // +++++
    return;        // +++++
  if (--us == 0)   // +++++
    return;        // +++++
  #endif

  // disable interrupts, otherwise the timer 0 overflow interrupt that
  // tracks milliseconds will make us delay longer than we want.
  oldSREG = SREG;
  cli();

  // busy wait
  __asm__ __volatile__ (
  "1: sbiw %0,1" "\n\t" // 2 cycles
  "brne 1b" :
  "=w" (us) :
  "0" (us) // 2 cycles
    );

  // reenable interrupts.
  SREG = oldSREG;
}

I am not sure if this has side effects if other sensors than DS18B20 are connected, but it works for my configuration.

jhh
Posts: 9
Joined: Tue Nov 24, 2015 2:49 pm

Re: DS18B20

Post by jhh » Mon Jul 18, 2016 4:07 pm

I also had problems with the DS18B20 sensor, showing -1000 for temperatures below ~21 deg C. I made the changes in "wiring.c" suggested above, and now i seams to work fine. I'm using the DS18B20 plug&sense sensor and an agriculture sensor board.

Please confirm if this will have any unexpected side effects.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest