Message Boards Message Boards


Trying to connect temperature sensor DS18B20

Posted 10 years ago
2 Replies
8 Total Likes
I really don't want to buy an expensive and boring weather station, so I decided to connect DS18B20 that costs $6 in a local hardware store.

Combining this and this tutorials I was managed to get the temperature using bash and save it to file. The script looks like this

root@raspbian:/t# cat gettemp
temp=$(cat /sys/bus/w1/devices/28-*/w1_slave | grep  -E -o ".{0,0}t=.{0,5}" | cut -c 3-)
temp=$(echo "scale=3; $temp/1000" | bc)
echo $temp > /t/curtemp

According th the idea, Wolfram code to acquire the temperature should look like this

<< "/t/curtemp"
And it works... But the problem is that ti works extremely slow... 

It takes about one second to acquire the temperature from bash and about 20 seconds to do it from Wolfram. The other interesting thing is that the more the delay between executions of the cell, the less the duration of measurement. The first execution lasts about 2 seconds. And it seems like the standby time before execution can compensate the execution time. If standby time was 10 seconds, the execution lasts 10 seconds. 
Very interesting yet very useless feature... My aim is a dynamic plot of temperature, updating every second, buy it seems like I'm following the wrong path... 
I need to read bash output, it can be faster, but I don't know how... 
There's one thing that can probably help
In[40]:= FindDevices[]
Out[40]= {DeviceObject[{"DefaultShellCommandDemo", 3}], DeviceObject[{
  "DelayedRandomSignalDemo", 3}], DeviceObject[{
  "GPIO", 4}], DeviceObject[{"RandomSignalDemo", 1}], DeviceObject[{
  "RaspberryPiWeatherStation", 3}], DeviceObject[{
  "RaspiCam", 3}], DeviceObject[{
  "ShellCommandDemo", 1}], DeviceObject[{
  "TinkerForgeWeatherStation", 3}]}
I like the DeviceObject[{"ShellCommandDemo", 1}], but attemps to read from it failed. 
Any ideas?

--- UPD ---

For now, I've made a data-collecting script, that collects data with maximum speed and stores it in Mathematica-friendly file.
 trap ctrl_c INT
 function ctrl_c() {
     echo Please, the last one...
         temp=$(cat /sys/bus/w1/devices/28-*/w1_slave | grep  -E -o ".{0,0}t=.{0,5}" | cut -c 3-)
         temp=$(echo "scale=3; $temp/1000" | bc)
         now=$(date +%s.%3N)
        rel=$(echo "scale=3; $now-$start" | bc)
        echo \{$rel,$temp\}
        echo \{$rel,$temp\}\}\; >> $file
    echo Print[\"data is stored in TempData variavle\"] >> $file
    exit $?

echo \(\* $(date) \*\) > $file
echo TempData={ >> $file
start=$(date +%s.%3N)
for (( ; ; ))
    temp=$(cat /sys/bus/w1/devices/28-*/w1_slave | grep  -E -o ".{0,0}t=.{0,5}" | cut -c 3-)
    temp=$(echo "scale=3; $temp/1000" | bc)
    now=$(date +%s.%3N)
    rel=$(echo "scale=3; $now-$start" | bc)
    echo \{$rel,$temp\},
    echo \{$rel,$temp\}, >> $file
The output can be used, for example, for plot

In[40]:= << "/t/templog"
Out[40]= data is stored in TempData variavle

POSTED BY: Himura Kazuto
2 Replies
This is a solution that only requires the Wolfram language.

Setup the temperature probe .
sudo mathematica

 devicefolder := First[FileNames["28-*", {"/sys/bus/w1/devices"}]]
 Run["sudo modprobe w1-gpio"]
 Run["sudo modprobe w1-therm"]
devicefile = FileNameJoin[{devicefolder, "w1_slave"}]

ReadList is used to read in the content of the device file  and StringCases extracts the temperature value.
[read := ReadList[devicefile, String]
{"86 01 4b 46 7f ff 0a 10 5e : crc=5e YES", "86 01 4b 46 7f ff 0a 10 \
5e t=24375"}
temperature[devicefile_String] := Flatten[StringCases[ReadList[devicefile, String],
    "t=" ~~ x___ :> ToExpression[x]/1000., 1]][[1]]

Store thedata

Touch the temperature sensor for a time, and then remove finger.
POSTED BY: Emerson Willard
I tried to use your method, Thanks for your reply, it was extremely useful!
So that's what I have
 In[39]:= devicefolder =
 First[FileNames["28-*", {"/sys/bus/w1/devices"}]]
 Out[39]= "/sys/bus/w1/devices/28-000004ed47ba"
 In[40]:= devicefile = FileNameJoin[{devicefolder, "w1_slave"}]
 Out[40]= "/sys/bus/w1/devices/28-000004ed47ba/w1_slave"
 read := ReadList[devicefile, String]
Out[42]= {"b9 01 4b 46 7f ff 07 10 d1 : crc=d1 YES", "b9 01 4b 46 7f ff 07 10 d1 t=27562"}

gettemp := ToExpression[StringCases[read, "t=" ~~ x__ :> x][[2]][[1]]]/1000.
Out[44]= 27.562

start = AbsoluteTime[];
data = {};
collecttemp = CreateScheduledTask[AppendTo[data, {AbsoluteTime[] - start, gettemp}], {1, 60}];
Dynamic[ListLinePlot[data, PlotMarkers -> Automatic]]
In[80]:= Length[data]
Out[80]:= 30
So I have a huge data lost. And I have to press "Continue waiting" button twice a mesurement when it asks me to disable Dynamic Updating. 

And I have Mathematica crashed at the end. 

Also there is one irritating thing: I can execute all this commands only with 20-seconds delay. If I don't make it, execution stucks for the rest of the time. May it be Raspbian problens?

--- UPD ---
Reinstalling Raspbian from image and overclocking to Medium helps nothing. I'm trying to avoid scheduling to fetch data on maximum speed:
start = AbsoluteTime[]; data = {};
Do[AppendTo[data, {AbsoluteTime[] - start, gettemp}], {60}]
Dynamic[ListLinePlot[data, PlotMarkers -> Automatic]]

but I still have to push "don't disable dynamics" and the gaps occurs before "Continue Waiting" click
POSTED BY: Himura Kazuto
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract