We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you've provided to them or that they've collected from your use of their services.

First steps and DS18B20

Nothing of the things described below would not be possible without the help of Pawel. Thanks to him the startup, plugging, installation and basic coding took us 1 evening. Seeing him I understood why “Windows limits efficiency”. When he sits at a linux console, he grows additional pair of hands with 8 fingers each. Pawel - many thanks to you!

The first impression after unpacking RPi is being surprised with its miniscule size. The computer is not much bigger than a credit card. That is really not much when you compare it with all the expectations ;)

In order to start working with the RPi you need to:

1. Plug in the SD card with an image of the operating system.  At  http://www.raspberrypi.org/downloads you will find the latest compilation of Raspbian (a system based on Debian).  The downloaded zip file needs to be unpacked and transferred to the SD cards with Win32DiskImager.  I used a 8GB put into a dedicated port of my laptop. It all took me 15 minutes.

Win32DiskImager

Source: https://wiki.ubuntu.com/Win32DiskImager

2. Plug in the Ethernet cable (connected on the other side to your switch)

3. Plug in the power cable (5V) ended with a microUSB plug.

All the above-presented steps are well described in the Getting Started instruction available at the web page of the Raspberry Foundation.

Since I do not have a TV or a computer screen with a HDMI input, I wanted to do everything through a console launched at my laptop with Windows 7. I needed to find the IP number of the RPi. After logging into my router (working under Tomato 1.27) I clicked the “Device List” command and found my Raspberry Pi with the IP equal to 192.168.1.164.

DeviceListTomato

Next, you need to run Putty, enter the found IP and change the Window, Translation, Remato character to UTF-8.  Its best to save the session for the future use.  After clicking Open the communication with your RPi should be launched.  The standard user is “pi”, the password “raspberry”. Here it is, blinking nicely at you!

PuttyScreen PuttyScreen2

To see the configuration menu, which you would normally see on the screen/TV (if such was plugged), type the command “sudo raspi-config”.

raspi-config

From the available configuration options it is enough to run the ‘expand_rootfs’ to extend the preloaded system image onto the whole SD and ‘change_timezone’ to correct the time settings.

One little comment to the ‘sudo’ command, which I understand as „execute the following as the super user”. It might sound like heresy but I consider the repetitive typing of ‘sudo’ to be a complete nonsense. Sudo here and sudo there, every tutorial repeats sudo. To be able to drop it you need to become the super user, which is possible in 2 steps:

"sudo passwd" - which should change the super user (root) password. For now enter a single space or a letter “x”.

"su" – mening – become the super user. Enter the password defined a second ago and here it is, you can forget the ‘sudo’. Just remember to change the password once you are done playing…

It is no time to connect the sensors. Adafruit presents a very detailed description on how it should be done. The pictures below should help to remove all doubts:

sensor connection1 sensor connection2 sensor connection3

In my case the connections were as follows:

IMAG0424

IMAG0427

 

You can see 4 DS18B20 sensors and – since we did not have a 4.7K resistor, 2 9K resistors were used.
It is time to write commands. In your putty enter the following:

modprobe w1-gpio

modprobe w1-therm

what should start the processes responsible for the 1-wire sensors. To check the if everything works type:

cd /sys/bus/w1/devices

ls

which changes the current directory to /sys/bus/w1/devices, where all the detected sensors and hubs are ‘mounted’ and lists the directory content.

I my case I saw:
root@raspberrypi:/sys/bus/w1/devices# ls
28-00000067a748 28-00000067ba5a 28-000002ff861f 28-000002fg961f w1_bus_master1

If you see the above on your RPi it means that your device is ready to read temperatures. In order to make the information accessible for the PLC with POST/GET queries it is necessary to run a www server with PHP. If you are interested in details, run a google search (Raspberry Pi webserver PHP). Those who like shortcuts should type:

apt-get install php5

Which should install and launch all that is needed. To check if you were successful, enter in the address bar of your browser the IP of the RPi and you should see the standard Apache message:

apacheWroks 

Any future content should be saved in the /var/www directory. For now place there 2 files:

1. test.php

<?php
require_once('OWireTherm.class.php');

error_reporting(E_ALL);
ini_set('display_errors', '1');

$SlaveFile = file("/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves");

if (!$SlaveFile) {
	echo "ERROR with slave-list file";
}
else {
	foreach ($SlaveFile as $line){
		$t1 = new OWireTherm(trim($line));
		if (($temp = $t1->readTemp()) !== false){
			echo $temp.";";
		} else {
			echo "ERROR";
		}
	}
}

2. OWireTherm.class.php

<?php
class OWireTherm {
	protected $id;

	public function __construct($id) {
		$this->id = $id;
	}

	protected function openFile() {
		return fopen("/sys/bus/w1/devices/$this->id/w1_slave", 'r');
	}

	public function readTemp() {
		$fp = $this->openFile();
		if (!$fp) {
			echo "Nie moge otworzyc pliku dla $this->id";
		return false;
	}

	$buff = fgets($fp);
	if (!preg_match('/YES$/', $buff)) {
		echo "Bledna suma CRC podczas odczytu";
		return false;
	}

	$buff = fgets($fp);
	if (!preg_match('/t=(-?[0-9]+)$/', $buff, $matches)) {
		echo "Niepoprawny odczyt temperatury ($buff)"; 
		return false;
	}

	return $matches[1]/1000;
	}
}

If both the files (test.php i OWireTherm.class.php) are placed in /var/www entering in your browser the following: http://192.168.1.164/test.php should let you see the temperatures of all your sensors separated by a colan (i.e. 14.875;14.75;14.437;).... Now we will reach out for the data from the PLC side.

I added 2 libraries to my CoDeSys project: WagoLibHttp_02.lib and WagoLibBase64_01.lib. Both can be downloaded from the WAGO web page. There are also interesting expamples of using the WagoLibHttp, which in details show what (and how much) is possible.

I created a new process in my program (Resources->Task configuration, right-click in the new window - > Append Task). It received a low priority and a “freewheeling” type. Then I added a program call of HttpComm(), which is in 95% based on Example 1 coming with the WagoLibHttp_02.lib. Here is the code:

- in variable definitions:

PROGRAM HttpComm
VAR
	xDoIt : BOOL; (*to initiate communication*)
	wState : WORD; (*storing the communication status*)
	
	(* HTTP_GET *)
	oHttpGet: HTTP_GET; (*the main function block*)
	sUrl : STRING(250):= '/test.php'; 
	xHttpSend : BOOL;
	diError : DINT;
	sStatus : STRING;
	abResponse : ARRAY [0..MAX_RECEIVE_TCP_CLIENT] OF BYTE;
	uiResponse : UINT;
	
	(* Parsing response data *)
	sTemperature : STRING;
	Temperatues : ARRAY [0..15] OF REAL; (*for storing received temperatures*)
	
	(* Helpers *)
	i : INT;
	TempCount : INT;
	iHelp : INT;
	abHelp : ARRAY [0..180] OF BYTE;
	psHelp : POINTER TO STRING(180);
END_VAR

- in the program:

oHttpGet(sServerName:= '192.168.1.164',
	wServerPort:= 80,
	pabUrlData:= ADR(sUrl),
	uiUrlLength:= LEN(sUrl),
	tTimeOut:= t#3s,
	xSend:= xHttpSend,
	diError=> diError,
	sStatus=> sStatus,
	abContentData=> abResponse,
	uiContentLength=> uiResponse);

CASE wState OF
	0: (* IDLE - wait for something to do *)
		IF xDoIt THEN
			xHttpSend := TRUE; (* Send HTTP-GET request *)
			wState := 10;
		END_IF

	10: (* Wait for HTTP-GET response data *)
		IF NOT xHttpSend THEN
			IF diError = 0 THEN
			(* Success *)
				wState := 20; (* Parse response data *)
			ELSE
			(* Error *)
				wState := 999; (* Try again next time *)
			END_IF
		END_IF

	20: (* Parse response data for 'Temperature:'*)
		i:=0; (*Counter of fields in adResponse array*)
		TempCount:=0; (*Counter of found temperatures->fields in Temperatures array*)
		iHelp:=0; (*counter for supportive*)

		WHILE (abResponse[i]>0) DO (*meaning as long as there is data in the adResponse table*)
			IF (abResponse[i]<>59) THEN (*meaning if response char is not = „;”*)
				abHelp[iHelp]:=abResponse[i];
				iHelp:=iHelp+1;
			ELSE (*here is the conversion of data stored in 
				abHelp array to STRING and then to REAL*)
				psHelp := ADR(abHelp);
				sTemperature := psHelp^;
				Temperatues[TempCount]:=STRING_TO_REAL(sTemperature);
				TempCount:=TempCount+1;
				iHelp:=0;
			END_IF
			i:=i+1;
		END_WHILE

		wState := 999;

	999: (* *)
		xDoIt := FALSE;
		wState := 0;
END_CASE

A simple visualization with a button and 4 text fields can be used to test the program:

PLC VISU done

Communication between PLC and RPi and reading temperatures at the presented configuration and with the shown scripts is by all means imperfect. The Apache server at its default configuration is slow and might need to be replaced by another, lighter solution. The scripts – both on the side of the server as well as the PLC – are lacking any proper error handling. Additionally, what might even be most important, connecting the 1-wire sensor as presented in this article is not feasible in case of an extensive network – many cables arranged in a star, placed close to 230VC wires. It is just a proof of a concept to show if at all those things can be done.

Since this simple test ended with a success, the following actions are needed:

  • building of a RPi extension on the basis of DS2482, which should enable servicing of a large network with many sensors (plus additionally adding a short-circuit protection),
  • improving the configuration of the RPi and all the installed services,
  • improvement of all the scripts to make them safe for the PLC so that everything would function irrespectively of what is received by the GET request.