Translate

Tuesday, September 9, 2014

Raspberry Pi - reading a DS18S20

One of the most common things for any embedded device is the capability to read temperatures.

Raspberry Pi doesn't has any ADC by default, so unless to hook one, the common way to read temperatures is via digital chips, like the DS 18S20.

The DS 18S20 is a 1-wire protocol chip-set from Dallas.
Fortunately somebody already wrote a bit banging support for the 1Wire protocol used by this chip-set , so it is only matter to connect the chip and enable some kernel modules to do so, at least in Raspbian (Wheezi).

I was able to duplicate the results described in the article RaspberryPI DS1820 without problems.
The example is based on a Perl script using the kernel services.

Here some my extra notes (I don't understand why so many people stopped to draw standard electronic schematics in favor of "cartoon" schematics).

Basic schematic to connect a DS1820 to the Raspberry Pi Gpio port.


Raspberry Pi GPIO pinout

DS1820 pinout







By default (as described in the article) the kernel module capable to handle the 1-Wire is disabled.
As first thing is necessary to enable it.




Open a terminal, then :
  • sudo modprobe wire
  • sudo modprobe w1-gpio  
  • sudo modprobe w1-therm

After that, to test if the DS1820 is ready and connected correctly :
  • cat /sys/bus/w1/devices/w1_bus_master1/w1_master_slave_count
The result should be the number of DS1820 connected.
To retrieve the serial number of the chip-sets :
  • cat /sys/bus/w1/devices/w1_bus_master1/w1_master_slaves
This is the Perl script used to read a sensor, copied from the article of David Mills,  RaspberryPI DS1820 (read that article for more details and how to read two sensors).

#!/usr/bin/perl
$mods = `cat /proc/modules`; 
if ($mods =~ /w1_gpio/ && $mods =~ /w1_therm/) 
   print "w1 modules already loaded \n"; 
else  
   print "loading w1 modules \n"; 
   $mod_gpio = `sudo modprobe w1-gpio`; 
   $mod_them = `sudo modprobe w1-therm`; 

$sensor_temp = `cat /sys/bus/w1/devices/10-*/w1_slave 2>&1`; 
if ($sensor_temp !~ /No such file or directory/) 
   if ($sensor_temp !~ /NO/) 
   { 
      $sensor_temp =~ /t=(\d+)/i; 
      $tempreature = (($1/1000)-6); # My sensor seems to read about 6 degrees high, so quick fudge to fix value  
      print "rPI temp = $tempreature\n";  
      exit; 
   } 
   die "Error locating sensor file or sensor CRC was invalid";  
}