[Home]Plotting DS18S20 Temperature Readings Using SVG

HomePage | RecentChanges | Preferences | My Website home page

Raspberry Pi and DS18S20 temperature measurement

This page records some work on using DS18S20 with Raspberry Pi and plotting using AWK, SVG and JavaScript.

Using the kernal extensions ( see links ) the Raspberry Pi can use the "one wire" interface to read the Dallas 18S20 temperature chips.

I use a shell script to poll the chips and append the readings to a file of JavaScript function calls and other text files.

An awk script is used to extract the text and populate the gbF() function calls. If written to a file, the file can be included into an SVG file.

Using JavaScript in an SVG file, I plot the data as a simple graph. The SVG file does a location.reload() to update.

This is run in the Midori 0.4.3 web browser that renders the SVG file.

example: http://www.dougrice.plus.com/raspberryPi_ds1820/loopDS18S20reportSVG.svg

files: http://www.dougrice.plus.com/raspberryPi_ds1820/

Raspberry Pi and DS18S20

One wire - DS18S20 reader

Used GPIO4 pin 7 - middle pin. 3v3 to power gnd to gnd

		/ 3v3  	
DS18S20	- top (|- buss --GPIO4--[4k7]--/
	  	\ gnd

Web pages to help:-

http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware

http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/ds18b20

Shell Script - loop.sh

The script below starts the kernel module for "OneWire" and loops polling all the devices onthe Bus.

I have 4 DS18S20, which I read and set userfield1,userfield2,userfield3,userfield4 parameters in gbF() guestbook Function. This is appended to gbookFtemp.js on the desk top. The date is set to when I read the devices.

#! /bin/bash
#	
#  Shell Script to poll temperature chips 
#  usage:	 bash loop.sh
#
# http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware
#
echo "---------------------"
ls /sys/bus
echo "---------------------"
sudo modprobe w1-gpio
sudo modprobe w1-therm

echo "---------------------"
ls /sys/bus
echo "---------------------"

while [[ 1 ]]
do
  echo "========" 		    > ~/Desktop/tmp.txt
  date 				   >> ~/Desktop/tmp.txt
  cat /sys/bus/w1/devices/10-*/name >> ~/Desktop/tmp.txt
  cat /sys/bus/w1/devices/10-*/w1* >> ~/Desktop/tmp.txt
  echo " "			   >> ~/Desktop/tmp.txt
  #
  # use AWK to extract the temperatures. appends gbF() to gbookFtemp.js
  #
  cat ~/Desktop/tmp.txt
  awk -f loop.awk ~/Desktop/tmp.txt 

  cat ~/Desktop/tmp.txt >> ~/Desktop/loop_log.txt
  sleep 3 
  
done  

Awk Script loop.awk

This awk script extracts the temperature and puts the results into the javascript include file.

#
#
# loop.awk
#
# usage: 	awk -f loop.awk loop_log.txt
#
#
# pull out the temperature from loop_log.txt written by loop.sh 
# Appends to "gbookFtemp.js"
#
#
#//gbF( name,email,postedOn,IPaddress,userfield1,userfield2,userfield3,userfield4,comments){


BEGIN {
  FS="="

  # zero the temperatures
  ln[1]=0
  ln[2]=0
  ln[3]=0
  ln[4]=0
  # print "" > "gbookFtemp.js"
  notFirst = 0
}

/====/{
  print $0
  getline
  print $0
  
  lnp=1
  cnt +=1
  if ( notFirst ){
    print "gbF( 'awk','t@pi','" lastDate " ','127.0.0.1'," ln[1] "," ln[2] "," ln[3] "," ln[4] ",'comments');" >> "gbookFtemp.js"
  }
  # prepare for next readings
  notFirst = 1
  ln[1]=0
  ln[2]=0
  ln[3]=0
  ln[4]=0
  lastDate = $0
}

/t=/{
  # found a line with a temperature
  ln[lnp] = ($NF/1000) 
  lnp ++
}

END {
  cnt +=1
  print "gbF( 'awk','t@pi','" lastDate " ','127.0.0.1'," ln[1] "," ln[2] "," ln[3] "," ln[4] ",'comments');" >> "gbookFtemp.js"
}

some "gbookFtemp.js"

The temperatures are saved wrapped in a function call.
gbF( 'awk','t@pi','Sun Feb  9 10:30:47 UTC 2014 ','127.0.0.1',17.375,18,17.5,17.312,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:30:53 UTC 2014 ','127.0.0.1',17.312,18,17.5,17.312,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:00 UTC 2014 ','127.0.0.1',17.375,19.187,17.562,17.375,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:06 UTC 2014 ','127.0.0.1',17.375,19.187,17.562,17.437,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:13 UTC 2014 ','127.0.0.1',17.437,23.25,17.562,17.5,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:20 UTC 2014 ','127.0.0.1',17.437,24.375,17.625,17.562,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:27 UTC 2014 ','127.0.0.1',17.5,25.375,17.687,17.562,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:33 UTC 2014 ','127.0.0.1',17.5,26.062,17.687,17.562,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:40 UTC 2014 ','127.0.0.1',17.5,26.687,17.687,17.625,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:46 UTC 2014 ','127.0.0.1',17.562,27.562,17.75,17.625,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:53 UTC 2014 ','127.0.0.1',17.562,28.437,17.75,17.687,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:31:59 UTC 2014 ','127.0.0.1',17.625,28.937,17.75,17.687,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:32:06 UTC 2014 ','127.0.0.1',17.625,-1.25,17.812,17.687,'comments');
gbF( 'awk','t@pi','Sun Feb  9 10:32:13 UTC 2014 ','127.0.0.1',17.625,29.5,17.812,17.687,'comments');

SVG - loopDS18S20reportSVG.svg

The SVG below includes the readings in gbookFtemp.js and plots them.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="600" height="600" >
<script type="text/ecmascript"><![CDATA[
//
// Include javascript guestbook and process it. Plots Temperature measurements from DS18S20.
// 

var count=1
var opStr = ""

var linePointsStr2 = ""
var linePointsStr3 = ""
var linePointsStr4 = ""
var linePointsStr5 = ""
var xIndex = 50
var tempStr =""

//
// This function is called once per guestbook entry stored in gbookFtemp.js
// There is a lot of junk in there, which needs to be ignored.
//

function gbF( name,email,postedOn,IPaddress,userfield1,userfield2,userfield3,userfield4,comments){
//  var yvalue = 200 + Math.random()*32
  scale = 10.0
  var yvalue = userfield1*1.0
  if ( yvalue != -1.25) {    linePointsStr2 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }  
  var yvalue = userfield2*1.0
  if ( yvalue != -1.25) {    linePointsStr3 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }  
  var yvalue = userfield3*1.0
  if ( yvalue != -1.25) {    linePointsStr4 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }
  var yvalue =  userfield4*1.0
  if ( yvalue != -1.25) {    linePointsStr5 += xIndex + "," + ( 400 - yvalue*scale ) + " "  }
  xIndex += 1
  tempStr = "last temperatures: " +userfield1 +","+userfield2+","+userfield3+","+userfield4
  
}

function plotMeasured() {
  //
  // Guestbox processed
  //
  obj2=document.getElementById("dhr2");
  obj2.setAttributeNS(null,"points", linePointsStr2  );

  obj3=document.getElementById("dhr3");
  obj3.setAttributeNS(null,"points", linePointsStr3  );

  obj4=document.getElementById("dhr4");
  obj4.setAttributeNS(null,"points", linePointsStr4  );

  obj5=document.getElementById("dhr5");
  obj5.setAttributeNS(null,"points", linePointsStr5  );
}

]]></script>

// window

<defs>
  <!-- Set up clip path to constrain graphs to plot window -->
  <clipPath id = "clip1">
    <path d = "M 48 53 L 548 53  L 548 420 L 48 420 L 48 53 "/>
  </clipPath>
  <radialGradient id = "g1" cx = "50%" cy = "50%" r = "50%" fx = "25%" fy = "25%">
    <stop stop-color = "#ffff66" offset = "0%"/>
    <stop stop-color = "#FFFFCC" offset = "50%"/>
    <stop stop-color = "white" offset = "100%"/>
  </radialGradient>
  <linearGradient id = "g2" x1 = "10%" y1 = "10%" x2 = "90%" y2 = "90%">
    <stop stop-color = "white" offset = "0%"/>
    <stop stop-color = "#7fff66" offset = "25%"/>
    <stop stop-color = "white" offset = "100%"/>
  </linearGradient>
</defs>

// outer square
<rect x="0" y="0" width="600" height="590" fill = "url(#g2)" /> 

//
// plot canvas
//
<rect x="48" y="53" width="500" height="500" stroke="blue" fill = "url(#g1)"  />

//
// define 4 polylines. javascript will change points later.
//

<polyline id="dhr2" fill="none" stroke="blue"   stroke-width="2" points="" clip-path = "url(#clip1)" />
<polyline id="dhr3" fill="none" stroke="lime"   stroke-width="2" points="" clip-path = "url(#clip1)" />
<polyline id="dhr4" fill="none" stroke="red"    stroke-width="2" points="" clip-path = "url(#clip1)" />
<polyline id="dhr5" fill="none" stroke="orange" stroke-width="2" points="" clip-path = "url(#clip1)" />

//
// minor axis lines
//
<line x1="52" y1="100" x2="545" y2="100" style="stroke:rgb(99,99,99);stroke-width:1" />
<line x1="52" y1="200" x2="545" y2="200" style="stroke:rgb(99,99,99);stroke-width:1" />
<line x1="52" y1="300" x2="545" y2="300" style="stroke:rgb(99,99,99);stroke-width:1" />
<line x1="52" y1="400" x2="545" y2="400" style="stroke:rgb(10,10,10);stroke-width:2" />
<line x1="52" y1="500" x2="545" y2="500" style="stroke:rgb(99,99,99);stroke-width:1" />


<text  x="260" y="20"  text-anchor="middle" font-family="Arial,Helvetica" font-size="14px" font-weight="bold" >Temperature Plot using SVG, run: bash loop.sh</text>
<text  x="260" y="40"  text-anchor="middle" font-family="Arial,Helvetica" font-size="14px" id="svg_21"        >data from gbookFtemp.js - DS18S20</text>
<text  x="260" y="580" text-anchor="middle" font-family="Arial,Helvetica" font-size="14px" font-weight="bold" >measurement</text>

<text transform="rotate(270,20,300)" x="20" y="300" font-family="Arial,Helvetica" text-anchor="middle" font-size="14px" pointer-events="none"  font-weight="bold" >Temperature Centigrade</text>

<text  x="30" y="500"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >-10 C </text>
<text  x="30" y="400"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >0 C </text>
<text  x="30" y="300"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >10 C </text>
<text  x="30" y="200"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >20 C </text>
<text  x="30" y="100"  text-anchor="middle" font-family="Arial,Helvetica" font-size="8px" >30 C </text>

<script type="text/ecmascript" xlink:href="gbookFtemp.js" />
//
// include data from guestbook and process.
//


//
// update polyline points 
//
<script type="text/ecmascript"><![CDATA[

 obj6=document.getElementById("svg_21");
 obj6.textContent = tempStr
 
 plotMeasured() 

 window.setInterval("location.reload();",6000);

]]></script>

</svg>


HomePage | RecentChanges | Preferences | My Website home page
This page is read-only | View other revisions
Last edited February 15, 2014 10:50 am by dougrice.plus.com
Search: